1use crate::error::{Error, Result};
25use crate::expressions::*;
26use crate::tokens::{Span, Token, TokenType, Tokenizer, TokenizerConfig};
27use std::collections::HashSet;
28use std::sync::LazyLock;
29
30pub static NO_PAREN_FUNCTIONS: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
38 let mut set = HashSet::new();
39 set.insert(TokenType::CurrentDate);
40 set.insert(TokenType::CurrentDateTime);
41 set.insert(TokenType::CurrentTime);
42 set.insert(TokenType::CurrentTimestamp);
43 set.insert(TokenType::CurrentUser);
44 set.insert(TokenType::CurrentRole);
45 set.insert(TokenType::CurrentSchema);
46 set.insert(TokenType::CurrentCatalog);
47 set.insert(TokenType::LocalTime);
49 set.insert(TokenType::LocalTimestamp);
50 set.insert(TokenType::SysTimestamp);
51 set.insert(TokenType::UtcDate);
52 set.insert(TokenType::UtcTime);
53 set.insert(TokenType::UtcTimestamp);
54 set.insert(TokenType::SessionUser);
55 set
56});
57
58pub static NO_PAREN_FUNCTION_NAMES: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
61 crate::function_registry::NO_PAREN_FUNCTION_NAME_LIST
62 .iter()
63 .copied()
64 .collect()
65});
66
67pub static STRUCT_TYPE_TOKENS: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
70 let mut set = HashSet::new();
71 set.insert(TokenType::File);
72 set.insert(TokenType::Nested);
73 set.insert(TokenType::Object);
74 set.insert(TokenType::Struct);
75 set
77});
78
79pub static NESTED_TYPE_TOKENS: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
82 let mut set = HashSet::new();
83 set.insert(TokenType::Array);
84 set.insert(TokenType::List);
85 set.insert(TokenType::LowCardinality);
86 set.insert(TokenType::Map);
87 set.insert(TokenType::Nullable);
88 set.insert(TokenType::Range);
89 set.insert(TokenType::File);
91 set.insert(TokenType::Nested);
92 set.insert(TokenType::Object);
93 set.insert(TokenType::Struct);
94 set
95});
96
97fn convert_name_is_known_custom(name: &str) -> bool {
101 matches!(
104 name,
105 "DATETIME2"
106 | "DATETIMEOFFSET"
107 | "SMALLDATETIME"
108 | "DATETIME"
109 | "NVARCHAR2"
110 | "VARCHAR2"
111 | "NCHAR"
112 | "MONEY"
113 | "SMALLMONEY"
114 | "TINYINT"
115 | "MEDIUMINT"
116 | "BYTEINT"
117 | "SUPER"
118 | "HLLSKETCH"
119 | "TIMETZ"
120 | "TIMESTAMPTZ"
121 | "SYSNAME"
122 | "XML"
123 | "SQL_VARIANT"
124 | "HIERARCHYID"
125 | "ROWVERSION"
126 | "IMAGE"
127 | "CURSOR"
128 | "TABLE"
129 | "UNIQUEIDENTIFIER"
130 | "VARIANT"
131 | "OBJECT"
132 | "NUMBER"
133 | "BINARY_FLOAT"
134 | "BINARY_DOUBLE"
135 | "CLOB"
136 | "NCLOB"
137 | "RAW"
138 | "LONG"
139 | "MEDIUMTEXT"
140 | "LONGTEXT"
141 | "MEDIUMBLOB"
142 | "LONGBLOB"
143 | "TINYTEXT"
144 | "TINYBLOB"
145 | "INT2"
146 | "INT4"
147 | "INT8"
148 | "FLOAT4"
149 | "FLOAT8"
150 | "SERIAL"
151 | "BIGSERIAL"
152 | "SMALLSERIAL"
153 | "YEAR"
154 | "FIXED"
155 | "SIGNED"
156 | "UNSIGNED"
157 | "ROW"
158 | "BIT"
159 | "BOOLEAN"
160 | "BOOL"
161 | "TEXT"
162 | "STRING"
163 | "NTEXT"
164 | "INT128"
165 | "INT256"
166 | "UINT8"
167 | "UINT16"
168 | "UINT32"
169 | "UINT64"
170 | "UINT128"
171 | "UINT256"
172 | "FLOAT32"
173 | "FLOAT64"
174 | "LOWCARDINALITY"
175 | "NULLABLE"
176 | "IPADDRESS"
177 | "IPV4"
178 | "IPV6"
179 | "AGGREGATEFUNCTION"
180 | "SIMPLEAGGREGATEFUNCTION"
181 | "FIXEDSTRING"
182 | "RING"
183 | "NESTED"
184 )
185}
186
187pub static ENUM_TYPE_TOKENS: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
190 let mut set = HashSet::new();
191 set.insert(TokenType::Dynamic);
192 set.insert(TokenType::Enum);
193 set.insert(TokenType::Enum8);
194 set.insert(TokenType::Enum16);
195 set
196});
197
198pub static AGGREGATE_TYPE_TOKENS: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
201 let mut set = HashSet::new();
202 set.insert(TokenType::AggregateFunction);
203 set.insert(TokenType::SimpleAggregateFunction);
204 set
205});
206
207pub static TYPE_TOKENS: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
210 let mut set = HashSet::new();
211 set.insert(TokenType::Bit);
213 set.insert(TokenType::Boolean);
214 set.insert(TokenType::TinyInt);
216 set.insert(TokenType::UTinyInt);
217 set.insert(TokenType::SmallInt);
218 set.insert(TokenType::USmallInt);
219 set.insert(TokenType::MediumInt);
220 set.insert(TokenType::UMediumInt);
221 set.insert(TokenType::Int);
222 set.insert(TokenType::UInt);
223 set.insert(TokenType::BigInt);
224 set.insert(TokenType::UBigInt);
225 set.insert(TokenType::BigNum);
226 set.insert(TokenType::Int128);
227 set.insert(TokenType::UInt128);
228 set.insert(TokenType::Int256);
229 set.insert(TokenType::UInt256);
230 set.insert(TokenType::Float);
232 set.insert(TokenType::Double);
233 set.insert(TokenType::UDouble);
234 set.insert(TokenType::Decimal);
236 set.insert(TokenType::Decimal32);
237 set.insert(TokenType::Decimal64);
238 set.insert(TokenType::Decimal128);
239 set.insert(TokenType::Decimal256);
240 set.insert(TokenType::DecFloat);
241 set.insert(TokenType::UDecimal);
242 set.insert(TokenType::BigDecimal);
243 set.insert(TokenType::Char);
245 set.insert(TokenType::NChar);
246 set.insert(TokenType::VarChar);
247 set.insert(TokenType::NVarChar);
248 set.insert(TokenType::BpChar);
249 set.insert(TokenType::Text);
250 set.insert(TokenType::MediumText);
251 set.insert(TokenType::LongText);
252 set.insert(TokenType::TinyText);
253 set.insert(TokenType::Name);
254 set.insert(TokenType::FixedString);
255 set.insert(TokenType::Binary);
257 set.insert(TokenType::VarBinary);
258 set.insert(TokenType::Blob);
259 set.insert(TokenType::MediumBlob);
260 set.insert(TokenType::LongBlob);
261 set.insert(TokenType::TinyBlob);
262 set.insert(TokenType::Date);
264 set.insert(TokenType::Date32);
265 set.insert(TokenType::Time);
266 set.insert(TokenType::TimeTz);
267 set.insert(TokenType::TimeNs);
268 set.insert(TokenType::Timestamp);
269 set.insert(TokenType::TimestampTz);
270 set.insert(TokenType::TimestampLtz);
271 set.insert(TokenType::TimestampNtz);
272 set.insert(TokenType::TimestampS);
273 set.insert(TokenType::TimestampMs);
274 set.insert(TokenType::TimestampNs);
275 set.insert(TokenType::DateTime);
276 set.insert(TokenType::DateTime2);
277 set.insert(TokenType::DateTime64);
278 set.insert(TokenType::SmallDateTime);
279 set.insert(TokenType::Year);
280 set.insert(TokenType::Interval);
281 set.insert(TokenType::Json);
283 set.insert(TokenType::JsonB);
284 set.insert(TokenType::Uuid);
286 set.insert(TokenType::Geography);
288 set.insert(TokenType::GeographyPoint);
289 set.insert(TokenType::Geometry);
290 set.insert(TokenType::Point);
291 set.insert(TokenType::Ring);
292 set.insert(TokenType::LineString);
293 set.insert(TokenType::MultiLineString);
294 set.insert(TokenType::Polygon);
295 set.insert(TokenType::MultiPolygon);
296 set.insert(TokenType::Int4Range);
298 set.insert(TokenType::Int4MultiRange);
299 set.insert(TokenType::Int8Range);
300 set.insert(TokenType::Int8MultiRange);
301 set.insert(TokenType::NumRange);
302 set.insert(TokenType::NumMultiRange);
303 set.insert(TokenType::TsRange);
304 set.insert(TokenType::TsMultiRange);
305 set.insert(TokenType::TsTzRange);
306 set.insert(TokenType::TsTzMultiRange);
307 set.insert(TokenType::DateRange);
308 set.insert(TokenType::DateMultiRange);
309 set.insert(TokenType::HllSketch);
311 set.insert(TokenType::HStore);
312 set.insert(TokenType::Serial);
313 set.insert(TokenType::SmallSerial);
314 set.insert(TokenType::BigSerial);
315 set.insert(TokenType::Xml);
317 set.insert(TokenType::Super);
319 set.insert(TokenType::PseudoType);
320 set.insert(TokenType::UserDefined);
321 set.insert(TokenType::Money);
322 set.insert(TokenType::SmallMoney);
323 set.insert(TokenType::RowVersion);
324 set.insert(TokenType::Image);
325 set.insert(TokenType::Variant);
326 set.insert(TokenType::Object);
327 set.insert(TokenType::ObjectIdentifier);
328 set.insert(TokenType::Inet);
329 set.insert(TokenType::IpAddress);
330 set.insert(TokenType::IpPrefix);
331 set.insert(TokenType::Ipv4);
332 set.insert(TokenType::Ipv6);
333 set.insert(TokenType::Unknown);
334 set.insert(TokenType::Null);
335 set.insert(TokenType::TDigest);
336 set.insert(TokenType::Vector);
337 set.insert(TokenType::Void);
338 set.insert(TokenType::Dynamic);
340 set.insert(TokenType::Enum);
341 set.insert(TokenType::Enum8);
342 set.insert(TokenType::Enum16);
343 set.insert(TokenType::Array);
345 set.insert(TokenType::List);
346 set.insert(TokenType::LowCardinality);
347 set.insert(TokenType::Map);
348 set.insert(TokenType::Nullable);
349 set.insert(TokenType::Range);
350 set.insert(TokenType::File);
351 set.insert(TokenType::Nested);
352 set.insert(TokenType::Struct);
353 set.insert(TokenType::AggregateFunction);
355 set.insert(TokenType::SimpleAggregateFunction);
356 set
357});
358
359pub static SIGNED_TO_UNSIGNED_TYPE_TOKEN: LazyLock<
362 std::collections::HashMap<TokenType, TokenType>,
363> = LazyLock::new(|| {
364 let mut map = std::collections::HashMap::new();
365 map.insert(TokenType::BigInt, TokenType::UBigInt);
366 map.insert(TokenType::Int, TokenType::UInt);
367 map.insert(TokenType::MediumInt, TokenType::UMediumInt);
368 map.insert(TokenType::SmallInt, TokenType::USmallInt);
369 map.insert(TokenType::TinyInt, TokenType::UTinyInt);
370 map.insert(TokenType::Decimal, TokenType::UDecimal);
371 map.insert(TokenType::Double, TokenType::UDouble);
372 map
373});
374
375pub static SUBQUERY_PREDICATES: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
378 let mut set = HashSet::new();
379 set.insert(TokenType::Any);
380 set.insert(TokenType::All);
381 set.insert(TokenType::Exists);
382 set.insert(TokenType::Some);
383 set
384});
385
386pub static DB_CREATABLES: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
389 let mut set = HashSet::new();
390 set.insert(TokenType::Database);
391 set.insert(TokenType::Dictionary);
392 set.insert(TokenType::FileFormat);
393 set.insert(TokenType::Model);
394 set.insert(TokenType::Namespace);
395 set.insert(TokenType::Schema);
396 set.insert(TokenType::SemanticView);
397 set.insert(TokenType::Sequence);
398 set.insert(TokenType::Sink);
399 set.insert(TokenType::Source);
400 set.insert(TokenType::Stage);
401 set.insert(TokenType::StorageIntegration);
402 set.insert(TokenType::Streamlit);
403 set.insert(TokenType::Table);
404 set.insert(TokenType::Tag);
405 set.insert(TokenType::View);
406 set.insert(TokenType::Warehouse);
407 set
408});
409
410pub static RESERVED_TOKENS: LazyLock<HashSet<TokenType>> = LazyLock::new(|| {
413 let mut set = HashSet::new();
414 set.insert(TokenType::Select);
416 set.insert(TokenType::From);
417 set.insert(TokenType::Where);
418 set.insert(TokenType::GroupBy);
419 set.insert(TokenType::OrderBy);
420 set.insert(TokenType::Having);
421 set.insert(TokenType::Limit);
422 set.insert(TokenType::Offset);
423 set.insert(TokenType::Union);
424 set.insert(TokenType::Intersect);
425 set.insert(TokenType::Except);
426 set.insert(TokenType::Join);
427 set.insert(TokenType::On);
428 set.insert(TokenType::With);
429 set.insert(TokenType::Into);
430 set.insert(TokenType::Values);
431 set.insert(TokenType::Set);
432 set.insert(TokenType::Create);
434 set.insert(TokenType::Drop);
435 set.insert(TokenType::Alter);
436 set.insert(TokenType::Truncate);
437 set.insert(TokenType::Insert);
439 set.insert(TokenType::Update);
440 set.insert(TokenType::Delete);
441 set.insert(TokenType::Merge);
442 set.insert(TokenType::Case);
444 set.insert(TokenType::When);
445 set.insert(TokenType::Then);
446 set.insert(TokenType::Else);
447 set.insert(TokenType::End);
448 set.insert(TokenType::And);
450 set.insert(TokenType::Or);
451 set.insert(TokenType::Not);
452 set.insert(TokenType::In);
454 set.insert(TokenType::Is);
455 set.insert(TokenType::Between);
456 set.insert(TokenType::Like);
457 set.insert(TokenType::ILike);
458 set.insert(TokenType::Exists);
459 set.insert(TokenType::Null);
461 set.insert(TokenType::True);
462 set.insert(TokenType::False);
463 set.insert(TokenType::LParen);
465 set.insert(TokenType::RParen);
466 set.insert(TokenType::LBracket);
467 set.insert(TokenType::RBracket);
468 set.insert(TokenType::LBrace);
469 set.insert(TokenType::RBrace);
470 set.insert(TokenType::Comma);
471 set.insert(TokenType::Semicolon);
472 set.insert(TokenType::Star);
473 set.insert(TokenType::Eq);
474 set.insert(TokenType::Neq);
475 set.insert(TokenType::Lt);
476 set.insert(TokenType::Lte);
477 set.insert(TokenType::Gt);
478 set.insert(TokenType::Gte);
479 set
480});
481
482pub struct Parser {
507 tokens: Vec<Token>,
508 current: usize,
509 config: ParserConfig,
510 source: Option<String>,
512 pending_leading_comments: Vec<String>,
516}
517
518#[derive(Debug, Clone, Default)]
525pub struct ParserConfig {
526 pub allow_trailing_commas: bool,
528 pub dialect: Option<crate::dialects::DialectType>,
530}
531
532impl Parser {
533 pub fn new(tokens: Vec<Token>) -> Self {
537 Self {
538 tokens,
539 current: 0,
540 config: ParserConfig::default(),
541 source: None,
542 pending_leading_comments: Vec::new(),
543 }
544 }
545
546 pub fn with_config(tokens: Vec<Token>, config: ParserConfig) -> Self {
548 Self {
549 tokens,
550 current: 0,
551 config,
552 source: None,
553 pending_leading_comments: Vec::new(),
554 }
555 }
556
557 pub fn with_source(tokens: Vec<Token>, config: ParserConfig, source: String) -> Self {
562 Self {
563 tokens,
564 current: 0,
565 config,
566 source: Some(source),
567 pending_leading_comments: Vec::new(),
568 }
569 }
570
571 pub fn parse_sql(sql: &str) -> Result<Vec<Expression>> {
588 let tokenizer = Tokenizer::default();
589 let tokens = tokenizer.tokenize(sql)?;
590 let mut parser = Parser::with_source(tokens, ParserConfig::default(), sql.to_string());
591 parser.parse()
592 }
593
594 pub fn parse_sql_with_config(
599 sql: &str,
600 tokenizer_config: TokenizerConfig,
601 ) -> Result<Vec<Expression>> {
602 let tokenizer = Tokenizer::new(tokenizer_config);
603 let tokens = tokenizer.tokenize(sql)?;
604 let mut parser = Parser::with_source(tokens, ParserConfig::default(), sql.to_string());
605 parser.parse()
606 }
607
608 pub fn parse(&mut self) -> Result<Vec<Expression>> {
613 let mut statements = Vec::new();
614
615 while !self.is_at_end() {
616 let mut stmt = self.parse_statement()?;
617
618 if self.check(TokenType::Semicolon) {
621 let semi_comments = self.current_leading_comments().to_vec();
622 if !semi_comments.is_empty() {
623 stmt = Expression::Annotated(Box::new(Annotated {
624 this: stmt,
625 trailing_comments: semi_comments,
626 }));
627 }
628 }
629
630 if matches!(
632 self.config.dialect,
633 Some(crate::dialects::DialectType::ClickHouse)
634 ) && self.check(TokenType::Settings)
635 {
636 self.skip(); let _ = self.parse_settings_property()?;
638 }
639
640 if matches!(
642 self.config.dialect,
643 Some(crate::dialects::DialectType::ClickHouse)
644 ) && self.check(TokenType::Format)
645 {
646 self.skip(); if self.check(TokenType::Null) {
649 self.skip();
650 } else if self.is_identifier_token() || self.check_keyword() {
651 self.skip();
652 }
653 }
654
655 if matches!(
657 self.config.dialect,
658 Some(crate::dialects::DialectType::ClickHouse)
659 ) && self.check_identifier("PARALLEL")
660 && self.check_next(TokenType::With)
661 {
662 self.skip(); self.skip(); statements.push(stmt);
665 continue;
666 }
667
668 if !self.is_at_end() && !self.check(TokenType::Semicolon) {
672 if matches!(
673 self.config.dialect,
674 Some(crate::dialects::DialectType::ClickHouse)
675 ) {
676 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
680 self.skip();
681 }
682 } else {
683 return Err(self.parse_error("Invalid expression / Unexpected token"));
684 }
685 }
686
687 while self.match_token(TokenType::Semicolon) {}
689
690 statements.push(stmt);
691 }
692
693 Ok(statements)
694 }
695
696 pub fn parse_statement(&mut self) -> Result<Expression> {
702 while self.match_token(TokenType::Semicolon) {}
704
705 if self.is_at_end() {
706 return Err(self.parse_error("Unexpected end of input"));
707 }
708
709 match self.peek().token_type {
710 TokenType::Hint => {
712 let hint_token = self.advance();
713 let hint_text = hint_token.text.clone();
714 let comment = format!("/* + {} */", hint_text.trim());
716
717 let mut stmt = self.parse_statement()?;
719
720 match &mut stmt {
722 Expression::Select(select) => {
723 select.leading_comments.insert(0, comment);
724 }
725 Expression::Insert(insert) => {
726 insert.leading_comments.insert(0, comment);
727 }
728 Expression::Update(update) => {
729 update.leading_comments.insert(0, comment);
730 }
731 Expression::Delete(delete) => {
732 delete.leading_comments.insert(0, comment);
733 }
734 Expression::CreateTable(ct) => {
735 ct.leading_comments.insert(0, comment);
736 }
737 _ => {
738 }
741 }
742 Ok(stmt)
743 }
744 TokenType::Select => self.parse_select(),
745 TokenType::With => self.parse_with(),
746 TokenType::Insert => self.parse_insert(),
747 TokenType::Replace => self.parse_replace(),
748 TokenType::Update => self.parse_update(),
749 TokenType::Delete => self.parse_delete(),
750 TokenType::Create => self.parse_create(),
751 TokenType::Drop => self.parse_drop(),
752 TokenType::Alter => self.parse_alter(),
753 TokenType::Truncate => {
754 if self.check_next(TokenType::LParen) {
757 self.parse_expression()
759 } else {
760 self.parse_truncate()
761 }
762 }
763 TokenType::Values => {
764 if self.check_next(TokenType::LParen)
766 || self.check_next(TokenType::Number)
767 || self.check_next(TokenType::String)
768 {
769 self.parse_values()
770 } else {
771 self.parse_expression()
773 }
774 }
775 TokenType::Use => self.parse_use(),
776 TokenType::Cache => self.parse_cache(),
777 TokenType::Uncache => self.parse_uncache(),
778 TokenType::Refresh => {
779 self.skip(); self.parse_refresh()?
781 .ok_or_else(|| self.parse_error("Failed to parse REFRESH statement"))
782 }
783 TokenType::Load => self.parse_load_data(),
784 TokenType::Grant => self.parse_grant(),
785 TokenType::Revoke => self.parse_revoke(),
786 TokenType::Comment => self.parse_comment(),
787 TokenType::Merge => {
788 self.skip(); self.parse_merge()?
790 .ok_or_else(|| self.parse_error("Failed to parse MERGE statement"))
791 }
792 TokenType::Set => self.parse_set(),
793 TokenType::Database
794 if matches!(
795 self.config.dialect,
796 Some(crate::dialects::DialectType::Teradata)
797 ) =>
798 {
799 self.skip(); let name = self.expect_identifier_or_keyword()?;
802 Ok(Expression::Use(Box::new(Use {
803 kind: None,
804 this: Identifier::new(name),
805 })))
806 }
807 TokenType::Lock
808 if matches!(
809 self.config.dialect,
810 Some(crate::dialects::DialectType::Teradata)
811 ) =>
812 {
813 self.parse_locking_statement()
814 }
815 TokenType::Command => {
816 self.skip(); self.parse_command()?
818 .ok_or_else(|| self.parse_error("Failed to parse COMMAND statement"))
819 }
820 TokenType::Rename
821 if matches!(
822 self.config.dialect,
823 Some(crate::dialects::DialectType::Teradata)
824 | Some(crate::dialects::DialectType::ClickHouse)
825 ) =>
826 {
827 self.skip(); self.parse_command()?
829 .ok_or_else(|| self.parse_error("Failed to parse RENAME statement"))
830 }
831 TokenType::Pragma => self.parse_pragma(),
832 TokenType::Rollback => self.parse_rollback(),
833 TokenType::Commit => self.parse_commit(),
834 TokenType::Begin => self.parse_transaction(),
835 TokenType::End => {
836 if matches!(
839 self.config.dialect,
840 Some(crate::dialects::DialectType::PostgreSQL)
841 ) {
842 self.parse_end_transaction()
843 } else {
844 self.skip(); Ok(Expression::Command(Box::new(Command {
846 this: "END".to_string(),
847 })))
848 }
849 }
850 TokenType::Start => self.parse_start_transaction(),
851 TokenType::Describe | TokenType::Desc => self.parse_describe(),
852 TokenType::Show => self.parse_show(),
853 TokenType::Copy => self.parse_copy(),
854 TokenType::Put => self.parse_put(),
855 TokenType::Kill
856 if matches!(
857 self.config.dialect,
858 Some(crate::dialects::DialectType::ClickHouse)
859 ) =>
860 {
861 self.skip(); self.parse_command()?
863 .ok_or_else(|| self.parse_error("Failed to parse KILL statement"))
864 }
865 TokenType::Kill => self.parse_kill(),
866 TokenType::Execute => {
867 if matches!(
869 self.config.dialect,
870 Some(crate::dialects::DialectType::ClickHouse)
871 ) {
872 self.skip(); self.parse_command()?
874 .ok_or_else(|| self.parse_error("Failed to parse EXECUTE statement"))
875 } else {
876 self.parse_execute()
877 }
878 }
879 TokenType::Declare => {
880 self.skip(); self.parse_declare()?
882 .ok_or_else(|| self.parse_error("Failed to parse DECLARE statement"))
883 }
884 TokenType::Get
887 if self.check_next(TokenType::DAt) || !self.check_next(TokenType::LParen) =>
888 {
889 self.parse_get_command()
890 }
891 TokenType::Var
892 if self.peek().text.eq_ignore_ascii_case("RM")
893 || self.peek().text.eq_ignore_ascii_case("REMOVE") =>
894 {
895 self.parse_rm_command()
896 }
897 TokenType::Var if self.peek().text.eq_ignore_ascii_case("CALL") => self.parse_call(),
898 TokenType::Var
899 if self.peek().text.eq_ignore_ascii_case("EXCHANGE")
900 && matches!(
901 self.config.dialect,
902 Some(crate::dialects::DialectType::ClickHouse)
903 ) =>
904 {
905 self.skip(); self.parse_command()?
907 .ok_or_else(|| self.parse_error("Failed to parse EXCHANGE statement"))
908 }
909 TokenType::Var if self.peek().text.eq_ignore_ascii_case("EXPLAIN") => {
911 self.parse_describe()
912 }
913 TokenType::Var
915 if self.peek().text.eq_ignore_ascii_case("LOCK")
916 || self.peek().text.eq_ignore_ascii_case("UNLOCK") =>
917 {
918 self.skip(); self.parse_command()?
920 .ok_or_else(|| self.parse_error("Failed to parse LOCK/UNLOCK statement"))
921 }
922 TokenType::Var if self.peek().text.eq_ignore_ascii_case("ANALYZE") => {
923 self.skip(); self.parse_analyze()?
925 .ok_or_else(|| self.parse_error("Failed to parse ANALYZE statement"))
926 }
927 TokenType::Var if self.peek().text.eq_ignore_ascii_case("PRINT") => {
929 self.skip(); self.parse_command()?
931 .ok_or_else(|| self.parse_error("Failed to parse PRINT statement"))
932 }
933 TokenType::Var if self.peek().text.eq_ignore_ascii_case("WAITFOR") => {
935 self.skip(); self.parse_command()?
937 .ok_or_else(|| self.parse_error("Failed to parse WAITFOR statement"))
938 }
939 TokenType::Var if self.peek().text.eq_ignore_ascii_case("BULK") => {
941 self.skip(); self.parse_command()?
943 .ok_or_else(|| self.parse_error("Failed to parse BULK INSERT statement"))
944 }
945 TokenType::Check
947 if matches!(
948 self.config.dialect,
949 Some(crate::dialects::DialectType::ClickHouse)
950 ) =>
951 {
952 self.skip(); self.parse_command()?
954 .ok_or_else(|| self.parse_error("Failed to parse CHECK statement"))
955 }
956 TokenType::Settings
958 if matches!(
959 self.config.dialect,
960 Some(crate::dialects::DialectType::ClickHouse)
961 ) =>
962 {
963 self.skip(); self.parse_command()?
965 .ok_or_else(|| self.parse_error("Failed to parse SETTINGS statement"))
966 }
967 TokenType::System
969 if matches!(
970 self.config.dialect,
971 Some(crate::dialects::DialectType::ClickHouse)
972 ) =>
973 {
974 self.skip(); self.parse_command()?
976 .ok_or_else(|| self.parse_error("Failed to parse SYSTEM statement"))
977 }
978 TokenType::Var
980 if self.peek().text.eq_ignore_ascii_case("RENAME")
981 && matches!(
982 self.config.dialect,
983 Some(crate::dialects::DialectType::ClickHouse)
984 ) =>
985 {
986 self.skip(); self.parse_command()?
988 .ok_or_else(|| self.parse_error("Failed to parse RENAME statement"))
989 }
990 TokenType::Var
993 if self.peek().text.eq_ignore_ascii_case("OPTIMIZE")
994 && matches!(
995 self.config.dialect,
996 Some(crate::dialects::DialectType::ClickHouse)
997 | Some(crate::dialects::DialectType::MySQL)
998 | Some(crate::dialects::DialectType::SingleStore)
999 | Some(crate::dialects::DialectType::Doris)
1000 | Some(crate::dialects::DialectType::StarRocks)
1001 ) =>
1002 {
1003 self.skip(); self.parse_command()?
1005 .ok_or_else(|| self.parse_error("Failed to parse OPTIMIZE statement"))
1006 }
1007 TokenType::Exists
1009 if matches!(
1010 self.config.dialect,
1011 Some(crate::dialects::DialectType::ClickHouse)
1012 ) && !self.check_next(TokenType::LParen) =>
1013 {
1014 self.skip(); self.parse_command()?
1016 .ok_or_else(|| self.parse_error("Failed to parse EXISTS statement"))
1017 }
1018 TokenType::Var
1020 if self.peek().text.eq_ignore_ascii_case("EXISTS")
1021 && matches!(
1022 self.config.dialect,
1023 Some(crate::dialects::DialectType::ClickHouse)
1024 ) =>
1025 {
1026 self.skip(); self.parse_command()?
1028 .ok_or_else(|| self.parse_error("Failed to parse EXISTS statement"))
1029 }
1030 TokenType::Var if self.peek().text.eq_ignore_ascii_case("ATTACH") => {
1032 self.skip(); if matches!(
1034 self.config.dialect,
1035 Some(crate::dialects::DialectType::ClickHouse)
1036 ) {
1037 self.parse_command()?
1038 .ok_or_else(|| self.parse_error("Failed to parse ATTACH statement"))
1039 } else {
1040 self.parse_attach_detach(true)
1041 }
1042 }
1043 TokenType::Var
1045 if self.peek().text.eq_ignore_ascii_case("UNDROP")
1046 && matches!(
1047 self.config.dialect,
1048 Some(crate::dialects::DialectType::ClickHouse)
1049 | Some(crate::dialects::DialectType::Snowflake)
1050 ) =>
1051 {
1052 self.skip(); self.parse_command()?
1054 .ok_or_else(|| self.parse_error("Failed to parse UNDROP statement"))
1055 }
1056 TokenType::Var
1058 if self.peek().text.eq_ignore_ascii_case("DETACH")
1059 && matches!(
1060 self.config.dialect,
1061 Some(crate::dialects::DialectType::ClickHouse)
1062 ) =>
1063 {
1064 self.skip(); self.parse_command()?
1066 .ok_or_else(|| self.parse_error("Failed to parse DETACH statement"))
1067 }
1068 TokenType::Var if self.peek().text.eq_ignore_ascii_case("DETACH") => {
1070 self.skip(); self.parse_attach_detach(false)
1072 }
1073 TokenType::Var if self.peek().text.eq_ignore_ascii_case("INSTALL") => {
1075 self.skip(); self.parse_install(false)
1077 }
1078 TokenType::Var if self.peek().text.eq_ignore_ascii_case("FORCE") => {
1080 self.skip(); self.parse_force_statement()
1082 }
1083 TokenType::Var if self.peek().text.eq_ignore_ascii_case("SUMMARIZE") => {
1085 self.skip(); self.parse_summarize_statement()
1087 }
1088 TokenType::Var if self.peek().text.eq_ignore_ascii_case("RESET") => {
1090 self.skip(); self.parse_as_command()?
1092 .ok_or_else(|| self.parse_error("Failed to parse RESET statement"))
1093 }
1094 TokenType::Pivot => {
1096 self.skip(); self.parse_simplified_pivot(false)?
1098 .ok_or_else(|| self.parse_error("Failed to parse PIVOT statement"))
1099 }
1100 TokenType::Unpivot => {
1101 self.skip(); self.parse_simplified_pivot(true)?
1103 .ok_or_else(|| self.parse_error("Failed to parse UNPIVOT statement"))
1104 }
1105 TokenType::Var if self.peek().text.eq_ignore_ascii_case("PIVOT_WIDER") => {
1107 self.skip(); self.parse_simplified_pivot(false)?
1109 .ok_or_else(|| self.parse_error("Failed to parse PIVOT_WIDER statement"))
1110 }
1111 TokenType::For => {
1113 self.skip(); self.parse_for_in()
1115 }
1116 TokenType::Var if self.peek().text.eq_ignore_ascii_case("LOOP") => {
1118 self.skip(); self.parse_command()?
1120 .ok_or_else(|| self.parse_error("Failed to parse LOOP statement"))
1121 }
1122 TokenType::Var if self.peek().text.eq_ignore_ascii_case("REPEAT") => {
1123 self.skip(); self.parse_command()?
1125 .ok_or_else(|| self.parse_error("Failed to parse REPEAT statement"))
1126 }
1127 TokenType::Var if self.peek().text.eq_ignore_ascii_case("WHILE") => {
1128 self.skip(); self.parse_command()?
1130 .ok_or_else(|| self.parse_error("Failed to parse WHILE statement"))
1131 }
1132 TokenType::Var if self.peek().text.eq_ignore_ascii_case("UNLOAD") => {
1134 self.parse_unload()
1135 }
1136 TokenType::Using => self.parse_using_external_function(),
1138 TokenType::Var if self.peek().text.eq_ignore_ascii_case("EXPORT") => {
1140 self.parse_export_data()
1141 }
1142 TokenType::Var if self.peek().text.eq_ignore_ascii_case("DEALLOCATE") => {
1144 self.parse_deallocate_prepare()
1145 }
1146 TokenType::From => self.parse_from_first_query(),
1148 TokenType::LParen => {
1149 let next_is_explain = self.current + 1 < self.tokens.len()
1152 && self.tokens[self.current + 1].token_type == TokenType::Var
1153 && self.tokens[self.current + 1]
1154 .text
1155 .eq_ignore_ascii_case("EXPLAIN");
1156 if self.check_next(TokenType::Select)
1157 || self.check_next(TokenType::With)
1158 || self.check_next(TokenType::Pivot)
1159 || self.check_next(TokenType::Unpivot)
1160 || self.check_next(TokenType::From)
1161 || next_is_explain
1162 {
1163 self.skip(); let inner = self.parse_statement()?;
1166 self.expect(TokenType::RParen)?;
1167 let subquery = Expression::Subquery(Box::new(Subquery {
1169 this: inner,
1170 alias: None,
1171 column_aliases: Vec::new(),
1172 order_by: None,
1173 limit: None,
1174 offset: None,
1175 distribute_by: None,
1176 sort_by: None,
1177 cluster_by: None,
1178 lateral: false,
1179 modifiers_inside: false,
1180 trailing_comments: Vec::new(),
1181 inferred_type: None,
1182 }));
1183 let result = self.parse_set_operation(subquery)?;
1185 self.parse_query_modifiers(result)
1187 } else if self.check_next(TokenType::LParen) {
1188 self.skip(); let inner = self.parse_statement()?;
1193 let result = self.parse_set_operation(inner)?;
1195 self.expect(TokenType::RParen)?;
1196 let subquery = Expression::Subquery(Box::new(Subquery {
1197 this: result,
1198 alias: None,
1199 column_aliases: Vec::new(),
1200 order_by: None,
1201 limit: None,
1202 offset: None,
1203 distribute_by: None,
1204 sort_by: None,
1205 cluster_by: None,
1206 lateral: false,
1207 modifiers_inside: false,
1208 trailing_comments: Vec::new(),
1209 inferred_type: None,
1210 }));
1211 let result = self.parse_set_operation(subquery)?;
1213 let pre_alias_comments = self.previous_trailing_comments().to_vec();
1214 if self.match_token(TokenType::As) {
1215 let alias = self.expect_identifier_or_keyword_with_quoted()?;
1216 let trailing_comments = self.previous_trailing_comments().to_vec();
1217 Ok(Expression::Alias(Box::new(Alias {
1218 this: result,
1219 alias,
1220 column_aliases: Vec::new(),
1221 pre_alias_comments,
1222 trailing_comments,
1223 inferred_type: None,
1224 })))
1225 } else {
1226 self.parse_query_modifiers(result)
1229 }
1230 } else {
1231 let expr = self.parse_expression()?;
1234 let pre_alias_comments = self.previous_trailing_comments().to_vec();
1235 if self.match_token(TokenType::As) {
1236 if self.match_token(TokenType::LParen) {
1238 let mut column_aliases = Vec::new();
1239 loop {
1240 let col_alias = self.expect_identifier_or_keyword_with_quoted()?;
1241 column_aliases.push(col_alias);
1242 if !self.match_token(TokenType::Comma) {
1243 break;
1244 }
1245 }
1246 self.expect(TokenType::RParen)?;
1247 let trailing_comments = self.previous_trailing_comments().to_vec();
1248 Ok(Expression::Alias(Box::new(Alias {
1249 this: expr,
1250 alias: Identifier::empty(),
1251 column_aliases,
1252 pre_alias_comments,
1253 trailing_comments,
1254 inferred_type: None,
1255 })))
1256 } else {
1257 let alias = self.expect_identifier_or_keyword_with_quoted()?;
1258 let trailing_comments = self.previous_trailing_comments().to_vec();
1259 Ok(Expression::Alias(Box::new(Alias {
1260 this: expr,
1261 alias,
1262 column_aliases: Vec::new(),
1263 pre_alias_comments,
1264 trailing_comments,
1265 inferred_type: None,
1266 })))
1267 }
1268 } else {
1269 Ok(expr)
1270 }
1271 }
1272 }
1273 _ => {
1274 let leading_comments = self.current_leading_comments().to_vec();
1276 let expr = self.parse_expression()?;
1278 let pre_alias_comments = self.previous_trailing_comments().to_vec();
1280 if self.match_token(TokenType::As) {
1281 let as_comments = self.previous_trailing_comments().to_vec();
1284 if self.match_token(TokenType::LParen) {
1286 let mut column_aliases = Vec::new();
1287 loop {
1288 let col_alias = self.expect_identifier_or_keyword_with_quoted()?;
1289 column_aliases.push(col_alias);
1290 if !self.match_token(TokenType::Comma) {
1291 break;
1292 }
1293 }
1294 self.expect(TokenType::RParen)?;
1295 let mut trailing_comments = as_comments;
1296 trailing_comments.extend_from_slice(self.previous_trailing_comments());
1297 Ok(Expression::Alias(Box::new(Alias {
1298 this: expr,
1299 alias: Identifier::empty(),
1300 column_aliases,
1301 pre_alias_comments,
1302 trailing_comments,
1303 inferred_type: None,
1304 })))
1305 } else {
1306 let alias = self.expect_identifier_or_keyword_with_quoted()?;
1307 let mut trailing_comments = self.previous_trailing_comments().to_vec();
1308 trailing_comments.extend(leading_comments.iter().cloned());
1311 Ok(Expression::Alias(Box::new(Alias {
1312 this: expr,
1313 alias,
1314 column_aliases: Vec::new(),
1315 pre_alias_comments,
1316 trailing_comments,
1317 inferred_type: None,
1318 })))
1319 }
1320 } else if (self.check(TokenType::Var) && !self.check_keyword())
1321 || self.is_command_keyword_as_alias()
1322 {
1323 let alias_text = self.advance().text.clone();
1326 let trailing_comments = self.previous_trailing_comments().to_vec();
1327 Ok(Expression::Alias(Box::new(Alias {
1328 this: expr,
1329 alias: Identifier::new(alias_text),
1330 column_aliases: Vec::new(),
1331 pre_alias_comments,
1332 trailing_comments,
1333 inferred_type: None,
1334 })))
1335 } else if !pre_alias_comments.is_empty() {
1336 match &expr {
1338 Expression::Literal(_) | Expression::Boolean(_) | Expression::Null(_) => {
1339 Ok(Expression::Annotated(Box::new(
1340 crate::expressions::Annotated {
1341 this: expr,
1342 trailing_comments: pre_alias_comments,
1343 },
1344 )))
1345 }
1346 _ => Ok(expr),
1348 }
1349 } else if !leading_comments.is_empty() {
1350 Ok(Expression::Annotated(Box::new(
1353 crate::expressions::Annotated {
1354 this: expr,
1355 trailing_comments: leading_comments,
1356 },
1357 )))
1358 } else {
1359 Ok(expr)
1360 }
1361 }
1362 }
1363 }
1364
1365 fn parse_select(&mut self) -> Result<Expression> {
1367 let select_token = self.expect(TokenType::Select)?;
1369 let leading_comments = select_token.comments;
1370 let post_select_comments = select_token.trailing_comments;
1371
1372 let hint = if self.check(TokenType::Hint) {
1374 Some(self.parse_hint()?)
1375 } else {
1376 None
1377 };
1378
1379 let top = if self.check(TokenType::Top)
1382 && !self.check_next(TokenType::Dot)
1383 && self.match_token(TokenType::Top)
1384 {
1385 let (amount, parenthesized) = if self.match_token(TokenType::LParen) {
1387 let expr = self.parse_expression()?;
1388 self.expect(TokenType::RParen)?;
1389 (expr, true)
1390 } else {
1391 (self.parse_primary()?, false)
1392 };
1393 let percent = self.match_token(TokenType::Percent);
1394 let with_ties = self.match_keywords(&[TokenType::With, TokenType::Ties]);
1395 Some(Top {
1396 this: amount,
1397 percent,
1398 with_ties,
1399 parenthesized,
1400 })
1401 } else {
1402 None
1403 };
1404
1405 let is_distinct_token = self.match_token(TokenType::Distinct)
1408 || (matches!(
1409 self.config.dialect,
1410 Some(crate::dialects::DialectType::Oracle)
1411 ) && self.match_token(TokenType::Unique));
1412 let (distinct, distinct_on) = if is_distinct_token {
1413 if self.match_token(TokenType::On) {
1414 self.expect(TokenType::LParen)?;
1416 let exprs = self.parse_expression_list()?;
1417 self.expect(TokenType::RParen)?;
1418 (true, Some(exprs))
1419 } else {
1420 (true, None)
1421 }
1422 } else if self.check_identifier("DISTINCTROW") {
1423 self.skip();
1425 (true, None)
1426 } else {
1427 if self.check(TokenType::All) && !self.check_next(TokenType::Dot) {
1429 self.skip();
1430 }
1431 (false, None)
1432 };
1433
1434 let top = if top.is_none()
1437 && self.check(TokenType::Top)
1438 && !self.check_next(TokenType::Dot)
1439 && self.match_token(TokenType::Top)
1440 {
1441 let (amount, parenthesized) = if self.match_token(TokenType::LParen) {
1442 let expr = self.parse_expression()?;
1443 self.expect(TokenType::RParen)?;
1444 (expr, true)
1445 } else {
1446 (self.parse_primary()?, false)
1447 };
1448 let percent = self.match_token(TokenType::Percent);
1449 let with_ties = self.match_keywords(&[TokenType::With, TokenType::Ties]);
1450 Some(Top {
1451 this: amount,
1452 percent,
1453 with_ties,
1454 parenthesized,
1455 })
1456 } else {
1457 top
1458 };
1459
1460 let mut operation_modifiers = Vec::new();
1464 let is_mysql_dialect = matches!(
1465 self.config.dialect,
1466 Some(crate::dialects::DialectType::MySQL)
1467 | Some(crate::dialects::DialectType::SingleStore)
1468 | Some(crate::dialects::DialectType::StarRocks)
1469 | Some(crate::dialects::DialectType::TiDB)
1470 | Some(crate::dialects::DialectType::Doris)
1471 );
1472 if is_mysql_dialect {
1473 const MYSQL_MODIFIERS: &[&str] = &[
1474 "HIGH_PRIORITY",
1475 "STRAIGHT_JOIN",
1476 "SQL_SMALL_RESULT",
1477 "SQL_BIG_RESULT",
1478 "SQL_BUFFER_RESULT",
1479 "SQL_NO_CACHE",
1480 "SQL_CALC_FOUND_ROWS",
1481 ];
1482 loop {
1483 if self.check(TokenType::StraightJoin) {
1484 self.skip();
1485 operation_modifiers.push("STRAIGHT_JOIN".to_string());
1486 } else if self.check(TokenType::Var) {
1487 let upper = self.peek().text.to_ascii_uppercase();
1488 if MYSQL_MODIFIERS.contains(&upper.as_str()) {
1489 self.skip();
1490 operation_modifiers.push(upper);
1491 } else {
1492 break;
1493 }
1494 } else {
1495 break;
1496 }
1497 }
1498 }
1499
1500 let kind = if self.match_token(TokenType::As) {
1502 if self.match_identifier("STRUCT") {
1503 Some("STRUCT".to_string())
1504 } else if self.match_identifier("VALUE") {
1505 Some("VALUE".to_string())
1506 } else {
1507 self.current -= 1;
1509 None
1510 }
1511 } else {
1512 None
1513 };
1514
1515 let mut expressions = self.parse_select_expressions()?;
1517
1518 let exclude = if matches!(
1525 self.config.dialect,
1526 Some(crate::dialects::DialectType::Redshift)
1527 ) {
1528 let mut retreat_for_exclude = false;
1534 if let Some(last_expr) = expressions.last() {
1535 match last_expr {
1538 Expression::Alias(alias)
1539 if alias.alias.name.eq_ignore_ascii_case("EXCLUDE") =>
1540 {
1541 if self.check(TokenType::LParen)
1544 || self.is_identifier_token()
1545 || self.is_safe_keyword_as_identifier()
1546 {
1547 let stripped = alias.this.clone();
1549 if let Some(last) = expressions.last_mut() {
1550 *last = stripped;
1551 }
1552 retreat_for_exclude = true;
1553 }
1554 }
1555 _ => {}
1556 }
1557 }
1558
1559 if retreat_for_exclude || self.check(TokenType::Exclude) {
1560 if !retreat_for_exclude {
1561 self.skip(); }
1563 let mut exclude_cols = Vec::new();
1565 if self.match_token(TokenType::LParen) {
1566 loop {
1568 let col_expr = self.parse_expression()?;
1569 exclude_cols.push(col_expr);
1570 if !self.match_token(TokenType::Comma) {
1571 break;
1572 }
1573 }
1574 self.match_token(TokenType::RParen);
1575 } else {
1576 loop {
1579 if self.is_at_end()
1580 || self.check(TokenType::From)
1581 || self.check(TokenType::Where)
1582 || self.check(TokenType::Semicolon)
1583 || self.check(TokenType::RParen)
1584 {
1585 break;
1586 }
1587 let col_expr = self.parse_expression()?;
1588 exclude_cols.push(col_expr);
1589 if !self.match_token(TokenType::Comma) {
1590 break;
1591 }
1592 }
1593 }
1594 if exclude_cols.is_empty() {
1595 None
1596 } else {
1597 Some(exclude_cols)
1598 }
1599 } else {
1600 None
1601 }
1602 } else {
1603 None
1604 };
1605
1606 let into = if self.match_text_seq(&["BULK", "COLLECT", "INTO"]) {
1609 let mut target_expressions = vec![self.parse_expression()?];
1612 while self.match_token(TokenType::Comma) {
1613 target_expressions.push(self.parse_expression()?);
1614 }
1615 if target_expressions.len() == 1 {
1616 Some(SelectInto {
1617 this: target_expressions.remove(0),
1618 temporary: false,
1619 unlogged: false,
1620 bulk_collect: true,
1621 expressions: Vec::new(),
1622 })
1623 } else {
1624 Some(SelectInto {
1627 this: Expression::Null(Null),
1628 temporary: false,
1629 unlogged: false,
1630 bulk_collect: true,
1631 expressions: target_expressions,
1632 })
1633 }
1634 } else if self.match_token(TokenType::Into) {
1635 let temporary = self.match_token(TokenType::Temporary) || self.match_identifier("TEMP");
1637 let unlogged = !temporary && self.match_identifier("UNLOGGED");
1638 let table_name = self.parse_table_ref()?;
1640 if self.match_token(TokenType::Comma) {
1643 let mut target_expressions = vec![Expression::Table(Box::new(table_name))];
1644 target_expressions.push(self.parse_expression()?);
1645 while self.match_token(TokenType::Comma) {
1646 target_expressions.push(self.parse_expression()?);
1647 }
1648 Some(SelectInto {
1649 this: Expression::Null(Null),
1650 temporary,
1651 unlogged,
1652 bulk_collect: false,
1653 expressions: target_expressions,
1654 })
1655 } else {
1656 Some(SelectInto {
1657 this: Expression::Table(Box::new(table_name)),
1658 temporary,
1659 unlogged,
1660 bulk_collect: false,
1661 expressions: Vec::new(),
1662 })
1663 }
1664 } else {
1665 None
1666 };
1667
1668 let from = if self.match_token(TokenType::From) {
1670 Some(self.parse_from()?)
1671 } else {
1672 None
1673 };
1674
1675 let mut joins = self.parse_joins()?;
1677
1678 while self.check(TokenType::Pivot) || self.check(TokenType::Unpivot) {
1681 if !joins.is_empty() {
1682 let last_idx = joins.len() - 1;
1683 if self.match_token(TokenType::Pivot) {
1686 let pivot = self.parse_pivot(Expression::Null(crate::expressions::Null))?;
1687 joins[last_idx].pivots.push(pivot);
1688 } else if self.match_token(TokenType::Unpivot) {
1689 let unpivot = self.parse_unpivot(Expression::Null(crate::expressions::Null))?;
1690 joins[last_idx].pivots.push(unpivot);
1691 }
1692 } else {
1693 break;
1695 }
1696 }
1697
1698 let lateral_views = self.parse_lateral_views()?;
1700
1701 let prewhere = if self.match_token(TokenType::Prewhere) {
1703 Some(self.parse_expression()?)
1704 } else {
1705 None
1706 };
1707
1708 let mut where_clause = if self.match_token(TokenType::Where) {
1710 Some(Where {
1711 this: self.parse_expression()?,
1712 })
1713 } else {
1714 None
1715 };
1716
1717 let connect = self.parse_connect()?;
1719
1720 let group_by = if self.check(TokenType::Group) {
1722 let group_comments = self.current_leading_comments().to_vec();
1723 if self.match_keywords(&[TokenType::Group, TokenType::By]) {
1724 let mut gb = self.parse_group_by()?;
1725 gb.comments = group_comments;
1726 Some(gb)
1727 } else {
1728 None
1729 }
1730 } else if matches!(
1731 self.config.dialect,
1732 Some(crate::dialects::DialectType::ClickHouse)
1733 ) && self.check(TokenType::With)
1734 && (self.check_next_identifier("TOTALS")
1735 || self.check_next(TokenType::Rollup)
1736 || self.check_next(TokenType::Cube))
1737 {
1738 self.skip(); let totals = self.match_identifier("TOTALS");
1741 let mut expressions = Vec::new();
1742 if self.match_token(TokenType::Rollup) {
1743 expressions.push(Expression::Rollup(Box::new(Rollup {
1744 expressions: Vec::new(),
1745 })));
1746 } else if self.match_token(TokenType::Cube) {
1747 expressions.push(Expression::Cube(Box::new(Cube {
1748 expressions: Vec::new(),
1749 })));
1750 }
1751 if !totals && self.check(TokenType::With) && self.check_next_identifier("TOTALS") {
1753 self.skip();
1754 self.skip();
1755 }
1756 Some(GroupBy {
1757 expressions,
1758 all: None,
1759 totals,
1760 comments: Vec::new(),
1761 })
1762 } else {
1763 None
1764 };
1765
1766 let having = if self.check(TokenType::Having) {
1768 let having_comments = self.current_leading_comments().to_vec();
1769 self.skip(); Some(Having {
1771 this: self.parse_expression()?,
1772 comments: having_comments,
1773 })
1774 } else {
1775 None
1776 };
1777
1778 let mut qualify = if self.match_token(TokenType::Qualify) {
1781 Some(Qualify {
1782 this: self.parse_expression()?,
1783 })
1784 } else {
1785 None
1786 };
1787
1788 let windows = if self.check(TokenType::Window) && {
1792 let next_pos = self.current + 1;
1793 next_pos < self.tokens.len()
1794 && (self.tokens[next_pos].token_type == TokenType::Var
1795 || self.tokens[next_pos].token_type == TokenType::Identifier)
1796 } {
1797 self.skip(); Some(self.parse_named_windows()?)
1799 } else {
1800 None
1801 };
1802
1803 let qualify_after_window = if qualify.is_none() && self.match_token(TokenType::Qualify) {
1805 qualify = Some(Qualify {
1806 this: self.parse_expression()?,
1807 });
1808 true
1809 } else {
1810 false
1811 };
1812
1813 let distribute_by = if self.match_keywords(&[TokenType::Distribute, TokenType::By]) {
1815 Some(self.parse_distribute_by()?)
1816 } else {
1817 None
1818 };
1819
1820 let cluster_by = if self.match_keywords(&[TokenType::Cluster, TokenType::By]) {
1822 Some(self.parse_cluster_by()?)
1823 } else {
1824 None
1825 };
1826
1827 let sort_by = if self.match_keywords(&[TokenType::Sort, TokenType::By]) {
1829 Some(self.parse_sort_by()?)
1830 } else {
1831 None
1832 };
1833
1834 let order_by = if self.check(TokenType::Order) {
1836 let order_comments = self.current_leading_comments().to_vec();
1837 if self.match_keywords(&[TokenType::Order, TokenType::Siblings, TokenType::By]) {
1838 let mut ob = self.parse_order_by_with_siblings(true)?;
1840 ob.comments = order_comments;
1841 Some(ob)
1842 } else if self.match_keywords(&[TokenType::Order, TokenType::By]) {
1843 let mut ob = self.parse_order_by()?;
1844 ob.comments = order_comments;
1845 Some(ob)
1846 } else {
1847 None
1848 }
1849 } else {
1850 None
1851 };
1852
1853 let pre_limit_comments = if self.check(TokenType::Limit) {
1858 let mut comments = self.previous_trailing_comments().to_vec();
1859 comments.extend_from_slice(self.current_leading_comments());
1861 comments
1862 } else {
1863 Vec::new()
1864 };
1865 let (limit, offset) = if self.match_token(TokenType::Limit) {
1866 if !pre_limit_comments.is_empty() {
1868 if let Some(ref mut w) = where_clause {
1869 Self::clear_rightmost_trailing_comments(&mut w.this);
1870 }
1871 }
1872 let saved_pos = self.current;
1878 let (first_expr, has_percent) = {
1879 let unary_result = self.parse_unary();
1880 match unary_result {
1881 Ok(expr) => {
1882 if self.check(TokenType::Percent) && self.is_percent_modifier() {
1883 self.skip();
1885 (expr, true)
1886 } else {
1887 self.current = saved_pos;
1889 let full_expr = self.parse_expression()?;
1890 let has_pct =
1892 if self.check(TokenType::Percent) && self.is_percent_modifier() {
1893 self.skip();
1894 true
1895 } else {
1896 false
1897 };
1898 (full_expr, has_pct)
1899 }
1900 }
1901 Err(_) => {
1902 self.current = saved_pos;
1904 let full_expr = self.parse_expression()?;
1905 let has_pct =
1906 if self.check(TokenType::Percent) && self.is_percent_modifier() {
1907 self.skip();
1908 true
1909 } else {
1910 false
1911 };
1912 (full_expr, has_pct)
1913 }
1914 }
1915 };
1916 if self.match_token(TokenType::Comma) {
1918 let second_expr = self.parse_expression()?;
1919 (
1921 Some(Limit {
1922 this: second_expr,
1923 percent: false,
1924 comments: pre_limit_comments.clone(),
1925 }),
1926 Some(Offset {
1927 this: first_expr,
1928 rows: None,
1929 }),
1930 )
1931 } else {
1932 (
1934 Some(Limit {
1935 this: first_expr,
1936 percent: has_percent,
1937 comments: pre_limit_comments,
1938 }),
1939 None,
1940 )
1941 }
1942 } else {
1943 (None, None)
1944 };
1945
1946 if limit.is_some() {
1948 let _ = self.match_keywords(&[TokenType::With, TokenType::Ties]);
1949 }
1950
1951 let (limit, offset) = if offset.is_none() && self.match_token(TokenType::Offset) {
1955 let expr = self.parse_expression()?;
1956 let rows = if self.match_token(TokenType::Row) || self.match_token(TokenType::Rows) {
1958 Some(true)
1959 } else {
1960 None
1961 };
1962 let offset = Some(Offset { this: expr, rows });
1963
1964 let limit = if limit.is_none() && self.match_token(TokenType::Limit) {
1966 let limit_expr = self.parse_expression()?;
1967 Some(Limit {
1968 this: limit_expr,
1969 percent: false,
1970 comments: Vec::new(),
1971 })
1972 } else {
1973 limit
1974 };
1975
1976 (limit, offset)
1977 } else {
1978 (limit, offset)
1979 };
1980
1981 let limit_by = if matches!(
1983 self.config.dialect,
1984 Some(crate::dialects::DialectType::ClickHouse)
1985 ) && limit.is_some()
1986 && self.match_token(TokenType::By)
1987 {
1988 let expressions = self.parse_expression_list()?;
1989 if expressions.is_empty() {
1990 return Err(self.parse_error("Expected expression after LIMIT BY"));
1991 }
1992 Some(expressions)
1993 } else {
1994 None
1995 };
1996
1997 let (limit, offset) = if limit_by.is_some() && self.match_token(TokenType::Limit) {
2000 let first_expr = self.parse_expression()?;
2001 if self.match_token(TokenType::Comma) {
2002 let count_expr = self.parse_expression()?;
2004 (
2005 Some(Limit {
2006 this: count_expr,
2007 percent: false,
2008 comments: Vec::new(),
2009 }),
2010 Some(Offset {
2011 this: first_expr,
2012 rows: None,
2013 }),
2014 )
2015 } else {
2016 (
2017 Some(Limit {
2018 this: first_expr,
2019 percent: false,
2020 comments: Vec::new(),
2021 }),
2022 offset,
2023 )
2024 }
2025 } else {
2026 (limit, offset)
2027 };
2028
2029 let fetch = if self.match_token(TokenType::Fetch) {
2031 Some(self.parse_fetch()?)
2032 } else {
2033 None
2034 };
2035
2036 let sample = self.parse_sample_clause()?;
2038
2039 let (locks, for_xml) = self.parse_locks_and_for_xml()?;
2041
2042 let option = if self.check_identifier("OPTION") && self.check_next(TokenType::LParen) {
2044 self.skip(); self.skip(); let mut content = String::from("OPTION(");
2047 let mut depth = 1;
2048 while !self.is_at_end() && depth > 0 {
2049 let tok = self.advance();
2050 if tok.token_type == TokenType::LParen {
2051 depth += 1;
2052 } else if tok.token_type == TokenType::RParen {
2053 depth -= 1;
2054 }
2055 if depth > 0 {
2056 if tok.token_type == TokenType::String {
2057 if content.len() > 7 && !content.ends_with('(') && !content.ends_with(' ') {
2058 content.push(' ');
2059 }
2060 content.push('\'');
2061 content.push_str(&tok.text.replace('\'', "''"));
2062 content.push('\'');
2063 } else if tok.token_type == TokenType::Eq {
2064 content.push_str(" = ");
2065 } else if tok.token_type == TokenType::Comma {
2066 content.push_str(", ");
2067 } else {
2068 if content.len() > 7 && !content.ends_with('(') && !content.ends_with(' ') {
2069 content.push(' ');
2070 }
2071 content.push_str(&tok.text);
2072 }
2073 }
2074 }
2075 content.push(')');
2076 Some(content)
2077 } else {
2078 None
2079 };
2080
2081 let (settings, format) = if matches!(
2083 self.config.dialect,
2084 Some(crate::dialects::DialectType::ClickHouse)
2085 ) {
2086 let mut settings: Option<Vec<Expression>> = None;
2087 let mut format: Option<Expression> = None;
2088
2089 loop {
2090 if settings.is_none() && self.match_token(TokenType::Settings) {
2091 let mut settings_exprs = Vec::new();
2092 loop {
2093 settings_exprs.push(self.parse_expression()?);
2094 if !self.match_token(TokenType::Comma) {
2095 break;
2096 }
2097 }
2098 settings = Some(settings_exprs);
2099 continue;
2100 }
2101
2102 if format.is_none() && self.match_token(TokenType::Format) {
2103 let ident = if self.check(TokenType::Null) {
2105 let text = self.advance().text;
2106 Identifier::new(text)
2107 } else {
2108 self.expect_identifier_or_keyword_with_quoted()?
2109 };
2110 format = Some(Expression::Identifier(ident));
2111 if matches!(
2114 self.config.dialect,
2115 Some(crate::dialects::DialectType::ClickHouse)
2116 ) && !self.is_at_end()
2117 && !self.check(TokenType::Semicolon)
2118 && !self.check(TokenType::Settings)
2119 {
2120 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
2121 self.skip();
2122 }
2123 }
2124 continue;
2125 }
2126
2127 break;
2128 }
2129
2130 (settings, format)
2131 } else {
2132 (None, None)
2133 };
2134
2135 let select = Select {
2136 expressions,
2137 from,
2138 joins,
2139 lateral_views,
2140 prewhere,
2141 where_clause,
2142 group_by,
2143 having,
2144 qualify,
2145 order_by,
2146 distribute_by,
2147 cluster_by,
2148 sort_by,
2149 limit,
2150 offset,
2151 limit_by,
2152 fetch,
2153 distinct,
2154 distinct_on,
2155 top,
2156 with: None,
2157 sample,
2158 settings,
2159 format,
2160 windows,
2161 hint,
2162 connect,
2163 into,
2164 locks,
2165 for_xml,
2166 leading_comments,
2167 post_select_comments,
2168 kind,
2169 operation_modifiers,
2170 qualify_after_window,
2171 option,
2172 exclude,
2173 };
2174
2175 let result = Expression::Select(Box::new(select));
2177 self.parse_set_operation(result)
2178 }
2179
2180 fn parse_with(&mut self) -> Result<Expression> {
2182 use crate::dialects::DialectType;
2183
2184 let with_token = self.expect(TokenType::With)?;
2185 let leading_comments = with_token.comments;
2186
2187 let recursive = self.match_token(TokenType::Recursive);
2188 let mut ctes = Vec::new();
2189
2190 loop {
2191 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
2194 let saved_pos = self.current;
2195 if let Ok(expr) = self.parse_expression() {
2196 let (inner_expr, alias_opt) = if let Expression::Alias(ref alias_box) = expr {
2199 (alias_box.this.clone(), Some(alias_box.alias.clone()))
2200 } else {
2201 (expr, None)
2202 };
2203
2204 if let Some(alias) = alias_opt {
2205 ctes.push(Cte {
2207 alias,
2208 this: inner_expr,
2209 columns: Vec::new(),
2210 materialized: None,
2211 key_expressions: Vec::new(),
2212 alias_first: false,
2213 comments: Vec::new(),
2214 });
2215
2216 if self.match_token(TokenType::Comma) {
2217 continue;
2218 }
2219 break;
2220 } else if self.match_token(TokenType::As)
2221 && self.is_identifier_or_keyword_token()
2222 {
2223 let alias = self.expect_identifier_or_keyword_with_quoted()?;
2225 ctes.push(Cte {
2226 alias,
2227 this: inner_expr,
2228 columns: Vec::new(),
2229 materialized: None,
2230 key_expressions: Vec::new(),
2231 alias_first: false,
2232 comments: Vec::new(),
2233 });
2234
2235 if self.match_token(TokenType::Comma) {
2236 continue;
2237 }
2238 break;
2239 } else if self.check(TokenType::Select) || self.check(TokenType::Comma) {
2240 ctes.push(Cte {
2242 alias: Identifier::new(format!("{}", inner_expr)),
2243 this: inner_expr,
2244 columns: Vec::new(),
2245 materialized: None,
2246 key_expressions: Vec::new(),
2247 alias_first: false,
2248 comments: Vec::new(),
2249 });
2250
2251 if self.match_token(TokenType::Comma) {
2252 continue;
2253 }
2254 break;
2255 }
2256 }
2257 self.current = saved_pos;
2259 }
2260
2261 let name = self.expect_identifier_or_alias_keyword_with_quoted()?;
2263
2264 let columns = if self.check(TokenType::LParen) && !self.check_next(TokenType::Select) {
2268 self.skip(); let cols = self.parse_identifier_list()?;
2270 self.expect(TokenType::RParen)?;
2271 cols
2272 } else {
2273 Vec::new()
2274 };
2275
2276 let key_expressions = if self.match_keywords(&[TokenType::Using, TokenType::Key]) {
2278 self.expect(TokenType::LParen)?;
2279 let keys = self.parse_identifier_list()?;
2280 self.expect(TokenType::RParen)?;
2281 keys
2282 } else {
2283 Vec::new()
2284 };
2285
2286 if matches!(self.config.dialect, Some(DialectType::ClickHouse))
2289 && self.check(TokenType::Arrow)
2290 {
2291 self.skip(); let body = self.parse_expression()?;
2293 let lambda = Expression::Lambda(Box::new(LambdaExpr {
2294 parameters: vec![name.clone()],
2295 body,
2296 colon: false,
2297 parameter_types: Vec::new(),
2298 }));
2299 if self.match_token(TokenType::As) && self.is_identifier_or_keyword_token() {
2301 let alias = self.expect_identifier_or_keyword_with_quoted()?;
2302 ctes.push(Cte {
2303 alias,
2304 this: lambda,
2305 columns: Vec::new(),
2306 materialized: None,
2307 key_expressions: Vec::new(),
2308 alias_first: false,
2309 comments: Vec::new(),
2310 });
2311 } else {
2312 ctes.push(Cte {
2314 alias: name,
2315 this: lambda,
2316 columns: Vec::new(),
2317 materialized: None,
2318 key_expressions: Vec::new(),
2319 alias_first: false,
2320 comments: Vec::new(),
2321 });
2322 }
2323 if self.match_token(TokenType::Comma) {
2324 continue;
2325 }
2326 break;
2327 }
2328
2329 let cte_comments = if self.match_token(TokenType::As) {
2331 self.previous_trailing_comments().to_vec()
2334 } else {
2335 Vec::new()
2336 };
2337
2338 let materialized = if self.match_token(TokenType::Materialized) {
2340 Some(true)
2341 } else if self.match_token(TokenType::Not) {
2342 self.expect(TokenType::Materialized)?;
2343 Some(false)
2344 } else {
2345 None
2346 };
2347
2348 self.expect(TokenType::LParen)?;
2349 let query = self.parse_statement()?;
2350 self.expect(TokenType::RParen)?;
2351
2352 ctes.push(Cte {
2353 alias: name,
2354 this: query,
2355 columns,
2356 materialized,
2357 key_expressions,
2358 alias_first: true,
2359 comments: cte_comments,
2360 });
2361
2362 if !self.match_token(TokenType::Comma) {
2363 if self.check(TokenType::With) {
2366 self.skip(); if self.match_token(TokenType::Recursive) && !recursive {
2369 }
2371 continue; }
2373 break;
2374 }
2375 self.match_token(TokenType::With);
2378 }
2379
2380 let search = self.parse_recursive_with_search()?;
2384
2385 let mut main_query = self.parse_statement()?;
2387
2388 loop {
2391 match main_query {
2392 Expression::Paren(paren) => {
2393 main_query = paren.this;
2394 }
2395 Expression::Subquery(ref sub)
2396 if sub.alias.is_none()
2397 && sub.order_by.is_none()
2398 && sub.limit.is_none()
2399 && sub.offset.is_none() =>
2400 {
2401 if let Expression::Subquery(sub) = main_query {
2403 main_query = sub.this;
2404 } else {
2405 break;
2406 }
2407 }
2408 _ => break,
2409 }
2410 }
2411
2412 let with_clause = With {
2414 ctes,
2415 recursive,
2416 leading_comments,
2417 search,
2418 };
2419 match &mut main_query {
2420 Expression::Select(ref mut select) => {
2421 select.with = Some(with_clause);
2422 }
2423 Expression::Union(ref mut union) => {
2424 union.with = Some(with_clause);
2425 }
2426 Expression::Intersect(ref mut intersect) => {
2427 intersect.with = Some(with_clause);
2428 }
2429 Expression::Except(ref mut except) => {
2430 except.with = Some(with_clause);
2431 }
2432 Expression::Update(ref mut update) => {
2433 update.with = Some(with_clause);
2434 }
2435 Expression::Insert(ref mut insert) => {
2436 insert.with = Some(with_clause);
2437 }
2438 Expression::Delete(ref mut delete) => {
2439 delete.with = Some(with_clause);
2440 }
2441 Expression::CreateTable(ref mut ct) => {
2442 ct.with_cte = Some(with_clause);
2443 }
2444 Expression::Pivot(ref mut pivot) => {
2445 pivot.with = Some(with_clause);
2446 }
2447 _ => {}
2448 }
2449
2450 Ok(main_query)
2451 }
2452
2453 fn parse_select_expressions(&mut self) -> Result<Vec<Expression>> {
2455 let mut expressions = Vec::new();
2456
2457 loop {
2458 let is_ch_keyword_func = matches!(
2463 self.config.dialect,
2464 Some(crate::dialects::DialectType::ClickHouse)
2465 ) && (self.check(TokenType::Except)
2466 || self.check(TokenType::Intersect))
2467 && self.check_next(TokenType::LParen);
2468 let is_ch_keyword_as_column = matches!(
2472 self.config.dialect,
2473 Some(crate::dialects::DialectType::ClickHouse)
2474 ) && (self.check(TokenType::From)
2475 || self.check(TokenType::Except))
2476 && {
2477 let next_tt = self
2478 .peek_nth(1)
2479 .map(|t| t.token_type)
2480 .unwrap_or(TokenType::Semicolon);
2481 matches!(
2482 next_tt,
2483 TokenType::Plus | TokenType::Dash | TokenType::Star | TokenType::Slash
2484 | TokenType::Percent | TokenType::Eq | TokenType::Neq | TokenType::Lt
2485 | TokenType::Gt | TokenType::Lte | TokenType::Gte
2486 | TokenType::And | TokenType::Or | TokenType::Comma | TokenType::Dot
2487 | TokenType::In | TokenType::Is | TokenType::Not | TokenType::Like
2488 | TokenType::Between | TokenType::Semicolon | TokenType::RParen
2489 | TokenType::As | TokenType::DPipe | TokenType::Amp | TokenType::Pipe
2490 | TokenType::LBracket
2491 | TokenType::From
2493 )
2494 };
2495 if !is_ch_keyword_func
2496 && !is_ch_keyword_as_column
2497 && (self.is_at_end()
2498 || self.check(TokenType::From)
2499 || self.check(TokenType::Where)
2500 || self.check(TokenType::Into)
2501 || self.check(TokenType::Union)
2502 || self.check(TokenType::Intersect)
2503 || self.check(TokenType::Except)
2504 || self.check(TokenType::Order)
2505 || self.check(TokenType::Limit)
2506 || self.check(TokenType::Semicolon)
2507 || self.check_text_seq(&["BULK", "COLLECT", "INTO"]))
2508 {
2509 break;
2510 }
2511
2512 if self.check(TokenType::Star) {
2514 self.skip();
2515 let star_trailing_comments = self.previous_trailing_comments().to_vec();
2516 let star = self.parse_star_modifiers_with_comments(None, star_trailing_comments)?;
2517 let mut star_expr = Expression::Star(star);
2518 if matches!(
2520 self.config.dialect,
2521 Some(crate::dialects::DialectType::ClickHouse)
2522 ) {
2523 while self.check(TokenType::Apply) {
2524 self.skip(); let apply_expr = if self.match_token(TokenType::LParen) {
2526 let expr = self.parse_expression()?;
2528 self.expect(TokenType::RParen)?;
2529 expr
2530 } else {
2531 self.parse_expression()?
2534 };
2535 star_expr = Expression::Apply(Box::new(crate::expressions::Apply {
2536 this: Box::new(star_expr),
2537 expression: Box::new(apply_expr),
2538 }));
2539 }
2540 }
2541 if matches!(
2544 self.config.dialect,
2545 Some(crate::dialects::DialectType::ClickHouse)
2546 ) && (self.check(TokenType::Except)
2547 || self.check(TokenType::Exclude)
2548 || self.check(TokenType::Replace))
2549 {
2550 self.parse_star_modifiers(None)?;
2552 while self.check(TokenType::Apply) {
2554 self.skip();
2555 let apply_expr = if self.match_token(TokenType::LParen) {
2556 let expr = self.parse_expression()?;
2557 self.expect(TokenType::RParen)?;
2558 expr
2559 } else {
2560 self.parse_expression()?
2561 };
2562 star_expr = Expression::Apply(Box::new(crate::expressions::Apply {
2563 this: Box::new(star_expr),
2564 expression: Box::new(apply_expr),
2565 }));
2566 }
2567 }
2568 if matches!(
2571 self.config.dialect,
2572 Some(crate::dialects::DialectType::ClickHouse)
2573 ) && matches!(
2574 self.peek().token_type,
2575 TokenType::Is
2576 | TokenType::And
2577 | TokenType::Or
2578 | TokenType::Eq
2579 | TokenType::Neq
2580 | TokenType::Lt
2581 | TokenType::Gt
2582 | TokenType::Lte
2583 | TokenType::Gte
2584 | TokenType::Not
2585 | TokenType::Plus
2586 | TokenType::Dash
2587 | TokenType::Slash
2588 | TokenType::Percent
2589 | TokenType::Like
2590 | TokenType::Between
2591 | TokenType::In
2592 ) {
2593 let left = star_expr;
2595 if self.check(TokenType::Is) {
2597 self.skip(); let not = self.match_token(TokenType::Not);
2599 if self.match_token(TokenType::Null) {
2600 star_expr = if not {
2601 Expression::Not(Box::new(UnaryOp {
2602 this: Expression::Is(Box::new(BinaryOp::new(
2603 left,
2604 Expression::Null(Null),
2605 ))),
2606 inferred_type: None,
2607 }))
2608 } else {
2609 Expression::Is(Box::new(BinaryOp::new(
2610 left,
2611 Expression::Null(Null),
2612 )))
2613 };
2614 } else {
2615 let right = self.parse_or()?;
2616 star_expr = if not {
2617 Expression::Not(Box::new(UnaryOp {
2618 this: Expression::Is(Box::new(BinaryOp::new(left, right))),
2619 inferred_type: None,
2620 }))
2621 } else {
2622 Expression::Is(Box::new(BinaryOp::new(left, right)))
2623 };
2624 }
2625 } else if self.match_token(TokenType::And) {
2626 let right = self.parse_or()?;
2627 star_expr = Expression::And(Box::new(BinaryOp::new(left, right)));
2628 } else if self.match_token(TokenType::Or) {
2629 let right = self.parse_or()?;
2630 star_expr = Expression::Or(Box::new(BinaryOp::new(left, right)));
2631 } else {
2632 let op_token = self.advance();
2633 let right = self.parse_or()?;
2634 star_expr = match op_token.token_type {
2635 TokenType::Eq => Expression::Eq(Box::new(BinaryOp::new(left, right))),
2636 TokenType::Neq => Expression::Neq(Box::new(BinaryOp::new(left, right))),
2637 TokenType::Lt => Expression::Lt(Box::new(BinaryOp::new(left, right))),
2638 TokenType::Gt => Expression::Gt(Box::new(BinaryOp::new(left, right))),
2639 TokenType::Lte => Expression::Lte(Box::new(BinaryOp::new(left, right))),
2640 TokenType::Gte => Expression::Gte(Box::new(BinaryOp::new(left, right))),
2641 TokenType::Plus => {
2642 Expression::Add(Box::new(BinaryOp::new(left, right)))
2643 }
2644 TokenType::Dash => {
2645 Expression::Sub(Box::new(BinaryOp::new(left, right)))
2646 }
2647 _ => left, };
2649 }
2650 }
2651 expressions.push(star_expr);
2652 } else {
2653 let leading_comments = self.current_leading_comments().to_vec();
2656 let expr = self.parse_expression()?;
2657
2658 let expr = if matches!(
2661 self.config.dialect,
2662 Some(crate::dialects::DialectType::ClickHouse)
2663 ) {
2664 let is_columns_func = match &expr {
2665 Expression::Function(f) => f.name.eq_ignore_ascii_case("COLUMNS"),
2666 Expression::MethodCall(m) => m.method.name.eq_ignore_ascii_case("COLUMNS"),
2667 Expression::Columns(_) => true,
2668 _ => false,
2669 };
2670 let is_qualified_star = matches!(&expr, Expression::Star(_));
2671 if (is_columns_func || is_qualified_star)
2672 && (self.check(TokenType::Except)
2673 || self.check(TokenType::Exclude)
2674 || self.check(TokenType::Replace)
2675 || self.check(TokenType::Apply))
2676 {
2677 let mut result = expr;
2678 loop {
2681 if self.check(TokenType::Except) || self.check(TokenType::Exclude) {
2682 self.skip();
2684 self.match_identifier("STRICT");
2685 if self.match_token(TokenType::LParen) {
2686 loop {
2687 if self.check(TokenType::RParen) {
2688 break;
2689 }
2690 let _ = self.parse_expression()?;
2691 if !self.match_token(TokenType::Comma) {
2692 break;
2693 }
2694 }
2695 self.expect(TokenType::RParen)?;
2696 } else if self.is_identifier_token()
2697 || self.is_safe_keyword_as_identifier()
2698 {
2699 let _ = self.parse_expression()?;
2700 }
2701 } else if self.check(TokenType::Replace) {
2702 self.skip();
2704 self.match_identifier("STRICT");
2705 if self.match_token(TokenType::LParen) {
2706 loop {
2707 if self.check(TokenType::RParen) {
2708 break;
2709 }
2710 let _ = self.parse_expression()?;
2711 if self.match_token(TokenType::As) {
2712 if self.is_identifier_token()
2713 || self.is_safe_keyword_as_identifier()
2714 {
2715 self.skip();
2716 }
2717 }
2718 if !self.match_token(TokenType::Comma) {
2719 break;
2720 }
2721 }
2722 self.expect(TokenType::RParen)?;
2723 } else {
2724 let _ = self.parse_expression()?;
2725 if self.match_token(TokenType::As) {
2726 if self.is_identifier_token()
2727 || self.is_safe_keyword_as_identifier()
2728 {
2729 self.skip();
2730 }
2731 }
2732 }
2733 } else if self.check(TokenType::Apply) {
2734 self.skip();
2736 let apply_expr = if self.match_token(TokenType::LParen) {
2737 let e = self.parse_expression()?;
2738 self.expect(TokenType::RParen)?;
2739 e
2740 } else {
2741 self.parse_expression()?
2742 };
2743 result = Expression::Apply(Box::new(crate::expressions::Apply {
2744 this: Box::new(result),
2745 expression: Box::new(apply_expr),
2746 }));
2747 } else {
2748 break;
2749 }
2750 }
2751 result
2752 } else {
2753 expr
2754 }
2755 } else {
2756 expr
2757 };
2758
2759 let pre_alias_comments = self.previous_trailing_comments().to_vec();
2761
2762 let expr = if self.check(TokenType::Colon) && !self.check_next(TokenType::Colon) {
2765 let alias_ident = match &expr {
2767 Expression::Identifier(id) => Some(id.clone()),
2768 Expression::Column(col) if col.table.is_none() => Some(col.name.clone()),
2769 _ => None,
2770 };
2771 if let Some(alias) = alias_ident {
2772 self.skip();
2774 let colon_comments = self.previous_trailing_comments().to_vec();
2775 let value = self.parse_expression()?;
2777 let value_trailing = self.previous_trailing_comments().to_vec();
2778 let mut all_trailing = pre_alias_comments.clone();
2782 all_trailing.extend(colon_comments);
2783 all_trailing.extend(value_trailing);
2784 Expression::Alias(Box::new(Alias {
2785 this: value,
2786 alias,
2787 column_aliases: Vec::new(),
2788 pre_alias_comments: Vec::new(),
2789 trailing_comments: all_trailing,
2790 inferred_type: None,
2791 }))
2792 } else {
2793 expr
2796 }
2797 } else if self.match_token(TokenType::As) {
2798 let as_comments = self.previous_trailing_comments().to_vec();
2801 if self.match_token(TokenType::LParen) {
2803 let mut column_aliases = Vec::new();
2804 loop {
2805 if let Some(col_expr) = self.parse_id_var()? {
2806 if let Expression::Identifier(id) = col_expr {
2807 column_aliases.push(id);
2808 }
2809 } else {
2810 break;
2811 }
2812 if !self.match_token(TokenType::Comma) {
2813 break;
2814 }
2815 }
2816 self.match_token(TokenType::RParen);
2817 let mut trailing_comments = as_comments;
2818 trailing_comments.extend_from_slice(self.previous_trailing_comments());
2819 Expression::Alias(Box::new(Alias {
2820 this: expr,
2821 alias: Identifier::new(String::new()),
2822 column_aliases,
2823 pre_alias_comments,
2824 trailing_comments,
2825 inferred_type: None,
2826 }))
2827 } else {
2828 let alias = self.expect_identifier_or_keyword_with_quoted()?;
2831 let mut trailing_comments = self.previous_trailing_comments().to_vec();
2832 if !self.pending_leading_comments.is_empty() {
2837 trailing_comments.extend(self.pending_leading_comments.drain(..));
2838 } else {
2839 trailing_comments.extend(leading_comments.iter().cloned());
2840 }
2841 Expression::Alias(Box::new(Alias {
2842 this: expr,
2843 alias,
2844 column_aliases: Vec::new(),
2845 pre_alias_comments,
2846 trailing_comments,
2847 inferred_type: None,
2848 }))
2849 }
2850 } else if ((self.check(TokenType::Var) && !self.check_keyword()) || self.check(TokenType::QuotedIdentifier) || self.can_be_alias_keyword() || self.is_command_keyword_as_alias() || self.check(TokenType::Overlaps)
2851 || (self.check(TokenType::Apply) && !self.check_next(TokenType::LParen)
2853 && matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse))))
2854 && !self.check_text_seq(&["BULK", "COLLECT", "INTO"])
2855 && !(matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse))
2857 && (self.check(TokenType::Format) || self.check(TokenType::Settings)))
2858 && !(
2861 self.check(TokenType::Fetch)
2862 || ((self.check(TokenType::Limit) || self.check(TokenType::Offset))
2863 && !matches!(
2864 self.config.dialect,
2865 Some(crate::dialects::DialectType::Spark)
2866 | Some(crate::dialects::DialectType::Hive)
2867 ))
2868 )
2869 && !self.check_text_seq(&["GROUP", "BY"])
2871 && !self.check_text_seq(&["ORDER", "BY"])
2872 && !self.check(TokenType::Window)
2874 && !(self.check_identifier("PARALLEL") && self.check_next(TokenType::With)
2876 && matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)))
2877 {
2878 let alias_token = self.advance();
2881 let alias_text = alias_token.text.clone();
2882 let is_quoted = alias_token.token_type == TokenType::QuotedIdentifier;
2883 let trailing_comments = self.previous_trailing_comments().to_vec();
2884 Expression::Alias(Box::new(Alias {
2885 this: expr,
2886 alias: Identifier {
2887 name: alias_text,
2888 quoted: is_quoted,
2889 trailing_comments: Vec::new(),
2890 span: None,
2891 },
2892 column_aliases: Vec::new(),
2893 pre_alias_comments,
2894 trailing_comments,
2895 inferred_type: None,
2896 }))
2897 } else if !pre_alias_comments.is_empty() {
2898 let already_has_trailing = matches!(
2901 &expr,
2902 Expression::Add(_)
2903 | Expression::Sub(_)
2904 | Expression::Mul(_)
2905 | Expression::Div(_)
2906 | Expression::Mod(_)
2907 | Expression::Concat(_)
2908 | Expression::BitwiseAnd(_)
2909 | Expression::BitwiseOr(_)
2910 | Expression::BitwiseXor(_)
2911 | Expression::Column(_)
2912 | Expression::Paren(_)
2913 | Expression::Annotated(_)
2914 | Expression::Cast(_)
2915 | Expression::Function(_)
2916 | Expression::Subquery(_)
2917 );
2918 if already_has_trailing {
2919 expr
2920 } else {
2921 Expression::Annotated(Box::new(Annotated {
2923 this: expr,
2924 trailing_comments: pre_alias_comments,
2925 }))
2926 }
2927 } else if !leading_comments.is_empty() {
2928 Expression::Annotated(Box::new(Annotated {
2930 this: expr,
2931 trailing_comments: leading_comments,
2932 }))
2933 } else {
2934 expr
2935 };
2936
2937 expressions.push(expr);
2938 }
2939
2940 if !self.match_token(TokenType::Comma) {
2941 break;
2942 }
2943
2944 let from_is_column = matches!(
2948 self.config.dialect,
2949 Some(crate::dialects::DialectType::ClickHouse)
2950 ) && self.check(TokenType::From)
2951 && {
2952 let next_tt = self
2953 .peek_nth(1)
2954 .map(|t| t.token_type)
2955 .unwrap_or(TokenType::Semicolon);
2956 matches!(
2957 next_tt,
2958 TokenType::Plus
2959 | TokenType::Dash
2960 | TokenType::Star
2961 | TokenType::Slash
2962 | TokenType::Percent
2963 | TokenType::Eq
2964 | TokenType::Neq
2965 | TokenType::Lt
2966 | TokenType::Gt
2967 | TokenType::Lte
2968 | TokenType::Gte
2969 | TokenType::And
2970 | TokenType::Or
2971 | TokenType::Comma
2972 | TokenType::Dot
2973 | TokenType::In
2974 | TokenType::Is
2975 | TokenType::Not
2976 | TokenType::Like
2977 | TokenType::Between
2978 | TokenType::Semicolon
2979 | TokenType::RParen
2980 | TokenType::As
2981 | TokenType::DPipe
2982 | TokenType::Amp
2983 | TokenType::Pipe
2984 | TokenType::LBracket
2985 )
2986 };
2987 if (self.config.allow_trailing_commas
2988 || matches!(
2989 self.config.dialect,
2990 Some(crate::dialects::DialectType::ClickHouse)
2991 ))
2992 && (!from_is_column && self.check_from_keyword()
2993 || self.check(TokenType::Where)
2994 || self.check(TokenType::GroupBy)
2995 || self.check(TokenType::Having)
2996 || self.check(TokenType::Order)
2997 || self.check(TokenType::Limit)
2998 || self.check(TokenType::Union)
2999 || self.check(TokenType::Intersect)
3000 || (self.check(TokenType::Except) && !self.check_next(TokenType::LParen) && !self.check_next(TokenType::Comma))
3001 || self.check(TokenType::Semicolon)
3002 || self.check(TokenType::RParen)
3003 || (self.check(TokenType::Settings) && !self.check_next(TokenType::LParen) && !self.check_next(TokenType::LBracket))
3005 || (self.check(TokenType::Format) && !self.check_next(TokenType::LParen))
3006 || self.is_at_end())
3007 {
3008 break;
3009 }
3010 }
3011
3012 Ok(expressions)
3013 }
3014
3015 fn parse_from_first_query(&mut self) -> Result<Expression> {
3019 self.expect(TokenType::From)?;
3020
3021 let from = self.parse_from()?;
3023
3024 let expressions = if self.check(TokenType::Select) {
3026 self.skip(); self.parse_select_expressions()?
3028 } else {
3029 vec![Expression::Star(crate::expressions::Star {
3031 table: None,
3032 except: None,
3033 replace: None,
3034 rename: None,
3035 trailing_comments: Vec::new(),
3036 span: None,
3037 })]
3038 };
3039
3040 let prewhere = if self.match_token(TokenType::Prewhere) {
3042 Some(self.parse_expression()?)
3043 } else {
3044 None
3045 };
3046
3047 let where_clause = if self.match_token(TokenType::Where) {
3049 Some(Where {
3050 this: self.parse_expression()?,
3051 })
3052 } else {
3053 None
3054 };
3055
3056 let group_by = if self.match_token(TokenType::Group) {
3058 self.expect(TokenType::By)?;
3059 let mut groups = Vec::new();
3060 loop {
3061 groups.push(self.parse_expression()?);
3062 if !self.match_token(TokenType::Comma) {
3063 break;
3064 }
3065 }
3066 Some(GroupBy {
3067 expressions: groups,
3068 all: None,
3069 totals: false,
3070 comments: Vec::new(),
3071 })
3072 } else {
3073 None
3074 };
3075
3076 let having = if self.match_token(TokenType::Having) {
3078 Some(Having {
3079 this: self.parse_expression()?,
3080 comments: Vec::new(),
3081 })
3082 } else {
3083 None
3084 };
3085
3086 let order_by = if self.match_token(TokenType::Order) {
3088 self.expect(TokenType::By)?;
3089 Some(self.parse_order_by()?)
3090 } else {
3091 None
3092 };
3093
3094 let limit = if self.match_token(TokenType::Limit) {
3096 let first_expr = self.parse_expression()?;
3097 Some(Limit {
3098 this: first_expr,
3099 percent: false,
3100 comments: Vec::new(),
3101 })
3102 } else {
3103 None
3104 };
3105
3106 let offset = if self.match_token(TokenType::Offset) {
3108 let expr = self.parse_expression()?;
3109 let rows = if self.match_token(TokenType::Row) || self.match_token(TokenType::Rows) {
3110 Some(true)
3111 } else {
3112 None
3113 };
3114 Some(Offset { this: expr, rows })
3115 } else {
3116 None
3117 };
3118
3119 let select = Select {
3121 expressions,
3122 from: Some(from),
3123 joins: Vec::new(),
3124 lateral_views: Vec::new(),
3125 prewhere,
3126 where_clause,
3127 group_by,
3128 having,
3129 qualify: None,
3130 order_by,
3131 distribute_by: None,
3132 cluster_by: None,
3133 sort_by: None,
3134 limit,
3135 offset,
3136 limit_by: None,
3137 fetch: None,
3138 distinct: false,
3139 distinct_on: None,
3140 top: None,
3141 with: None,
3142 sample: None,
3143 settings: None,
3144 format: None,
3145 windows: None,
3146 hint: None,
3147 connect: None,
3148 into: None,
3149 locks: Vec::new(),
3150 for_xml: Vec::new(),
3151 leading_comments: Vec::new(),
3152 post_select_comments: Vec::new(),
3153 kind: None,
3154 operation_modifiers: Vec::new(),
3155 qualify_after_window: false,
3156 option: None,
3157 exclude: None,
3158 };
3159
3160 let result = Expression::Select(Box::new(select));
3162 self.parse_set_operation(result)
3163 }
3164
3165 fn parse_from(&mut self) -> Result<From> {
3167 let mut expressions = Vec::new();
3168
3169 loop {
3170 let pre_table_comments = if !self.is_at_end() {
3173 self.tokens[self.current].comments.clone()
3174 } else {
3175 Vec::new()
3176 };
3177 if !pre_table_comments.is_empty() && !self.is_at_end() {
3179 self.tokens[self.current].comments.clear();
3180 }
3181
3182 let mut table = self.parse_table_expression()?;
3183
3184 if !pre_table_comments.is_empty() {
3186 match &mut table {
3187 Expression::Pivot(p) => {
3188 if let Expression::Table(ref mut t) = p.this {
3191 t.leading_comments = pre_table_comments;
3192 }
3193 }
3194 Expression::Table(ref mut t) => {
3195 t.trailing_comments.extend(pre_table_comments);
3196 }
3197 _ => {}
3198 }
3199 }
3200 expressions.push(table);
3201
3202 if !self.match_token(TokenType::Comma) {
3203 break;
3204 }
3205
3206 let is_redshift = matches!(
3211 self.config.dialect,
3212 Some(crate::dialects::DialectType::Redshift)
3213 );
3214 let is_unpivot_boundary = !is_redshift && self.check(TokenType::Unpivot);
3215 if self.is_at_end()
3216 || is_unpivot_boundary
3217 || matches!(
3218 self.peek().token_type,
3219 TokenType::Where
3220 | TokenType::GroupBy
3221 | TokenType::Having
3222 | TokenType::Order
3223 | TokenType::Limit
3224 | TokenType::Offset
3225 | TokenType::Union
3226 | TokenType::Intersect
3227 | TokenType::Except
3228 | TokenType::Semicolon
3229 | TokenType::RParen
3230 | TokenType::Window
3231 | TokenType::Qualify
3232 | TokenType::Distribute
3233 | TokenType::Cluster
3234 | TokenType::Pivot
3235 )
3236 {
3237 break;
3238 }
3239 }
3240
3241 Ok(From { expressions })
3242 }
3243
3244 fn parse_table_expression(&mut self) -> Result<Expression> {
3246 let has_only = self.match_token(TokenType::Only);
3249
3250 if self.match_text_seq(&["ROWS", "FROM"]) {
3253 return self.parse_rows_from();
3254 }
3255
3256 if self.match_token(TokenType::Unpivot) {
3262 return self.parse_redshift_unpivot_table();
3263 }
3264
3265 let mut expr = if self.check(TokenType::Values) && self.check_next(TokenType::LParen) {
3266 self.parse_values()?
3269 } else if self.check(TokenType::Values)
3270 && matches!(
3271 self.config.dialect,
3272 Some(crate::dialects::DialectType::ClickHouse)
3273 )
3274 {
3275 let token = self.advance();
3277 let ident = Identifier::new(token.text);
3278 let trailing_comments = self.previous_trailing_comments().to_vec();
3279 Expression::boxed_table(TableRef {
3280 name: ident,
3281 schema: None,
3282 catalog: None,
3283 alias: None,
3284 alias_explicit_as: false,
3285 column_aliases: Vec::new(),
3286 leading_comments: Vec::new(),
3287 trailing_comments,
3288 when: None,
3289 only: false,
3290 final_: false,
3291 table_sample: None,
3292 hints: Vec::new(),
3293 system_time: None,
3294 partitions: Vec::new(),
3295 identifier_func: None,
3296 changes: None,
3297 version: None,
3298 span: None,
3299 })
3300 } else if self.check(TokenType::DAt) {
3301 self.parse_stage_reference()?
3303 } else if self.check(TokenType::Var) && self.peek().text.starts_with('@') {
3304 self.parse_stage_reference_from_var()?
3307 } else if self.check(TokenType::String) && self.peek().text.starts_with('@') {
3308 self.parse_stage_reference_from_string()?
3310 } else if self.match_token(TokenType::Lateral) {
3311 if self.check(TokenType::LParen) {
3312 self.expect(TokenType::LParen)?;
3314 if self.check(TokenType::Select)
3315 || self.check(TokenType::With)
3316 || self.check(TokenType::From)
3317 {
3318 let query = self.parse_statement()?;
3319 self.expect(TokenType::RParen)?;
3320 Expression::Subquery(Box::new(Subquery {
3321 this: query,
3322 alias: None,
3323 column_aliases: Vec::new(),
3324 order_by: None,
3325 limit: None,
3326 offset: None,
3327 lateral: true,
3328 modifiers_inside: false,
3329 trailing_comments: Vec::new(),
3330 distribute_by: None,
3331 sort_by: None,
3332 cluster_by: None,
3333 inferred_type: None,
3334 }))
3335 } else {
3336 let table_expr = self.parse_table_expression()?;
3338 self.expect(TokenType::RParen)?;
3339 Expression::Subquery(Box::new(Subquery {
3340 this: table_expr,
3341 alias: None,
3342 column_aliases: Vec::new(),
3343 order_by: None,
3344 limit: None,
3345 offset: None,
3346 lateral: true,
3347 modifiers_inside: false,
3348 trailing_comments: Vec::new(),
3349 distribute_by: None,
3350 sort_by: None,
3351 cluster_by: None,
3352 inferred_type: None,
3353 }))
3354 }
3355 } else {
3356 let first_ident = self.expect_identifier_or_keyword_with_quoted()?;
3359 let first_name = first_ident.name.clone();
3360
3361 self.expect(TokenType::LParen)?;
3363 let args = if self.check(TokenType::RParen) {
3364 Vec::new()
3365 } else {
3366 self.parse_function_arguments()?
3367 };
3368 self.expect(TokenType::RParen)?;
3369
3370 let mut func_expr = if first_name.eq_ignore_ascii_case("UNNEST") {
3372 let mut args_iter = args.into_iter();
3373 let this = args_iter
3374 .next()
3375 .ok_or_else(|| self.parse_error("Expected expression in UNNEST"))?;
3376 let expressions: Vec<Expression> = args_iter.collect();
3377 Expression::Unnest(Box::new(crate::expressions::UnnestFunc {
3378 this,
3379 expressions,
3380 with_ordinality: false,
3381 alias: None,
3382 offset_alias: None,
3383 }))
3384 } else {
3385 Expression::Function(Box::new(Function {
3386 name: first_name,
3387 args,
3388 distinct: false,
3389 trailing_comments: Vec::new(),
3390 use_bracket_syntax: false,
3391 no_parens: false,
3392 quoted: false,
3393 span: None,
3394 inferred_type: None,
3395 }))
3396 };
3397
3398 let mut with_offset_alias: Option<crate::expressions::Identifier> = None;
3400 let ordinality = if self.match_token(TokenType::With) {
3401 if self.match_token(TokenType::Ordinality) {
3402 Some(Box::new(Expression::Boolean(BooleanLiteral {
3403 value: true,
3404 })))
3405 } else if self.check(TokenType::Offset) || self.check_identifier("OFFSET") {
3406 self.skip(); if matches!(
3410 self.config.dialect,
3411 Some(crate::dialects::DialectType::BigQuery)
3412 ) {
3413 let has_as = self.match_token(TokenType::As);
3414 if has_as
3415 || self.check(TokenType::Identifier)
3416 || self.check(TokenType::Var)
3417 {
3418 let alias_name = self.advance().text;
3419 with_offset_alias = Some(crate::expressions::Identifier {
3420 name: alias_name,
3421 quoted: false,
3422 trailing_comments: Vec::new(),
3423 span: None,
3424 });
3425 }
3426 }
3427 Some(Box::new(Expression::Boolean(BooleanLiteral {
3428 value: true,
3429 })))
3430 } else {
3431 self.current -= 1;
3433 None
3434 }
3435 } else {
3436 None
3437 };
3438
3439 if ordinality.is_some() {
3441 if let Expression::Unnest(ref mut u) = func_expr {
3442 u.with_ordinality = true;
3443 u.offset_alias = with_offset_alias;
3444 }
3445 }
3446
3447 let alias_ident = if self.match_token(TokenType::As) {
3449 Some(self.expect_identifier_or_keyword_with_quoted()?)
3450 } else if !self.is_at_end()
3451 && !self.check(TokenType::Comma)
3452 && !self.check(TokenType::RParen)
3453 && !self.check(TokenType::On)
3454 && !self.check(TokenType::Cross)
3455 && !self.check(TokenType::Inner)
3456 && !self.check(TokenType::Left)
3457 && !self.check(TokenType::Right)
3458 && !self.check(TokenType::Full)
3459 && !self.check(TokenType::Join)
3460 && !self.check(TokenType::Where)
3461 && !self.check(TokenType::Order)
3462 && !self.check(TokenType::Limit)
3463 && !self.check(TokenType::Semicolon)
3464 && (self.check(TokenType::Identifier) || self.check(TokenType::Var))
3465 {
3466 Some(self.expect_identifier_or_keyword_with_quoted()?)
3467 } else {
3468 None
3469 };
3470 let alias_quoted = alias_ident.as_ref().map_or(false, |id| id.quoted);
3471 let alias = alias_ident.map(|id| id.name);
3472
3473 let column_aliases = if alias.is_some() && self.match_token(TokenType::LParen) {
3475 let mut cols = Vec::new();
3476 loop {
3477 cols.push(self.expect_identifier_or_keyword()?);
3478 if !self.match_token(TokenType::Comma) {
3479 break;
3480 }
3481 }
3482 self.expect(TokenType::RParen)?;
3483 cols
3484 } else {
3485 Vec::new()
3486 };
3487
3488 Expression::Lateral(Box::new(Lateral {
3489 this: Box::new(func_expr),
3490 view: None,
3491 outer: None,
3492 alias,
3493 alias_quoted,
3494 cross_apply: None,
3495 ordinality,
3496 column_aliases,
3497 }))
3498 }
3499 } else if self.match_token(TokenType::LParen) {
3500 if self.check(TokenType::Values) {
3502 let mut values = self.parse_values()?;
3504 self.expect(TokenType::RParen)?;
3505 let (alias, column_aliases) = if let Expression::Values(ref mut v) = values {
3507 (v.alias.take(), std::mem::take(&mut v.column_aliases))
3508 } else {
3509 (None, Vec::new())
3510 };
3511 Expression::Subquery(Box::new(Subquery {
3512 this: values,
3513 alias,
3514 column_aliases,
3515 order_by: None,
3516 limit: None,
3517 offset: None,
3518 distribute_by: None,
3519 sort_by: None,
3520 cluster_by: None,
3521 lateral: false,
3522 modifiers_inside: false,
3523 trailing_comments: self.previous_trailing_comments().to_vec(),
3524 inferred_type: None,
3525 }))
3526 } else if self.check(TokenType::Select)
3527 || self.check(TokenType::With)
3528 || self.check(TokenType::Pivot)
3529 || self.check(TokenType::Unpivot)
3530 || self.check(TokenType::From)
3531 || self.check(TokenType::Merge)
3532 || self.check(TokenType::Describe)
3533 || (self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("EXPLAIN"))
3534 || (self.check(TokenType::Var)
3535 && self.peek().text.eq_ignore_ascii_case("SUMMARIZE"))
3536 {
3537 let query = self.parse_statement()?;
3538 self.expect(TokenType::RParen)?;
3539 let trailing = self.previous_trailing_comments().to_vec();
3540 let result = if self.check(TokenType::Union)
3544 || self.check(TokenType::Intersect)
3545 || self.check(TokenType::Except)
3546 {
3547 let left = Expression::Subquery(Box::new(Subquery {
3548 this: query,
3549 alias: None,
3550 column_aliases: Vec::new(),
3551 order_by: None,
3552 limit: None,
3553 offset: None,
3554 lateral: false,
3555 modifiers_inside: false,
3556 trailing_comments: Vec::new(),
3557 distribute_by: None,
3558 sort_by: None,
3559 cluster_by: None,
3560 inferred_type: None,
3561 }));
3562 self.parse_set_operation(left)?
3563 } else {
3564 query
3565 };
3566 Expression::Subquery(Box::new(Subquery {
3567 this: result,
3568 alias: None,
3569 column_aliases: Vec::new(),
3570 order_by: None,
3571 limit: None,
3572 offset: None,
3573 distribute_by: None,
3574 sort_by: None,
3575 cluster_by: None,
3576 lateral: false,
3577 modifiers_inside: false,
3578 trailing_comments: trailing,
3579 inferred_type: None,
3580 }))
3581 } else if self.check(TokenType::LParen) {
3582 let inner = self.parse_table_expression()?;
3585
3586 let inner = if self.match_token(TokenType::As) {
3588 let alias = self.expect_identifier()?;
3589 if let Expression::Subquery(mut subq) = inner {
3590 subq.alias = Some(Identifier::new(alias));
3591 Expression::Subquery(subq)
3592 } else {
3593 Expression::Alias(Box::new(Alias::new(inner, Identifier::new(alias))))
3594 }
3595 } else if self.is_identifier_token()
3596 && !self.check(TokenType::Union)
3597 && !self.check(TokenType::Intersect)
3598 && !self.check(TokenType::Except)
3599 && !self.check(TokenType::Cross)
3600 && !self.check(TokenType::Inner)
3601 && !self.check(TokenType::Left)
3602 && !self.check(TokenType::Right)
3603 && !self.check(TokenType::Full)
3604 && !self.check(TokenType::Join)
3605 && !self.check(TokenType::Order)
3606 && !self.check(TokenType::Limit)
3607 && !self.check(TokenType::Offset)
3608 && !self.check(TokenType::Xor)
3609 {
3610 let alias = self.expect_identifier()?;
3612 if let Expression::Subquery(mut subq) = inner {
3613 subq.alias = Some(Identifier::new(alias));
3614 Expression::Subquery(subq)
3615 } else {
3616 Expression::Alias(Box::new(Alias::new(inner, Identifier::new(alias))))
3617 }
3618 } else {
3619 inner
3620 };
3621
3622 if matches!(
3624 self.config.dialect,
3625 Some(crate::dialects::DialectType::ClickHouse)
3626 ) && self.check(TokenType::Comma)
3627 {
3628 let mut exprs = vec![inner];
3629 while self.match_token(TokenType::Comma) {
3630 if self.check(TokenType::RParen) {
3631 break;
3632 }
3633 let e = self.parse_expression()?;
3634 exprs.push(e);
3635 }
3636 self.expect(TokenType::RParen)?;
3637 return Ok(Expression::Tuple(Box::new(Tuple { expressions: exprs })));
3638 }
3639
3640 let had_set_operation = self.check(TokenType::Union)
3642 || self.check(TokenType::Intersect)
3643 || self.check(TokenType::Except);
3644 let result = if had_set_operation {
3645 let set_result = self.parse_set_operation(inner)?;
3648 set_result
3649 } else if self.check(TokenType::Cross)
3650 || self.check(TokenType::Inner)
3651 || self.check(TokenType::Left)
3652 || self.check(TokenType::Right)
3653 || self.check(TokenType::Full)
3654 || self.check(TokenType::Join)
3655 {
3656 let joins = self.parse_joins()?;
3658 let lateral_views = self.parse_lateral_views()?;
3659 Expression::JoinedTable(Box::new(JoinedTable {
3660 left: inner,
3661 joins,
3662 lateral_views,
3663 alias: None,
3664 }))
3665 } else {
3666 inner
3667 };
3668
3669 let result = if self.check(TokenType::Order) {
3671 self.expect(TokenType::Order)?;
3673 self.expect(TokenType::By)?;
3674 let order_by = self.parse_order_by()?;
3675 let limit = if self.match_token(TokenType::Limit) {
3676 Some(Limit {
3677 this: self.parse_expression()?,
3678 percent: false,
3679 comments: Vec::new(),
3680 })
3681 } else {
3682 None
3683 };
3684 let offset = if self.match_token(TokenType::Offset) {
3685 Some(Offset {
3686 this: self.parse_expression()?,
3687 rows: None,
3688 })
3689 } else {
3690 None
3691 };
3692 Expression::Subquery(Box::new(Subquery {
3693 this: result,
3694 alias: None,
3695 column_aliases: Vec::new(),
3696 order_by: Some(order_by),
3697 limit,
3698 offset,
3699 distribute_by: None,
3700 sort_by: None,
3701 cluster_by: None,
3702 lateral: false,
3703 modifiers_inside: true, trailing_comments: Vec::new(),
3705 inferred_type: None,
3706 }))
3707 } else if self.check(TokenType::Limit) || self.check(TokenType::Offset) {
3708 let limit = if self.match_token(TokenType::Limit) {
3710 Some(Limit {
3711 this: self.parse_expression()?,
3712 percent: false,
3713 comments: Vec::new(),
3714 })
3715 } else {
3716 None
3717 };
3718 let offset = if self.match_token(TokenType::Offset) {
3719 Some(Offset {
3720 this: self.parse_expression()?,
3721 rows: None,
3722 })
3723 } else {
3724 None
3725 };
3726 Expression::Subquery(Box::new(Subquery {
3727 this: result,
3728 alias: None,
3729 column_aliases: Vec::new(),
3730 order_by: None,
3731 limit,
3732 offset,
3733 distribute_by: None,
3734 sort_by: None,
3735 cluster_by: None,
3736 lateral: false,
3737 modifiers_inside: true, trailing_comments: Vec::new(),
3739 inferred_type: None,
3740 }))
3741 } else {
3742 result
3743 };
3744
3745 self.expect(TokenType::RParen)?;
3746 let had_modifiers = matches!(&result, Expression::Subquery(s) if s.order_by.is_some() || s.limit.is_some() || s.offset.is_some());
3753 let result_is_subquery_of_set_op = matches!(&result, Expression::Subquery(s) if matches!(&s.this, Expression::Union(_) | Expression::Intersect(_) | Expression::Except(_)));
3754 if had_modifiers || result_is_subquery_of_set_op {
3755 result
3757 } else {
3758 Expression::Paren(Box::new(Paren {
3760 this: result,
3761 trailing_comments: Vec::new(),
3762 }))
3763 }
3764 } else if self.is_identifier_token()
3765 || self.is_safe_keyword_as_identifier()
3766 || self.can_be_alias_keyword()
3767 {
3768 let (left, joins) = self.parse_table_expression_with_joins()?;
3771 let lateral_views = self.parse_lateral_views()?;
3773 self.expect(TokenType::RParen)?;
3774 if joins.is_empty() && lateral_views.is_empty() {
3775 Expression::Paren(Box::new(Paren {
3777 this: left,
3778 trailing_comments: Vec::new(),
3779 }))
3780 } else {
3781 Expression::JoinedTable(Box::new(JoinedTable {
3783 left,
3784 joins,
3785 lateral_views,
3786 alias: None, }))
3788 }
3789 } else {
3790 let query = self.parse_statement()?;
3791 self.expect(TokenType::RParen)?;
3792 Expression::Subquery(Box::new(Subquery {
3793 this: query,
3794 alias: None,
3795 column_aliases: Vec::new(),
3796 order_by: None,
3797 limit: None,
3798 offset: None,
3799 distribute_by: None,
3800 sort_by: None,
3801 cluster_by: None,
3802 lateral: false,
3803 modifiers_inside: false,
3804 trailing_comments: self.previous_trailing_comments().to_vec(),
3805 inferred_type: None,
3806 }))
3807 }
3808 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier() || self.can_be_alias_keyword()
3809 || (matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)) && self.check(TokenType::Number))
3810 || self.is_mysql_numeric_identifier()
3811 || (self.check(TokenType::Pivot) && !self.check_next(TokenType::LParen))
3813 || (self.check(TokenType::Unpivot) && !self.check_next(TokenType::LParen))
3814 || (matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)) && self.check(TokenType::LBrace))
3816 || (matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse))
3818 && (self.check(TokenType::Union) || self.check(TokenType::Except) || self.check(TokenType::Intersect))
3819 && !self.check_next(TokenType::All) && !self.check_next(TokenType::Distinct)
3820 && !self.check_next(TokenType::Select) && !self.check_next(TokenType::LParen))
3821 {
3822 if matches!(
3830 self.config.dialect,
3831 Some(crate::dialects::DialectType::DuckDB)
3832 ) && self.check_next(TokenType::Colon)
3833 && !(self.current + 2 < self.tokens.len()
3834 && self.tokens[self.current + 2].token_type == TokenType::Colon)
3835 {
3836 let alias_ident = self.parse_bigquery_table_part()?;
3838 let pre_alias_comments = self.previous_trailing_comments().to_vec();
3839 self.expect(TokenType::Colon)?;
3841 let colon_comments = self.previous_trailing_comments().to_vec();
3842 let mut table_expr = self.parse_table_expression()?;
3844 let mut all_comments = pre_alias_comments;
3846 all_comments.extend(colon_comments);
3847 match &mut table_expr {
3849 Expression::Table(ref mut t) => {
3850 t.alias = Some(alias_ident);
3851 t.alias_explicit_as = true; if !all_comments.is_empty() {
3856 let existing_comments = std::mem::take(&mut t.trailing_comments);
3857 t.trailing_comments = all_comments;
3858 t.trailing_comments.extend(existing_comments);
3859 }
3860 }
3861 Expression::Subquery(ref mut s) => {
3862 s.alias = Some(alias_ident);
3863 }
3864 Expression::Function(ref mut _f) => {
3865 return Ok(Expression::Alias(Box::new(Alias {
3867 this: table_expr,
3868 alias: alias_ident,
3869 column_aliases: Vec::new(),
3870 pre_alias_comments: all_comments,
3871 trailing_comments: Vec::new(),
3872 inferred_type: None,
3873 })));
3874 }
3875 _ => {
3876 return Ok(Expression::Alias(Box::new(Alias {
3878 this: table_expr,
3879 alias: alias_ident,
3880 column_aliases: Vec::new(),
3881 pre_alias_comments: all_comments,
3882 trailing_comments: Vec::new(),
3883 inferred_type: None,
3884 })));
3885 }
3886 }
3887 return Ok(table_expr);
3888 }
3889
3890 let first_ident = self.parse_bigquery_table_part()?;
3891 let first_name = first_ident.name.clone();
3892
3893 if self.match_token(TokenType::Dot) {
3895 if self.check(TokenType::Dot) {
3897 self.skip(); let table_ident = self.parse_bigquery_table_part()?;
3900 let trailing_comments = self.previous_trailing_comments().to_vec();
3901 return Ok(Expression::boxed_table(TableRef {
3902 catalog: Some(first_ident),
3903 schema: Some(Identifier::new("")), name: table_ident,
3905 alias: None,
3906 alias_explicit_as: false,
3907 column_aliases: Vec::new(),
3908 leading_comments: Vec::new(),
3909 trailing_comments,
3910 when: None,
3911 only: false,
3912 final_: false,
3913 table_sample: None,
3914 hints: Vec::new(),
3915 system_time: None,
3916 partitions: Vec::new(),
3917 identifier_func: None,
3918 changes: None,
3919 version: None,
3920 span: None,
3921 }));
3922 }
3923
3924 if matches!(
3927 self.config.dialect,
3928 Some(crate::dialects::DialectType::BigQuery)
3929 ) && self.check(TokenType::Star)
3930 {
3931 self.skip(); let trailing_comments = self.previous_trailing_comments().to_vec();
3933 return Ok(Expression::boxed_table(TableRef {
3934 catalog: None,
3935 schema: Some(first_ident),
3936 name: Identifier::new("*"),
3937 alias: None,
3938 alias_explicit_as: false,
3939 column_aliases: Vec::new(),
3940 leading_comments: Vec::new(),
3941 trailing_comments,
3942 when: None,
3943 only: false,
3944 final_: false,
3945 table_sample: None,
3946 hints: Vec::new(),
3947 system_time: None,
3948 partitions: Vec::new(),
3949 identifier_func: None,
3950 changes: None,
3951 version: None,
3952 span: None,
3953 }));
3954 }
3955
3956 let second_ident = self.parse_bigquery_table_part()?;
3959 let second_name = second_ident.name.clone();
3960
3961 if self.match_token(TokenType::Dot) {
3962 if matches!(
3964 self.config.dialect,
3965 Some(crate::dialects::DialectType::BigQuery)
3966 ) && self.check(TokenType::Star)
3967 {
3968 self.skip(); let trailing_comments = self.previous_trailing_comments().to_vec();
3970 return Ok(Expression::boxed_table(TableRef {
3971 catalog: Some(first_ident),
3972 schema: Some(second_ident),
3973 name: Identifier::new("*"),
3974 alias: None,
3975 alias_explicit_as: false,
3976 column_aliases: Vec::new(),
3977 leading_comments: Vec::new(),
3978 trailing_comments,
3979 when: None,
3980 only: false,
3981 final_: false,
3982 table_sample: None,
3983 hints: Vec::new(),
3984 system_time: None,
3985 partitions: Vec::new(),
3986 identifier_func: None,
3987 changes: None,
3988 version: None,
3989 span: None,
3990 }));
3991 }
3992 let third_ident = self.parse_bigquery_table_part()?;
3994 let third_name = third_ident.name.clone();
3995
3996 if self.match_token(TokenType::Dot) {
3998 let fourth_ident = self.parse_bigquery_table_part()?;
3999 let mut table_name = fourth_ident;
4001 if matches!(
4002 self.config.dialect,
4003 Some(crate::dialects::DialectType::BigQuery)
4004 ) && self.check(TokenType::Star)
4005 && self.is_connected()
4006 {
4007 self.skip(); table_name.name.push('*');
4009 }
4010 let trailing_comments = self.previous_trailing_comments().to_vec();
4011 Expression::boxed_table(TableRef {
4013 catalog: Some(Identifier::new(format!(
4014 "{}.{}",
4015 first_name, second_name
4016 ))),
4017 schema: Some(third_ident),
4018 name: table_name,
4019 alias: None,
4020 alias_explicit_as: false,
4021 column_aliases: Vec::new(),
4022 leading_comments: Vec::new(),
4023 trailing_comments,
4024 when: None,
4025 only: false,
4026 final_: false,
4027 table_sample: None,
4028 hints: Vec::new(),
4029 system_time: None,
4030 partitions: Vec::new(),
4031 identifier_func: None,
4032 changes: None,
4033 version: None,
4034 span: None,
4035 })
4036 } else if self.match_token(TokenType::LParen) {
4037 let args = if self.check(TokenType::RParen) {
4039 Vec::new()
4040 } else {
4041 self.parse_function_arguments()?
4042 };
4043 self.expect(TokenType::RParen)?;
4044 let trailing_comments = self.previous_trailing_comments().to_vec();
4045 Expression::Function(Box::new(Function {
4046 name: format!("{}.{}.{}", first_name, second_name, third_name),
4047 args,
4048 distinct: false,
4049 trailing_comments,
4050 use_bracket_syntax: false,
4051 no_parens: false,
4052 quoted: false,
4053 span: None,
4054 inferred_type: None,
4055 }))
4056 } else {
4057 let mut table_name = third_ident;
4060 if matches!(
4061 self.config.dialect,
4062 Some(crate::dialects::DialectType::BigQuery)
4063 ) && self.check(TokenType::Star)
4064 && self.is_connected()
4065 {
4066 self.skip(); table_name.name.push('*');
4068 }
4069 let trailing_comments = self.previous_trailing_comments().to_vec();
4070 Expression::boxed_table(TableRef {
4071 catalog: Some(first_ident),
4072 schema: Some(second_ident),
4073 name: table_name,
4074 alias: None,
4075 alias_explicit_as: false,
4076 column_aliases: Vec::new(),
4077 leading_comments: Vec::new(),
4078 trailing_comments,
4079 when: None,
4080 only: false,
4081 final_: false,
4082 table_sample: None,
4083 hints: Vec::new(),
4084 system_time: None,
4085 partitions: Vec::new(),
4086 identifier_func: None,
4087 changes: None,
4088 version: None,
4089 span: None,
4090 })
4091 }
4092 } else if self.match_token(TokenType::LParen) {
4093 let args = if self.check(TokenType::RParen) {
4095 Vec::new()
4096 } else {
4097 self.parse_function_arguments()?
4098 };
4099 self.expect(TokenType::RParen)?;
4100 let trailing_comments = self.previous_trailing_comments().to_vec();
4101 Expression::Function(Box::new(Function {
4102 name: format!("{}.{}", first_name, second_name),
4103 args,
4104 distinct: false,
4105 trailing_comments,
4106 use_bracket_syntax: false,
4107 no_parens: false,
4108 quoted: false,
4109 span: None,
4110 inferred_type: None,
4111 }))
4112 } else {
4113 let mut table_name = second_ident;
4116 if matches!(
4117 self.config.dialect,
4118 Some(crate::dialects::DialectType::BigQuery)
4119 ) && self.check(TokenType::Star)
4120 && self.is_connected()
4121 {
4122 self.skip(); table_name.name.push('*');
4124 }
4125 let trailing_comments = self.previous_trailing_comments().to_vec();
4126 Expression::boxed_table(TableRef {
4127 catalog: None,
4128 schema: Some(first_ident),
4129 name: table_name,
4130 alias: None,
4131 alias_explicit_as: false,
4132 column_aliases: Vec::new(),
4133 leading_comments: Vec::new(),
4134 trailing_comments,
4135 when: None,
4136 only: false,
4137 final_: false,
4138 table_sample: None,
4139 hints: Vec::new(),
4140 system_time: None,
4141 partitions: Vec::new(),
4142 identifier_func: None,
4143 changes: None,
4144 version: None,
4145 span: None,
4146 })
4147 }
4148 } else if self.match_token(TokenType::LParen) {
4149 if first_name.eq_ignore_ascii_case("JSON_TABLE") {
4151 let this = self
4153 .parse_bitwise()?
4154 .unwrap_or(Expression::Null(crate::expressions::Null));
4155
4156 let this_with_format = if self.match_text_seq(&["FORMAT", "JSON"]) {
4158 Expression::JSONFormat(Box::new(crate::expressions::JSONFormat {
4159 this: Some(Box::new(this)),
4160 options: Vec::new(),
4161 is_json: None,
4162 to_json: None,
4163 }))
4164 } else {
4165 this
4166 };
4167
4168 let path = if self.match_token(TokenType::Comma) {
4170 if let Some(s) = self.parse_string()? {
4171 Some(Box::new(s))
4172 } else {
4173 None
4174 }
4175 } else {
4176 None
4177 };
4178
4179 let error_handling = if self.match_identifier("ERROR")
4182 && self.match_text_seq(&["ON", "ERROR"])
4183 {
4184 Some(Box::new(Expression::Var(Box::new(Var {
4185 this: "ERROR ON ERROR".to_string(),
4186 }))))
4187 } else if self.match_text_seq(&["NULL", "ON", "ERROR"]) {
4188 Some(Box::new(Expression::Var(Box::new(Var {
4189 this: "NULL ON ERROR".to_string(),
4190 }))))
4191 } else {
4192 None
4193 };
4194
4195 let empty_handling = if self.match_identifier("ERROR")
4197 && self.match_text_seq(&["ON", "EMPTY"])
4198 {
4199 Some(Box::new(Expression::Var(Box::new(Var {
4200 this: "ERROR ON EMPTY".to_string(),
4201 }))))
4202 } else if self.match_text_seq(&["NULL", "ON", "EMPTY"]) {
4203 Some(Box::new(Expression::Var(Box::new(Var {
4204 this: "NULL ON EMPTY".to_string(),
4205 }))))
4206 } else {
4207 None
4208 };
4209
4210 let schema = self.parse_json_table_columns()?;
4212
4213 self.expect(TokenType::RParen)?;
4214
4215 Expression::JSONTable(Box::new(JSONTable {
4216 this: Box::new(this_with_format),
4217 schema: schema.map(Box::new),
4218 path,
4219 error_handling,
4220 empty_handling,
4221 }))
4222 } else if first_name.eq_ignore_ascii_case("XMLTABLE") {
4223 if let Some(xml_table) = self.parse_xml_table()? {
4226 self.expect(TokenType::RParen)?;
4227 xml_table
4228 } else {
4229 return Err(self.parse_error("Failed to parse XMLTABLE"));
4230 }
4231 } else if first_name.eq_ignore_ascii_case("OPENJSON") {
4232 if let Some(openjson_expr) = self.parse_open_json()? {
4235 openjson_expr
4236 } else {
4237 return Err(self.parse_error("Failed to parse OPENJSON"));
4238 }
4239 } else if first_name.eq_ignore_ascii_case("SEMANTIC_VIEW") {
4240 let semantic_view = self.parse_semantic_view()?;
4243 self.expect(TokenType::RParen)?;
4244 semantic_view
4245 } else if (first_name.eq_ignore_ascii_case("view")
4246 || first_name.eq_ignore_ascii_case("merge"))
4247 && (self.check(TokenType::Select) || self.check(TokenType::With))
4248 {
4249 let query = self.parse_statement()?;
4252 self.expect(TokenType::RParen)?;
4253 let trailing_comments = self.previous_trailing_comments().to_vec();
4254 Expression::Function(Box::new(Function {
4255 name: first_name.to_string(),
4256 args: vec![query],
4257 distinct: false,
4258 trailing_comments,
4259 use_bracket_syntax: false,
4260 no_parens: false,
4261 quoted: false,
4262 span: None,
4263 inferred_type: None,
4264 }))
4265 } else {
4266 let args = if self.check(TokenType::RParen) {
4268 Vec::new()
4269 } else {
4270 self.parse_function_arguments()?
4271 };
4272 self.expect(TokenType::RParen)?;
4273 let trailing_comments = self.previous_trailing_comments().to_vec();
4274
4275 if first_name.eq_ignore_ascii_case("UNNEST") {
4277 let with_ordinality = self
4280 .match_keywords(&[TokenType::With, TokenType::Ordinality])
4281 || self.match_text_seq(&["WITH", "OFFSET"]);
4282 let offset_alias = if with_ordinality
4284 && matches!(
4285 self.config.dialect,
4286 Some(crate::dialects::DialectType::BigQuery)
4287 ) {
4288 let has_as = self.match_token(TokenType::As);
4289 if has_as
4290 || (self.check(TokenType::Identifier) || self.check(TokenType::Var))
4291 {
4292 let alias_name = self.advance().text;
4293 Some(crate::expressions::Identifier {
4294 name: alias_name,
4295 quoted: false,
4296 trailing_comments: Vec::new(),
4297 span: None,
4298 })
4299 } else {
4300 None
4301 }
4302 } else {
4303 None
4304 };
4305 let mut args_iter = args.into_iter();
4306 let this = args_iter
4307 .next()
4308 .ok_or_else(|| self.parse_error("Expected expression in UNNEST"))?;
4309 let expressions: Vec<Expression> = args_iter.collect();
4310 Expression::Unnest(Box::new(crate::expressions::UnnestFunc {
4311 this,
4312 expressions,
4313 with_ordinality,
4314 alias: None,
4315 offset_alias,
4316 }))
4317 } else {
4318 let with_ordinality =
4320 self.match_keywords(&[TokenType::With, TokenType::Ordinality]);
4321 let func_name = if with_ordinality {
4322 format!("{} WITH ORDINALITY", first_name)
4323 } else {
4324 first_name.clone()
4325 };
4326 let func = Function {
4327 name: func_name,
4328 args,
4329 distinct: false,
4330 trailing_comments,
4331 use_bracket_syntax: false,
4332 no_parens: false,
4333 quoted: false,
4334 span: None,
4335 inferred_type: None,
4336 };
4337 let func_expr = Expression::Function(Box::new(func));
4338
4339 if self.check(TokenType::Dot) {
4343 self.skip(); let part1 = self.parse_bigquery_table_part()?;
4345 if self.match_token(TokenType::Dot) {
4346 let part2 = self.parse_bigquery_table_part()?;
4347 if self.match_token(TokenType::Dot) {
4348 let part3 = self.parse_bigquery_table_part()?;
4350 let tc = self.previous_trailing_comments().to_vec();
4351 Expression::boxed_table(TableRef {
4352 catalog: Some(part1),
4353 schema: Some(part2),
4354 name: part3,
4355 alias: None,
4356 alias_explicit_as: false,
4357 column_aliases: Vec::new(),
4358 leading_comments: Vec::new(),
4359 trailing_comments: tc,
4360 when: None,
4361 only: false,
4362 final_: false,
4363 table_sample: None,
4364 hints: Vec::new(),
4365 system_time: None,
4366 partitions: Vec::new(),
4367 identifier_func: Some(Box::new(func_expr)),
4368 changes: None,
4369 version: None,
4370 span: None,
4371 })
4372 } else {
4373 let tc = self.previous_trailing_comments().to_vec();
4375 Expression::boxed_table(TableRef {
4376 catalog: None,
4377 schema: Some(part1),
4378 name: part2,
4379 alias: None,
4380 alias_explicit_as: false,
4381 column_aliases: Vec::new(),
4382 leading_comments: Vec::new(),
4383 trailing_comments: tc,
4384 when: None,
4385 only: false,
4386 final_: false,
4387 table_sample: None,
4388 hints: Vec::new(),
4389 system_time: None,
4390 partitions: Vec::new(),
4391 identifier_func: Some(Box::new(func_expr)),
4392 changes: None,
4393 version: None,
4394 span: None,
4395 })
4396 }
4397 } else {
4398 let tc = self.previous_trailing_comments().to_vec();
4400 Expression::boxed_table(TableRef {
4401 catalog: None,
4402 schema: None,
4403 name: part1,
4404 alias: None,
4405 alias_explicit_as: false,
4406 column_aliases: Vec::new(),
4407 leading_comments: Vec::new(),
4408 trailing_comments: tc,
4409 when: None,
4410 only: false,
4411 final_: false,
4412 table_sample: None,
4413 hints: Vec::new(),
4414 system_time: None,
4415 partitions: Vec::new(),
4416 identifier_func: Some(Box::new(func_expr)),
4417 changes: None,
4418 version: None,
4419 span: None,
4420 })
4421 }
4422 } else {
4423 func_expr
4424 }
4425 }
4426 }
4427 } else {
4428 let mut table_name = first_ident;
4431 if matches!(
4432 self.config.dialect,
4433 Some(crate::dialects::DialectType::BigQuery)
4434 ) && self.check(TokenType::Star)
4435 && self.is_connected()
4436 {
4437 self.skip(); table_name.name.push('*');
4439 }
4440 let trailing_comments = self.previous_trailing_comments().to_vec();
4441 Expression::boxed_table(TableRef {
4442 catalog: None,
4443 schema: None,
4444 name: table_name,
4445 alias: None,
4446 alias_explicit_as: false,
4447 column_aliases: Vec::new(),
4448 leading_comments: Vec::new(),
4449 trailing_comments,
4450 when: None,
4451 only: false,
4452 final_: false,
4453 table_sample: None,
4454 hints: Vec::new(),
4455 system_time: None,
4456 partitions: Vec::new(),
4457 identifier_func: None,
4458 changes: None,
4459 version: None,
4460 span: None,
4461 })
4462 }
4463 } else if self.check(TokenType::LBrace) {
4464 if let Some(param) = self.parse_clickhouse_braced_parameter()? {
4466 param
4467 } else {
4468 self.skip(); if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
4471 let name_token = self.advance();
4472 self.expect(TokenType::RBrace)?;
4473 Expression::Parameter(Box::new(Parameter {
4474 name: Some(name_token.text.clone()),
4475 index: None,
4476 style: ParameterStyle::Brace,
4477 quoted: false,
4478 string_quoted: false,
4479 expression: None,
4480 }))
4481 } else {
4482 return Err(self.parse_error("Expected identifier after {"));
4483 }
4484 }
4485 } else if self.check(TokenType::Dollar) && self.check_next(TokenType::LBrace) {
4486 self.skip(); self.skip(); if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
4491 let name_token = self.advance();
4492 let expression = if self.match_token(TokenType::Colon) {
4494 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
4495 let expr_token = self.advance();
4496 Some(expr_token.text.clone())
4497 } else {
4498 return Err(self.parse_error("Expected identifier after : in ${...}"));
4499 }
4500 } else {
4501 None
4502 };
4503 self.expect(TokenType::RBrace)?;
4504 Expression::Parameter(Box::new(Parameter {
4505 name: Some(name_token.text.clone()),
4506 index: None,
4507 style: ParameterStyle::DollarBrace,
4508 quoted: false,
4509 string_quoted: false,
4510 expression,
4511 }))
4512 } else {
4513 return Err(self.parse_error("Expected identifier after ${"));
4514 }
4515 } else if self.check(TokenType::String) {
4516 let string_token = self.advance();
4519 let table_name = Identifier {
4520 name: string_token.text.clone(),
4521 quoted: true,
4522 trailing_comments: Vec::new(),
4523 span: None,
4524 };
4525 let trailing_comments = self.previous_trailing_comments().to_vec();
4526 Expression::boxed_table(TableRef {
4527 catalog: None,
4528 schema: None,
4529 name: table_name,
4530 alias: None,
4531 alias_explicit_as: false,
4532 column_aliases: Vec::new(),
4533 leading_comments: Vec::new(),
4534 trailing_comments,
4535 when: None,
4536 only: false,
4537 final_: false,
4538 table_sample: None,
4539 hints: Vec::new(),
4540 system_time: None,
4541 partitions: Vec::new(),
4542 identifier_func: None,
4543 changes: None,
4544 version: None,
4545 span: None,
4546 })
4547 } else {
4548 return Err(self.parse_error(format!(
4549 "Expected table name or subquery, got {:?}",
4550 self.peek().token_type
4551 )));
4552 };
4553
4554 self.match_token(TokenType::Star);
4557
4558 if self.check_keyword_text("CHANGES") {
4561 if let Some(changes_expr) = self.parse_changes()? {
4562 if let Expression::Table(ref mut table) = expr {
4563 if let Expression::Changes(changes_box) = changes_expr {
4564 table.changes = Some(changes_box);
4565 }
4566 }
4567 }
4568 }
4569
4570 if self.check(TokenType::Before) || self.check_keyword_text("AT") {
4572 if let Some(historical_expr) = self.parse_historical_data()? {
4573 if let Expression::Table(ref mut table) = expr {
4575 if let Expression::HistoricalData(hd) = historical_expr {
4576 table.when = Some(hd);
4577 }
4578 }
4579 }
4580 }
4581
4582 if !matches!(
4589 self.config.dialect,
4590 Some(crate::dialects::DialectType::BigQuery)
4591 ) && self.check(TokenType::For)
4592 && self.current + 1 < self.tokens.len()
4593 && self.tokens[self.current + 1]
4594 .text
4595 .eq_ignore_ascii_case("SYSTEM_TIME")
4596 {
4597 self.skip(); self.skip(); let system_time_str = if self.match_token(TokenType::As) {
4600 if self.check_keyword_text("OF") {
4602 self.skip(); let start = self.current;
4604 while !self.is_at_end()
4606 && !self.check(TokenType::Semicolon)
4607 && !self.check(TokenType::Where)
4608 && !self.check(TokenType::Join)
4609 && !self.check(TokenType::Left)
4610 && !self.check(TokenType::Right)
4611 && !self.check(TokenType::Inner)
4612 && !self.check(TokenType::Outer)
4613 && !self.check(TokenType::Full)
4614 && !self.check(TokenType::Cross)
4615 && !self.check(TokenType::Order)
4616 && !self.check(TokenType::Group)
4617 && !self.check(TokenType::Having)
4618 && !self.check(TokenType::Limit)
4619 && !self.check(TokenType::Union)
4620 && !self.check(TokenType::Except)
4621 && !self.check(TokenType::Intersect)
4622 && !self.check(TokenType::As)
4623 && !self.check(TokenType::Comma)
4624 && !self.check(TokenType::RParen)
4625 && !self.check(TokenType::With)
4626 && !self.check(TokenType::Pivot)
4627 && !self.check(TokenType::Unpivot)
4628 {
4629 self.skip();
4630 }
4631 let expr_text = self.tokens_to_sql_uppercased(start, self.current);
4632 format!("FOR SYSTEM_TIME AS OF {}", expr_text)
4633 } else {
4634 "FOR SYSTEM_TIME AS".to_string()
4635 }
4636 } else if self.match_token(TokenType::Between) {
4637 let start = self.current;
4639 while !self.is_at_end() && !self.check(TokenType::And) {
4640 self.skip();
4641 }
4642 let expr1_text = self.tokens_to_sql_uppercased(start, self.current);
4643 self.skip(); let start2 = self.current;
4645 while !self.is_at_end()
4646 && !self.check(TokenType::Semicolon)
4647 && !self.check(TokenType::Where)
4648 && !self.check(TokenType::Join)
4649 && !self.check(TokenType::Left)
4650 && !self.check(TokenType::Right)
4651 && !self.check(TokenType::Inner)
4652 && !self.check(TokenType::Outer)
4653 && !self.check(TokenType::Full)
4654 && !self.check(TokenType::Cross)
4655 && !self.check(TokenType::Order)
4656 && !self.check(TokenType::Group)
4657 && !self.check(TokenType::Having)
4658 && !self.check(TokenType::Limit)
4659 && !self.check(TokenType::Union)
4660 && !self.check(TokenType::Except)
4661 && !self.check(TokenType::Intersect)
4662 && !self.check(TokenType::As)
4663 && !self.check(TokenType::Comma)
4664 && !self.check(TokenType::RParen)
4665 && !self.check(TokenType::With)
4666 && !self.check(TokenType::Pivot)
4667 && !self.check(TokenType::Unpivot)
4668 {
4669 self.skip();
4670 }
4671 let expr2_text = self.tokens_to_sql_uppercased(start2, self.current);
4672 format!("FOR SYSTEM_TIME BETWEEN {} AND {}", expr1_text, expr2_text)
4673 } else if self.match_token(TokenType::From) {
4674 let start = self.current;
4676 while !self.is_at_end() && !self.check(TokenType::To) {
4677 self.skip();
4678 }
4679 let expr1_text = self.tokens_to_sql_uppercased(start, self.current);
4680 self.skip(); let start2 = self.current;
4682 while !self.is_at_end()
4683 && !self.check(TokenType::Semicolon)
4684 && !self.check(TokenType::Where)
4685 && !self.check(TokenType::As)
4686 && !self.check(TokenType::Comma)
4687 && !self.check(TokenType::RParen)
4688 {
4689 self.skip();
4690 }
4691 let expr2_text = self.tokens_to_sql_uppercased(start2, self.current);
4692 format!("FOR SYSTEM_TIME FROM {} TO {}", expr1_text, expr2_text)
4693 } else if self.check_identifier("CONTAINED") {
4694 self.skip(); self.expect(TokenType::In)?;
4696 self.expect(TokenType::LParen)?;
4697 let start = self.current;
4698 let mut depth = 1;
4699 while !self.is_at_end() && depth > 0 {
4700 if self.check(TokenType::LParen) {
4701 depth += 1;
4702 }
4703 if self.check(TokenType::RParen) {
4704 depth -= 1;
4705 if depth == 0 {
4706 break;
4707 }
4708 }
4709 self.skip();
4710 }
4711 let inner_text = self.tokens_to_sql_uppercased(start, self.current);
4712 self.expect(TokenType::RParen)?;
4713 format!("FOR SYSTEM_TIME CONTAINED IN ({})", inner_text)
4714 } else if self.match_token(TokenType::All) {
4715 "FOR SYSTEM_TIME ALL".to_string()
4716 } else {
4717 "FOR SYSTEM_TIME".to_string()
4718 };
4719 if let Expression::Table(ref mut table) = expr {
4720 table.system_time = Some(system_time_str);
4721 }
4722 }
4723
4724 if self.check(TokenType::For) && self.current + 1 < self.tokens.len() {
4728 let next_text = &self.tokens[self.current + 1].text;
4729 if next_text.eq_ignore_ascii_case("VERSION")
4730 || next_text.eq_ignore_ascii_case("TIMESTAMP")
4731 {
4732 self.skip(); let version_kind = self.advance().text.to_ascii_uppercase(); if self.match_token(TokenType::As) && self.check_keyword_text("OF") {
4737 self.skip(); if let Some(value_expr) = self.parse_bitwise()? {
4741 let version = crate::expressions::Version {
4742 this: Box::new(Expression::Identifier(Identifier::new(&version_kind))),
4743 kind: "AS OF".to_string(),
4744 expression: Some(Box::new(value_expr)),
4745 };
4746 if let Expression::Table(ref mut table) = expr {
4747 table.version = Some(Box::new(version));
4748 }
4749 }
4750 }
4751 }
4752 }
4753
4754 if self.current < self.tokens.len() {
4758 let current_text = &self.tokens[self.current].text;
4759 if (current_text.eq_ignore_ascii_case("TIMESTAMP")
4760 || current_text.eq_ignore_ascii_case("VERSION"))
4761 && self.current + 2 < self.tokens.len()
4762 && self.tokens[self.current + 1].token_type == TokenType::As
4763 && self.tokens[self.current + 2]
4764 .text
4765 .eq_ignore_ascii_case("OF")
4766 {
4767 let version_kind = self.advance().text.to_ascii_uppercase(); self.skip(); self.skip(); if let Some(value_expr) = self.parse_bitwise()? {
4773 let version = crate::expressions::Version {
4774 this: Box::new(Expression::Identifier(Identifier::new(&version_kind))),
4775 kind: "AS OF".to_string(),
4776 expression: Some(Box::new(value_expr)),
4777 };
4778 if let Expression::Table(ref mut table) = expr {
4779 table.version = Some(Box::new(version));
4780 }
4781 }
4782 }
4783 }
4784
4785 let supports_partition_selection = matches!(
4788 self.config.dialect,
4789 Some(crate::dialects::DialectType::MySQL)
4790 | Some(crate::dialects::DialectType::SingleStore)
4791 | Some(crate::dialects::DialectType::Doris)
4792 | Some(crate::dialects::DialectType::StarRocks)
4793 );
4794 if supports_partition_selection && self.match_token(TokenType::Partition) {
4795 if self.match_token(TokenType::LParen) {
4796 let mut partitions = Vec::new();
4797 loop {
4798 let partition_name = self.expect_identifier_or_keyword_with_quoted()?;
4799 partitions.push(partition_name);
4800 if !self.match_token(TokenType::Comma) {
4801 break;
4802 }
4803 }
4804 self.expect(TokenType::RParen)?;
4805 if let Expression::Table(ref mut table) = expr {
4806 table.partitions = partitions;
4807 }
4808 }
4809 }
4810
4811 if self.check(TokenType::TableSample) || self.check(TokenType::Sample) {
4814 if let Some(sample) = self.parse_table_level_sample()? {
4815 if let Expression::Table(ref mut table) = expr {
4816 table.table_sample = Some(Box::new(sample));
4817 } else {
4818 expr = Expression::TableSample(Box::new(crate::expressions::TableSample {
4821 this: Some(Box::new(expr)),
4822 sample: Some(Box::new(sample)),
4823 expressions: Vec::new(),
4824 method: None,
4825 bucket_numerator: None,
4826 bucket_denominator: None,
4827 bucket_field: None,
4828 percent: None,
4829 rows: None,
4830 size: None,
4831 seed: None,
4832 }));
4833 }
4834 }
4835 }
4836
4837 if self.check(TokenType::With) && self.check_next(TokenType::LParen) {
4839 if let Expression::Table(ref mut table) = expr {
4840 if let Some(hint_expr) = self.parse_table_hints()? {
4841 match hint_expr {
4844 Expression::Tuple(tuple) => {
4845 table.hints = tuple.expressions;
4846 }
4847 other => {
4848 table.hints = vec![other];
4849 }
4850 }
4851 }
4852 }
4853 }
4854
4855 if self.check_keyword_text("USE")
4857 || self.check(TokenType::Ignore)
4858 || self.check_keyword_text("FORCE")
4859 {
4860 let next_idx = self.current + 1;
4862 let is_index_hint = next_idx < self.tokens.len() && {
4863 let next_text = &self.tokens[next_idx].text;
4864 next_text.eq_ignore_ascii_case("INDEX") || next_text.eq_ignore_ascii_case("KEY")
4865 };
4866 if is_index_hint {
4867 if let Expression::Table(ref mut table) = expr {
4868 if let Some(hint_expr) = self.parse_table_hints()? {
4869 match hint_expr {
4870 Expression::Tuple(tuple) => {
4871 table.hints = tuple.expressions;
4872 }
4873 other => {
4874 table.hints = vec![other];
4875 }
4876 }
4877 }
4878 }
4879 }
4880 }
4881
4882 if self.check_identifier("INDEXED") {
4884 self.skip(); self.expect(TokenType::By)?;
4886 let first_part = self.expect_identifier_or_keyword()?;
4888 let index_name = if self.match_token(TokenType::Dot) {
4889 let second_part = self.expect_identifier_or_keyword()?;
4890 format!("{}.{}", first_part, second_part)
4891 } else {
4892 first_part
4893 };
4894 if let Expression::Table(ref mut table) = expr {
4895 table.hints.push(Expression::Identifier(Identifier {
4896 name: format!("INDEXED BY {}", index_name),
4897 quoted: false,
4898 trailing_comments: Vec::new(),
4899 span: None,
4900 }));
4901 }
4902 } else if self.check(TokenType::Not) && self.check_next_identifier("INDEXED") {
4903 self.skip(); self.skip(); if let Expression::Table(ref mut table) = expr {
4906 table.hints.push(Expression::Identifier(Identifier {
4907 name: "NOT INDEXED".to_string(),
4908 quoted: false,
4909 trailing_comments: Vec::new(),
4910 span: None,
4911 }));
4912 }
4913 }
4914
4915 if self.check(TokenType::Pivot) && self.check_next(TokenType::LParen) {
4918 self.skip(); expr = self.parse_pivot(expr)?;
4920 }
4921 if self.check(TokenType::Unpivot) && self.is_unpivot_clause_start() {
4924 self.skip(); expr = self.parse_unpivot(expr)?;
4926 }
4927 else if self.check(TokenType::MatchRecognize)
4929 && !matches!(&expr, Expression::Pivot(_) | Expression::Unpivot(_))
4930 {
4931 self.skip();
4932 expr = self.parse_match_recognize(Some(expr))?;
4933 }
4934
4935 if self.match_token(TokenType::As) {
4937 if self.check(TokenType::LParen) {
4939 self.skip(); let mut column_aliases = Vec::new();
4941 loop {
4942 if self.check(TokenType::RParen) {
4943 break;
4944 }
4945 column_aliases.push(Identifier::new(self.expect_identifier_or_keyword()?));
4946 if !self.match_token(TokenType::Comma) {
4947 break;
4948 }
4949 }
4950 self.expect(TokenType::RParen)?;
4951 expr = Expression::Alias(Box::new(Alias {
4952 this: expr,
4953 alias: Identifier::new(String::new()),
4954 column_aliases,
4955 pre_alias_comments: Vec::new(),
4956 trailing_comments: Vec::new(),
4957 inferred_type: None,
4958 }));
4959 } else {
4960 let alias_ident_parsed = self.expect_identifier_or_alias_keyword_with_quoted()?;
4961 let alias = alias_ident_parsed.name;
4962 let alias_is_quoted = alias_ident_parsed.quoted;
4963 let make_alias_ident = |name: String| -> Identifier {
4964 if alias_is_quoted {
4965 Identifier::quoted(name)
4966 } else {
4967 Identifier::new(name)
4968 }
4969 };
4970 if self.match_token(TokenType::LParen) {
4972 let has_typed_columns = self.check_typed_column_list();
4976
4977 if has_typed_columns {
4978 let mut typed_cols = Vec::new();
4980 loop {
4981 if self.check(TokenType::RParen) {
4982 break;
4983 }
4984 let col_name = self.expect_identifier_or_keyword_with_quoted()?;
4986 let col_type = self.parse_data_type()?;
4988 let mut col_def = ColumnDef::new(col_name.name.clone(), col_type);
4990 col_def.name = col_name;
4991 typed_cols.push(Expression::ColumnDef(Box::new(col_def)));
4992
4993 if !self.match_token(TokenType::Comma) {
4994 break;
4995 }
4996 }
4997 self.expect(TokenType::RParen)?;
4998
4999 let table_alias = Expression::TableAlias(Box::new(TableAlias {
5001 this: Some(Box::new(Expression::Identifier(make_alias_ident(alias)))),
5002 columns: typed_cols,
5003 }));
5004
5005 expr = Expression::Tuple(Box::new(Tuple {
5007 expressions: vec![expr, table_alias],
5008 }));
5009 } else {
5010 let mut aliases = Vec::new();
5013 loop {
5014 if self.check(TokenType::RParen) {
5015 break;
5016 }
5017 aliases.push(Identifier::new(self.expect_identifier_or_keyword()?));
5018 if !self.match_token(TokenType::Comma) {
5019 break;
5020 }
5021 }
5022 self.expect(TokenType::RParen)?;
5023
5024 expr = match expr {
5025 Expression::Table(mut t) => {
5026 t.alias = Some(make_alias_ident(alias));
5027 t.alias_explicit_as = true;
5028 t.column_aliases = aliases;
5029 Expression::Table(t)
5030 }
5031 Expression::Subquery(mut s) => {
5032 s.alias = Some(make_alias_ident(alias));
5033 s.column_aliases = aliases;
5034 Expression::Subquery(s)
5035 }
5036 Expression::Pivot(mut p) => {
5037 p.alias = Some(make_alias_ident(alias));
5038 Expression::Pivot(p)
5039 }
5040 Expression::Unpivot(mut u) => {
5041 u.alias = Some(make_alias_ident(alias));
5042 Expression::Unpivot(u)
5043 }
5044 Expression::MatchRecognize(mut mr) => {
5045 mr.alias = Some(make_alias_ident(alias));
5046 mr.alias_explicit_as = true;
5047 Expression::MatchRecognize(mr)
5048 }
5049 Expression::JoinedTable(mut jt) => {
5050 jt.alias = Some(make_alias_ident(alias));
5051 Expression::JoinedTable(jt)
5052 }
5053 _ => Expression::Alias(Box::new(Alias {
5054 this: expr,
5055 alias: make_alias_ident(alias),
5056 column_aliases: aliases,
5057 pre_alias_comments: Vec::new(),
5058 trailing_comments: Vec::new(),
5059 inferred_type: None,
5060 })),
5061 };
5062 }
5063 } else {
5064 let default_column_aliases = if matches!(
5066 self.config.dialect,
5067 Some(crate::dialects::DialectType::ClickHouse)
5068 ) && matches!(&expr, Expression::Function(func) if func.name.eq_ignore_ascii_case("generate_series"))
5069 {
5070 vec![Identifier::new("generate_series")]
5071 } else {
5072 Vec::new()
5073 };
5074 expr = match expr {
5075 Expression::Table(mut t) => {
5076 t.alias = Some(make_alias_ident(alias));
5077 t.alias_explicit_as = true;
5078 t.column_aliases = Vec::new();
5079 Expression::Table(t)
5080 }
5081 Expression::Subquery(mut s) => {
5082 s.alias = Some(make_alias_ident(alias));
5083 s.column_aliases = Vec::new();
5084 Expression::Subquery(s)
5085 }
5086 Expression::Pivot(mut p) => {
5087 p.alias = Some(make_alias_ident(alias));
5088 Expression::Pivot(p)
5089 }
5090 Expression::Unpivot(mut u) => {
5091 u.alias = Some(make_alias_ident(alias));
5092 Expression::Unpivot(u)
5093 }
5094 Expression::MatchRecognize(mut mr) => {
5095 mr.alias = Some(make_alias_ident(alias));
5096 mr.alias_explicit_as = true;
5097 Expression::MatchRecognize(mr)
5098 }
5099 Expression::JoinedTable(mut jt) => {
5100 jt.alias = Some(make_alias_ident(alias));
5101 Expression::JoinedTable(jt)
5102 }
5103 _ => Expression::Alias(Box::new(Alias {
5104 this: expr,
5105 alias: make_alias_ident(alias),
5106 column_aliases: default_column_aliases,
5107 pre_alias_comments: Vec::new(),
5108 trailing_comments: Vec::new(),
5109 inferred_type: None,
5110 })),
5111 };
5112 }
5113 } } else if (self.check(TokenType::QuotedIdentifier)
5115 || (self.check(TokenType::Var) && !self.check_keyword() && !self.check_identifier("MATCH_CONDITION")
5116 && !(self.check_identifier("ARRAY") && self.check_next(TokenType::Join)
5117 && matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)))
5118 && !(self.check_identifier("OPTION") && self.check_next(TokenType::LParen))
5120 && !(self.check_identifier("LOCK") && self.check_next(TokenType::In))
5122 && !(self.check_identifier("PARALLEL") && self.check_next(TokenType::With)
5124 && matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)))
5125 && !(self.check_identifier("POSITIONAL") && self.check_next(TokenType::Join))))
5127 || self.is_command_keyword_as_alias()
5128 || (matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse))
5131 && (self.check(TokenType::First) || self.check(TokenType::Last)))
5132 || (self.check(TokenType::Pivot) && !self.check_next(TokenType::LParen))
5134 || (self.check(TokenType::Unpivot) && !self.is_unpivot_clause_start())
5135 || (self.check(TokenType::Partition) && !matches!(
5137 self.config.dialect,
5138 Some(crate::dialects::DialectType::MySQL)
5139 | Some(crate::dialects::DialectType::SingleStore)
5140 | Some(crate::dialects::DialectType::Doris)
5141 | Some(crate::dialects::DialectType::StarRocks)
5142 ))
5143 || (self.check(TokenType::Window) && {
5144 let next_pos = self.current + 1;
5146 next_pos >= self.tokens.len()
5147 || (self.tokens[next_pos].token_type != TokenType::Var
5148 && self.tokens[next_pos].token_type != TokenType::Identifier)
5149 })
5150 {
5151 let is_keyword_alias = self.peek().token_type.is_keyword();
5154 let is_quoted_alias = self.peek().token_type == TokenType::QuotedIdentifier;
5155 let alias = self.advance().text.clone();
5156 let mut column_aliases = if self.match_token(TokenType::LParen) {
5159 let mut aliases = Vec::new();
5160 loop {
5161 aliases.push(Identifier::new(self.expect_identifier_or_keyword()?));
5162 if !self.match_token(TokenType::Comma) {
5163 break;
5164 }
5165 }
5166 self.expect(TokenType::RParen)?;
5167 aliases
5168 } else {
5169 Vec::new()
5170 };
5171 if column_aliases.is_empty()
5172 && matches!(
5173 self.config.dialect,
5174 Some(crate::dialects::DialectType::ClickHouse)
5175 )
5176 && matches!(&expr, Expression::Function(func) if func.name.eq_ignore_ascii_case("generate_series"))
5177 {
5178 column_aliases = vec![Identifier::new("generate_series")];
5179 }
5180 let make_alias_ident = |name: String| -> Identifier {
5181 if is_quoted_alias {
5182 Identifier::quoted(name)
5183 } else {
5184 Identifier::new(name)
5185 }
5186 };
5187 expr = match expr {
5188 Expression::Table(mut t) => {
5189 t.alias = Some(make_alias_ident(alias));
5190 t.alias_explicit_as = is_keyword_alias;
5191 t.column_aliases = column_aliases;
5192 Expression::Table(t)
5193 }
5194 Expression::Subquery(mut s) => {
5195 s.alias = Some(make_alias_ident(alias));
5196 s.column_aliases = column_aliases;
5197 Expression::Subquery(s)
5198 }
5199 Expression::Pivot(mut p) => {
5200 p.alias = Some(make_alias_ident(alias));
5201 Expression::Pivot(p)
5202 }
5203 Expression::Unpivot(mut u) => {
5204 u.alias = Some(make_alias_ident(alias));
5205 Expression::Unpivot(u)
5206 }
5207 Expression::MatchRecognize(mut mr) => {
5208 mr.alias = Some(make_alias_ident(alias));
5209 Expression::MatchRecognize(mr)
5210 }
5211 Expression::JoinedTable(mut jt) => {
5212 jt.alias = Some(make_alias_ident(alias));
5213 Expression::JoinedTable(jt)
5214 }
5215 _ => Expression::Alias(Box::new(Alias {
5216 this: expr,
5217 alias: make_alias_ident(alias),
5218 column_aliases,
5219 pre_alias_comments: Vec::new(),
5220 trailing_comments: Vec::new(),
5221 inferred_type: None,
5222 })),
5223 };
5224 }
5225
5226 if matches!(
5228 self.config.dialect,
5229 Some(crate::dialects::DialectType::ClickHouse)
5230 ) && self.check(TokenType::LParen)
5231 && matches!(&expr, Expression::Subquery(s) if s.alias.is_none())
5232 {
5233 let mut look = self.current + 1;
5235 let mut is_col_list = true;
5236 let mut col_count = 0;
5237 loop {
5238 if look >= self.tokens.len() {
5239 is_col_list = false;
5240 break;
5241 }
5242 let tt = self.tokens[look].token_type;
5243 if tt == TokenType::Identifier
5244 || tt == TokenType::Var
5245 || tt == TokenType::QuotedIdentifier
5246 || tt.is_keyword()
5247 {
5248 col_count += 1;
5249 look += 1;
5250 } else {
5251 is_col_list = false;
5252 break;
5253 }
5254 if look >= self.tokens.len() {
5255 is_col_list = false;
5256 break;
5257 }
5258 if self.tokens[look].token_type == TokenType::Comma {
5259 look += 1;
5260 } else if self.tokens[look].token_type == TokenType::RParen {
5261 break;
5262 } else {
5263 is_col_list = false;
5264 break;
5265 }
5266 }
5267 if is_col_list && col_count >= 1 {
5268 self.skip(); let mut aliases = Vec::new();
5270 loop {
5271 aliases.push(Identifier::new(self.advance().text.clone()));
5272 if !self.match_token(TokenType::Comma) {
5273 break;
5274 }
5275 }
5276 self.expect(TokenType::RParen)?;
5277 if let Expression::Subquery(ref mut s) = expr {
5278 s.column_aliases = aliases;
5279 }
5280 }
5281 }
5282
5283 if matches!(
5285 self.config.dialect,
5286 Some(crate::dialects::DialectType::ClickHouse)
5287 ) && self.match_token(TokenType::Final)
5288 {
5289 if let Expression::Table(ref mut table) = expr {
5290 table.final_ = true;
5291 }
5292 }
5293
5294 if self.check_identifier("INDEXED") {
5296 self.skip(); self.expect(TokenType::By)?;
5298 let first_part = self.expect_identifier_or_keyword()?;
5299 let index_name = if self.match_token(TokenType::Dot) {
5300 let second_part = self.expect_identifier_or_keyword()?;
5301 format!("{}.{}", first_part, second_part)
5302 } else {
5303 first_part
5304 };
5305 if let Expression::Table(ref mut table) = expr {
5306 table.hints.push(Expression::Identifier(Identifier {
5307 name: format!("INDEXED BY {}", index_name),
5308 quoted: false,
5309 trailing_comments: Vec::new(),
5310 span: None,
5311 }));
5312 }
5313 }
5314
5315 if self.check_keyword_text("USE")
5317 || self.check(TokenType::Ignore)
5318 || self.check_keyword_text("FORCE")
5319 {
5320 let next_idx = self.current + 1;
5321 let is_index_hint = next_idx < self.tokens.len() && {
5322 let next_text = &self.tokens[next_idx].text;
5323 next_text.eq_ignore_ascii_case("INDEX") || next_text.eq_ignore_ascii_case("KEY")
5324 };
5325 if is_index_hint {
5326 if let Expression::Table(ref mut table) = expr {
5327 if let Some(hint_expr) = self.parse_table_hints()? {
5328 match hint_expr {
5329 Expression::Tuple(tuple) => {
5330 table.hints = tuple.expressions;
5331 }
5332 other => {
5333 table.hints = vec![other];
5334 }
5335 }
5336 }
5337 }
5338 }
5339 }
5340
5341 if self.check(TokenType::Pivot) && self.check_next(TokenType::LParen) {
5344 self.skip(); expr = self.parse_pivot(expr)?;
5346 } else if self.check(TokenType::Unpivot) && self.is_unpivot_clause_start() {
5347 self.skip(); expr = self.parse_unpivot(expr)?;
5349 }
5350
5351 if self.match_identifier("AT") {
5356 let index_alias = self.expect_identifier_or_keyword()?;
5357 let column_expr = match expr {
5359 Expression::Table(t) => {
5360 let mut parts = Vec::new();
5363 if let Some(cat) = t.catalog {
5364 parts.push(cat.name);
5365 }
5366 if let Some(schema) = t.schema {
5367 parts.push(schema.name);
5368 }
5369 parts.push(t.name.name);
5370 let col_name = parts.join(".");
5371 let alias_expr = if let Some(alias) = t.alias {
5372 Expression::Alias(Box::new(Alias {
5373 this: Expression::boxed_column(Column {
5374 name: Identifier::new(&col_name),
5375 table: None,
5376 join_mark: false,
5377 trailing_comments: Vec::new(),
5378 span: None,
5379 inferred_type: None,
5380 }),
5381 alias,
5382 column_aliases: t.column_aliases,
5383 pre_alias_comments: Vec::new(),
5384 trailing_comments: t.trailing_comments,
5385 inferred_type: None,
5386 }))
5387 } else {
5388 Expression::boxed_column(Column {
5389 name: Identifier::new(&col_name),
5390 table: None,
5391 join_mark: false,
5392 trailing_comments: t.trailing_comments,
5393 span: None,
5394 inferred_type: None,
5395 })
5396 };
5397 alias_expr
5398 }
5399 other => other, };
5401 expr = Expression::AtIndex(Box::new(AtIndex {
5402 this: Box::new(column_expr),
5403 expression: Box::new(Expression::Identifier(Identifier::new(index_alias))),
5404 }));
5405 }
5406
5407 if self.check(TokenType::TableSample) || self.check(TokenType::Sample) {
5410 if let Some(sample) = self.parse_table_level_sample()? {
5411 let post_sample_comments = self.previous_trailing_comments().to_vec();
5413 if let Expression::Table(ref mut table) = expr {
5414 table.table_sample = Some(Box::new(sample));
5415 if !post_sample_comments.is_empty() {
5416 table.trailing_comments.extend(post_sample_comments);
5417 }
5418 } else {
5419 expr = Expression::TableSample(Box::new(crate::expressions::TableSample {
5421 this: Some(Box::new(expr)),
5422 sample: Some(Box::new(sample)),
5423 expressions: Vec::new(),
5424 method: None,
5425 bucket_numerator: None,
5426 bucket_denominator: None,
5427 bucket_field: None,
5428 percent: None,
5429 rows: None,
5430 size: None,
5431 seed: None,
5432 }));
5433 }
5434 }
5435 }
5436
5437 if has_only {
5439 if let Expression::Table(ref mut table) = expr {
5440 table.only = true;
5441 }
5442 }
5443
5444 if self.check(TokenType::For)
5447 && self.current + 1 < self.tokens.len()
5448 && self.tokens[self.current + 1]
5449 .text
5450 .eq_ignore_ascii_case("SYSTEM_TIME")
5451 {
5452 self.skip(); self.skip(); if self.match_token(TokenType::As) && self.check_keyword_text("OF") {
5455 self.skip(); let start = self.current;
5457 while !self.is_at_end()
5459 && !self.check(TokenType::Semicolon)
5460 && !self.check(TokenType::Where)
5461 && !self.check(TokenType::Join)
5462 && !self.check(TokenType::Left)
5463 && !self.check(TokenType::Right)
5464 && !self.check(TokenType::Inner)
5465 && !self.check(TokenType::Outer)
5466 && !self.check(TokenType::Full)
5467 && !self.check(TokenType::Cross)
5468 && !self.check(TokenType::Order)
5469 && !self.check(TokenType::Group)
5470 && !self.check(TokenType::Having)
5471 && !self.check(TokenType::Limit)
5472 && !self.check(TokenType::Union)
5473 && !self.check(TokenType::Except)
5474 && !self.check(TokenType::Intersect)
5475 && !self.check(TokenType::Comma)
5476 && !self.check(TokenType::RParen)
5477 {
5478 self.skip();
5479 }
5480 let expr_text = self.tokens_to_sql(start, self.current);
5481 let system_time_str = format!("FOR SYSTEM_TIME AS OF {}", expr_text);
5482 if let Expression::Table(ref mut table) = expr {
5483 table.system_time = Some(system_time_str);
5484 }
5485 }
5486 }
5487
5488 if matches!(
5492 self.config.dialect,
5493 Some(crate::dialects::DialectType::BigQuery)
5494 ) {
5495 if let Expression::Table(ref mut table) = expr {
5496 if table.schema.is_none() && table.catalog.is_none() && table.alias.is_none() {
5499 let name_upper = table.name.name.to_ascii_uppercase();
5500 if name_upper.contains("INFORMATION_SCHEMA.") {
5501 table.alias = Some(table.name.clone());
5503 table.alias_explicit_as = true;
5504 }
5505 }
5506 else if let Some(ref schema) = table.schema {
5511 if schema.name.eq_ignore_ascii_case("INFORMATION_SCHEMA") {
5512 let merged_name = format!("{}.{}", schema.name, table.name.name);
5514 let original_table_name = table.name.name.clone();
5515
5516 if table.alias.is_none() {
5518 table.alias = Some(Identifier::new(original_table_name));
5519 table.alias_explicit_as = true;
5520 }
5521
5522 table.name = Identifier {
5524 name: merged_name,
5525 quoted: true,
5526 trailing_comments: Vec::new(),
5527 span: None,
5528 };
5529
5530 table.schema = table.catalog.take();
5532 }
5534 }
5535 }
5536 }
5537
5538 Ok(expr)
5539 }
5540
5541 fn parse_pivot(&mut self, source: Expression) -> Result<Expression> {
5544 self.expect(TokenType::LParen)?;
5545
5546 let mut expressions = Vec::new();
5550 loop {
5551 if self.check(TokenType::For) || self.check(TokenType::RParen) {
5552 break;
5553 }
5554 let func = self.parse_primary()?;
5556 let expr = if self.match_token(TokenType::As) {
5558 let alias_name = self.expect_identifier_or_keyword()?;
5560 Expression::Alias(Box::new(Alias::new(func, Identifier::new(alias_name))))
5561 } else if !self.check(TokenType::Comma)
5562 && !self.check(TokenType::For)
5563 && !self.check(TokenType::RParen)
5564 {
5565 if let Some(id) = self.parse_id_var()? {
5567 let alias_name = match &id {
5568 Expression::Identifier(ident) => ident.name.clone(),
5569 Expression::Column(col) => col.name.name.clone(),
5570 _ => String::new(),
5571 };
5572 if !alias_name.is_empty() {
5573 Expression::Alias(Box::new(Alias::new(func, Identifier::new(alias_name))))
5574 } else {
5575 func
5576 }
5577 } else {
5578 func
5579 }
5580 } else {
5581 func
5582 };
5583 expressions.push(expr);
5584 if !self.match_token(TokenType::Comma) {
5585 break;
5586 }
5587 if self.check(TokenType::For) {
5589 break;
5590 }
5591 }
5592
5593 self.expect(TokenType::For)?;
5595
5596 let mut fields = Vec::new();
5597 loop {
5598 let field = self.parse_standard_pivot_in()?;
5599 fields.push(field);
5600
5601 if !self.match_token(TokenType::For) {
5603 break;
5604 }
5605 }
5606
5607 let default_on_null = if self.match_text_seq(&["DEFAULT", "ON", "NULL"]) {
5609 if self.match_token(TokenType::LParen) {
5610 let val = self.parse_expression()?;
5611 self.expect(TokenType::RParen)?;
5612 Some(Box::new(val))
5613 } else {
5614 None
5615 }
5616 } else {
5617 None
5618 };
5619
5620 let group = self.parse_group()?;
5622
5623 self.expect(TokenType::RParen)?;
5624
5625 Ok(Expression::Pivot(Box::new(Pivot {
5626 this: source,
5627 expressions,
5628 fields,
5629 using: Vec::new(),
5630 group: group.map(Box::new),
5631 unpivot: false,
5632 into: None,
5633 alias: None,
5634 include_nulls: None,
5635 default_on_null,
5636 with: None,
5637 })))
5638 }
5639
5640 fn parse_standard_pivot_in(&mut self) -> Result<Expression> {
5642 let column = self.parse_primary()?;
5644
5645 self.expect(TokenType::In)?;
5647
5648 if self.match_token(TokenType::LParen) {
5650 let in_exprs = if self.match_text_seq(&["ANY"]) {
5652 let order = self.parse_order()?;
5653 vec![Expression::PivotAny(Box::new(PivotAny {
5654 this: order.map(Box::new),
5655 }))]
5656 } else {
5657 let mut vals = Vec::new();
5659 loop {
5660 if self.check(TokenType::RParen) {
5661 break;
5662 }
5663 if let Some(val) = self.parse_select_or_expression()? {
5664 let val = if self.match_token(TokenType::As) {
5667 let alias_expr = self.parse_bitwise()?.ok_or_else(|| {
5670 self.parse_error(
5671 "Expected expression after AS in PIVOT/UNPIVOT IN clause",
5672 )
5673 })?;
5674 Expression::PivotAlias(Box::new(PivotAlias {
5675 this: val,
5676 alias: alias_expr,
5677 }))
5678 } else {
5679 val
5680 };
5681 vals.push(val);
5682 }
5683 if !self.match_token(TokenType::Comma) {
5684 break;
5685 }
5686 }
5687 vals
5688 };
5689 self.expect(TokenType::RParen)?;
5690 Ok(Expression::In(Box::new(In {
5691 this: column,
5692 expressions: in_exprs,
5693 query: None,
5694 not: false,
5695 global: false,
5696 unnest: None,
5697 is_field: false,
5698 })))
5699 } else {
5700 let field_id = self.parse_id_var()?.unwrap_or(Expression::Null(Null));
5703 Ok(Expression::In(Box::new(In {
5704 this: column,
5705 expressions: Vec::new(),
5706 query: Some(field_id),
5707 not: false,
5708 global: false,
5709 unnest: None,
5710 is_field: true,
5711 })))
5712 }
5713 }
5714
5715 fn parse_unpivot(&mut self, source: Expression) -> Result<Expression> {
5721 let include_nulls = if self.match_text_seq(&["INCLUDE", "NULLS"]) {
5723 Some(true)
5724 } else if self.match_text_seq(&["EXCLUDE", "NULLS"]) {
5725 Some(false)
5726 } else {
5727 None
5728 };
5729
5730 self.expect(TokenType::LParen)?;
5731
5732 let (value_column, value_column_parenthesized, extra_value_columns) =
5735 if self.match_token(TokenType::LParen) {
5736 let col = self.expect_identifier_or_keyword()?;
5738 let mut extra_cols = Vec::new();
5739 while self.match_token(TokenType::Comma) {
5740 extra_cols.push(Identifier::new(self.expect_identifier_or_keyword()?));
5741 }
5742 self.expect(TokenType::RParen)?;
5743 (Identifier::new(col), true, extra_cols)
5744 } else {
5745 (
5746 Identifier::new(self.expect_identifier_or_keyword()?),
5747 false,
5748 Vec::new(),
5749 )
5750 };
5751
5752 self.expect(TokenType::For)?;
5754 let name_column = Identifier::new(self.expect_identifier_or_keyword()?);
5755
5756 self.expect(TokenType::In)?;
5761 self.expect(TokenType::LParen)?;
5762 let columns = {
5763 let mut cols = Vec::new();
5764 loop {
5765 if self.check(TokenType::RParen) {
5766 break;
5767 }
5768 let col_expr = if self.check(TokenType::LParen) {
5770 let saved = self.current;
5772 self.skip(); let mut tuple_cols = Vec::new();
5775 let first = self.expect_identifier_or_keyword();
5776 if let Ok(first_id) = first {
5777 tuple_cols.push(Expression::column(first_id));
5778 while self.match_token(TokenType::Comma) {
5779 if let Ok(id) = self.expect_identifier_or_keyword() {
5780 tuple_cols.push(Expression::column(id));
5781 } else {
5782 break;
5783 }
5784 }
5785 if self.match_token(TokenType::RParen) && tuple_cols.len() > 1 {
5786 Some(Expression::Tuple(Box::new(Tuple {
5788 expressions: tuple_cols,
5789 })))
5790 } else {
5791 self.current = saved;
5793 self.parse_select_or_expression()?
5794 }
5795 } else {
5796 self.current = saved;
5798 self.parse_select_or_expression()?
5799 }
5800 } else {
5801 self.parse_select_or_expression()?
5802 };
5803
5804 if let Some(col) = col_expr {
5805 let col = if self.match_token(TokenType::As) {
5807 let alias_expr = self.parse_bitwise()?.ok_or_else(|| {
5809 self.parse_error("Expected expression after AS in UNPIVOT IN clause")
5810 })?;
5811 Expression::PivotAlias(Box::new(PivotAlias {
5812 this: col,
5813 alias: alias_expr,
5814 }))
5815 } else {
5816 col
5817 };
5818 cols.push(col);
5819 }
5820 if !self.match_token(TokenType::Comma) {
5821 break;
5822 }
5823 }
5824 cols
5825 };
5826 self.expect(TokenType::RParen)?;
5827
5828 self.expect(TokenType::RParen)?;
5829
5830 Ok(Expression::Unpivot(Box::new(Unpivot {
5831 this: source,
5832 value_column,
5833 name_column,
5834 columns,
5835 alias: None,
5836 value_column_parenthesized,
5837 include_nulls,
5838 extra_value_columns,
5839 })))
5840 }
5841
5842 fn parse_redshift_unpivot_table(&mut self) -> Result<Expression> {
5848 let this = self.parse_primary()?;
5855
5856 let alias = if self.match_token(TokenType::As) {
5858 let val_alias = self.expect_identifier_or_keyword()?;
5859 if self.match_text_seq(&["AT"]) {
5861 let attr_alias = self.expect_identifier_or_keyword()?;
5862 Some(Identifier::new(format!("{} AT {}", val_alias, attr_alias)))
5866 } else {
5867 Some(Identifier::new(val_alias))
5868 }
5869 } else {
5870 None
5871 };
5872
5873 Ok(Expression::Pivot(Box::new(Pivot {
5880 this,
5881 expressions: Vec::new(),
5882 fields: Vec::new(),
5883 using: Vec::new(),
5884 group: None,
5885 unpivot: true,
5886 into: None,
5887 alias,
5888 include_nulls: None,
5889 default_on_null: None,
5890 with: None,
5891 })))
5892 }
5893
5894 fn parse_bigquery_table_part(&mut self) -> Result<Identifier> {
5898 use crate::dialects::DialectType;
5899
5900 if matches!(self.config.dialect, Some(DialectType::BigQuery))
5902 && self.check(TokenType::Number)
5903 {
5904 let num_token = self.advance().clone();
5905 let mut name = num_token.text.clone();
5906
5907 while !self.is_at_end() && self.is_connected() {
5910 let tok = self.advance().clone();
5911 name.push_str(&tok.text);
5912 }
5913
5914 return Ok(Identifier {
5915 name,
5916 quoted: true,
5917 trailing_comments: Vec::new(),
5918 span: None,
5919 });
5920 }
5921
5922 if matches!(self.config.dialect, Some(DialectType::MySQL)) && self.check(TokenType::Number)
5924 {
5925 let num_token = self.advance().clone();
5926 let mut name = num_token.text.clone();
5927
5928 while !self.is_at_end()
5930 && self.is_connected()
5931 && (self.check(TokenType::Var) || self.check(TokenType::Identifier))
5932 {
5933 let tok = self.advance().clone();
5934 name.push_str(&tok.text);
5935 }
5936
5937 return Ok(Identifier {
5938 name,
5939 quoted: true,
5940 trailing_comments: Vec::new(),
5941 span: None,
5942 });
5943 }
5944
5945 let mut ident = self.expect_identifier_or_keyword_with_quoted()?;
5946
5947 if matches!(self.config.dialect, Some(DialectType::BigQuery)) && !ident.quoted {
5949 if self.check(TokenType::Dash) && self.is_connected_dash() {
5951 let mut name = ident.name.clone();
5952
5953 while self.check(TokenType::Dash) && self.is_connected_dash() {
5954 self.skip(); name.push('-');
5956 let part = self.advance().clone();
5958 name.push_str(&part.text);
5959 while !self.is_at_end()
5961 && self.is_connected()
5962 && !self.check(TokenType::Dot)
5963 && !self.check(TokenType::Dash)
5964 && !self.check(TokenType::LParen)
5965 && !self.check(TokenType::RParen)
5966 {
5967 let tok = self.advance().clone();
5968 name.push_str(&tok.text);
5969 }
5970 }
5971
5972 ident = Identifier {
5973 name,
5974 quoted: false,
5975 trailing_comments: Vec::new(),
5976 span: None,
5977 };
5978 }
5979 }
5980
5981 Ok(ident)
5982 }
5983
5984 fn is_connected_dash(&self) -> bool {
5987 if !self.check(TokenType::Dash) {
5988 return false;
5989 }
5990 if self.current + 1 >= self.tokens.len() {
5991 return false;
5992 }
5993 let dash_token = &self.tokens[self.current];
5994 let next_token = &self.tokens[self.current + 1];
5995
5996 let next_is_valid = matches!(
5999 next_token.token_type,
6000 TokenType::Identifier
6001 | TokenType::Var
6002 | TokenType::Number
6003 | TokenType::All
6004 | TokenType::Select
6005 | TokenType::From
6006 | TokenType::Where
6007 ) || next_token.token_type.is_keyword();
6008
6009 let adjacent = dash_token.span.end + 1 == next_token.span.start
6011 || dash_token.span.end == next_token.span.start;
6012
6013 next_is_valid && adjacent
6014 }
6015
6016 fn is_connected(&self) -> bool {
6018 if self.current == 0 || self.current >= self.tokens.len() {
6019 return false;
6020 }
6021 let prev_token = &self.tokens[self.current - 1];
6022 let curr_token = &self.tokens[self.current];
6023 prev_token.span.end == curr_token.span.start
6026 }
6027
6028 fn parse_table_ref(&mut self) -> Result<TableRef> {
6030 let table_ref_leading_comments = self.current_leading_comments().to_vec();
6032 let mut result = self.parse_table_ref_inner()?;
6033 if !table_ref_leading_comments.is_empty() && result.leading_comments.is_empty() {
6034 result.leading_comments = table_ref_leading_comments;
6035 }
6036 Ok(result)
6037 }
6038
6039 fn parse_table_ref_inner(&mut self) -> Result<TableRef> {
6040 if self.check_identifier("IDENTIFIER") && self.check_next(TokenType::LParen) {
6042 self.skip(); self.skip(); let arg = if self.check(TokenType::String) {
6046 let s = self.advance().text.clone();
6047 Expression::Literal(Box::new(Literal::String(s)))
6048 } else if self.check(TokenType::Parameter) {
6049 let var = self.advance().text.clone();
6051 Expression::Var(Box::new(crate::expressions::Var { this: var }))
6052 } else if self.check(TokenType::Dollar) {
6053 self.skip(); let var_name = self.expect_identifier()?;
6056 Expression::Var(Box::new(crate::expressions::Var {
6057 this: format!("${}", var_name),
6058 }))
6059 } else {
6060 let ident = self.expect_identifier()?;
6062 Expression::Identifier(Identifier::new(ident))
6063 };
6064 self.expect(TokenType::RParen)?;
6065 let trailing_comments = self.previous_trailing_comments().to_vec();
6066 let identifier_func = Expression::Function(Box::new(crate::expressions::Function {
6068 name: "IDENTIFIER".to_string(),
6069 args: vec![arg],
6070 distinct: false,
6071 trailing_comments: Vec::new(),
6072 use_bracket_syntax: false,
6073 no_parens: false,
6074 quoted: false,
6075 span: None,
6076 inferred_type: None,
6077 }));
6078 return Ok(TableRef {
6079 catalog: None,
6080 schema: None,
6081 name: Identifier::empty(),
6082 alias: None,
6083 alias_explicit_as: false,
6084 column_aliases: Vec::new(),
6085 leading_comments: Vec::new(),
6086 trailing_comments,
6087 when: None,
6088 only: false,
6089 final_: false,
6090 table_sample: None,
6091 hints: Vec::new(),
6092 system_time: None,
6093 partitions: Vec::new(),
6094 identifier_func: Some(Box::new(identifier_func)),
6095 changes: None,
6096 version: None,
6097 span: None,
6098 });
6099 }
6100
6101 let first = self.parse_bigquery_table_part()?;
6102
6103 if self.match_token(TokenType::Dot) {
6105 if self.check(TokenType::Dot) {
6107 self.skip(); let table = self.parse_bigquery_table_part()?;
6110 let trailing_comments = self.previous_trailing_comments().to_vec();
6111 Ok(TableRef {
6112 catalog: Some(first),
6113 schema: Some(Identifier::new("")), name: table,
6115 alias: None,
6116 alias_explicit_as: false,
6117 column_aliases: Vec::new(),
6118 leading_comments: Vec::new(),
6119 trailing_comments,
6120 when: None,
6121 only: false,
6122 final_: false,
6123 table_sample: None,
6124 hints: Vec::new(),
6125 system_time: None,
6126 partitions: Vec::new(),
6127 identifier_func: None,
6128 changes: None,
6129 version: None,
6130 span: None,
6131 })
6132 } else {
6133 if matches!(
6136 self.config.dialect,
6137 Some(crate::dialects::DialectType::BigQuery)
6138 ) && self.check(TokenType::Star)
6139 {
6140 self.skip(); let trailing_comments = self.previous_trailing_comments().to_vec();
6142 return Ok(TableRef {
6143 catalog: None,
6144 schema: Some(first),
6145 name: Identifier::new("*"),
6146 alias: None,
6147 alias_explicit_as: false,
6148 column_aliases: Vec::new(),
6149 leading_comments: Vec::new(),
6150 trailing_comments,
6151 when: None,
6152 only: false,
6153 final_: false,
6154 table_sample: None,
6155 hints: Vec::new(),
6156 system_time: None,
6157 partitions: Vec::new(),
6158 identifier_func: None,
6159 changes: None,
6160 version: None,
6161 span: None,
6162 });
6163 }
6164 let table = self.parse_bigquery_table_part()?;
6165 if self.match_token(TokenType::Dot) {
6167 if matches!(
6169 self.config.dialect,
6170 Some(crate::dialects::DialectType::BigQuery)
6171 ) && self.check(TokenType::Star)
6172 {
6173 self.skip(); let trailing_comments = self.previous_trailing_comments().to_vec();
6175 return Ok(TableRef {
6176 catalog: Some(first),
6177 schema: Some(table),
6178 name: Identifier::new("*"),
6179 alias: None,
6180 alias_explicit_as: false,
6181 column_aliases: Vec::new(),
6182 leading_comments: Vec::new(),
6183 trailing_comments,
6184 when: None,
6185 only: false,
6186 final_: false,
6187 table_sample: None,
6188 hints: Vec::new(),
6189 system_time: None,
6190 partitions: Vec::new(),
6191 identifier_func: None,
6192 changes: None,
6193 version: None,
6194 span: None,
6195 });
6196 }
6197 let actual_table = self.parse_bigquery_table_part()?;
6198 let trailing_comments = self.previous_trailing_comments().to_vec();
6199 Ok(TableRef {
6200 catalog: Some(first),
6201 schema: Some(table),
6202 name: actual_table,
6203 alias: None,
6204 alias_explicit_as: false,
6205 column_aliases: Vec::new(),
6206 leading_comments: Vec::new(),
6207 trailing_comments,
6208 when: None,
6209 only: false,
6210 final_: false,
6211 table_sample: None,
6212 hints: Vec::new(),
6213 system_time: None,
6214 partitions: Vec::new(),
6215 identifier_func: None,
6216 changes: None,
6217 version: None,
6218 span: None,
6219 })
6220 } else {
6221 let trailing_comments = self.previous_trailing_comments().to_vec();
6222 Ok(TableRef {
6223 catalog: None,
6224 schema: Some(first),
6225 name: table,
6226 alias: None,
6227 alias_explicit_as: false,
6228 column_aliases: Vec::new(),
6229 leading_comments: Vec::new(),
6230 trailing_comments,
6231 when: None,
6232 only: false,
6233 final_: false,
6234 table_sample: None,
6235 hints: Vec::new(),
6236 system_time: None,
6237 partitions: Vec::new(),
6238 identifier_func: None,
6239 changes: None,
6240 version: None,
6241 span: None,
6242 })
6243 }
6244 }
6245 } else {
6246 let trailing_comments = self.previous_trailing_comments().to_vec();
6247 Ok(TableRef {
6248 catalog: None,
6249 schema: None,
6250 name: first,
6251 alias: None,
6252 alias_explicit_as: false,
6253 column_aliases: Vec::new(),
6254 leading_comments: Vec::new(),
6255 trailing_comments,
6256 when: None,
6257 only: false,
6258 final_: false,
6259 table_sample: None,
6260 hints: Vec::new(),
6261 system_time: None,
6262 partitions: Vec::new(),
6263 identifier_func: None,
6264 changes: None,
6265 version: None,
6266 span: None,
6267 })
6268 }
6269 }
6270
6271 fn parse_datetime_field(&mut self) -> Result<DateTimeField> {
6273 let token = self.advance();
6274 let original_name = token.text.clone();
6275 let name = original_name.to_ascii_uppercase();
6276 match name.as_str() {
6277 "YEAR" => Ok(DateTimeField::Year),
6278 "MONTH" => Ok(DateTimeField::Month),
6279 "DAY" => Ok(DateTimeField::Day),
6280 "HOUR" => Ok(DateTimeField::Hour),
6281 "MINUTE" => Ok(DateTimeField::Minute),
6282 "SECOND" => Ok(DateTimeField::Second),
6283 "MILLISECOND" => Ok(DateTimeField::Millisecond),
6284 "MICROSECOND" => Ok(DateTimeField::Microsecond),
6285 "DOW" | "DAYOFWEEK" => Ok(DateTimeField::DayOfWeek),
6286 "DOY" | "DAYOFYEAR" => Ok(DateTimeField::DayOfYear),
6287 "WEEK" => {
6288 if self.match_token(TokenType::LParen) {
6290 let modifier = self.expect_identifier_or_keyword()?;
6291 self.expect(TokenType::RParen)?;
6292 Ok(DateTimeField::WeekWithModifier(modifier))
6293 } else {
6294 Ok(DateTimeField::Week)
6295 }
6296 }
6297 "QUARTER" => Ok(DateTimeField::Quarter),
6298 "EPOCH" => Ok(DateTimeField::Epoch),
6299 "TIMEZONE" => Ok(DateTimeField::Timezone),
6300 "TIMEZONE_HOUR" => Ok(DateTimeField::TimezoneHour),
6301 "TIMEZONE_MINUTE" => Ok(DateTimeField::TimezoneMinute),
6302 "DATE" => Ok(DateTimeField::Date),
6303 "TIME" => Ok(DateTimeField::Time),
6304 _ => Ok(DateTimeField::Custom(original_name)),
6306 }
6307 }
6308
6309 fn parse_table_expression_with_joins(&mut self) -> Result<(Expression, Vec<Join>)> {
6312 let left = self.parse_table_expression()?;
6314
6315 let joins = self.parse_joins()?;
6317
6318 Ok((left, joins))
6319 }
6320
6321 fn parse_joins(&mut self) -> Result<Vec<Join>> {
6327 let mut joins = Vec::with_capacity(2);
6328 let mut nesting_group: usize = 0;
6329
6330 loop {
6333 let joins_before = joins.len();
6334
6335 loop {
6337 let pos_before_join_kind = self.current;
6338 let join_kind_result = self.try_parse_join_kind();
6339 let (kind, needs_join_keyword, use_inner_keyword, use_outer_keyword, join_hint) =
6340 match join_kind_result {
6341 Some(r) => r,
6342 None => break,
6343 };
6344 let mut join_comments = Vec::new();
6348 if pos_before_join_kind < self.tokens.len() {
6350 join_comments
6351 .extend(self.tokens[pos_before_join_kind].comments.iter().cloned());
6352 }
6353 for i in pos_before_join_kind..self.current {
6354 if i < self.tokens.len() {
6355 join_comments.extend(self.tokens[i].trailing_comments.iter().cloned());
6356 }
6357 }
6358 let directed = if needs_join_keyword && self.check_identifier("DIRECTED") {
6360 self.skip();
6361 true
6362 } else {
6363 false
6364 };
6365 if needs_join_keyword {
6366 self.expect(TokenType::Join)?;
6367 }
6368
6369 let table = if matches!(kind, JoinKind::Array | JoinKind::LeftArray) {
6371 let mut items = Vec::new();
6372 if !self.is_at_end()
6374 && !self.check(TokenType::Semicolon)
6375 && !self.check(TokenType::RParen)
6376 {
6377 loop {
6378 let expr = self.parse_expression()?;
6379 let item = if self.match_token(TokenType::As) {
6380 let alias_name = self.expect_identifier_or_safe_keyword()?;
6381 Expression::Alias(Box::new(Alias {
6382 this: expr,
6383 alias: Identifier::new(alias_name),
6384 column_aliases: Vec::new(),
6385 pre_alias_comments: Vec::new(),
6386 trailing_comments: Vec::new(),
6387 inferred_type: None,
6388 }))
6389 } else {
6390 expr
6391 };
6392 items.push(item);
6393 if !self.match_token(TokenType::Comma) {
6394 break;
6395 }
6396 }
6397 } if items.len() == 1 {
6399 items.pop().unwrap()
6400 } else if items.is_empty() {
6401 Expression::Null(Null)
6402 } else {
6403 Expression::Tuple(Box::new(Tuple { expressions: items }))
6404 }
6405 } else {
6406 self.parse_table_expression()?
6407 };
6408
6409 let table = if matches!(
6411 kind,
6412 JoinKind::AsOf | JoinKind::AsOfLeft | JoinKind::AsOfRight
6413 ) && (self.check(TokenType::Offset) || self.check(TokenType::Limit))
6414 && self
6415 .peek_nth(1)
6416 .map(|t| t.text.eq_ignore_ascii_case("MATCH_CONDITION"))
6417 == Some(true)
6418 {
6419 let alias_name = self.advance().text.clone();
6420 Expression::Alias(Box::new(Alias {
6421 this: table,
6422 alias: Identifier::new(alias_name),
6423 column_aliases: Vec::new(),
6424 pre_alias_comments: Vec::new(),
6425 trailing_comments: Vec::new(),
6426 inferred_type: None,
6427 }))
6428 } else {
6429 table
6430 };
6431
6432 let has_match_condition = self.check_identifier("MATCH_CONDITION");
6435 let has_inline_condition = self.check(TokenType::On)
6436 || self.check(TokenType::Using)
6437 || has_match_condition;
6438 let next_is_join = self.check_join_keyword();
6439
6440 let match_condition = if has_match_condition && !next_is_join {
6442 if self.match_identifier("MATCH_CONDITION") {
6443 self.expect(TokenType::LParen)?;
6444 let condition = self.parse_expression()?;
6445 self.expect(TokenType::RParen)?;
6446 Some(condition)
6447 } else {
6448 None
6449 }
6450 } else {
6451 None
6452 };
6453
6454 let (on, using) = if (has_inline_condition || match_condition.is_some())
6455 && !self.check_join_keyword()
6456 {
6457 if self.match_token(TokenType::On) {
6459 (Some(self.parse_expression()?), Vec::new())
6460 } else if self.match_token(TokenType::Using) {
6461 let has_parens = self.match_token(TokenType::LParen);
6463 let cols = self.parse_using_column_list()?;
6465 if has_parens {
6466 self.expect(TokenType::RParen)?;
6467 }
6468 (None, cols)
6469 } else {
6470 (None, Vec::new())
6471 }
6472 } else {
6473 (None, Vec::new())
6474 };
6475
6476 joins.push(Join {
6477 this: table,
6478 on,
6479 using,
6480 kind,
6481 use_inner_keyword,
6482 use_outer_keyword,
6483 deferred_condition: false,
6484 join_hint,
6485 match_condition,
6486 pivots: Vec::new(),
6487 comments: join_comments,
6488 nesting_group,
6489 directed,
6490 });
6491 }
6492
6493 let unconditioned: Vec<usize> = joins[joins_before..]
6496 .iter()
6497 .enumerate()
6498 .filter(|(_, j)| j.on.is_none() && j.using.is_empty())
6499 .map(|(i, _)| joins_before + i)
6500 .collect();
6501
6502 let mut idx = unconditioned.len();
6503 while idx > 0 {
6504 if self.match_token(TokenType::On) {
6505 idx -= 1;
6506 let join_idx = unconditioned[idx];
6507 joins[join_idx].on = Some(self.parse_expression()?);
6508 joins[join_idx].deferred_condition = true;
6509 } else if self.match_token(TokenType::Using) {
6510 idx -= 1;
6511 let join_idx = unconditioned[idx];
6512 let has_parens = self.match_token(TokenType::LParen);
6513 let cols = if has_parens && self.check(TokenType::RParen) {
6515 Vec::new()
6516 } else {
6517 self.parse_using_column_list()?
6519 };
6520 joins[join_idx].using = cols;
6521 if has_parens {
6522 self.expect(TokenType::RParen)?;
6523 }
6524 joins[join_idx].deferred_condition = true;
6525 } else {
6526 break;
6527 }
6528 }
6529
6530 if joins.len() == joins_before {
6532 break;
6533 }
6534
6535 if !self.check_join_keyword() {
6537 break;
6538 }
6539 nesting_group += 1;
6540 }
6541
6542 Ok(joins)
6543 }
6544
6545 fn check_join_keyword(&self) -> bool {
6547 self.check(TokenType::Join) ||
6548 self.check(TokenType::Inner) ||
6549 self.check(TokenType::Left) ||
6550 self.check(TokenType::Right) ||
6551 self.check(TokenType::Full) ||
6552 self.check(TokenType::Cross) ||
6553 self.check(TokenType::Natural) ||
6554 self.check(TokenType::Outer) ||
6555 (matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)) &&
6557 (self.check_identifier("ARRAY") || self.check_identifier("GLOBAL") || self.check(TokenType::All) || self.check(TokenType::Any) || self.check_identifier("PASTE")))
6558 }
6559
6560 fn try_parse_join_kind(&mut self) -> Option<(JoinKind, bool, bool, bool, Option<String>)> {
6563 if matches!(
6564 self.config.dialect,
6565 Some(crate::dialects::DialectType::ClickHouse)
6566 ) {
6567 let start = self.current;
6568 let mut global = false;
6569 let mut strictness: Option<String> = None;
6570 let mut kind: Option<JoinKind> = None;
6571 let mut use_outer = false;
6572 let mut use_inner = false;
6573
6574 if self.match_identifier("GLOBAL") {
6575 global = true;
6576 }
6577
6578 loop {
6579 if strictness.is_none() && self.match_token(TokenType::All) {
6580 strictness = Some("ALL".to_string());
6581 continue;
6582 }
6583 if strictness.is_none() && self.match_token(TokenType::Any) {
6584 strictness = Some("ANY".to_string());
6585 continue;
6586 }
6587 if strictness.is_none() && self.match_token(TokenType::AsOf) {
6588 strictness = Some("ASOF".to_string());
6589 continue;
6590 }
6591 if strictness.is_none() && self.match_token(TokenType::Semi) {
6592 strictness = Some("SEMI".to_string());
6593 continue;
6594 }
6595 if strictness.is_none() && self.match_token(TokenType::Anti) {
6596 strictness = Some("ANTI".to_string());
6597 continue;
6598 }
6599 if kind.is_none() && self.match_token(TokenType::Left) {
6600 use_outer = self.match_token(TokenType::Outer);
6601 use_inner = self.match_token(TokenType::Inner);
6602 kind = Some(JoinKind::Left);
6603 continue;
6604 }
6605 if kind.is_none() && self.match_token(TokenType::Right) {
6606 use_outer = self.match_token(TokenType::Outer);
6607 use_inner = self.match_token(TokenType::Inner);
6608 kind = Some(JoinKind::Right);
6609 continue;
6610 }
6611 if kind.is_none() && self.match_token(TokenType::Full) {
6612 use_outer = self.match_token(TokenType::Outer);
6613 kind = Some(JoinKind::Full);
6614 continue;
6615 }
6616 if kind.is_none() && self.match_token(TokenType::Inner) {
6617 use_inner = true;
6618 kind = Some(JoinKind::Inner);
6619 continue;
6620 }
6621 break;
6622 }
6623
6624 if self.check_identifier("ARRAY") && self.check_next(TokenType::Join) {
6626 let array_kind = if matches!(kind, Some(JoinKind::Left)) {
6627 JoinKind::LeftArray
6628 } else {
6629 JoinKind::Array
6630 };
6631 self.skip(); return Some((array_kind, true, false, false, None));
6634 }
6635
6636 if self.check_identifier("PASTE") && self.check_next(TokenType::Join) {
6638 self.skip(); return Some((JoinKind::Paste, true, false, false, None));
6641 }
6642
6643 if global || strictness.is_some() || kind.is_some() {
6644 if self.check(TokenType::Join) {
6645 let join_kind = kind.unwrap_or(JoinKind::Inner);
6646 let mut hints = Vec::new();
6647 if global {
6648 hints.push("GLOBAL".to_string());
6649 }
6650 if let Some(strict) = strictness {
6651 hints.push(strict);
6652 }
6653 let join_hint = if hints.is_empty() {
6654 None
6655 } else {
6656 Some(hints.join(" "))
6657 };
6658 return Some((join_kind, true, use_inner, use_outer, join_hint));
6659 } else {
6660 self.current = start;
6661 }
6662 }
6663 }
6664
6665 if self.match_token(TokenType::AsOf) {
6667 if self.match_token(TokenType::Left) {
6669 let use_outer = self.match_token(TokenType::Outer);
6670 Some((JoinKind::AsOfLeft, true, false, use_outer, None))
6671 } else if self.match_token(TokenType::Right) {
6672 let use_outer = self.match_token(TokenType::Outer);
6673 Some((JoinKind::AsOfRight, true, false, use_outer, None))
6674 } else if self.match_token(TokenType::Inner) {
6675 Some((JoinKind::AsOf, true, true, false, None))
6676 } else {
6677 Some((JoinKind::AsOf, true, false, false, None))
6679 }
6680 } else if self.check(TokenType::Inner) {
6681 let saved = self.current;
6684 self.skip(); if self.check(TokenType::Union)
6686 || self.check(TokenType::Intersect)
6687 || self.check(TokenType::Except)
6688 {
6689 self.current = saved; return None;
6691 }
6692 let join_hint = self.parse_tsql_join_hint();
6694 Some((JoinKind::Inner, true, true, false, join_hint)) } else if self.check(TokenType::Left) {
6696 let saved = self.current;
6698 self.skip(); let at_set_op = self.check(TokenType::Union)
6701 || self.check(TokenType::Intersect)
6702 || self.check(TokenType::Except);
6703 let at_inner_set_op = self.check(TokenType::Inner) && {
6704 let saved2 = self.current;
6705 self.skip();
6706 let is_setop = self.check(TokenType::Union)
6707 || self.check(TokenType::Intersect)
6708 || self.check(TokenType::Except);
6709 self.current = saved2;
6710 is_setop
6711 };
6712 if at_set_op || at_inner_set_op {
6713 self.current = saved; return None;
6715 }
6716 self.current = saved;
6718 self.match_token(TokenType::Left); let use_outer = self.match_token(TokenType::Outer);
6720 let use_inner = self.match_token(TokenType::Inner);
6721 let join_hint = self.parse_tsql_join_hint();
6722 if self.match_token(TokenType::Semi) {
6724 Some((JoinKind::LeftSemi, true, use_inner, use_outer, join_hint))
6725 } else if self.match_token(TokenType::Anti) {
6726 Some((JoinKind::LeftAnti, true, use_inner, use_outer, join_hint))
6727 } else if self.match_token(TokenType::Lateral) {
6728 Some((JoinKind::LeftLateral, true, use_inner, use_outer, join_hint))
6729 } else {
6730 Some((JoinKind::Left, true, use_inner, use_outer, join_hint))
6731 }
6732 } else if self.check(TokenType::Right) {
6733 let saved = self.current;
6735 self.skip(); let at_set_op = self.check(TokenType::Union)
6737 || self.check(TokenType::Intersect)
6738 || self.check(TokenType::Except);
6739 let at_inner_set_op = self.check(TokenType::Inner) && {
6740 let saved2 = self.current;
6741 self.skip();
6742 let is_setop = self.check(TokenType::Union)
6743 || self.check(TokenType::Intersect)
6744 || self.check(TokenType::Except);
6745 self.current = saved2;
6746 is_setop
6747 };
6748 if at_set_op || at_inner_set_op {
6749 self.current = saved; return None;
6751 }
6752 self.current = saved;
6754 self.match_token(TokenType::Right); let use_outer = self.match_token(TokenType::Outer);
6756 let use_inner = self.match_token(TokenType::Inner);
6757 let join_hint = self.parse_tsql_join_hint();
6758 if self.match_token(TokenType::Semi) {
6760 Some((JoinKind::RightSemi, true, use_inner, use_outer, join_hint))
6761 } else if self.match_token(TokenType::Anti) {
6762 Some((JoinKind::RightAnti, true, use_inner, use_outer, join_hint))
6763 } else {
6764 Some((JoinKind::Right, true, use_inner, use_outer, join_hint))
6765 }
6766 } else if self.check(TokenType::Full) {
6767 let saved = self.current;
6769 self.skip(); let at_set_op = self.check(TokenType::Union)
6771 || self.check(TokenType::Intersect)
6772 || self.check(TokenType::Except);
6773 let at_inner_set_op = self.check(TokenType::Inner) && {
6774 let saved2 = self.current;
6775 self.skip();
6776 let is_setop = self.check(TokenType::Union)
6777 || self.check(TokenType::Intersect)
6778 || self.check(TokenType::Except);
6779 self.current = saved2;
6780 is_setop
6781 };
6782 if at_set_op || at_inner_set_op {
6783 self.current = saved; return None;
6785 }
6786 self.current = saved;
6788 self.match_token(TokenType::Full); let use_outer = self.match_token(TokenType::Outer);
6790 let join_hint = self.parse_tsql_join_hint();
6791 Some((JoinKind::Full, true, false, use_outer, join_hint))
6792 } else if self.match_token(TokenType::Cross) {
6793 if self.match_token(TokenType::Apply) {
6795 Some((JoinKind::CrossApply, false, false, false, None))
6796 } else {
6797 Some((JoinKind::Cross, true, false, false, None))
6798 }
6799 } else if self.match_token(TokenType::Natural) {
6800 if self.match_token(TokenType::Left) {
6802 let use_outer = self.match_token(TokenType::Outer);
6803 Some((JoinKind::NaturalLeft, true, false, use_outer, None))
6804 } else if self.match_token(TokenType::Right) {
6805 let use_outer = self.match_token(TokenType::Outer);
6806 Some((JoinKind::NaturalRight, true, false, use_outer, None))
6807 } else if self.match_token(TokenType::Full) {
6808 let use_outer = self.match_token(TokenType::Outer);
6809 Some((JoinKind::NaturalFull, true, false, use_outer, None))
6810 } else if self.match_token(TokenType::Inner) {
6811 Some((JoinKind::Natural, true, true, false, None))
6812 } else {
6813 Some((JoinKind::Natural, true, false, false, None))
6814 }
6815 } else if self.match_token(TokenType::Outer) {
6816 if self.match_token(TokenType::Apply) {
6818 Some((JoinKind::OuterApply, false, false, true, None))
6819 } else {
6820 Some((JoinKind::Outer, true, false, true, None))
6822 }
6823 } else if self.check(TokenType::Lateral) {
6824 if self.current + 1 < self.tokens.len()
6826 && self.tokens[self.current + 1].token_type == TokenType::View
6827 {
6828 None
6830 } else {
6831 self.skip(); Some((JoinKind::Lateral, true, false, false, None))
6833 }
6834 } else if self.match_token(TokenType::Semi) {
6835 Some((JoinKind::Semi, true, false, false, None))
6836 } else if self.match_token(TokenType::Anti) {
6837 Some((JoinKind::Anti, true, false, false, None))
6838 } else if self.check_identifier("POSITIONAL") && self.check_next(TokenType::Join) {
6839 self.skip(); Some((JoinKind::Positional, true, false, false, None))
6842 } else if self.match_token(TokenType::StraightJoin) {
6843 Some((JoinKind::Straight, false, false, false, None))
6845 } else if self.check(TokenType::Join) {
6846 Some((JoinKind::Inner, true, false, false, None)) } else if self.match_token(TokenType::Comma) {
6848 Some((JoinKind::Implicit, false, false, false, None)) } else {
6851 None
6852 }
6853 }
6854
6855 fn parse_tsql_join_hint(&mut self) -> Option<String> {
6857 if self.check_identifier("LOOP") {
6858 self.skip();
6859 Some("LOOP".to_string())
6860 } else if self.check_identifier("HASH") {
6861 self.skip();
6862 Some("HASH".to_string())
6863 } else if self.check_identifier("REMOTE") {
6864 self.skip();
6865 Some("REMOTE".to_string())
6866 } else if self.check(TokenType::Merge) && {
6867 let next_pos = self.current + 1;
6870 next_pos < self.tokens.len() && self.tokens[next_pos].token_type == TokenType::Join
6871 } {
6872 self.skip();
6873 Some("MERGE".to_string())
6874 } else {
6875 None
6876 }
6877 }
6878
6879 fn parse_group_by(&mut self) -> Result<GroupBy> {
6881 let all = if self.match_token(TokenType::All) {
6884 Some(true)
6885 } else if self.match_token(TokenType::Distinct) {
6886 Some(false)
6887 } else {
6888 None
6889 };
6890
6891 let mut expressions = Vec::new();
6892
6893 if all.is_some() && self.is_at_query_modifier_or_end() {
6897 return Ok(GroupBy {
6898 expressions,
6899 all,
6900 totals: false,
6901 comments: Vec::new(),
6902 });
6903 }
6904
6905 if all.is_some()
6907 && self.check(TokenType::With)
6908 && (self.check_next(TokenType::Cube)
6909 || self.check_next(TokenType::Rollup)
6910 || self.check_next_identifier("TOTALS"))
6911 {
6912 let mut totals = false;
6913 if self.check_next(TokenType::Cube) || self.check_next(TokenType::Rollup) {
6915 self.skip(); if self.match_token(TokenType::Cube) {
6917 expressions.push(Expression::Cube(Box::new(Cube {
6918 expressions: Vec::new(),
6919 })));
6920 } else if self.match_token(TokenType::Rollup) {
6921 expressions.push(Expression::Rollup(Box::new(Rollup {
6922 expressions: Vec::new(),
6923 })));
6924 }
6925 }
6926 if self.check(TokenType::With) && self.check_next_identifier("TOTALS") {
6928 self.skip(); self.skip(); totals = true;
6931 }
6932 return Ok(GroupBy {
6933 expressions,
6934 all,
6935 totals,
6936 comments: Vec::new(),
6937 });
6938 }
6939
6940 loop {
6941 let expr = if self.check_identifier("GROUPING")
6943 && self
6944 .peek_nth(1)
6945 .map_or(false, |t| t.text.eq_ignore_ascii_case("SETS"))
6946 && {
6947 self.skip();
6948 self.skip();
6949 true
6950 } {
6951 self.expect(TokenType::LParen)?;
6953 let args = self.parse_grouping_sets_args()?;
6954 self.expect(TokenType::RParen)?;
6955 Expression::Function(Box::new(Function {
6956 name: "GROUPING SETS".to_string(),
6957 args,
6958 distinct: false,
6959 trailing_comments: Vec::new(),
6960 use_bracket_syntax: false,
6961 no_parens: false,
6962 quoted: false,
6963 span: None,
6964 inferred_type: None,
6965 }))
6966 } else if self.match_token(TokenType::Cube) {
6967 self.expect(TokenType::LParen)?;
6969 let args = self.parse_expression_list()?;
6970 self.expect(TokenType::RParen)?;
6971 Expression::Function(Box::new(Function {
6972 name: "CUBE".to_string(),
6973 args,
6974 distinct: false,
6975 trailing_comments: Vec::new(),
6976 use_bracket_syntax: false,
6977 no_parens: false,
6978 quoted: false,
6979 span: None,
6980 inferred_type: None,
6981 }))
6982 } else if self.match_token(TokenType::Rollup) {
6983 self.expect(TokenType::LParen)?;
6985 let args = self.parse_expression_list()?;
6986 self.expect(TokenType::RParen)?;
6987 Expression::Function(Box::new(Function {
6988 name: "ROLLUP".to_string(),
6989 args,
6990 distinct: false,
6991 trailing_comments: Vec::new(),
6992 use_bracket_syntax: false,
6993 no_parens: false,
6994 quoted: false,
6995 span: None,
6996 inferred_type: None,
6997 }))
6998 } else {
6999 self.parse_expression()?
7000 };
7001
7002 let expr = if matches!(
7004 self.config.dialect,
7005 Some(crate::dialects::DialectType::ClickHouse)
7006 ) && self.check(TokenType::As)
7007 && !self.check_next(TokenType::LParen)
7008 {
7009 self.skip(); let alias = self.expect_identifier_or_keyword_with_quoted()?;
7011 Expression::Alias(Box::new(Alias::new(expr, alias)))
7012 } else {
7013 expr
7014 };
7015
7016 expressions.push(expr);
7017
7018 if !self.match_token(TokenType::Comma) {
7019 if self.check(TokenType::Cube)
7022 || self.check(TokenType::Rollup)
7023 || (self.check_identifier("GROUPING")
7024 && self
7025 .peek_nth(1)
7026 .map_or(false, |t| t.text.eq_ignore_ascii_case("SETS")))
7027 {
7028 continue;
7029 }
7030 break;
7031 }
7032 }
7033
7034 if self.check(TokenType::With)
7039 && (self.check_next(TokenType::Cube) || self.check_next(TokenType::Rollup))
7040 {
7041 self.skip(); if self.match_token(TokenType::Cube) {
7043 expressions.push(Expression::Cube(Box::new(Cube {
7045 expressions: Vec::new(),
7046 })));
7047 } else if self.match_token(TokenType::Rollup) {
7048 expressions.push(Expression::Rollup(Box::new(Rollup {
7050 expressions: Vec::new(),
7051 })));
7052 }
7053 }
7054
7055 let totals = if self.check(TokenType::With) && self.check_next_identifier("TOTALS") {
7057 self.skip(); self.skip(); true
7060 } else {
7061 false
7062 };
7063
7064 Ok(GroupBy {
7065 expressions,
7066 all,
7067 totals,
7068 comments: Vec::new(),
7069 })
7070 }
7071
7072 fn parse_grouping_sets_args(&mut self) -> Result<Vec<Expression>> {
7074 let mut args = Vec::new();
7075
7076 loop {
7077 let expr = if self.check_identifier("GROUPING")
7079 && self
7080 .peek_nth(1)
7081 .map_or(false, |t| t.text.eq_ignore_ascii_case("SETS"))
7082 && {
7083 self.skip();
7084 self.skip();
7085 true
7086 } {
7087 self.expect(TokenType::LParen)?;
7089 let inner_args = self.parse_grouping_sets_args()?;
7090 self.expect(TokenType::RParen)?;
7091 Expression::Function(Box::new(Function {
7092 name: "GROUPING SETS".to_string(),
7093 args: inner_args,
7094 distinct: false,
7095 trailing_comments: Vec::new(),
7096 use_bracket_syntax: false,
7097 no_parens: false,
7098 quoted: false,
7099 span: None,
7100 inferred_type: None,
7101 }))
7102 } else if self.match_token(TokenType::Cube) {
7103 self.expect(TokenType::LParen)?;
7105 let inner_args = self.parse_expression_list()?;
7106 self.expect(TokenType::RParen)?;
7107 Expression::Function(Box::new(Function {
7108 name: "CUBE".to_string(),
7109 args: inner_args,
7110 distinct: false,
7111 trailing_comments: Vec::new(),
7112 use_bracket_syntax: false,
7113 no_parens: false,
7114 quoted: false,
7115 span: None,
7116 inferred_type: None,
7117 }))
7118 } else if self.match_token(TokenType::Rollup) {
7119 self.expect(TokenType::LParen)?;
7121 let inner_args = self.parse_expression_list()?;
7122 self.expect(TokenType::RParen)?;
7123 Expression::Function(Box::new(Function {
7124 name: "ROLLUP".to_string(),
7125 args: inner_args,
7126 distinct: false,
7127 trailing_comments: Vec::new(),
7128 use_bracket_syntax: false,
7129 no_parens: false,
7130 quoted: false,
7131 span: None,
7132 inferred_type: None,
7133 }))
7134 } else if self.check(TokenType::LParen) {
7135 self.skip(); if self.check(TokenType::RParen) {
7138 self.skip();
7140 Expression::Tuple(Box::new(Tuple {
7141 expressions: Vec::new(),
7142 }))
7143 } else {
7144 let inner = self.parse_expression_list()?;
7145 self.expect(TokenType::RParen)?;
7146 Expression::Tuple(Box::new(Tuple { expressions: inner }))
7147 }
7148 } else {
7149 self.parse_expression()?
7150 };
7151
7152 args.push(expr);
7153
7154 if !self.match_token(TokenType::Comma) {
7155 break;
7156 }
7157 }
7158
7159 Ok(args)
7160 }
7161
7162 fn parse_order_by(&mut self) -> Result<OrderBy> {
7164 self.parse_order_by_with_siblings(false)
7165 }
7166
7167 fn parse_order_by_with_siblings(&mut self, siblings: bool) -> Result<OrderBy> {
7169 let mut expressions = Vec::new();
7170
7171 loop {
7172 let expr = self.parse_expression()?;
7173
7174 let expr = if matches!(
7177 self.config.dialect,
7178 Some(crate::dialects::DialectType::ClickHouse)
7179 ) && self.check(TokenType::As)
7180 && !self.check_next(TokenType::LParen)
7181 && !self.check_next(TokenType::Select)
7182 && !self.check_next(TokenType::With)
7183 {
7184 self.skip(); let alias = self.expect_identifier_or_keyword_with_quoted()?;
7186 Expression::Alias(Box::new(Alias::new(expr, alias)))
7187 } else {
7188 expr
7189 };
7190
7191 let (desc, explicit_asc) = if self.match_token(TokenType::Desc) {
7192 (true, false)
7193 } else if self.match_token(TokenType::Asc) {
7194 (false, true)
7195 } else {
7196 (false, false)
7197 };
7198
7199 let nulls_first = if self.match_token(TokenType::Nulls) {
7200 if self.match_token(TokenType::First) {
7201 Some(true)
7202 } else if self.match_token(TokenType::Last) {
7203 Some(false)
7204 } else {
7205 return Err(self.parse_error("Expected FIRST or LAST after NULLS"));
7206 }
7207 } else {
7208 None
7209 };
7210
7211 let with_fill = if self.match_text_seq(&["WITH", "FILL"]) {
7213 let from_ = if self.match_token(TokenType::From) {
7214 Some(Box::new(self.parse_or()?))
7215 } else {
7216 None
7217 };
7218 let to = if self.match_text_seq(&["TO"]) {
7219 Some(Box::new(self.parse_or()?))
7220 } else {
7221 None
7222 };
7223 let step = if self.match_text_seq(&["STEP"]) {
7224 Some(Box::new(self.parse_or()?))
7225 } else {
7226 None
7227 };
7228 let staleness = if self.match_text_seq(&["STALENESS"]) {
7230 Some(Box::new(self.parse_or()?))
7231 } else {
7232 None
7233 };
7234 let interpolate = if self.match_text_seq(&["INTERPOLATE"]) {
7235 if self.match_token(TokenType::LParen) {
7236 let mut items = Vec::new();
7238 loop {
7239 if self.check(TokenType::RParen) {
7240 break;
7241 }
7242 let quoted = self.check(TokenType::QuotedIdentifier);
7243 let name_text = self.expect_identifier_or_safe_keyword()?;
7244 let name_id = Identifier {
7245 name: name_text,
7246 quoted,
7247 trailing_comments: Vec::new(),
7248 span: None,
7249 };
7250 let item = if self.match_token(TokenType::As) {
7251 let expr = self.parse_expression()?;
7252 Expression::Alias(Box::new(Alias {
7254 this: expr,
7255 alias: name_id,
7256 column_aliases: Vec::new(),
7257 pre_alias_comments: Vec::new(),
7258 trailing_comments: Vec::new(),
7259 inferred_type: None,
7260 }))
7261 } else {
7262 Expression::Identifier(name_id)
7263 };
7264 items.push(item);
7265 if !self.match_token(TokenType::Comma) {
7266 break;
7267 }
7268 }
7269 self.expect(TokenType::RParen)?;
7270 if items.len() == 1 {
7271 Some(Box::new(items.into_iter().next().unwrap()))
7272 } else {
7273 Some(Box::new(Expression::Tuple(Box::new(
7274 crate::expressions::Tuple { expressions: items },
7275 ))))
7276 }
7277 } else {
7278 None
7279 }
7280 } else {
7281 None
7282 };
7283 Some(Box::new(WithFill {
7284 from_,
7285 to,
7286 step,
7287 staleness,
7288 interpolate,
7289 }))
7290 } else {
7291 None
7292 };
7293
7294 expressions.push(Ordered {
7295 this: expr,
7296 desc,
7297 nulls_first,
7298 explicit_asc,
7299 with_fill,
7300 });
7301
7302 if !self.match_token(TokenType::Comma) {
7303 break;
7304 }
7305
7306 if self.is_at_end() || self.check(TokenType::Semicolon) {
7308 break;
7309 }
7310 }
7311
7312 Ok(OrderBy {
7313 expressions,
7314 siblings,
7315 comments: Vec::new(),
7316 })
7317 }
7318
7319 fn parse_query_modifiers(&mut self, inner: Expression) -> Result<Expression> {
7323 let distribute_by = if self.match_keywords(&[TokenType::Distribute, TokenType::By]) {
7325 let exprs = self.parse_expression_list()?;
7326 Some(DistributeBy { expressions: exprs })
7327 } else {
7328 None
7329 };
7330
7331 let (sort_by, cluster_by) = if self.match_keywords(&[TokenType::Sort, TokenType::By]) {
7333 let mut orders = Vec::new();
7335 loop {
7336 if let Some(ordered) = self.parse_ordered_item()? {
7337 orders.push(ordered);
7338 } else {
7339 break;
7340 }
7341 if !self.match_token(TokenType::Comma) {
7342 break;
7343 }
7344 }
7345 (
7346 Some(SortBy {
7347 expressions: orders,
7348 }),
7349 None,
7350 )
7351 } else if self.match_keywords(&[TokenType::Cluster, TokenType::By]) {
7352 let mut orders = Vec::new();
7354 loop {
7355 if let Some(ordered) = self.parse_ordered_item()? {
7356 orders.push(ordered);
7357 } else {
7358 break;
7359 }
7360 if !self.match_token(TokenType::Comma) {
7361 break;
7362 }
7363 }
7364 (
7365 None,
7366 Some(ClusterBy {
7367 expressions: orders,
7368 }),
7369 )
7370 } else {
7371 (None, None)
7372 };
7373
7374 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
7376 Some(self.parse_order_by()?)
7377 } else {
7378 None
7379 };
7380
7381 let limit = if self.match_token(TokenType::Limit) {
7383 Some(Limit {
7384 this: self.parse_expression()?,
7385 percent: false,
7386 comments: Vec::new(),
7387 })
7388 } else {
7389 None
7390 };
7391
7392 let offset = if self.match_token(TokenType::Offset) {
7394 Some(Offset {
7395 this: self.parse_expression()?,
7396 rows: None,
7397 })
7398 } else {
7399 None
7400 };
7401
7402 if order_by.is_some()
7404 || limit.is_some()
7405 || offset.is_some()
7406 || distribute_by.is_some()
7407 || sort_by.is_some()
7408 || cluster_by.is_some()
7409 {
7410 if let Expression::Subquery(mut subq) = inner {
7412 subq.order_by = order_by;
7413 subq.limit = limit;
7414 subq.offset = offset;
7415 subq.distribute_by = distribute_by;
7416 subq.sort_by = sort_by;
7417 subq.cluster_by = cluster_by;
7418 Ok(Expression::Subquery(subq))
7419 } else if let Expression::Paren(paren) = inner {
7420 Ok(Expression::Subquery(Box::new(Subquery {
7424 this: Expression::Paren(paren),
7425 alias: None,
7426 column_aliases: Vec::new(),
7427 order_by,
7428 limit,
7429 offset,
7430 distribute_by,
7431 sort_by,
7432 cluster_by,
7433 lateral: false,
7434 modifiers_inside: false,
7435 trailing_comments: Vec::new(),
7436 inferred_type: None,
7437 })))
7438 } else {
7439 Ok(Expression::Subquery(Box::new(Subquery {
7440 this: inner,
7441 alias: None,
7442 column_aliases: Vec::new(),
7443 order_by,
7444 limit,
7445 offset,
7446 distribute_by,
7447 sort_by,
7448 cluster_by,
7449 lateral: false,
7450 modifiers_inside: false,
7451 trailing_comments: Vec::new(),
7452 inferred_type: None,
7453 })))
7454 }
7455 } else {
7456 Ok(inner)
7458 }
7459 }
7460
7461 fn parse_order_by_list(&mut self) -> Result<Vec<Ordered>> {
7464 let mut expressions = Vec::new();
7465
7466 loop {
7467 let expr = self.parse_expression()?;
7468
7469 let (desc, explicit_asc) = if self.match_token(TokenType::Desc) {
7470 (true, false)
7471 } else if self.match_token(TokenType::Asc) {
7472 (false, true)
7473 } else {
7474 (false, false)
7475 };
7476
7477 let nulls_first = if self.match_token(TokenType::Nulls) {
7478 if self.match_token(TokenType::First) {
7479 Some(true)
7480 } else if self.match_token(TokenType::Last) {
7481 Some(false)
7482 } else {
7483 return Err(self.parse_error("Expected FIRST or LAST after NULLS"));
7484 }
7485 } else {
7486 None
7487 };
7488
7489 expressions.push(Ordered {
7490 this: expr,
7491 desc,
7492 nulls_first,
7493 explicit_asc,
7494 with_fill: None,
7495 });
7496
7497 if !self.match_token(TokenType::Comma) {
7498 break;
7499 }
7500 }
7501
7502 Ok(expressions)
7503 }
7504
7505 fn parse_distribute_by(&mut self) -> Result<DistributeBy> {
7507 let mut expressions = Vec::new();
7508
7509 loop {
7510 expressions.push(self.parse_expression()?);
7511 if !self.match_token(TokenType::Comma) {
7512 break;
7513 }
7514 }
7515
7516 Ok(DistributeBy { expressions })
7517 }
7518
7519 fn parse_cluster_by(&mut self) -> Result<ClusterBy> {
7521 let mut expressions = Vec::new();
7522
7523 loop {
7524 let expr = self.parse_expression()?;
7525
7526 let (desc, explicit_asc) = if self.match_token(TokenType::Desc) {
7527 (true, false)
7528 } else if self.match_token(TokenType::Asc) {
7529 (false, true)
7530 } else {
7531 (false, false)
7532 };
7533
7534 expressions.push(Ordered {
7535 this: expr,
7536 desc,
7537 nulls_first: None,
7538 explicit_asc,
7539 with_fill: None,
7540 });
7541
7542 if !self.match_token(TokenType::Comma) {
7543 break;
7544 }
7545 }
7546
7547 Ok(ClusterBy { expressions })
7548 }
7549
7550 fn parse_sort_by(&mut self) -> Result<SortBy> {
7552 let mut expressions = Vec::new();
7553
7554 loop {
7555 let expr = self.parse_expression()?;
7556
7557 let (desc, explicit_asc) = if self.match_token(TokenType::Desc) {
7558 (true, false)
7559 } else if self.match_token(TokenType::Asc) {
7560 (false, true)
7561 } else {
7562 (false, false)
7563 };
7564
7565 let nulls_first = if self.match_token(TokenType::Nulls) {
7566 if self.match_token(TokenType::First) {
7567 Some(true)
7568 } else if self.match_token(TokenType::Last) {
7569 Some(false)
7570 } else {
7571 return Err(self.parse_error("Expected FIRST or LAST after NULLS"));
7572 }
7573 } else {
7574 None
7575 };
7576
7577 expressions.push(Ordered {
7578 this: expr,
7579 desc,
7580 nulls_first,
7581 explicit_asc,
7582 with_fill: None,
7583 });
7584
7585 if !self.match_token(TokenType::Comma) {
7586 break;
7587 }
7588 }
7589
7590 Ok(SortBy { expressions })
7591 }
7592
7593 fn parse_locks_and_for_xml(&mut self) -> Result<(Vec<Lock>, Vec<Expression>)> {
7598 let mut locks = Vec::new();
7599 let mut for_xml = Vec::new();
7600
7601 loop {
7602 let (update, key) = if self.match_keywords(&[TokenType::For, TokenType::Update]) {
7603 (
7605 Some(Box::new(Expression::Boolean(BooleanLiteral {
7606 value: true,
7607 }))),
7608 None,
7609 )
7610 } else if self.check(TokenType::For) && self.check_next_identifier("XML") {
7611 self.skip(); self.skip(); for_xml = self.parse_for_xml_options()?;
7615 break; } else if self.check(TokenType::For) && self.check_next_identifier("SHARE") {
7617 self.skip(); self.skip(); (None, None)
7621 } else if self.check_identifier("LOCK") && self.check_next(TokenType::In) {
7622 self.skip(); self.skip(); if self.match_identifier("SHARE") {
7626 let _ = self.match_identifier("MODE");
7627 }
7628 (None, None)
7629 } else if self.check(TokenType::For) && self.check_next(TokenType::Key) {
7630 self.skip(); self.skip(); if !self.match_identifier("SHARE") {
7634 break; }
7636 (
7637 None,
7638 Some(Box::new(Expression::Boolean(BooleanLiteral {
7639 value: true,
7640 }))),
7641 )
7642 } else if self.check(TokenType::For) && self.check_next(TokenType::No) {
7643 self.skip(); self.skip(); if !self.match_identifier("KEY") || !self.match_token(TokenType::Update) {
7647 break; }
7649 (
7650 Some(Box::new(Expression::Boolean(BooleanLiteral {
7651 value: true,
7652 }))),
7653 Some(Box::new(Expression::Boolean(BooleanLiteral {
7654 value: true,
7655 }))),
7656 )
7657 } else {
7658 break;
7660 };
7661
7662 let expressions = if self.match_token(TokenType::Of) {
7664 let mut tables = Vec::new();
7665 loop {
7666 let table = self.parse_table_ref()?;
7668 tables.push(Expression::Table(Box::new(table)));
7669 if !self.match_token(TokenType::Comma) {
7670 break;
7671 }
7672 }
7673 tables
7674 } else {
7675 Vec::new()
7676 };
7677
7678 let wait = if self.match_identifier("NOWAIT") {
7684 Some(Box::new(Expression::Boolean(BooleanLiteral {
7686 value: true,
7687 })))
7688 } else if self.match_identifier("WAIT") {
7689 Some(Box::new(self.parse_primary()?))
7691 } else if self.match_identifier("SKIP") && self.match_identifier("LOCKED") {
7692 Some(Box::new(Expression::Boolean(BooleanLiteral {
7694 value: false,
7695 })))
7696 } else {
7697 None
7698 };
7699
7700 locks.push(Lock {
7701 update,
7702 expressions,
7703 wait,
7704 key,
7705 });
7706 }
7707
7708 Ok((locks, for_xml))
7709 }
7710
7711 fn parse_for_xml_options(&mut self) -> Result<Vec<Expression>> {
7714 let mut options = Vec::new();
7715
7716 loop {
7717 if let Some(opt) = self.parse_for_xml_single_option()? {
7720 options.push(opt);
7721 } else {
7722 break;
7723 }
7724
7725 if !self.match_token(TokenType::Comma) {
7727 break;
7728 }
7729 }
7730
7731 Ok(options)
7732 }
7733
7734 fn parse_for_xml_single_option(&mut self) -> Result<Option<Expression>> {
7736 if self.match_identifier("PATH") {
7741 let expression = if self.match_token(TokenType::LParen) {
7742 let expr = self.parse_string()?;
7743 self.expect(TokenType::RParen)?;
7744 expr
7745 } else {
7746 None
7747 };
7748 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7749 this: Box::new(Expression::Var(Box::new(Var {
7750 this: "PATH".to_string(),
7751 }))),
7752 expression: expression.map(|e| Box::new(e)),
7753 }))));
7754 }
7755
7756 if self.match_identifier("RAW") {
7757 let expression = if self.match_token(TokenType::LParen) {
7758 let expr = self.parse_string()?;
7759 self.expect(TokenType::RParen)?;
7760 expr
7761 } else {
7762 None
7763 };
7764 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7765 this: Box::new(Expression::Var(Box::new(Var {
7766 this: "RAW".to_string(),
7767 }))),
7768 expression: expression.map(|e| Box::new(e)),
7769 }))));
7770 }
7771
7772 if self.match_identifier("AUTO") {
7773 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7774 this: Box::new(Expression::Var(Box::new(Var {
7775 this: "AUTO".to_string(),
7776 }))),
7777 expression: None,
7778 }))));
7779 }
7780
7781 if self.match_identifier("EXPLICIT") {
7782 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7783 this: Box::new(Expression::Var(Box::new(Var {
7784 this: "EXPLICIT".to_string(),
7785 }))),
7786 expression: None,
7787 }))));
7788 }
7789
7790 if self.match_identifier("TYPE") {
7791 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7792 this: Box::new(Expression::Var(Box::new(Var {
7793 this: "TYPE".to_string(),
7794 }))),
7795 expression: None,
7796 }))));
7797 }
7798
7799 if self.match_identifier("BINARY") {
7800 if self.match_identifier("BASE64") {
7802 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7803 this: Box::new(Expression::Var(Box::new(Var {
7804 this: "BINARY BASE64".to_string(),
7805 }))),
7806 expression: None,
7807 }))));
7808 } else {
7809 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7810 this: Box::new(Expression::Var(Box::new(Var {
7811 this: "BINARY".to_string(),
7812 }))),
7813 expression: None,
7814 }))));
7815 }
7816 }
7817
7818 if self.match_identifier("ELEMENTS") {
7819 let suboption = if self.match_identifier("XSINIL") {
7821 Some("XSINIL".to_string())
7822 } else if self.match_identifier("ABSENT") {
7823 Some("ABSENT".to_string())
7824 } else {
7825 None
7826 };
7827 let option_name = match &suboption {
7828 Some(sub) => format!("ELEMENTS {}", sub),
7829 None => "ELEMENTS".to_string(),
7830 };
7831 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7832 this: Box::new(Expression::Var(Box::new(Var { this: option_name }))),
7833 expression: None,
7834 }))));
7835 }
7836
7837 if self.match_identifier("ROOT") {
7838 let expression = if self.match_token(TokenType::LParen) {
7839 let expr = self.parse_string()?;
7840 self.expect(TokenType::RParen)?;
7841 expr
7842 } else {
7843 None
7844 };
7845 return Ok(Some(Expression::QueryOption(Box::new(QueryOption {
7846 this: Box::new(Expression::Var(Box::new(Var {
7847 this: "ROOT".to_string(),
7848 }))),
7849 expression: expression.map(|e| Box::new(e)),
7850 }))));
7851 }
7852
7853 Ok(None)
7855 }
7856
7857 fn parse_connect(&mut self) -> Result<Option<Connect>> {
7861 let start_before = if self.match_keywords(&[TokenType::Start, TokenType::With]) {
7863 Some(self.parse_expression()?)
7864 } else {
7865 None
7866 };
7867
7868 if !self.match_keywords(&[TokenType::Connect, TokenType::By]) {
7870 if start_before.is_some() {
7871 return Err(self.parse_error("START WITH without CONNECT BY"));
7872 }
7873 return Ok(None);
7874 }
7875
7876 let nocycle = self.match_token(TokenType::NoCycle);
7878
7879 let connect = self.parse_connect_expression()?;
7881
7882 let start = if start_before.is_some() {
7884 start_before
7885 } else if self.match_keywords(&[TokenType::Start, TokenType::With]) {
7886 Some(self.parse_expression()?)
7887 } else {
7888 None
7889 };
7890
7891 Ok(Some(Connect {
7892 start,
7893 connect,
7894 nocycle,
7895 }))
7896 }
7897
7898 fn parse_connect_expression(&mut self) -> Result<Expression> {
7900 self.parse_connect_or()
7901 }
7902
7903 fn parse_connect_or(&mut self) -> Result<Expression> {
7905 let mut left = self.parse_connect_and()?;
7906
7907 while self.match_token(TokenType::Or) {
7908 let right = self.parse_connect_and()?;
7909 left = Expression::Or(Box::new(BinaryOp::new(left, right)));
7910 }
7911
7912 Ok(Self::maybe_rebalance_boolean_chain(left, false))
7913 }
7914
7915 fn parse_connect_and(&mut self) -> Result<Expression> {
7917 let mut left = self.parse_connect_comparison()?;
7918
7919 while self.match_token(TokenType::And) {
7920 let right = self.parse_connect_comparison()?;
7921 left = Expression::And(Box::new(BinaryOp::new(left, right)));
7922 }
7923
7924 Ok(Self::maybe_rebalance_boolean_chain(left, true))
7925 }
7926
7927 fn parse_connect_comparison(&mut self) -> Result<Expression> {
7929 let left = self.parse_connect_primary()?;
7930
7931 if self.match_token(TokenType::Eq) {
7932 let right = self.parse_connect_primary()?;
7933 return Ok(Expression::Eq(Box::new(BinaryOp::new(left, right))));
7934 }
7935 if self.match_token(TokenType::Neq) {
7936 let right = self.parse_connect_primary()?;
7937 return Ok(Expression::Neq(Box::new(BinaryOp::new(left, right))));
7938 }
7939 if self.match_token(TokenType::Lt) {
7940 let right = self.parse_connect_primary()?;
7941 return Ok(Expression::Lt(Box::new(BinaryOp::new(left, right))));
7942 }
7943 if self.match_token(TokenType::Lte) {
7944 let right = self.parse_connect_primary()?;
7945 return Ok(Expression::Lte(Box::new(BinaryOp::new(left, right))));
7946 }
7947 if self.match_token(TokenType::Gt) {
7948 let right = self.parse_connect_primary()?;
7949 return Ok(Expression::Gt(Box::new(BinaryOp::new(left, right))));
7950 }
7951 if self.match_token(TokenType::Gte) {
7952 let right = self.parse_connect_primary()?;
7953 return Ok(Expression::Gte(Box::new(BinaryOp::new(left, right))));
7954 }
7955
7956 Ok(left)
7957 }
7958
7959 fn parse_connect_primary(&mut self) -> Result<Expression> {
7961 if self.match_token(TokenType::Prior) {
7963 let expr = self.parse_primary()?;
7964 return Ok(Expression::Prior(Box::new(Prior { this: expr })));
7965 }
7966
7967 if let Some(connect_by_root) = self.try_parse_connect_by_root_expression()? {
7968 return Ok(connect_by_root);
7969 }
7970
7971 self.parse_primary()
7972 }
7973
7974 fn try_parse_connect_by_root_expression(&mut self) -> Result<Option<Expression>> {
7978 if !(self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("CONNECT_BY_ROOT"))
7979 {
7980 return Ok(None);
7981 }
7982
7983 self.skip();
7984
7985 let this = if self.match_token(TokenType::LParen) {
7986 let expr = self.parse_expression()?;
7987 self.expect(TokenType::RParen)?;
7988 expr
7989 } else {
7990 self.parse_column()?.ok_or_else(|| {
7991 self.parse_error("Expected expression or column after CONNECT_BY_ROOT")
7992 })?
7993 };
7994
7995 Ok(Some(Expression::ConnectByRoot(Box::new(ConnectByRoot {
7996 this,
7997 }))))
7998 }
7999
8000 fn parse_match_recognize(&mut self, source: Option<Expression>) -> Result<Expression> {
8003 self.expect(TokenType::LParen)?;
8004
8005 let partition_by = if self.match_keywords(&[TokenType::Partition, TokenType::By]) {
8007 Some(self.parse_expression_list()?)
8008 } else {
8009 None
8010 };
8011
8012 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
8014 Some(self.parse_order_by()?.expressions)
8015 } else {
8016 None
8017 };
8018
8019 let measures = if self.match_token(TokenType::Measures) {
8021 Some(self.parse_match_recognize_measures()?)
8022 } else {
8023 None
8024 };
8025
8026 let rows = self.parse_match_recognize_rows()?;
8028
8029 let after = self.parse_match_recognize_after()?;
8031
8032 let pattern = if self.match_token(TokenType::Pattern) {
8034 Some(self.parse_match_recognize_pattern()?)
8035 } else {
8036 None
8037 };
8038
8039 let define = if self.match_token(TokenType::Define) {
8041 Some(self.parse_match_recognize_define()?)
8042 } else {
8043 None
8044 };
8045
8046 self.expect(TokenType::RParen)?;
8047
8048 Ok(Expression::MatchRecognize(Box::new(MatchRecognize {
8051 this: source.map(Box::new),
8052 partition_by,
8053 order_by,
8054 measures,
8055 rows,
8056 after,
8057 pattern,
8058 define,
8059 alias: None,
8060 alias_explicit_as: false,
8061 })))
8062 }
8063
8064 fn parse_match_recognize_measures(&mut self) -> Result<Vec<MatchRecognizeMeasure>> {
8066 let mut measures = Vec::new();
8067
8068 loop {
8069 let window_frame = if self.match_token(TokenType::Running) {
8071 Some(MatchRecognizeSemantics::Running)
8072 } else if self.match_token(TokenType::Final) {
8073 Some(MatchRecognizeSemantics::Final)
8074 } else {
8075 None
8076 };
8077
8078 let mut expr = self.parse_expression()?;
8079
8080 if self.match_token(TokenType::As) {
8082 let alias = Identifier::new(self.expect_identifier()?);
8083 expr = Expression::Alias(Box::new(Alias::new(expr, alias)));
8084 }
8085
8086 measures.push(MatchRecognizeMeasure {
8087 this: expr,
8088 window_frame,
8089 });
8090
8091 if !self.match_token(TokenType::Comma) {
8092 break;
8093 }
8094 }
8095
8096 Ok(measures)
8097 }
8098
8099 fn parse_match_recognize_rows(&mut self) -> Result<Option<MatchRecognizeRows>> {
8101 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("ONE") {
8103 self.skip(); if !self.match_token(TokenType::Row) {
8105 return Err(self.parse_error("Expected ROW after ONE"));
8106 }
8107 if !(self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("PER")) {
8108 return Err(self.parse_error("Expected PER after ONE ROW"));
8109 }
8110 self.skip(); if !self.match_token(TokenType::Match) {
8112 return Err(self.parse_error("Expected MATCH after ONE ROW PER"));
8113 }
8114 return Ok(Some(MatchRecognizeRows::OneRowPerMatch));
8115 }
8116
8117 if self.match_token(TokenType::All) {
8119 if !self.match_token(TokenType::Rows) {
8120 return Err(self.parse_error("Expected ROWS after ALL"));
8121 }
8122 if !(self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("PER")) {
8123 return Err(self.parse_error("Expected PER after ALL ROWS"));
8124 }
8125 self.skip(); if !self.match_token(TokenType::Match) {
8127 return Err(self.parse_error("Expected MATCH after ALL ROWS PER"));
8128 }
8129
8130 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("SHOW") {
8132 self.skip();
8133 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("EMPTY") {
8134 self.skip();
8135 if self.check(TokenType::Var)
8136 && self.peek().text.eq_ignore_ascii_case("MATCHES")
8137 {
8138 self.skip();
8139 return Ok(Some(MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches));
8140 }
8141 }
8142 return Err(self.parse_error("Expected EMPTY MATCHES after SHOW"));
8143 }
8144
8145 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("OMIT") {
8146 self.skip();
8147 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("EMPTY") {
8148 self.skip();
8149 if self.check(TokenType::Var)
8150 && self.peek().text.eq_ignore_ascii_case("MATCHES")
8151 {
8152 self.skip();
8153 return Ok(Some(MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches));
8154 }
8155 }
8156 return Err(self.parse_error("Expected EMPTY MATCHES after OMIT"));
8157 }
8158
8159 if self.match_token(TokenType::With) {
8160 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("UNMATCHED")
8161 {
8162 self.skip();
8163 if self.match_token(TokenType::Rows) {
8164 return Ok(Some(MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows));
8165 }
8166 }
8167 return Err(self.parse_error("Expected UNMATCHED ROWS after WITH"));
8168 }
8169
8170 return Ok(Some(MatchRecognizeRows::AllRowsPerMatch));
8171 }
8172
8173 Ok(None)
8174 }
8175
8176 fn parse_match_recognize_after(&mut self) -> Result<Option<MatchRecognizeAfter>> {
8178 if !self.match_token(TokenType::After) {
8179 return Ok(None);
8180 }
8181
8182 if !self.match_token(TokenType::Match) {
8183 return Err(self.parse_error("Expected MATCH after AFTER"));
8184 }
8185
8186 if !(self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("SKIP")) {
8188 return Err(self.parse_error("Expected SKIP after AFTER MATCH"));
8189 }
8190 self.skip(); if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("PAST") {
8194 self.skip();
8195 if self.match_token(TokenType::Last) {
8196 if self.match_token(TokenType::Row) {
8197 return Ok(Some(MatchRecognizeAfter::PastLastRow));
8198 }
8199 }
8200 return Err(self.parse_error("Expected LAST ROW after PAST"));
8201 }
8202
8203 if self.match_token(TokenType::To) {
8205 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("NEXT") {
8206 self.skip();
8207 if self.match_token(TokenType::Row) {
8208 return Ok(Some(MatchRecognizeAfter::ToNextRow));
8209 }
8210 return Err(self.parse_error("Expected ROW after NEXT"));
8211 }
8212
8213 if self.match_token(TokenType::First) {
8214 let name = self.expect_identifier()?;
8215 return Ok(Some(MatchRecognizeAfter::ToFirst(Identifier::new(name))));
8216 }
8217
8218 if self.match_token(TokenType::Last) {
8219 let name = self.expect_identifier()?;
8220 return Ok(Some(MatchRecognizeAfter::ToLast(Identifier::new(name))));
8221 }
8222
8223 return Err(self.parse_error("Expected NEXT ROW, FIRST x, or LAST x after TO"));
8224 }
8225
8226 Err(self.parse_error("Expected PAST LAST ROW or TO ... after AFTER MATCH SKIP"))
8227 }
8228
8229 fn parse_match_recognize_pattern(&mut self) -> Result<String> {
8231 self.expect(TokenType::LParen)?;
8232
8233 let mut depth = 1;
8234 let mut pattern = String::new();
8235
8236 while depth > 0 && !self.is_at_end() {
8237 let token = self.advance();
8238 match token.token_type {
8239 TokenType::LParen => {
8240 depth += 1;
8241 pattern.push('(');
8242 }
8243 TokenType::RParen => {
8244 depth -= 1;
8245 if depth > 0 {
8246 pattern.push(')');
8247 }
8248 }
8249 _ => {
8250 let is_quantifier = matches!(token.text.as_str(), "+" | "*" | "?")
8252 || token.text.starts_with('{');
8253
8254 if !pattern.is_empty()
8255 && !pattern.ends_with('(')
8256 && !pattern.ends_with(' ')
8257 && !is_quantifier
8258 {
8259 pattern.push(' ');
8260 }
8261 pattern.push_str(&token.text);
8262 }
8263 }
8264 }
8265
8266 if depth > 0 {
8267 return Err(self.parse_error("Unclosed parenthesis in PATTERN clause"));
8268 }
8269
8270 Ok(pattern.trim().to_string())
8271 }
8272
8273 fn parse_match_recognize_define(&mut self) -> Result<Vec<(Identifier, Expression)>> {
8275 let mut definitions = Vec::new();
8276
8277 loop {
8278 let name = Identifier::new(self.expect_identifier()?);
8279 self.expect(TokenType::As)?;
8280 let expr = self.parse_expression()?;
8281
8282 definitions.push((name, expr));
8283
8284 if !self.match_token(TokenType::Comma) {
8285 break;
8286 }
8287 }
8288
8289 Ok(definitions)
8290 }
8291
8292 fn parse_lateral_views(&mut self) -> Result<Vec<LateralView>> {
8295 let mut views = Vec::new();
8296
8297 while self.match_keywords(&[TokenType::Lateral, TokenType::View]) {
8298 let outer = self.match_token(TokenType::Outer);
8300
8301 let this = self.parse_primary()?;
8304
8305 let table_alias = if self.check(TokenType::Var) && !self.check_keyword() {
8307 Some(Identifier::new(self.expect_identifier()?))
8308 } else {
8309 None
8310 };
8311
8312 let column_aliases = if self.match_token(TokenType::As) {
8315 let mut aliases = Vec::new();
8316 if self.match_token(TokenType::LParen) {
8318 loop {
8319 aliases.push(Identifier::new(self.expect_identifier_or_keyword()?));
8320 if !self.match_token(TokenType::Comma) {
8321 break;
8322 }
8323 }
8324 self.expect(TokenType::RParen)?;
8325 } else {
8326 loop {
8329 aliases.push(Identifier::new(self.expect_identifier_or_keyword()?));
8330 if !self.match_token(TokenType::Comma) {
8331 break;
8332 }
8333 if !self.is_identifier_or_keyword_token() {
8336 break;
8337 }
8338 if self.peek().token_type == TokenType::Lateral
8340 || self.peek().token_type == TokenType::Where
8341 || self.peek().token_type == TokenType::Group
8342 || self.peek().token_type == TokenType::Having
8343 || self.peek().token_type == TokenType::Order
8344 || self.peek().token_type == TokenType::Limit
8345 {
8346 break;
8347 }
8348 }
8349 }
8350 aliases
8351 } else {
8352 Vec::new()
8353 };
8354
8355 views.push(LateralView {
8356 this,
8357 table_alias,
8358 column_aliases,
8359 outer,
8360 });
8361 }
8362
8363 Ok(views)
8364 }
8365
8366 fn parse_named_windows(&mut self) -> Result<Vec<NamedWindow>> {
8368 let mut windows = Vec::new();
8369
8370 loop {
8371 let name = self.expect_identifier()?;
8372 self.expect(TokenType::As)?;
8373 self.expect(TokenType::LParen)?;
8374
8375 let window_name = if (self.check(TokenType::Identifier)
8377 || self.check(TokenType::Var)
8378 || self.check(TokenType::QuotedIdentifier))
8379 && !self.check(TokenType::Partition)
8380 && !self.check(TokenType::Order)
8381 && self.peek_nth(1).map_or(true, |t| {
8382 matches!(
8383 t.token_type,
8384 TokenType::Partition
8385 | TokenType::Order
8386 | TokenType::Rows
8387 | TokenType::Range
8388 | TokenType::Groups
8389 | TokenType::RParen
8390 | TokenType::Comma
8391 )
8392 }) {
8393 Some(self.expect_identifier()?)
8394 } else {
8395 None
8396 };
8397
8398 let partition_by = if self.match_keywords(&[TokenType::Partition, TokenType::By]) {
8400 Some(self.parse_expression_list()?)
8401 } else {
8402 None
8403 };
8404
8405 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
8406 Some(self.parse_order_by()?)
8407 } else {
8408 None
8409 };
8410
8411 let frame = self.parse_window_frame()?;
8412
8413 self.expect(TokenType::RParen)?;
8414
8415 windows.push(NamedWindow {
8416 name: Identifier::new(name),
8417 spec: Over {
8418 window_name: window_name.map(|n| Identifier::new(n)),
8419 partition_by: partition_by.unwrap_or_default(),
8420 order_by: order_by.map(|o| o.expressions).unwrap_or_default(),
8421 frame,
8422 alias: None,
8423 },
8424 });
8425
8426 if !self.match_token(TokenType::Comma) {
8427 break;
8428 }
8429 }
8430
8431 Ok(windows)
8432 }
8433
8434 fn parse_hint(&mut self) -> Result<Hint> {
8436 let token = self.advance();
8437 let hint_text = token.text.clone();
8438
8439 let expressions = if hint_text.is_empty() {
8442 Vec::new()
8443 } else {
8444 vec![HintExpression::Raw(hint_text)]
8445 };
8446
8447 Ok(Hint { expressions })
8448 }
8449
8450 fn parse_sample_clause(&mut self) -> Result<Option<Sample>> {
8452 let is_using_sample = if self.check(TokenType::Using)
8454 && self.current + 1 < self.tokens.len()
8455 && self.tokens[self.current + 1].token_type == TokenType::Sample
8456 {
8457 self.skip(); self.skip(); true
8460 } else {
8461 false
8462 };
8463
8464 let use_sample_keyword = if is_using_sample {
8465 true
8467 } else if self.match_token(TokenType::Sample) {
8468 true
8469 } else if self.match_token(TokenType::TableSample) {
8470 false
8471 } else {
8472 return Ok(None);
8473 };
8474
8475 let (method, method_before_size, explicit_method) =
8477 if self.match_token(TokenType::Bernoulli) {
8478 (SampleMethod::Bernoulli, true, true)
8479 } else if self.match_token(TokenType::System) {
8480 (SampleMethod::System, true, true)
8481 } else if self.match_token(TokenType::Block) {
8482 (SampleMethod::Block, true, true)
8483 } else if self.match_token(TokenType::Row) {
8484 (SampleMethod::Row, true, true)
8485 } else if self.check_identifier("RESERVOIR") {
8486 self.skip();
8487 (SampleMethod::Reservoir, true, true)
8488 } else {
8489 (SampleMethod::Bernoulli, false, false)
8492 };
8493
8494 let has_paren = self.match_token(TokenType::LParen);
8496
8497 if self.match_identifier("BUCKET") {
8499 let bucket_numerator = self.parse_primary()?;
8500 self.match_identifier("OUT");
8501 self.match_token(TokenType::Of); let bucket_denominator = self.parse_primary()?;
8503 let bucket_field = if self.match_token(TokenType::On) {
8504 Some(Box::new(self.parse_primary()?))
8505 } else {
8506 None
8507 };
8508 if has_paren {
8509 self.expect(TokenType::RParen)?;
8510 }
8511 return Ok(Some(Sample {
8512 method: SampleMethod::Bucket,
8513 size: bucket_numerator.clone(),
8514 seed: None,
8515 offset: None,
8516 unit_after_size: false,
8517 use_sample_keyword,
8518 explicit_method: true, method_before_size: false, use_seed_keyword: false,
8521 bucket_numerator: Some(Box::new(bucket_numerator)),
8522 bucket_denominator: Some(Box::new(bucket_denominator)),
8523 bucket_field,
8524 is_using_sample,
8525 is_percent: false,
8526 suppress_method_output: false,
8527 }));
8528 }
8529
8530 let size = self.parse_unary()?;
8532
8533 let (method, unit_after_size, is_percent) = if self.check(TokenType::Percent) {
8536 self.skip(); if method_before_size {
8540 (method, true, true)
8541 } else {
8542 (SampleMethod::Percent, true, true)
8543 }
8544 } else if self.match_token(TokenType::Rows) {
8545 if method_before_size {
8547 (method, true, false)
8548 } else {
8549 (SampleMethod::Row, true, false)
8550 }
8551 } else {
8552 (method, false, false)
8554 };
8555
8556 if has_paren {
8557 self.expect(TokenType::RParen)?;
8558 }
8559
8560 let (method, seed, use_seed_keyword, explicit_method) =
8565 if is_using_sample && self.check(TokenType::LParen) {
8566 self.skip(); let method_from_parens =
8570 if self.check_identifier("BERNOULLI") || self.check(TokenType::Bernoulli) {
8571 self.skip();
8572 Some(SampleMethod::Bernoulli)
8573 } else if self.check_identifier("SYSTEM") || self.check(TokenType::System) {
8574 self.skip();
8575 Some(SampleMethod::System)
8576 } else if self.check_identifier("RESERVOIR") {
8577 self.skip();
8578 Some(SampleMethod::Reservoir)
8579 } else {
8580 None
8581 };
8582 let seed = if self.match_token(TokenType::Comma) {
8584 Some(self.parse_expression()?)
8585 } else {
8586 None
8587 };
8588 self.expect(TokenType::RParen)?;
8589 let final_method = method_from_parens.unwrap_or(method);
8590 (final_method, seed, false, true)
8591 } else {
8592 let (seed, use_seed_keyword) = if self.match_token(TokenType::Seed) {
8594 self.expect(TokenType::LParen)?;
8595 let seed_value = self.parse_expression()?;
8596 self.expect(TokenType::RParen)?;
8597 (Some(seed_value), true)
8598 } else if self.match_token(TokenType::Repeatable) {
8599 self.expect(TokenType::LParen)?;
8600 let seed_value = self.parse_expression()?;
8601 self.expect(TokenType::RParen)?;
8602 (Some(seed_value), false)
8603 } else {
8604 (None, false)
8605 };
8606 let explicit_method = explicit_method || unit_after_size;
8607 (method, seed, use_seed_keyword, explicit_method)
8608 };
8609
8610 let (method, unit_after_size) = if is_using_sample && !explicit_method {
8614 (SampleMethod::Reservoir, false) } else if is_using_sample && unit_after_size && !method_before_size {
8617 if matches!(method, SampleMethod::Percent) {
8620 (SampleMethod::System, true)
8622 } else if matches!(method, SampleMethod::Row) {
8623 (SampleMethod::Reservoir, true)
8625 } else {
8626 (method, unit_after_size)
8627 }
8628 } else {
8629 (method, unit_after_size)
8630 };
8631
8632 Ok(Some(Sample {
8635 method,
8636 size,
8637 seed,
8638 offset: None,
8639 unit_after_size,
8640 use_sample_keyword,
8641 explicit_method: true, method_before_size: true, use_seed_keyword,
8644 bucket_numerator: None,
8645 bucket_denominator: None,
8646 bucket_field: None,
8647 is_using_sample,
8648 is_percent,
8649 suppress_method_output: false,
8650 }))
8651 }
8652
8653 fn parse_table_level_sample(&mut self) -> Result<Option<Sample>> {
8656 let use_sample_keyword = if self.match_token(TokenType::Sample) {
8658 true
8659 } else if self.match_token(TokenType::TableSample) {
8660 false
8661 } else {
8662 return Ok(None);
8663 };
8664 let _ = use_sample_keyword; if matches!(
8669 self.config.dialect,
8670 Some(crate::dialects::DialectType::Teradata)
8671 ) && use_sample_keyword
8672 && !self.check(TokenType::LParen)
8673 {
8674 let mut expressions = vec![self.parse_unary()?];
8675 while self.match_token(TokenType::Comma) {
8676 expressions.push(self.parse_unary()?);
8677 }
8678 let size = if expressions.len() == 1 {
8679 expressions.into_iter().next().unwrap()
8680 } else {
8681 Expression::Tuple(Box::new(Tuple { expressions }))
8682 };
8683 return Ok(Some(Sample {
8684 method: SampleMethod::Percent,
8685 size,
8686 seed: None,
8687 offset: None,
8688 unit_after_size: false,
8689 use_sample_keyword,
8690 explicit_method: false,
8691 method_before_size: false,
8692 use_seed_keyword: false,
8693 bucket_numerator: None,
8694 bucket_denominator: None,
8695 bucket_field: None,
8696 is_using_sample: false,
8697 is_percent: false,
8698 suppress_method_output: false,
8699 }));
8700 }
8701
8702 if matches!(
8704 self.config.dialect,
8705 Some(crate::dialects::DialectType::ClickHouse)
8706 ) && use_sample_keyword
8707 && !self.check(TokenType::LParen)
8708 {
8709 let size = self.parse_expression()?;
8710 let offset = if self.match_token(TokenType::Offset) {
8711 Some(self.parse_expression()?)
8712 } else {
8713 None
8714 };
8715 return Ok(Some(Sample {
8716 method: SampleMethod::Bernoulli,
8717 size,
8718 seed: None,
8719 offset,
8720 unit_after_size: false,
8721 use_sample_keyword,
8722 explicit_method: false,
8723 method_before_size: false,
8724 use_seed_keyword: false,
8725 bucket_numerator: None,
8726 bucket_denominator: None,
8727 bucket_field: None,
8728 is_using_sample: false,
8729 is_percent: false,
8730 suppress_method_output: false,
8731 }));
8732 }
8733
8734 let (method, explicit_method, method_before_size) = if self.check_identifier("RESERVOIR") {
8736 self.skip();
8737 (SampleMethod::Reservoir, true, true)
8738 } else if self.match_token(TokenType::Bernoulli) {
8739 (SampleMethod::Bernoulli, true, true)
8740 } else if self.match_token(TokenType::System) {
8741 (SampleMethod::System, true, true)
8742 } else if self.match_token(TokenType::Block) {
8743 (SampleMethod::Block, true, true)
8744 } else if self.match_token(TokenType::Row) {
8745 (SampleMethod::Row, true, true)
8746 } else {
8747 (SampleMethod::Bernoulli, false, false)
8749 };
8750
8751 self.expect(TokenType::LParen)?;
8753
8754 if self.match_identifier("BUCKET") {
8756 let bucket_numerator = self.parse_primary()?;
8757 self.match_identifier("OUT");
8758 self.match_token(TokenType::Of);
8759 let bucket_denominator = self.parse_primary()?;
8760 let bucket_field = if self.match_token(TokenType::On) {
8761 Some(Box::new(self.parse_primary()?))
8762 } else {
8763 None
8764 };
8765 self.expect(TokenType::RParen)?;
8766 return Ok(Some(Sample {
8767 method: SampleMethod::Bucket,
8768 size: bucket_numerator.clone(),
8769 seed: None,
8770 offset: None,
8771 unit_after_size: false,
8772 use_sample_keyword,
8773 explicit_method: true,
8774 method_before_size: false,
8775 use_seed_keyword: false,
8776 bucket_numerator: Some(Box::new(bucket_numerator)),
8777 bucket_denominator: Some(Box::new(bucket_denominator)),
8778 bucket_field,
8779 is_using_sample: false,
8780 is_percent: false,
8781 suppress_method_output: false,
8782 }));
8783 }
8784
8785 let size = self.parse_unary()?;
8786
8787 let (method, unit_after_size, is_percent) =
8789 if self.check(TokenType::Percent) && self.peek().text.eq_ignore_ascii_case("PERCENT") {
8790 self.skip();
8791 if explicit_method {
8793 (method, true, true)
8794 } else {
8795 (SampleMethod::Percent, true, true)
8796 }
8797 } else if self.match_token(TokenType::Rows) {
8798 if explicit_method {
8800 (method, true, false)
8801 } else {
8802 (SampleMethod::Row, true, false)
8803 }
8804 } else if self.check(TokenType::Percent) && self.peek().text == "%" {
8805 self.skip();
8807 if explicit_method {
8808 (method, true, true)
8809 } else {
8810 (SampleMethod::Percent, true, true)
8811 }
8812 } else {
8813 (method, false, false)
8814 };
8815
8816 self.expect(TokenType::RParen)?;
8817
8818 let (seed, use_seed_keyword) = if self.match_token(TokenType::Seed) {
8820 self.expect(TokenType::LParen)?;
8821 let seed_value = self.parse_expression()?;
8822 self.expect(TokenType::RParen)?;
8823 (Some(seed_value), true)
8824 } else if self.match_token(TokenType::Repeatable) {
8825 self.expect(TokenType::LParen)?;
8826 let seed_value = self.parse_expression()?;
8827 self.expect(TokenType::RParen)?;
8828 (Some(seed_value), false)
8829 } else {
8830 (None, false)
8831 };
8832
8833 Ok(Some(Sample {
8834 method,
8835 size,
8836 seed,
8837 offset: None,
8838 unit_after_size,
8839 use_sample_keyword,
8840 explicit_method,
8841 method_before_size,
8842 use_seed_keyword,
8843 bucket_numerator: None,
8844 bucket_denominator: None,
8845 bucket_field: None,
8846 is_using_sample: false, is_percent,
8848 suppress_method_output: false,
8849 }))
8850 }
8851
8852 fn parse_set_operation(&mut self, left: Expression) -> Result<Expression> {
8854 let (side, kind) = self.parse_set_operation_side_kind();
8857
8858 let set_op_leading_comments = if self.check(TokenType::Union)
8861 || self.check(TokenType::Intersect)
8862 || self.check(TokenType::Except)
8863 {
8864 self.current_leading_comments().to_vec()
8865 } else {
8866 Vec::new()
8867 };
8868
8869 let left = if !set_op_leading_comments.is_empty() {
8871 Expression::Annotated(Box::new(Annotated {
8872 this: left,
8873 trailing_comments: set_op_leading_comments,
8874 }))
8875 } else {
8876 left
8877 };
8878
8879 if self.match_token(TokenType::Union) {
8880 let all = self.match_token(TokenType::All);
8881 let distinct = if !all {
8882 self.match_token(TokenType::Distinct)
8883 } else {
8884 false
8885 };
8886
8887 let (by_name, strict, corresponding, on_columns) =
8889 self.parse_set_operation_corresponding()?;
8890
8891 let kind = if corresponding && !strict && side.is_none() && kind.is_none() {
8894 Some("INNER".to_string())
8895 } else {
8896 kind
8897 };
8898
8899 let right = self.parse_select_or_paren_select()?;
8900 let mut result = Expression::Union(Box::new(Union {
8902 left,
8903 right,
8904 all,
8905 distinct,
8906 with: None,
8907 order_by: None,
8908 limit: None,
8909 offset: None,
8910 distribute_by: None,
8911 sort_by: None,
8912 cluster_by: None,
8913 by_name,
8914 side,
8915 kind,
8916 corresponding,
8917 strict,
8918 on_columns,
8919 }));
8920 result = self.parse_set_operation(result)?;
8921 self.parse_set_operation_modifiers(&mut result)?;
8923 Ok(result)
8924 } else if self.match_token(TokenType::Intersect) {
8925 let all = self.match_token(TokenType::All);
8926 let distinct = if !all {
8927 self.match_token(TokenType::Distinct)
8928 } else {
8929 false
8930 };
8931
8932 let (by_name, strict, corresponding, on_columns) =
8934 self.parse_set_operation_corresponding()?;
8935
8936 let kind = if corresponding && !strict && side.is_none() && kind.is_none() {
8939 Some("INNER".to_string())
8940 } else {
8941 kind
8942 };
8943
8944 let right = self.parse_select_or_paren_select()?;
8945 let mut result = Expression::Intersect(Box::new(Intersect {
8946 left,
8947 right,
8948 all,
8949 distinct,
8950 with: None,
8951 order_by: None,
8952 limit: None,
8953 offset: None,
8954 distribute_by: None,
8955 sort_by: None,
8956 cluster_by: None,
8957 by_name,
8958 side,
8959 kind,
8960 corresponding,
8961 strict,
8962 on_columns,
8963 }));
8964 result = self.parse_set_operation(result)?;
8965 self.parse_set_operation_modifiers(&mut result)?;
8966 Ok(result)
8967 } else if self.match_token(TokenType::Except) {
8968 let all = self.match_token(TokenType::All);
8969 let distinct = if !all {
8970 self.match_token(TokenType::Distinct)
8971 } else {
8972 false
8973 };
8974
8975 let (by_name, strict, corresponding, on_columns) =
8977 self.parse_set_operation_corresponding()?;
8978
8979 let kind = if corresponding && !strict && side.is_none() && kind.is_none() {
8982 Some("INNER".to_string())
8983 } else {
8984 kind
8985 };
8986
8987 let right = self.parse_select_or_paren_select()?;
8988 let mut result = Expression::Except(Box::new(Except {
8989 left,
8990 right,
8991 all,
8992 distinct,
8993 with: None,
8994 order_by: None,
8995 limit: None,
8996 offset: None,
8997 distribute_by: None,
8998 sort_by: None,
8999 cluster_by: None,
9000 by_name,
9001 side,
9002 kind,
9003 corresponding,
9004 strict,
9005 on_columns,
9006 }));
9007 result = self.parse_set_operation(result)?;
9008 self.parse_set_operation_modifiers(&mut result)?;
9009 Ok(result)
9010 } else if side.is_some() || kind.is_some() {
9011 Err(self
9013 .parse_error("Expected UNION, INTERSECT, or EXCEPT after set operation modifier"))
9014 } else {
9015 Ok(left)
9016 }
9017 }
9018
9019 fn parse_set_operation_side_kind(&mut self) -> (Option<String>, Option<String>) {
9022 let mut side = None;
9023 let mut kind = None;
9024
9025 if self.check(TokenType::Left)
9027 || self.check(TokenType::Right)
9028 || self.check(TokenType::Full)
9029 {
9030 let saved = self.current;
9032 let side_token = self.advance();
9033 let side_text = side_token.text.to_ascii_uppercase();
9034
9035 if self.check(TokenType::Union)
9037 || self.check(TokenType::Intersect)
9038 || self.check(TokenType::Except)
9039 || self.check(TokenType::Inner)
9040 {
9041 side = Some(side_text);
9042 } else {
9043 self.current = saved;
9045 return (None, None);
9046 }
9047 }
9048
9049 if self.check(TokenType::Inner) {
9051 let saved = self.current;
9052 self.skip(); if self.check(TokenType::Union)
9056 || self.check(TokenType::Intersect)
9057 || self.check(TokenType::Except)
9058 {
9059 kind = Some("INNER".to_string());
9060 } else {
9061 self.current = saved;
9063 if side.is_some() {
9064 self.current = saved - 1;
9066 }
9067 return (None, None);
9068 }
9069 }
9070
9071 (side, kind)
9072 }
9073
9074 fn parse_set_operation_corresponding(&mut self) -> Result<(bool, bool, bool, Vec<Expression>)> {
9077 let mut by_name = false;
9078 let mut strict = false;
9079 let mut corresponding = false;
9080 let mut on_columns = Vec::new();
9081
9082 if self.match_token(TokenType::By) && self.match_identifier("NAME") {
9084 by_name = true;
9085 }
9086 else if self.match_identifier("STRICT") {
9088 if self.match_identifier("CORRESPONDING") {
9089 strict = true;
9090 corresponding = true;
9091 } else {
9092 self.current -= 1;
9094 }
9095 }
9096 else if self.match_identifier("CORRESPONDING") {
9098 corresponding = true;
9099 }
9100
9101 if corresponding && self.match_token(TokenType::By) {
9103 self.expect(TokenType::LParen)?;
9104 on_columns = self
9105 .parse_identifier_list()?
9106 .into_iter()
9107 .map(|id| {
9108 Expression::boxed_column(Column {
9109 name: id,
9110 table: None,
9111 join_mark: false,
9112 trailing_comments: Vec::new(),
9113 span: None,
9114 inferred_type: None,
9115 })
9116 })
9117 .collect();
9118 self.expect(TokenType::RParen)?;
9119 }
9120
9121 Ok((by_name, strict, corresponding, on_columns))
9122 }
9123
9124 fn parse_set_operation_modifiers(&mut self, expr: &mut Expression) -> Result<()> {
9126 let order_by = if self.match_token(TokenType::Order) {
9128 self.expect(TokenType::By)?;
9129 Some(self.parse_order_by()?)
9130 } else {
9131 None
9132 };
9133
9134 let limit = if self.match_token(TokenType::Limit) {
9136 Some(Box::new(self.parse_expression()?))
9137 } else {
9138 None
9139 };
9140
9141 let offset = if self.match_token(TokenType::Offset) {
9143 Some(Box::new(self.parse_expression()?))
9144 } else {
9145 None
9146 };
9147
9148 match expr {
9150 Expression::Union(ref mut union) => {
9151 if order_by.is_some() {
9152 union.order_by = order_by;
9153 }
9154 if limit.is_some() {
9155 union.limit = limit;
9156 }
9157 if offset.is_some() {
9158 union.offset = offset;
9159 }
9160 }
9161 Expression::Intersect(ref mut intersect) => {
9162 if order_by.is_some() {
9163 intersect.order_by = order_by;
9164 }
9165 if limit.is_some() {
9166 intersect.limit = limit;
9167 }
9168 if offset.is_some() {
9169 intersect.offset = offset;
9170 }
9171 }
9172 Expression::Except(ref mut except) => {
9173 if order_by.is_some() {
9174 except.order_by = order_by;
9175 }
9176 if limit.is_some() {
9177 except.limit = limit;
9178 }
9179 if offset.is_some() {
9180 except.offset = offset;
9181 }
9182 }
9183 _ => {}
9184 }
9185 Ok(())
9186 }
9187
9188 fn parse_select_or_paren_select(&mut self) -> Result<Expression> {
9190 if self.match_token(TokenType::LParen) {
9191 if self.check(TokenType::Select)
9193 || self.check(TokenType::With)
9194 || self.check(TokenType::From)
9195 {
9196 let query = self.parse_statement()?;
9197 self.expect(TokenType::RParen)?;
9198 let alias = if self.match_token(TokenType::As) {
9200 Some(Identifier::new(self.expect_identifier()?))
9201 } else {
9202 None
9203 };
9204 Ok(Expression::Subquery(Box::new(Subquery {
9206 this: query,
9207 alias,
9208 column_aliases: Vec::new(),
9209 order_by: None,
9210 limit: None,
9211 offset: None,
9212 lateral: false,
9213 modifiers_inside: false,
9214 trailing_comments: Vec::new(),
9215 distribute_by: None,
9216 sort_by: None,
9217 cluster_by: None,
9218 inferred_type: None,
9219 })))
9220 } else if self.check(TokenType::LParen) {
9221 let inner = self.parse_select_or_paren_select()?;
9223 let result = self.parse_set_operation(inner)?;
9225 self.expect(TokenType::RParen)?;
9226 let alias = if self.match_token(TokenType::As) {
9228 Some(Identifier::new(self.expect_identifier()?))
9229 } else {
9230 None
9231 };
9232 Ok(Expression::Subquery(Box::new(Subquery {
9234 this: result,
9235 alias,
9236 column_aliases: Vec::new(),
9237 order_by: None,
9238 limit: None,
9239 offset: None,
9240 lateral: false,
9241 modifiers_inside: false,
9242 trailing_comments: Vec::new(),
9243 distribute_by: None,
9244 sort_by: None,
9245 cluster_by: None,
9246 inferred_type: None,
9247 })))
9248 } else {
9249 Err(self.parse_error("Expected SELECT or ( after ("))
9250 }
9251 } else if self.check(TokenType::From) {
9252 self.parse_from_first_query()
9254 } else if self.check(TokenType::With) {
9255 self.parse_statement()
9257 } else {
9258 self.parse_select()
9259 }
9260 }
9261
9262 fn parse_insert(&mut self) -> Result<Expression> {
9264 let insert_token = self.expect(TokenType::Insert)?;
9265 let leading_comments = insert_token.comments;
9266
9267 let hint = if self.check(TokenType::Hint) {
9269 Some(self.parse_hint()?)
9270 } else {
9271 None
9272 };
9273
9274 let conflict_action = if self.match_token(TokenType::Or) {
9276 if self.match_identifier("ABORT") {
9277 Some("ABORT".to_string())
9278 } else if self.match_identifier("FAIL") {
9279 Some("FAIL".to_string())
9280 } else if self.match_token(TokenType::Ignore) {
9281 Some("IGNORE".to_string())
9282 } else if self.match_token(TokenType::Replace) {
9283 Some("REPLACE".to_string())
9284 } else if self.match_token(TokenType::Rollback) {
9285 Some("ROLLBACK".to_string())
9286 } else {
9287 return Err(self.parse_error(
9288 "Expected ABORT, FAIL, IGNORE, REPLACE, or ROLLBACK after INSERT OR",
9289 ));
9290 }
9291 } else {
9292 None
9293 };
9294
9295 let ignore = conflict_action.is_none() && self.match_token(TokenType::Ignore);
9297
9298 let overwrite = self.match_token(TokenType::Overwrite);
9300
9301 if !overwrite && (self.match_token(TokenType::All) || self.match_token(TokenType::First)) {
9304 if let Some(multi_insert) = self.parse_multitable_inserts(leading_comments.clone())? {
9305 return Ok(multi_insert);
9306 }
9307 }
9308
9309 let local_directory = overwrite && self.match_token(TokenType::Local);
9312 let is_directory = (overwrite || local_directory) && self.match_identifier("DIRECTORY");
9313
9314 if is_directory {
9315 let path = self.expect_string()?;
9317 let row_format = if self.match_keywords(&[TokenType::Row, TokenType::Format]) {
9319 let delimited = self.match_identifier("DELIMITED");
9321 let mut fields_terminated_by = None;
9322 let mut collection_items_terminated_by = None;
9323 let mut map_keys_terminated_by = None;
9324 let mut lines_terminated_by = None;
9325 let mut null_defined_as = None;
9326
9327 loop {
9329 if self.match_identifier("FIELDS") || self.match_identifier("FIELD") {
9330 self.match_identifier("TERMINATED");
9331 self.match_token(TokenType::By);
9332 fields_terminated_by = Some(self.expect_string()?);
9333 } else if self.match_identifier("COLLECTION") {
9334 self.match_identifier("ITEMS");
9335 self.match_identifier("TERMINATED");
9336 self.match_token(TokenType::By);
9337 collection_items_terminated_by = Some(self.expect_string()?);
9338 } else if self.match_identifier("MAP") {
9339 self.match_identifier("KEYS");
9340 self.match_identifier("TERMINATED");
9341 self.match_token(TokenType::By);
9342 map_keys_terminated_by = Some(self.expect_string()?);
9343 } else if self.match_identifier("LINES") {
9344 self.match_identifier("TERMINATED");
9345 self.match_token(TokenType::By);
9346 lines_terminated_by = Some(self.expect_string()?);
9347 } else if self.match_token(TokenType::Null) {
9348 self.match_identifier("DEFINED");
9349 self.match_token(TokenType::As);
9350 null_defined_as = Some(self.expect_string()?);
9351 } else {
9352 break;
9353 }
9354 }
9355
9356 Some(RowFormat {
9357 delimited,
9358 fields_terminated_by,
9359 collection_items_terminated_by,
9360 map_keys_terminated_by,
9361 lines_terminated_by,
9362 null_defined_as,
9363 })
9364 } else {
9365 None
9366 };
9367
9368 let stored_as = if self.match_identifier("STORED") {
9370 self.expect(TokenType::As)?;
9371 Some(self.expect_identifier()?)
9372 } else {
9373 None
9374 };
9375
9376 let query = self.parse_statement()?;
9378
9379 return Ok(Expression::Insert(Box::new(Insert {
9380 table: TableRef::new(""),
9381 columns: Vec::new(),
9382 values: Vec::new(),
9383 query: Some(query),
9384 overwrite,
9385 partition: Vec::new(),
9386 directory: Some(DirectoryInsert {
9387 local: local_directory,
9388 path,
9389 row_format,
9390 stored_as,
9391 }),
9392 returning: Vec::new(),
9393 output: None,
9394 on_conflict: None,
9395 leading_comments,
9396 if_exists: false,
9397 with: None,
9398 ignore,
9399 source_alias: None,
9400 alias: None,
9401 alias_explicit_as: false,
9402 default_values: false,
9403 by_name: false,
9404 conflict_action: conflict_action.clone(),
9405 is_replace: false,
9406 replace_where: None,
9407 source: None,
9408 hint: hint.clone(),
9409 function_target: None,
9410 partition_by: None,
9411 settings: Vec::new(),
9412 })));
9413 }
9414
9415 if overwrite {
9416 self.match_token(TokenType::Table);
9418 } else {
9419 self.expect(TokenType::Into)?;
9420 self.match_token(TokenType::Table);
9422 }
9423
9424 let mut function_target: Option<Box<Expression>> = None;
9426 if self.match_token(TokenType::Function) {
9427 let func_name = self.expect_identifier_or_keyword()?;
9429 self.expect(TokenType::LParen)?;
9430 let args = if self.check(TokenType::RParen) {
9431 Vec::new()
9432 } else {
9433 self.parse_expression_list()?
9434 };
9435 self.expect(TokenType::RParen)?;
9436 function_target = Some(Box::new(Expression::Function(Box::new(Function {
9437 name: func_name,
9438 args,
9439 distinct: false,
9440 trailing_comments: Vec::new(),
9441 use_bracket_syntax: false,
9442 no_parens: false,
9443 quoted: false,
9444 span: None,
9445 inferred_type: None,
9446 }))));
9447 }
9448
9449 let table_name = if function_target.is_some() {
9450 Identifier::new(String::new())
9452 } else {
9453 self.expect_identifier_or_keyword_with_quoted()?
9455 };
9456 let table = if self.match_token(TokenType::Dot) {
9458 let schema = table_name;
9459 let name = self.expect_identifier_or_keyword_with_quoted()?;
9460 let trailing_comments = self.previous_trailing_comments().to_vec();
9461 TableRef {
9462 name,
9463 schema: Some(schema),
9464 catalog: None,
9465 alias: None,
9466 alias_explicit_as: false,
9467 column_aliases: Vec::new(),
9468 leading_comments: Vec::new(),
9469 trailing_comments,
9470 when: None,
9471 only: false,
9472 final_: false,
9473 table_sample: None,
9474 hints: Vec::new(),
9475 system_time: None,
9476 partitions: Vec::new(),
9477 identifier_func: None,
9478 changes: None,
9479 version: None,
9480 span: None,
9481 }
9482 } else {
9483 let trailing_comments = self.previous_trailing_comments().to_vec();
9484 TableRef {
9485 name: table_name,
9486 schema: None,
9487 catalog: None,
9488 alias: None,
9489 alias_explicit_as: false,
9490 column_aliases: Vec::new(),
9491 leading_comments: Vec::new(),
9492 when: None,
9493 only: false,
9494 final_: false,
9495 table_sample: None,
9496 hints: Vec::new(),
9497 system_time: None,
9498 trailing_comments,
9499 partitions: Vec::new(),
9500 identifier_func: None,
9501 changes: None,
9502 version: None,
9503 span: None,
9504 }
9505 };
9506
9507 let (alias, alias_explicit_as) = if self.match_token(TokenType::As) {
9509 (Some(Identifier::new(self.expect_identifier()?)), true)
9510 } else if self.is_identifier_token()
9511 && !self.check(TokenType::Values)
9512 && !self.check(TokenType::Select)
9513 && !self.check(TokenType::Default)
9514 && !self.check(TokenType::By)
9515 && !self.check(TokenType::Partition)
9516 && !self.check(TokenType::Output)
9517 && !self.check(TokenType::If)
9518 && !self.check(TokenType::Replace)
9519 && !self.check(TokenType::Table)
9520 && !self.check(TokenType::LParen)
9521 {
9522 (Some(Identifier::new(self.expect_identifier()?)), false)
9524 } else {
9525 (None, false)
9526 };
9527
9528 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
9530
9531 let replace_where =
9533 if self.match_token(TokenType::Replace) && self.match_token(TokenType::Where) {
9534 Some(Box::new(self.parse_or()?))
9535 } else {
9536 None
9537 };
9538
9539 let mut partition_by_expr: Option<Box<Expression>> = None;
9543 let partition = if self.check(TokenType::Partition) && self.check_next(TokenType::By) {
9544 self.skip(); self.skip(); partition_by_expr = Some(Box::new(self.parse_expression()?));
9548 Vec::new()
9549 } else if self.match_token(TokenType::Partition) {
9550 self.expect(TokenType::LParen)?;
9551 let mut parts = Vec::new();
9552 loop {
9553 let col = Identifier::new(self.expect_identifier()?);
9554 let value = if self.match_token(TokenType::Eq) {
9555 Some(self.parse_expression()?)
9556 } else {
9557 None
9558 };
9559 parts.push((col, value));
9560 if !self.match_token(TokenType::Comma) {
9561 break;
9562 }
9563 }
9564 self.expect(TokenType::RParen)?;
9565 parts
9566 } else {
9567 Vec::new()
9568 };
9569
9570 let insert_settings = if self.match_token(TokenType::Settings) {
9572 let mut settings = Vec::new();
9573 loop {
9574 settings.push(self.parse_expression()?);
9575 if !self.match_token(TokenType::Comma) {
9576 break;
9577 }
9578 }
9579 settings
9580 } else {
9581 Vec::new()
9582 };
9583
9584 let columns = if self.check(TokenType::LParen) {
9587 if self
9589 .peek_nth(1)
9590 .map(|t| t.token_type == TokenType::Select || t.token_type == TokenType::With)
9591 .unwrap_or(false)
9592 {
9593 Vec::new()
9595 } else if matches!(
9596 self.config.dialect,
9597 Some(crate::dialects::DialectType::ClickHouse)
9598 ) && {
9599 let peek1 = self.peek_nth(1).map(|t| t.token_type);
9601 peek1 == Some(TokenType::Star)
9602 || (peek1 == Some(TokenType::Var)
9603 && self.peek_nth(2).map(|t| t.token_type) == Some(TokenType::Dot)
9604 && self.peek_nth(3).map(|t| t.token_type) == Some(TokenType::Star))
9605 || (peek1 == Some(TokenType::Var)
9606 && self
9607 .peek_nth(1)
9608 .map(|t| t.text.eq_ignore_ascii_case("COLUMNS"))
9609 .unwrap_or(false))
9610 } {
9611 self.skip(); let mut depth = 1i32;
9614 while !self.is_at_end() && depth > 0 {
9615 if self.check(TokenType::LParen) {
9616 depth += 1;
9617 }
9618 if self.check(TokenType::RParen) {
9619 depth -= 1;
9620 if depth == 0 {
9621 break;
9622 }
9623 }
9624 self.skip();
9625 }
9626 self.expect(TokenType::RParen)?;
9627 Vec::new() } else {
9629 self.skip(); let cols = self.parse_identifier_list()?;
9631 self.expect(TokenType::RParen)?;
9632 cols
9633 }
9634 } else {
9635 Vec::new()
9636 };
9637
9638 let output = if self.match_token(TokenType::Output) {
9640 Some(self.parse_output_clause()?)
9641 } else {
9642 None
9643 };
9644
9645 let by_name = self.match_token(TokenType::By) && self.match_identifier("NAME");
9647
9648 let default_values =
9650 self.match_token(TokenType::Default) && self.match_token(TokenType::Values);
9651
9652 let (values, query) = if default_values {
9654 (Vec::new(), None)
9656 } else if matches!(
9657 self.config.dialect,
9658 Some(crate::dialects::DialectType::ClickHouse)
9659 ) && self.check(TokenType::Format)
9660 && self.peek_nth(1).is_some_and(|t| {
9661 !t.text.eq_ignore_ascii_case("VALUES")
9662 && (t.token_type == TokenType::Var || t.token_type == TokenType::Identifier)
9663 })
9664 {
9665 self.skip(); let format_name = self.advance().text.clone(); while !self.is_at_end() && !self.check(TokenType::Semicolon) {
9671 self.skip();
9672 }
9673 (
9675 Vec::new(),
9676 Some(Expression::Command(Box::new(crate::expressions::Command {
9677 this: format!("FORMAT {}", format_name),
9678 }))),
9679 )
9680 } else if matches!(
9681 self.config.dialect,
9682 Some(crate::dialects::DialectType::ClickHouse)
9683 ) && self.match_text_seq(&["FORMAT", "VALUES"])
9684 {
9685 let mut all_values = Vec::new();
9686
9687 loop {
9688 self.expect(TokenType::LParen)?;
9689 let row = self.parse_expression_list()?;
9690 self.expect(TokenType::RParen)?;
9691 all_values.push(row);
9692
9693 if !self.match_token(TokenType::Comma) {
9694 break;
9695 }
9696 }
9697
9698 (all_values, None)
9699 } else if self.match_token(TokenType::Values) {
9700 let mut all_values = Vec::new();
9701
9702 if matches!(
9704 self.config.dialect,
9705 Some(crate::dialects::DialectType::ClickHouse)
9706 ) && (self.check(TokenType::Semicolon) || self.is_at_end())
9707 {
9708 return Ok(Expression::Command(Box::new(crate::expressions::Command {
9710 this: "INSERT INTO VALUES".to_string(),
9711 })));
9712 }
9713
9714 if matches!(
9716 self.config.dialect,
9717 Some(crate::dialects::DialectType::ClickHouse)
9718 ) && !self.check(TokenType::LParen)
9719 {
9720 loop {
9721 let val = self.parse_expression()?;
9722 all_values.push(vec![val]);
9723 if !self.match_token(TokenType::Comma) {
9724 break;
9725 }
9726 }
9727 } else {
9728 loop {
9729 self.expect(TokenType::LParen)?;
9730 let row = if self.check(TokenType::RParen) {
9732 Vec::new()
9733 } else {
9734 self.parse_values_expression_list()?
9735 };
9736 self.expect(TokenType::RParen)?;
9737 all_values.push(row);
9738
9739 if !self.match_token(TokenType::Comma) {
9740 if matches!(
9742 self.config.dialect,
9743 Some(crate::dialects::DialectType::ClickHouse)
9744 ) && self.check(TokenType::LParen)
9745 {
9746 continue;
9747 }
9748 break;
9749 }
9750 if matches!(
9752 self.config.dialect,
9753 Some(crate::dialects::DialectType::ClickHouse)
9754 ) && !self.check(TokenType::LParen)
9755 {
9756 break;
9757 }
9758 }
9759 } (all_values, None)
9762 } else if self.check(TokenType::Table) {
9763 (Vec::new(), None)
9766 } else {
9767 (Vec::new(), Some(self.parse_statement()?))
9768 };
9769
9770 let source = if self.match_token(TokenType::Table) {
9772 let source_name = self.expect_identifier_with_quoted()?;
9774 let source_table = if self.match_token(TokenType::Dot) {
9775 let schema = source_name;
9776 let name = self.expect_identifier_with_quoted()?;
9777 let trailing_comments = self.previous_trailing_comments().to_vec();
9778 TableRef {
9779 name,
9780 schema: Some(schema),
9781 catalog: None,
9782 alias: None,
9783 alias_explicit_as: false,
9784 column_aliases: Vec::new(),
9785 leading_comments: Vec::new(),
9786 trailing_comments,
9787 when: None,
9788 only: false,
9789 final_: false,
9790 table_sample: None,
9791 hints: Vec::new(),
9792 system_time: None,
9793 partitions: Vec::new(),
9794 identifier_func: None,
9795 changes: None,
9796 version: None,
9797 span: None,
9798 }
9799 } else {
9800 let trailing_comments = self.previous_trailing_comments().to_vec();
9801 TableRef {
9802 name: source_name,
9803 schema: None,
9804 catalog: None,
9805 alias: None,
9806 alias_explicit_as: false,
9807 column_aliases: Vec::new(),
9808 leading_comments: Vec::new(),
9809 trailing_comments,
9810 when: None,
9811 only: false,
9812 final_: false,
9813 table_sample: None,
9814 hints: Vec::new(),
9815 system_time: None,
9816 partitions: Vec::new(),
9817 identifier_func: None,
9818 changes: None,
9819 version: None,
9820 span: None,
9821 }
9822 };
9823 Some(Expression::Table(Box::new(source_table)))
9824 } else {
9825 None
9826 };
9827
9828 let source_alias = if self.match_token(TokenType::As) {
9830 Some(Identifier::new(self.expect_identifier()?))
9831 } else {
9832 None
9833 };
9834
9835 let on_conflict = if self.match_token(TokenType::On) {
9837 if self.match_identifier("CONFLICT") {
9838 Some(Box::new(self.parse_on_conflict()?))
9839 } else if self.match_identifier("DUPLICATE") {
9840 self.expect(TokenType::Key)?;
9842 self.expect(TokenType::Update)?;
9843
9844 let mut sets = Vec::new();
9846 loop {
9847 let col_name = self.expect_identifier_with_quoted()?;
9849 let column = if self.match_token(TokenType::Dot) {
9851 let col = self.expect_identifier_with_quoted()?;
9852 Expression::boxed_column(Column {
9853 name: col,
9854 table: Some(col_name),
9855 join_mark: false,
9856 trailing_comments: Vec::new(),
9857 span: None,
9858 inferred_type: None,
9859 })
9860 } else {
9861 Expression::Identifier(col_name)
9862 };
9863 self.expect(TokenType::Eq)?;
9864 let value = self.parse_expression()?;
9865 sets.push(Expression::Eq(Box::new(BinaryOp {
9866 left: column,
9867 right: value,
9868 left_comments: Vec::new(),
9869 operator_comments: Vec::new(),
9870 trailing_comments: Vec::new(),
9871 inferred_type: None,
9872 })));
9873 if !self.match_token(TokenType::Comma) {
9874 break;
9875 }
9876 }
9877
9878 Some(Box::new(Expression::OnConflict(Box::new(OnConflict {
9879 duplicate: Some(Box::new(Expression::Boolean(BooleanLiteral {
9880 value: true,
9881 }))),
9882 expressions: sets,
9883 action: None,
9884 conflict_keys: None,
9885 index_predicate: None,
9886 constraint: None,
9887 where_: None,
9888 }))))
9889 } else {
9890 return Err(self.parse_error("Expected CONFLICT or DUPLICATE after ON"));
9892 }
9893 } else {
9894 None
9895 };
9896
9897 let returning = if self.match_token(TokenType::Returning) {
9899 self.parse_select_expressions()?
9900 } else {
9901 Vec::new()
9902 };
9903
9904 Ok(Expression::Insert(Box::new(Insert {
9905 table,
9906 columns,
9907 values,
9908 query,
9909 overwrite,
9910 partition,
9911 directory: None,
9912 returning,
9913 output,
9914 on_conflict,
9915 leading_comments,
9916 if_exists,
9917 with: None,
9918 ignore,
9919 source_alias,
9920 alias,
9921 alias_explicit_as,
9922 default_values,
9923 by_name,
9924 conflict_action,
9925 is_replace: false,
9926 replace_where,
9927 source: source.map(Box::new),
9928 hint,
9929 function_target,
9930 partition_by: partition_by_expr,
9931 settings: insert_settings,
9932 })))
9933 }
9934
9935 fn parse_on_conflict(&mut self) -> Result<Expression> {
9939 let constraint =
9941 if self.match_token(TokenType::On) && self.match_token(TokenType::Constraint) {
9942 let name = self.expect_identifier()?;
9943 Some(Box::new(Expression::Identifier(Identifier::new(name))))
9944 } else {
9945 None
9946 };
9947
9948 let conflict_keys = if constraint.is_none() && self.match_token(TokenType::LParen) {
9950 let keys = self.parse_expression_list()?;
9951 self.expect(TokenType::RParen)?;
9952 Some(Box::new(Expression::Tuple(Box::new(Tuple {
9953 expressions: keys,
9954 }))))
9955 } else {
9956 None
9957 };
9958
9959 let index_predicate = if self.match_token(TokenType::Where) {
9961 Some(Box::new(self.parse_expression()?))
9962 } else {
9963 None
9964 };
9965
9966 if !self.match_identifier("DO") {
9968 return Err(self.parse_error("Expected DO after ON CONFLICT"));
9969 }
9970
9971 let action = if self.match_identifier("NOTHING") {
9972 Some(Box::new(Expression::Identifier(Identifier::new(
9974 "NOTHING".to_string(),
9975 ))))
9976 } else if self.match_token(TokenType::Update) {
9977 self.expect(TokenType::Set)?;
9979 let mut sets = Vec::new();
9980 loop {
9981 let col_name = self.expect_identifier_with_quoted()?;
9983 let column = if self.match_token(TokenType::Dot) {
9985 let col = self.expect_identifier_with_quoted()?;
9986 Expression::boxed_column(Column {
9987 name: col,
9988 table: Some(col_name),
9989 join_mark: false,
9990 trailing_comments: Vec::new(),
9991 span: None,
9992 inferred_type: None,
9993 })
9994 } else {
9995 Expression::Identifier(col_name)
9996 };
9997 self.expect(TokenType::Eq)?;
9998 let value = self.parse_expression()?;
9999 sets.push(Expression::Eq(Box::new(BinaryOp {
10000 left: column,
10001 right: value,
10002 left_comments: Vec::new(),
10003 operator_comments: Vec::new(),
10004 trailing_comments: Vec::new(),
10005 inferred_type: None,
10006 })));
10007 if !self.match_token(TokenType::Comma) {
10008 break;
10009 }
10010 }
10011 Some(Box::new(Expression::Tuple(Box::new(Tuple {
10012 expressions: sets,
10013 }))))
10014 } else {
10015 return Err(self.parse_error("Expected NOTHING or UPDATE after DO"));
10016 };
10017
10018 let where_ = if self.match_token(TokenType::Where) {
10020 Some(Box::new(self.parse_expression()?))
10021 } else {
10022 None
10023 };
10024
10025 Ok(Expression::OnConflict(Box::new(OnConflict {
10026 duplicate: None,
10027 expressions: Vec::new(),
10028 action,
10029 conflict_keys,
10030 index_predicate,
10031 constraint,
10032 where_,
10033 })))
10034 }
10035
10036 fn parse_replace(&mut self) -> Result<Expression> {
10038 let replace_token = self.expect(TokenType::Replace)?;
10041 let leading_comments = replace_token.comments;
10042
10043 if self.check(TokenType::LParen) {
10044 self.expect(TokenType::LParen)?;
10046 let args = self.parse_expression_list()?;
10047 self.expect(TokenType::RParen)?;
10048 return Ok(Expression::Function(Box::new(Function {
10049 name: "REPLACE".to_string(),
10050 args,
10051 distinct: false,
10052 trailing_comments: Vec::new(),
10053 use_bracket_syntax: false,
10054 no_parens: false,
10055 quoted: false,
10056 span: None,
10057 inferred_type: None,
10058 })));
10059 }
10060
10061 if matches!(
10063 self.config.dialect,
10064 Some(crate::dialects::DialectType::Teradata)
10065 ) && self.check(TokenType::View)
10066 {
10067 return self.parse_create_view(true, false, false, false, None, None, None, false);
10068 }
10069
10070 if matches!(
10073 self.config.dialect,
10074 Some(crate::dialects::DialectType::ClickHouse)
10075 ) && (self.check(TokenType::Table) || self.check(TokenType::Temporary))
10076 {
10077 let temporary = self.match_token(TokenType::Temporary);
10078 return self.parse_create_table(true, temporary, leading_comments.clone(), None);
10079 }
10080
10081 if matches!(
10083 self.config.dialect,
10084 Some(crate::dialects::DialectType::ClickHouse)
10085 ) && (self.check(TokenType::Dictionary) || self.check_identifier("DICTIONARY"))
10086 {
10087 let mut parts = vec!["REPLACE".to_string()];
10088 let mut _paren_depth = 0i32;
10089 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
10090 let token = self.advance();
10091 if token.token_type == TokenType::LParen {
10092 _paren_depth += 1;
10093 }
10094 if token.token_type == TokenType::RParen {
10095 _paren_depth -= 1;
10096 }
10097 let text = if token.token_type == TokenType::String {
10098 format!("'{}'", token.text)
10099 } else if token.token_type == TokenType::QuotedIdentifier {
10100 format!("\"{}\"", token.text)
10101 } else {
10102 token.text.clone()
10103 };
10104 parts.push(text);
10105 }
10106 return Ok(Expression::Command(Box::new(crate::expressions::Command {
10107 this: parts.join(" "),
10108 })));
10109 }
10110
10111 self.match_token(TokenType::Into);
10113
10114 let table_name = self.expect_identifier_or_safe_keyword_with_quoted()?;
10115 let table = if self.match_token(TokenType::Dot) {
10116 let second_name = self.expect_identifier_or_safe_keyword_with_quoted()?;
10117 TableRef {
10118 name: second_name,
10119 schema: Some(table_name),
10120 catalog: None,
10121 alias: None,
10122 alias_explicit_as: false,
10123 column_aliases: Vec::new(),
10124 leading_comments: Vec::new(),
10125 trailing_comments: Vec::new(),
10126 when: None,
10127 only: false,
10128 final_: false,
10129 table_sample: None,
10130 hints: Vec::new(),
10131 system_time: None,
10132 partitions: Vec::new(),
10133 identifier_func: None,
10134 changes: None,
10135 version: None,
10136 span: None,
10137 }
10138 } else {
10139 TableRef::new(table_name.name)
10140 };
10141
10142 let columns = if self.match_token(TokenType::LParen) {
10144 let mut cols = Vec::new();
10145 loop {
10146 if self.check(TokenType::RParen) {
10147 break;
10148 }
10149 let col = self.expect_identifier_with_quoted()?;
10150 cols.push(col);
10151 if !self.match_token(TokenType::Comma) {
10152 break;
10153 }
10154 }
10155 self.expect(TokenType::RParen)?;
10156 cols
10157 } else {
10158 Vec::new()
10159 };
10160
10161 let mut values = Vec::new();
10163 let query = if self.match_token(TokenType::Values) {
10164 loop {
10165 self.expect(TokenType::LParen)?;
10166 let row = self.parse_expression_list()?;
10167 self.expect(TokenType::RParen)?;
10168 values.push(row);
10169 if !self.match_token(TokenType::Comma) {
10170 break;
10171 }
10172 }
10173 None
10174 } else if !self.is_at_end() && !self.check(TokenType::Semicolon) {
10175 Some(self.parse_statement()?)
10177 } else {
10178 None
10179 };
10180
10181 Ok(Expression::Insert(Box::new(Insert {
10182 table,
10183 columns,
10184 values,
10185 query,
10186 overwrite: false,
10187 partition: Vec::new(),
10188 directory: None,
10189 returning: Vec::new(),
10190 output: None,
10191 on_conflict: None,
10192 leading_comments,
10193 if_exists: false,
10194 with: None,
10195 ignore: false,
10196 source_alias: None,
10197 alias: None,
10198 alias_explicit_as: false,
10199 default_values: false,
10200 by_name: false,
10201 conflict_action: None,
10202 is_replace: true,
10203 replace_where: None,
10204 source: None,
10205 hint: None,
10206 function_target: None,
10207 partition_by: None,
10208 settings: Vec::new(),
10209 })))
10210 }
10211
10212 fn parse_update(&mut self) -> Result<Expression> {
10214 let update_token = self.expect(TokenType::Update)?;
10215 let leading_comments = update_token.comments;
10216
10217 if self.check_identifier("STATISTICS") {
10219 let mut parts = vec!["UPDATE".to_string()];
10220 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
10221 parts.push(self.advance().text);
10222 }
10223 return Ok(Expression::Command(Box::new(Command {
10224 this: parts.join(" "),
10225 })));
10226 }
10227
10228 let has_only = self.match_token(TokenType::Only);
10230
10231 let first_name = self.expect_identifier_with_quoted()?;
10233 let mut table = if self.match_token(TokenType::Dot) {
10234 let second_name = self.expect_identifier_with_quoted()?;
10235 if self.match_token(TokenType::Dot) {
10237 let table_name = self.expect_identifier_with_quoted()?;
10238 TableRef {
10239 name: table_name,
10240 schema: Some(second_name),
10241 catalog: Some(first_name),
10242 alias: None,
10243 alias_explicit_as: false,
10244 column_aliases: Vec::new(),
10245 leading_comments: Vec::new(),
10246 trailing_comments: Vec::new(),
10247 when: None,
10248 only: false,
10249 final_: false,
10250 table_sample: None,
10251 hints: Vec::new(),
10252 system_time: None,
10253 partitions: Vec::new(),
10254 identifier_func: None,
10255 changes: None,
10256 version: None,
10257 span: None,
10258 }
10259 } else {
10260 TableRef {
10261 name: second_name,
10262 schema: Some(first_name),
10263 catalog: None,
10264 alias: None,
10265 alias_explicit_as: false,
10266 column_aliases: Vec::new(),
10267 leading_comments: Vec::new(),
10268 trailing_comments: Vec::new(),
10269 when: None,
10270 only: false,
10271 final_: false,
10272 table_sample: None,
10273 hints: Vec::new(),
10274 system_time: None,
10275 partitions: Vec::new(),
10276 identifier_func: None,
10277 changes: None,
10278 version: None,
10279 span: None,
10280 }
10281 }
10282 } else {
10283 TableRef::from_identifier(first_name)
10284 };
10285 table.trailing_comments = self.previous_trailing_comments().to_vec();
10286 if has_only {
10287 table.only = true;
10288 }
10289
10290 if self.match_token(TokenType::As) {
10292 table.alias = Some(self.expect_identifier_with_quoted()?);
10293 table.alias_explicit_as = true;
10294 } else if self.is_identifier_token() && !self.check(TokenType::Set) {
10295 table.alias = Some(self.expect_identifier_with_quoted()?);
10297 table.alias_explicit_as = false;
10298 }
10299
10300 let mut extra_tables = Vec::new();
10303 while self.match_token(TokenType::Comma) {
10304 let first_name = self.expect_identifier_with_quoted()?;
10306 let mut extra_table = if self.match_token(TokenType::Dot) {
10307 let second_name = self.expect_identifier_with_quoted()?;
10308 if self.match_token(TokenType::Dot) {
10309 let table_name = self.expect_identifier_with_quoted()?;
10310 TableRef {
10311 name: table_name,
10312 schema: Some(second_name),
10313 catalog: Some(first_name),
10314 alias: None,
10315 alias_explicit_as: false,
10316 column_aliases: Vec::new(),
10317 leading_comments: Vec::new(),
10318 trailing_comments: Vec::new(),
10319 when: None,
10320 only: false,
10321 final_: false,
10322 table_sample: None,
10323 hints: Vec::new(),
10324 system_time: None,
10325 partitions: Vec::new(),
10326 identifier_func: None,
10327 changes: None,
10328 version: None,
10329 span: None,
10330 }
10331 } else {
10332 TableRef {
10333 name: second_name,
10334 schema: Some(first_name),
10335 catalog: None,
10336 alias: None,
10337 alias_explicit_as: false,
10338 column_aliases: Vec::new(),
10339 leading_comments: Vec::new(),
10340 trailing_comments: Vec::new(),
10341 when: None,
10342 only: false,
10343 final_: false,
10344 table_sample: None,
10345 hints: Vec::new(),
10346 system_time: None,
10347 partitions: Vec::new(),
10348 identifier_func: None,
10349 changes: None,
10350 version: None,
10351 span: None,
10352 }
10353 }
10354 } else {
10355 TableRef::from_identifier(first_name)
10356 };
10357 if self.match_token(TokenType::As) {
10359 extra_table.alias = Some(self.expect_identifier_with_quoted()?);
10360 extra_table.alias_explicit_as = true;
10361 } else if self.is_identifier_token()
10362 && !self.check(TokenType::Set)
10363 && !self.check_keyword()
10364 {
10365 extra_table.alias = Some(self.expect_identifier_with_quoted()?);
10366 extra_table.alias_explicit_as = false;
10367 }
10368 extra_tables.push(extra_table);
10369 }
10370
10371 let mut table_joins = Vec::new();
10373 while let Some((kind, _, use_inner_keyword, use_outer_keyword, _join_hint)) =
10374 self.try_parse_join_kind()
10375 {
10376 if self.check(TokenType::Join) {
10377 self.skip(); }
10379 let join_expr = self.parse_table_expression()?;
10381 let on_condition = if self.match_token(TokenType::On) {
10383 Some(self.parse_expression()?)
10384 } else {
10385 None
10386 };
10387 table_joins.push(Join {
10388 this: join_expr,
10389 on: on_condition,
10390 using: Vec::new(),
10391 kind,
10392 use_inner_keyword,
10393 use_outer_keyword,
10394 deferred_condition: false,
10395 join_hint: None,
10396 match_condition: None,
10397 pivots: Vec::new(),
10398 comments: Vec::new(),
10399 nesting_group: 0,
10400 directed: false,
10401 });
10402 }
10403
10404 let (from_before_set, early_from_clause, early_from_joins) =
10407 if self.match_token(TokenType::From) {
10408 let from_clause = self.parse_from()?;
10409 let from_joins = self.parse_joins()?;
10410 (true, Some(from_clause), from_joins)
10411 } else {
10412 (false, None, Vec::new())
10413 };
10414
10415 self.expect(TokenType::Set)?;
10416
10417 let mut set = Vec::new();
10418 loop {
10419 let mut col_ident = self.expect_identifier_or_safe_keyword_with_quoted()?;
10422 while self.match_token(TokenType::Dot) {
10423 let part = self.expect_identifier_or_safe_keyword_with_quoted()?;
10424 col_ident = Identifier {
10426 name: format!("{}.{}", col_ident.name, part.name),
10427 quoted: col_ident.quoted || part.quoted,
10428 trailing_comments: Vec::new(),
10429 span: None,
10430 };
10431 }
10432 self.expect(TokenType::Eq)?;
10433 let value = self.parse_expression()?;
10434 set.push((col_ident, value));
10435
10436 if !self.match_token(TokenType::Comma) {
10437 break;
10438 }
10439 }
10440
10441 let output = if self.match_token(TokenType::Output) {
10443 Some(self.parse_output_clause()?)
10444 } else {
10445 None
10446 };
10447
10448 let (from_clause, from_joins) = if from_before_set {
10450 (early_from_clause, early_from_joins)
10451 } else if self.match_token(TokenType::From) {
10452 let from_clause = Some(self.parse_from()?);
10453 let from_joins = self.parse_joins()?;
10454 (from_clause, from_joins)
10455 } else {
10456 (None, Vec::new())
10457 };
10458
10459 let where_clause = if self.match_token(TokenType::Where) {
10460 Some(Where {
10461 this: self.parse_expression()?,
10462 })
10463 } else {
10464 None
10465 };
10466
10467 let returning = if self.match_token(TokenType::Returning) {
10469 self.parse_select_expressions()?
10470 } else {
10471 Vec::new()
10472 };
10473
10474 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
10476 Some(self.parse_order_by()?)
10477 } else {
10478 None
10479 };
10480
10481 let limit = if self.match_token(TokenType::Limit) {
10483 Some(self.parse_expression()?)
10484 } else {
10485 None
10486 };
10487
10488 Ok(Expression::Update(Box::new(Update {
10489 table,
10490 extra_tables,
10491 table_joins,
10492 set,
10493 from_clause,
10494 from_joins,
10495 where_clause,
10496 returning,
10497 output,
10498 with: None,
10499 leading_comments,
10500 limit,
10501 order_by,
10502 from_before_set,
10503 })))
10504 }
10505
10506 fn parse_delete(&mut self) -> Result<Expression> {
10516 let delete_token = self.expect(TokenType::Delete)?;
10517 let leading_comments = delete_token.comments;
10518
10519 let mut tables = Vec::new();
10522 let mut early_output = None;
10523 let _has_from = if self.check(TokenType::From) {
10524 self.skip(); true
10526 } else {
10527 loop {
10532 let tref = self.parse_table_ref()?;
10533 tables.push(tref);
10534 if !self.match_token(TokenType::Comma) {
10535 break;
10536 }
10537 }
10538 if self.match_token(TokenType::Output) {
10540 early_output = Some(self.parse_output_clause()?);
10541 }
10542 if self.check(TokenType::From) {
10543 self.skip(); true
10545 } else {
10546 false
10548 }
10549 };
10550
10551 let has_only = self.match_token(TokenType::Only);
10553 let mut table = if _has_from {
10554 self.parse_table_ref()?
10557 } else {
10558 if !tables.is_empty() {
10561 tables.remove(0)
10562 } else {
10563 return Err(self.parse_error("Expected table name in DELETE statement"));
10564 }
10565 };
10566 if has_only {
10567 table.only = true;
10568 }
10569
10570 let on_cluster = self.parse_on_cluster_clause()?;
10572
10573 let mut extra_from_tables = Vec::new();
10575 if _has_from
10576 && tables.is_empty()
10577 && self.check(TokenType::Comma)
10578 && !self.check(TokenType::Where)
10579 {
10580 while self.match_token(TokenType::Comma) {
10583 let extra_name = self.expect_identifier_with_quoted()?;
10584 let extra_ref = TableRef::from_identifier(extra_name);
10585 extra_from_tables.push(extra_ref);
10586 }
10587 }
10588
10589 let mut tables_from_using = false;
10591 if !extra_from_tables.is_empty() {
10592 tables.push(table.clone());
10594 tables.append(&mut extra_from_tables);
10595 tables_from_using = true;
10596 }
10597
10598 let force_index = if self.match_text_seq(&["FORCE", "INDEX"]) {
10600 self.expect(TokenType::LParen)?;
10601 let idx_name = self.expect_identifier_with_quoted()?;
10602 self.expect(TokenType::RParen)?;
10603 Some(idx_name.name)
10604 } else {
10605 None
10606 };
10607
10608 let (alias, alias_explicit_as) = if force_index.is_none() && self.match_token(TokenType::As)
10610 {
10611 (Some(self.expect_identifier_with_quoted()?), true)
10612 } else if force_index.is_none()
10613 && self.is_identifier_token()
10614 && !self.check(TokenType::Using)
10615 && !self.check(TokenType::Where)
10616 && !self.check(TokenType::Inner)
10617 && !self.check(TokenType::Left)
10618 && !self.check(TokenType::Right)
10619 && !self.check(TokenType::Cross)
10620 && !self.check(TokenType::Full)
10621 && !self.check(TokenType::Join)
10622 && !self.check_identifier("FORCE")
10623 {
10624 (Some(self.expect_identifier_with_quoted()?), false)
10625 } else {
10626 (None, false)
10627 };
10628
10629 let mut joins = self.parse_joins()?;
10631
10632 let mut using = Vec::new();
10634 if self.match_token(TokenType::Using) {
10635 loop {
10636 if self.check(TokenType::LParen) {
10638 let is_values = self.current + 1 < self.tokens.len()
10640 && self.tokens[self.current + 1].token_type == TokenType::Values;
10641 let subquery = if is_values {
10642 self.skip(); let values = self.parse_values()?;
10645 self.expect(TokenType::RParen)?;
10646 Expression::Paren(Box::new(Paren {
10647 this: values,
10648 trailing_comments: Vec::new(),
10649 }))
10650 } else {
10651 self.parse_primary()?
10653 };
10654 let using_alias = if self.match_token(TokenType::As) {
10656 let alias_name = self.expect_identifier_with_quoted()?;
10657 let col_aliases = if self.match_token(TokenType::LParen) {
10659 let aliases = self.parse_identifier_list()?;
10660 self.expect(TokenType::RParen)?;
10661 aliases
10662 } else {
10663 Vec::new()
10664 };
10665 Some((alias_name, col_aliases))
10666 } else {
10667 None
10668 };
10669 let mut tref = TableRef::new("");
10671 if let Some((alias_name, col_aliases)) = using_alias {
10672 tref.alias = Some(alias_name);
10673 tref.alias_explicit_as = true;
10674 tref.column_aliases = col_aliases;
10675 }
10676 tref.hints = vec![subquery];
10679 using.push(tref);
10680 } else {
10681 let using_table = self.expect_identifier_with_quoted()?;
10682 let mut using_ref = TableRef::from_identifier(using_table);
10683
10684 if self.check_join_keyword() {
10686 using.push(using_ref);
10688 let mut using_joins = self.parse_joins()?;
10689 joins.append(&mut using_joins);
10690 break;
10691 }
10692
10693 if self.match_token(TokenType::As) {
10695 using_ref.alias = Some(self.expect_identifier_with_quoted()?);
10696 using_ref.alias_explicit_as = true;
10697 } else if self.is_identifier_token()
10698 && !self.check(TokenType::Comma)
10699 && !self.check(TokenType::Where)
10700 {
10701 using_ref.alias = Some(self.expect_identifier_with_quoted()?);
10702 }
10703 using.push(using_ref);
10704 }
10705 if !self.match_token(TokenType::Comma) {
10706 break;
10707 }
10708 }
10709 }
10710
10711 if matches!(
10713 self.config.dialect,
10714 Some(crate::dialects::DialectType::ClickHouse)
10715 ) && self.check(TokenType::In)
10716 && self
10717 .peek_nth(1)
10718 .is_some_and(|t| t.text.eq_ignore_ascii_case("PARTITION"))
10719 {
10720 self.skip(); self.skip(); let _partition = self.parse_primary()?;
10724 }
10725
10726 let output = if early_output.is_some() {
10728 early_output
10729 } else if self.match_token(TokenType::Output) {
10730 Some(self.parse_output_clause()?)
10731 } else {
10732 None
10733 };
10734
10735 let where_clause = if self.match_token(TokenType::Where) {
10736 Some(Where {
10737 this: self.parse_expression()?,
10738 })
10739 } else {
10740 None
10741 };
10742
10743 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
10745 Some(self.parse_order_by()?)
10746 } else {
10747 None
10748 };
10749
10750 let limit = if self.match_token(TokenType::Limit) {
10752 Some(self.parse_expression()?)
10753 } else {
10754 None
10755 };
10756
10757 let returning = if self.match_token(TokenType::Returning) {
10759 self.parse_select_expressions()?
10760 } else {
10761 Vec::new()
10762 };
10763
10764 Ok(Expression::Delete(Box::new(Delete {
10765 table,
10766 on_cluster,
10767 alias,
10768 alias_explicit_as,
10769 using,
10770 where_clause,
10771 output,
10772 leading_comments,
10773 with: None,
10774 limit,
10775 order_by,
10776 returning,
10777 tables,
10778 tables_from_using,
10779 joins,
10780 force_index,
10781 no_from: !_has_from,
10782 })))
10783 }
10784
10785 fn parse_create(&mut self) -> Result<Expression> {
10789 let create_pos = self.current; let create_token = self.expect(TokenType::Create)?;
10791 let leading_comments = create_token.comments;
10792
10793 let or_replace = self.match_keywords(&[TokenType::Or, TokenType::Replace]);
10795 let or_alter = !or_replace && self.match_text_seq(&["OR", "ALTER"]);
10796
10797 let temporary = self.match_token(TokenType::Temporary);
10799
10800 let materialized = self.match_token(TokenType::Materialized);
10802
10803 let mut algorithm: Option<String> = None;
10806 let mut definer: Option<String> = None;
10807 let mut security: Option<FunctionSecurity> = None;
10808
10809 while self.match_identifier("ALGORITHM")
10810 || self.match_identifier("DEFINER")
10811 || self.match_identifier("SQL")
10812 {
10813 let option_name = self.previous().text.to_ascii_uppercase();
10814
10815 if option_name == "ALGORITHM" && self.match_token(TokenType::Eq) {
10816 let value = self.expect_identifier_or_keyword()?;
10818 algorithm = Some(value.to_ascii_uppercase());
10819 } else if option_name == "DEFINER" && self.match_token(TokenType::Eq) {
10820 let mut definer_value = String::new();
10822 while !self.is_at_end()
10823 && !self.check(TokenType::View)
10824 && !self.check_identifier("ALGORITHM")
10825 && !self.check_identifier("DEFINER")
10826 && !self.check_identifier("SQL")
10827 && !self.check_identifier("SECURITY")
10828 {
10829 definer_value.push_str(&self.advance().text);
10830 }
10831 definer = Some(definer_value);
10832 } else if option_name == "SQL" && self.match_identifier("SECURITY") {
10833 if self.match_identifier("DEFINER") {
10835 security = Some(FunctionSecurity::Definer);
10836 } else if self.match_identifier("INVOKER") {
10837 security = Some(FunctionSecurity::Invoker);
10838 }
10839 }
10840 }
10841
10842 let secure = self.match_identifier("SECURE");
10844
10845 let mut table_modifier: Option<String> = if self.check_identifier("DYNAMIC") {
10847 self.skip();
10848 Some("DYNAMIC".to_string())
10849 } else if self.check_identifier("ICEBERG") {
10850 self.skip();
10851 Some("ICEBERG".to_string())
10852 } else if self.check_identifier("EXTERNAL") {
10853 self.skip();
10854 Some("EXTERNAL".to_string())
10855 } else if self.check_identifier("HYBRID") {
10856 self.skip();
10857 Some("HYBRID".to_string())
10858 } else if self.check_identifier("TRANSIENT") {
10859 self.skip();
10860 Some("TRANSIENT".to_string())
10861 } else if self.check_identifier("UNLOGGED") {
10862 self.skip();
10863 Some("UNLOGGED".to_string())
10864 } else if self.check_identifier("DICTIONARY") {
10865 self.skip();
10866 Some("DICTIONARY".to_string())
10867 } else if self.check(TokenType::Dictionary) {
10868 self.skip();
10869 Some("DICTIONARY".to_string())
10870 } else {
10871 None
10872 };
10873
10874 if matches!(
10876 self.config.dialect,
10877 Some(crate::dialects::DialectType::Teradata)
10878 ) {
10879 let mut parts = Vec::new();
10880 loop {
10881 if self.match_token(TokenType::Set) {
10882 parts.push(self.previous().text.to_ascii_uppercase());
10883 } else if self.match_identifier("MULTISET") {
10884 parts.push(self.previous().text.to_ascii_uppercase());
10885 } else if self.match_identifier("VOLATILE") {
10886 parts.push(self.previous().text.to_ascii_uppercase());
10887 } else if self.match_identifier("GLOBAL") {
10888 parts.push(self.previous().text.to_ascii_uppercase());
10889 } else if self.match_token(TokenType::Temporary) {
10890 parts.push(self.previous().text.to_ascii_uppercase());
10891 } else {
10892 break;
10893 }
10894 }
10895 if !parts.is_empty() {
10896 table_modifier = Some(parts.join(" "));
10897 }
10898 }
10899
10900 if table_modifier.as_deref() == Some("DICTIONARY") {
10901 return self.parse_create_table(
10902 or_replace,
10903 temporary,
10904 leading_comments,
10905 table_modifier.as_deref(),
10906 );
10907 }
10908
10909 match self.peek().token_type {
10910 TokenType::Table => {
10911 if self.current + 1 < self.tokens.len()
10913 && self.tokens[self.current + 1].token_type == TokenType::Function
10914 {
10915 self.skip(); return self.parse_create_function(or_replace, or_alter, temporary, true);
10917 }
10918 let modifier = if materialized {
10919 Some("MATERIALIZED")
10920 } else {
10921 table_modifier.as_deref()
10922 };
10923 self.parse_create_table(or_replace, temporary, leading_comments, modifier)
10924 }
10925 TokenType::Dictionary => {
10926 self.parse_create_table(or_replace, temporary, leading_comments, Some("DICTIONARY"))
10927 }
10928 TokenType::View => self.parse_create_view(
10929 or_replace,
10930 or_alter,
10931 materialized,
10932 temporary,
10933 algorithm,
10934 definer,
10935 security,
10936 secure,
10937 ),
10938 TokenType::Unique => {
10939 self.skip(); let clustered = if self.check_identifier("CLUSTERED") {
10942 self.skip();
10943 Some("CLUSTERED".to_string())
10944 } else if self.check_identifier("NONCLUSTERED") {
10945 self.skip();
10946 Some("NONCLUSTERED".to_string())
10947 } else {
10948 None
10949 };
10950 if self.check_identifier("COLUMNSTORE") {
10952 self.skip();
10953 let clustered = clustered
10955 .map(|c| format!("{} COLUMNSTORE", c))
10956 .or_else(|| Some("COLUMNSTORE".to_string()));
10957 self.parse_create_index_with_clustered(true, clustered)
10958 } else {
10959 self.parse_create_index_with_clustered(true, clustered)
10960 }
10961 }
10962 TokenType::Index => self.parse_create_index_with_clustered(false, None),
10963 TokenType::Schema => self.parse_create_schema(leading_comments),
10964 TokenType::Database => self.parse_create_database(),
10965 TokenType::Function => {
10966 self.parse_create_function(or_replace, or_alter, temporary, false)
10967 }
10968 TokenType::Procedure => self.parse_create_procedure(or_replace, or_alter),
10969 TokenType::Sequence => self.parse_create_sequence(temporary, or_replace),
10970 TokenType::Trigger => {
10971 self.parse_create_trigger(or_replace, or_alter, false, create_pos)
10972 }
10973 TokenType::Constraint => {
10974 self.skip(); self.parse_create_trigger(or_replace, or_alter, true, create_pos)
10976 }
10977 TokenType::Type => self.parse_create_type(),
10978 TokenType::Domain => self.parse_create_domain(),
10979 _ => {
10980 if self.check_identifier("CLUSTERED") || self.check_identifier("NONCLUSTERED") {
10982 let clustered_text = self.advance().text.to_ascii_uppercase();
10983 let clustered = if self.check_identifier("COLUMNSTORE") {
10985 self.skip();
10986 Some(format!("{} COLUMNSTORE", clustered_text))
10987 } else {
10988 Some(clustered_text)
10989 };
10990 return self.parse_create_index_with_clustered(false, clustered);
10991 }
10992 if self.check_identifier("COLUMNSTORE") && {
10994 let pos = self.current;
10995 let result = pos + 1 < self.tokens.len()
10996 && self.tokens[pos + 1].token_type == TokenType::Index;
10997 result
10998 } {
10999 self.skip(); return self.parse_create_index_with_clustered(
11002 false,
11003 Some("NONCLUSTERED COLUMNSTORE".to_string()),
11004 );
11005 }
11006 if self.check_identifier("TAG") {
11008 return self.parse_create_tag(or_replace);
11009 }
11010 if self.check_identifier("STAGE") {
11011 return self.parse_create_stage(or_replace, temporary);
11012 }
11013 if self.check_identifier("STREAM") {
11014 return self.parse_create_stream(or_replace);
11015 }
11016 if self.check_identifier("TASK") {
11017 return self.parse_create_task(or_replace);
11018 }
11019 if (self.check_identifier("FILE") || self.check(TokenType::File)) && {
11020 let next = self.current + 1;
11021 next < self.tokens.len()
11022 && (self.tokens[next].text.eq_ignore_ascii_case("FORMAT"))
11023 } {
11024 return self.parse_create_file_format(or_replace, temporary);
11025 }
11026 if self.check_identifier("SYNONYM") {
11028 self.skip(); let name = self.parse_table_ref()?;
11030 self.expect(TokenType::For)?;
11031 let target = self.parse_table_ref()?;
11032 return Ok(Expression::CreateSynonym(Box::new(
11033 crate::expressions::CreateSynonym { name, target },
11034 )));
11035 }
11036 {
11039 let start = self.current;
11040 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
11041 self.skip();
11042 }
11043 let sql = self.tokens_to_sql(start, self.current);
11044 let mut prefix = String::from("CREATE");
11045 if or_replace {
11046 prefix.push_str(" OR REPLACE");
11047 }
11048 if temporary {
11049 prefix.push_str(" TEMPORARY");
11050 }
11051 if materialized {
11052 prefix.push_str(" MATERIALIZED");
11053 }
11054 prefix.push(' ');
11055 prefix.push_str(&sql);
11056 Ok(Expression::Raw(Raw { sql: prefix }))
11057 }
11058 }
11059 }
11060 }
11061
11062 fn parse_create_table(
11064 &mut self,
11065 or_replace: bool,
11066 temporary: bool,
11067 leading_comments: Vec<String>,
11068 table_modifier: Option<&str>,
11069 ) -> Result<Expression> {
11070 if table_modifier == Some("DICTIONARY") {
11071 let _ = self.match_token(TokenType::Dictionary);
11072 } else {
11073 self.expect(TokenType::Table)?;
11074 }
11075
11076 let if_not_exists =
11078 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
11079
11080 let is_special_modifier = matches!(
11081 table_modifier,
11082 Some(
11083 "DYNAMIC"
11084 | "ICEBERG"
11085 | "EXTERNAL"
11086 | "HYBRID"
11087 | "UNLOGGED"
11088 | "DICTIONARY"
11089 | "MATERIALIZED"
11090 )
11091 ) || (table_modifier.is_some()
11092 && matches!(
11093 self.config.dialect,
11094 Some(crate::dialects::DialectType::Teradata)
11095 ));
11096 let is_clickhouse = matches!(
11097 self.config.dialect,
11098 Some(crate::dialects::DialectType::ClickHouse)
11099 );
11100
11101 let name = self.parse_table_ref()?;
11103
11104 let uuid = if matches!(
11106 self.config.dialect,
11107 Some(crate::dialects::DialectType::ClickHouse)
11108 ) && self.check_identifier("UUID")
11109 {
11110 self.skip(); let uuid_token = self.advance().clone();
11112 let uuid_text = uuid_token.text.trim_matches('\'').to_string();
11114 Some(uuid_text)
11115 } else {
11116 None
11117 };
11118
11119 let on_cluster = self.parse_on_cluster_clause()?;
11121
11122 let teradata_post_name_options = if matches!(
11124 self.config.dialect,
11125 Some(crate::dialects::DialectType::Teradata)
11126 ) {
11127 self.parse_teradata_post_name_options()
11128 } else {
11129 Vec::new()
11130 };
11131
11132 if self.match_keywords(&[TokenType::Partition, TokenType::Of]) {
11134 return self.parse_create_table_partition_of(
11135 name,
11136 if_not_exists,
11137 temporary,
11138 or_replace,
11139 table_modifier,
11140 leading_comments,
11141 );
11142 }
11143
11144 if matches!(
11146 self.config.dialect,
11147 Some(crate::dialects::DialectType::ClickHouse)
11148 ) && self.check_identifier("EMPTY")
11149 {
11150 if self.check_next(TokenType::As) {
11151 self.skip(); self.skip(); let start = self.current;
11155 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
11156 self.skip();
11157 }
11158 let rest_sql = self.tokens_to_sql(start, self.current);
11159 let mut prefix = String::from("CREATE TABLE");
11160 if if_not_exists {
11161 prefix.push_str(" IF NOT EXISTS");
11162 }
11163 prefix.push(' ');
11164 prefix.push_str(&name.name.name);
11165 prefix.push_str(" EMPTY AS ");
11166 prefix.push_str(&rest_sql);
11167 return Ok(Expression::Raw(Raw { sql: prefix }));
11168 }
11169 }
11170
11171 let shallow_clone = self.check_identifier("SHALLOW");
11175 let deep_clone = self.check_identifier("DEEP");
11176 if shallow_clone || deep_clone {
11177 self.skip(); }
11179 let is_copy = self.check(TokenType::Copy) && !self.check_next_identifier("GRANTS");
11182 if self.check_identifier("CLONE") || is_copy {
11183 self.skip(); if matches!(
11186 self.config.dialect,
11187 Some(crate::dialects::DialectType::ClickHouse)
11188 ) {
11189 let _ = self.match_token(TokenType::As);
11190 }
11191 let source = self.parse_table_ref()?;
11192 let at_clause = if self.match_identifier("AT") || self.match_token(TokenType::Before) {
11195 let keyword = self.previous().text.to_ascii_uppercase();
11196 self.expect(TokenType::LParen)?;
11197 let mut result = format!("{} (", keyword);
11199 let mut prev_token_type: Option<TokenType> = None;
11200 let mut paren_depth = 1;
11201 while !self.is_at_end() && paren_depth > 0 {
11202 let token = self.advance();
11203 if token.token_type == TokenType::LParen {
11204 paren_depth += 1;
11205 } else if token.token_type == TokenType::RParen {
11206 paren_depth -= 1;
11207 if paren_depth == 0 {
11208 break;
11209 }
11210 }
11211 let needs_space = !result.ends_with('(')
11212 && prev_token_type != Some(TokenType::Arrow)
11213 && prev_token_type != Some(TokenType::Dash)
11214 && prev_token_type != Some(TokenType::LParen)
11215 && prev_token_type != Some(TokenType::Comma) && token.token_type != TokenType::LParen; if needs_space
11218 && token.token_type != TokenType::RParen
11219 && token.token_type != TokenType::Comma
11220 {
11221 result.push(' ');
11222 }
11223 if token.token_type == TokenType::String {
11225 result.push('\'');
11226 result.push_str(&token.text.replace('\'', "''"));
11227 result.push('\'');
11228 } else {
11229 result.push_str(&token.text);
11230 }
11231 if token.token_type == TokenType::Arrow || token.token_type == TokenType::Comma
11232 {
11233 result.push(' ');
11234 }
11235 prev_token_type = Some(token.token_type);
11236 }
11237 result.push(')');
11238 Some(Expression::Raw(Raw { sql: result }))
11239 } else {
11240 None
11241 };
11242 return Ok(Expression::CreateTable(Box::new(CreateTable {
11244 name,
11245 on_cluster: on_cluster.clone(),
11246 columns: Vec::new(),
11247 constraints: Vec::new(),
11248 if_not_exists,
11249 temporary,
11250 or_replace,
11251 table_modifier: table_modifier.map(|s| s.to_string()),
11252 as_select: None,
11253 as_select_parenthesized: false,
11254 on_commit: None,
11255 clone_source: Some(source),
11256 clone_at_clause: at_clause,
11257 shallow_clone,
11258 is_copy,
11259 leading_comments,
11260 with_properties: Vec::new(),
11261 teradata_post_name_options: teradata_post_name_options.clone(),
11262 with_data: None,
11263 with_statistics: None,
11264 teradata_indexes: Vec::new(),
11265 with_cte: None,
11266 properties: Vec::new(),
11267 partition_of: None,
11268 post_table_properties: Vec::new(),
11269 mysql_table_options: Vec::new(),
11270 inherits: Vec::new(),
11271 on_property: None,
11272 copy_grants: false,
11273 using_template: None,
11274 rollup: None,
11275 uuid: uuid.clone(),
11276 })));
11277 }
11278
11279 let with_properties = if self.match_token(TokenType::With) {
11281 self.parse_with_properties()?
11282 } else {
11283 Vec::new()
11284 };
11285
11286 let copy_grants = self.match_text_seq(&["COPY", "GRANTS"]);
11288
11289 let using_template = if self.match_text_seq(&["USING", "TEMPLATE"]) {
11291 Some(Box::new(self.parse_primary()?))
11292 } else {
11293 None
11294 };
11295
11296 if using_template.is_some() {
11298 return Ok(Expression::CreateTable(Box::new(CreateTable {
11299 name,
11300 on_cluster: on_cluster.clone(),
11301 columns: Vec::new(),
11302 constraints: Vec::new(),
11303 if_not_exists,
11304 temporary,
11305 or_replace,
11306 table_modifier: table_modifier.map(|s| s.to_string()),
11307 as_select: None,
11308 as_select_parenthesized: false,
11309 on_commit: None,
11310 clone_source: None,
11311 clone_at_clause: None,
11312 shallow_clone: false,
11313 is_copy: false,
11314 leading_comments,
11315 with_properties,
11316 teradata_post_name_options: teradata_post_name_options.clone(),
11317 with_data: None,
11318 with_statistics: None,
11319 teradata_indexes: Vec::new(),
11320 with_cte: None,
11321 properties: Vec::new(),
11322 partition_of: None,
11323 post_table_properties: Vec::new(),
11324 mysql_table_options: Vec::new(),
11325 inherits: Vec::new(),
11326 on_property: None,
11327 copy_grants,
11328 using_template,
11329 rollup: None,
11330 uuid: uuid.clone(),
11331 })));
11332 }
11333
11334 let mut redshift_ctas_properties: Vec<Expression> = Vec::new();
11337 loop {
11338 if self.match_identifier("DISTKEY") {
11339 if self.match_token(TokenType::LParen) {
11341 let col = self.expect_identifier()?;
11342 self.expect(TokenType::RParen)?;
11343 redshift_ctas_properties.push(Expression::DistKeyProperty(Box::new(
11344 DistKeyProperty {
11345 this: Box::new(Expression::boxed_column(Column {
11346 name: Identifier::new(col),
11347 table: None,
11348 join_mark: false,
11349 trailing_comments: Vec::new(),
11350 span: None,
11351 inferred_type: None,
11352 })),
11353 },
11354 )));
11355 }
11356 } else if self.check_identifier("COMPOUND") || self.check_identifier("INTERLEAVED") {
11357 let modifier = self.advance().text.to_ascii_uppercase();
11359 if self.match_identifier("SORTKEY") && self.match_token(TokenType::LParen) {
11360 let mut cols = Vec::new();
11361 loop {
11362 let col = self.expect_identifier()?;
11363 cols.push(Expression::boxed_column(Column {
11364 name: Identifier::new(col),
11365 table: None,
11366 join_mark: false,
11367 trailing_comments: Vec::new(),
11368 span: None,
11369 inferred_type: None,
11370 }));
11371 if !self.match_token(TokenType::Comma) {
11372 break;
11373 }
11374 }
11375 self.expect(TokenType::RParen)?;
11376 let compound_value = if modifier == "COMPOUND" {
11377 Some(Box::new(Expression::Boolean(BooleanLiteral {
11378 value: true,
11379 })))
11380 } else {
11381 None
11382 };
11383 redshift_ctas_properties.push(Expression::SortKeyProperty(Box::new(
11384 SortKeyProperty {
11385 this: Box::new(Expression::Tuple(Box::new(Tuple {
11386 expressions: cols,
11387 }))),
11388 compound: compound_value,
11389 },
11390 )));
11391 }
11392 } else if self.match_identifier("SORTKEY") {
11393 if self.match_token(TokenType::LParen) {
11395 let mut cols = Vec::new();
11396 loop {
11397 let col = self.expect_identifier()?;
11398 cols.push(Expression::boxed_column(Column {
11399 name: Identifier::new(col),
11400 table: None,
11401 join_mark: false,
11402 trailing_comments: Vec::new(),
11403 span: None,
11404 inferred_type: None,
11405 }));
11406 if !self.match_token(TokenType::Comma) {
11407 break;
11408 }
11409 }
11410 self.expect(TokenType::RParen)?;
11411 redshift_ctas_properties.push(Expression::SortKeyProperty(Box::new(
11412 SortKeyProperty {
11413 this: Box::new(Expression::Tuple(Box::new(Tuple {
11414 expressions: cols,
11415 }))),
11416 compound: None,
11417 },
11418 )));
11419 }
11420 } else if self.match_identifier("DISTSTYLE") {
11421 if self.match_texts(&["ALL", "EVEN", "AUTO", "KEY"]) {
11423 let style = self.previous().text.to_ascii_uppercase();
11424 redshift_ctas_properties.push(Expression::DistStyleProperty(Box::new(
11425 DistStyleProperty {
11426 this: Box::new(Expression::Var(Box::new(Var { this: style }))),
11427 },
11428 )));
11429 }
11430 } else if self.match_identifier("BACKUP") {
11431 if self.match_texts(&["YES", "NO"]) {
11433 let value = self.previous().text.to_ascii_uppercase();
11434 redshift_ctas_properties.push(Expression::BackupProperty(Box::new(
11435 BackupProperty {
11436 this: Box::new(Expression::Var(Box::new(Var { this: value }))),
11437 },
11438 )));
11439 }
11440 } else {
11441 break;
11442 }
11443 }
11444
11445 if self.match_token(TokenType::As) {
11447 if is_clickhouse
11451 && !self.check(TokenType::Select)
11452 && !self.check(TokenType::With)
11453 && !self.check(TokenType::LParen)
11454 && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
11455 {
11456 let is_table_func = self.current + 1 < self.tokens.len()
11458 && self.tokens[self.current + 1].token_type == TokenType::LParen;
11459 let source = if is_table_func {
11460 self.parse_primary()?;
11462 let mut table_properties: Vec<Expression> = Vec::new();
11463 self.parse_clickhouse_table_properties(&mut table_properties)?;
11464 return Ok(Expression::CreateTable(Box::new(CreateTable {
11465 name,
11466 on_cluster: on_cluster.clone(),
11467 columns: Vec::new(),
11468 constraints: Vec::new(),
11469 if_not_exists,
11470 temporary,
11471 or_replace,
11472 table_modifier: table_modifier.map(|s| s.to_string()),
11473 as_select: None,
11474 as_select_parenthesized: false,
11475 on_commit: None,
11476 clone_source: None,
11477 clone_at_clause: None,
11478 shallow_clone: false,
11479 is_copy: false,
11480 leading_comments,
11481 with_properties,
11482 teradata_post_name_options: teradata_post_name_options.clone(),
11483 with_data: None,
11484 with_statistics: None,
11485 teradata_indexes: Vec::new(),
11486 with_cte: None,
11487 properties: table_properties,
11488 partition_of: None,
11489 post_table_properties: redshift_ctas_properties,
11490 mysql_table_options: Vec::new(),
11491 inherits: Vec::new(),
11492 on_property: None,
11493 copy_grants,
11494 using_template: None,
11495 rollup: None,
11496 uuid: uuid.clone(),
11497 })));
11498 } else {
11499 self.parse_table_ref()?
11500 };
11501 let mut table_properties: Vec<Expression> = Vec::new();
11503 self.parse_clickhouse_table_properties(&mut table_properties)?;
11504 return Ok(Expression::CreateTable(Box::new(CreateTable {
11505 name,
11506 on_cluster: on_cluster.clone(),
11507 columns: Vec::new(),
11508 constraints: Vec::new(),
11509 if_not_exists,
11510 temporary,
11511 or_replace,
11512 table_modifier: table_modifier.map(|s| s.to_string()),
11513 as_select: None,
11514 as_select_parenthesized: false,
11515 on_commit: None,
11516 clone_source: Some(source),
11517 clone_at_clause: None,
11518 shallow_clone: false,
11519 is_copy: false,
11520 leading_comments,
11521 with_properties,
11522 teradata_post_name_options: teradata_post_name_options.clone(),
11523 with_data: None,
11524 with_statistics: None,
11525 teradata_indexes: Vec::new(),
11526 with_cte: None,
11527 properties: table_properties,
11528 partition_of: None,
11529 post_table_properties: redshift_ctas_properties,
11530 mysql_table_options: Vec::new(),
11531 inherits: Vec::new(),
11532 on_property: None,
11533 copy_grants,
11534 using_template: None,
11535 rollup: None,
11536 uuid: uuid.clone(),
11537 })));
11538 }
11539
11540 let mut as_select_parenthesized = self.check(TokenType::LParen);
11545 let query = if as_select_parenthesized {
11546 let subquery = self.parse_primary()?;
11549 if matches!(
11552 &subquery,
11553 Expression::Union(_) | Expression::Intersect(_) | Expression::Except(_)
11554 ) {
11555 as_select_parenthesized = false;
11556 subquery
11557 } else {
11558 if let Expression::Subquery(ref sq) = subquery {
11561 if sq.limit.is_some() || sq.offset.is_some() || sq.order_by.is_some() {
11562 subquery
11564 } else {
11565 if let Expression::Subquery(sq) = subquery {
11567 sq.this
11568 } else {
11569 subquery
11570 }
11571 }
11572 } else if let Expression::Paren(p) = subquery {
11573 p.this
11574 } else {
11575 subquery
11576 }
11577 }
11578 } else if self.check(TokenType::With) {
11579 self.parse_statement()?
11581 } else {
11582 self.parse_select()?
11583 };
11584
11585 let (with_data, with_statistics, teradata_indexes) =
11587 self.parse_teradata_table_options();
11588 let on_commit = if matches!(
11589 self.config.dialect,
11590 Some(crate::dialects::DialectType::Teradata)
11591 ) && self.check(TokenType::On)
11592 && self.check_next(TokenType::Commit)
11593 {
11594 self.skip(); self.skip(); if self.match_keywords(&[TokenType::Preserve, TokenType::Rows]) {
11597 Some(OnCommit::PreserveRows)
11598 } else if self.match_keywords(&[TokenType::Delete, TokenType::Rows]) {
11599 Some(OnCommit::DeleteRows)
11600 } else {
11601 return Err(
11602 self.parse_error("Expected PRESERVE ROWS or DELETE ROWS after ON COMMIT")
11603 );
11604 }
11605 } else {
11606 None
11607 };
11608
11609 return Ok(Expression::CreateTable(Box::new(CreateTable {
11610 name,
11611 on_cluster: on_cluster.clone(),
11612 columns: Vec::new(),
11613 constraints: Vec::new(),
11614 if_not_exists,
11615 temporary,
11616 or_replace,
11617 table_modifier: table_modifier.map(|s| s.to_string()),
11618 as_select: Some(query),
11619 as_select_parenthesized,
11620 on_commit,
11621 clone_source: None,
11622 clone_at_clause: None,
11623 shallow_clone: false,
11624 is_copy: false,
11625 leading_comments,
11626 with_properties,
11627 teradata_post_name_options: teradata_post_name_options.clone(),
11628 with_data,
11629 with_statistics,
11630 teradata_indexes,
11631 with_cte: None,
11632 properties: Vec::new(),
11633 partition_of: None,
11634 post_table_properties: redshift_ctas_properties,
11635 mysql_table_options: Vec::new(),
11636 inherits: Vec::new(),
11637 on_property: None,
11638 copy_grants,
11639 using_template: None,
11640 rollup: None,
11641 uuid: uuid.clone(),
11642 })));
11643 }
11644
11645 if is_clickhouse && !self.check(TokenType::LParen) {
11647 let starts_props = self.check_identifier("ENGINE")
11648 || self.check(TokenType::Order)
11649 || self.check(TokenType::Sample)
11650 || self.check(TokenType::Settings)
11651 || self.check(TokenType::Comment)
11652 || self.check(TokenType::As);
11653
11654 if starts_props {
11655 let mut table_properties: Vec<Expression> = Vec::new();
11656 self.parse_clickhouse_table_properties(&mut table_properties)?;
11657
11658 let as_select = if self.match_token(TokenType::As) {
11659 Some(self.parse_statement()?)
11660 } else {
11661 None
11662 };
11663 let as_select_parenthesized = as_select.is_some();
11664
11665 if as_select.is_some() {
11666 self.parse_clickhouse_table_properties(&mut table_properties)?;
11667 }
11668
11669 return Ok(Expression::CreateTable(Box::new(CreateTable {
11670 name,
11671 on_cluster: on_cluster.clone(),
11672 columns: Vec::new(),
11673 constraints: Vec::new(),
11674 if_not_exists,
11675 temporary,
11676 or_replace,
11677 table_modifier: table_modifier.map(|s| s.to_string()),
11678 as_select,
11679 as_select_parenthesized,
11680 on_commit: None,
11681 clone_source: None,
11682 clone_at_clause: None,
11683 shallow_clone: false,
11684 is_copy: false,
11685 leading_comments,
11686 with_properties,
11687 teradata_post_name_options: teradata_post_name_options.clone(),
11688 with_data: None,
11689 with_statistics: None,
11690 teradata_indexes: Vec::new(),
11691 with_cte: None,
11692 properties: table_properties,
11693 partition_of: None,
11694 post_table_properties: Vec::new(),
11695 mysql_table_options: Vec::new(),
11696 inherits: Vec::new(),
11697 on_property: None,
11698 copy_grants,
11699 using_template: None,
11700 rollup: None,
11701 uuid: uuid.clone(),
11702 })));
11703 }
11704 }
11705
11706 if !self.check(TokenType::LParen) && is_special_modifier {
11709 let mut extra_options = Vec::new();
11711 while !self.is_at_end()
11714 && !self.check(TokenType::As)
11715 && !self.check(TokenType::Semicolon)
11716 {
11717 if self.is_identifier_token()
11718 || self.is_safe_keyword_as_identifier()
11719 || self.check(TokenType::Warehouse)
11720 {
11721 let key = self.advance().text;
11722 if self.match_token(TokenType::Eq) {
11723 let value = if self.check(TokenType::String) {
11725 let v = format!("'{}'", self.peek().text);
11726 self.skip();
11727 v
11728 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier()
11729 {
11730 self.advance().text
11731 } else {
11732 break;
11733 };
11734 extra_options.push((key, value));
11735 } else {
11736 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
11738 let value = self.advance().text;
11739 extra_options.push((key, value));
11740 }
11741 }
11742 } else {
11743 break;
11744 }
11745 }
11746 let as_select = if self.match_token(TokenType::As) {
11748 Some(self.parse_statement()?)
11749 } else {
11750 None
11751 };
11752 return Ok(Expression::CreateTable(Box::new(CreateTable {
11753 name,
11754 on_cluster: on_cluster.clone(),
11755 columns: Vec::new(),
11756 constraints: Vec::new(),
11757 if_not_exists,
11758 temporary,
11759 or_replace,
11760 table_modifier: table_modifier.map(|s| s.to_string()),
11761 as_select,
11762 as_select_parenthesized: false,
11763 on_commit: None,
11764 clone_source: None,
11765 clone_at_clause: None,
11766 shallow_clone: false,
11767 is_copy: false,
11768 leading_comments,
11769 with_properties: extra_options,
11770 teradata_post_name_options: teradata_post_name_options.clone(),
11771 with_data: None,
11772 with_statistics: None,
11773 teradata_indexes: Vec::new(),
11774 with_cte: None,
11775 properties: Vec::new(),
11776 partition_of: None,
11777 post_table_properties: Vec::new(),
11778 mysql_table_options: Vec::new(),
11779 inherits: Vec::new(),
11780 on_property: None,
11781 copy_grants,
11782 using_template: None,
11783 rollup: None,
11784 uuid: uuid.clone(),
11785 })));
11786 }
11787
11788 if self.check(TokenType::Like) {
11790 self.skip(); let source_ref = self.parse_table_ref()?;
11792 return Ok(Expression::CreateTable(Box::new(CreateTable {
11793 name,
11794 on_cluster: on_cluster.clone(),
11795 columns: Vec::new(),
11796 constraints: vec![TableConstraint::Like {
11797 source: source_ref,
11798 options: Vec::new(),
11799 }],
11800 if_not_exists,
11801 temporary,
11802 or_replace,
11803 table_modifier: table_modifier.map(|s| s.to_string()),
11804 as_select: None,
11805 as_select_parenthesized: false,
11806 on_commit: None,
11807 clone_source: None,
11808 clone_at_clause: None,
11809 shallow_clone: false,
11810 is_copy: false,
11811 leading_comments,
11812 with_properties,
11813 teradata_post_name_options: teradata_post_name_options.clone(),
11814 with_data: None,
11815 with_statistics: None,
11816 teradata_indexes: Vec::new(),
11817 with_cte: None,
11818 properties: Vec::new(),
11819 partition_of: None,
11820 post_table_properties: Vec::new(),
11821 mysql_table_options: Vec::new(),
11822 inherits: Vec::new(),
11823 on_property: None,
11824 copy_grants,
11825 using_template: None,
11826 rollup: None,
11827 uuid: uuid.clone(),
11828 })));
11829 }
11830
11831 if self.match_keyword("TAG")
11833 || (self.match_token(TokenType::With) && self.match_keyword("TAG"))
11834 {
11835 let tags = self.parse_tags()?;
11836 return Ok(Expression::CreateTable(Box::new(CreateTable {
11837 name,
11838 on_cluster: on_cluster.clone(),
11839 columns: Vec::new(),
11840 constraints: vec![TableConstraint::Tags(tags)],
11841 if_not_exists,
11842 temporary,
11843 or_replace,
11844 table_modifier: table_modifier.map(|s| s.to_string()),
11845 as_select: None,
11846 as_select_parenthesized: false,
11847 on_commit: None,
11848 clone_source: None,
11849 clone_at_clause: None,
11850 shallow_clone: false,
11851 is_copy: false,
11852 leading_comments,
11853 with_properties,
11854 teradata_post_name_options: teradata_post_name_options.clone(),
11855 with_data: None,
11856 with_statistics: None,
11857 teradata_indexes: Vec::new(),
11858 with_cte: None,
11859 properties: Vec::new(),
11860 partition_of: None,
11861 post_table_properties: Vec::new(),
11862 mysql_table_options: Vec::new(),
11863 inherits: Vec::new(),
11864 on_property: None,
11865 copy_grants,
11866 using_template: None,
11867 rollup: None,
11868 uuid: uuid.clone(),
11869 })));
11870 }
11871
11872 if self.check_identifier("TBLPROPERTIES")
11875 || self.check_identifier("LOCATION")
11876 || self.check_identifier("STORED")
11877 || self.check(TokenType::Row)
11878 || self.check(TokenType::Using)
11879 || self.check_identifier("CLUSTERED")
11880 || self.check_identifier("PARTITIONED")
11881 || self.check_identifier("COMMENT")
11882 {
11883 let hive_properties = self.parse_hive_table_properties()?;
11885
11886 let as_select = if self.match_token(TokenType::As) {
11888 Some(self.parse_statement()?)
11889 } else {
11890 None
11891 };
11892
11893 return Ok(Expression::CreateTable(Box::new(CreateTable {
11894 name,
11895 on_cluster: on_cluster.clone(),
11896 columns: Vec::new(),
11897 constraints: Vec::new(),
11898 if_not_exists,
11899 temporary,
11900 or_replace,
11901 table_modifier: table_modifier.map(|s| s.to_string()),
11902 as_select,
11903 as_select_parenthesized: false,
11904 on_commit: None,
11905 clone_source: None,
11906 clone_at_clause: None,
11907 shallow_clone: false,
11908 is_copy: false,
11909 leading_comments,
11910 with_properties,
11911 teradata_post_name_options: teradata_post_name_options.clone(),
11912 with_data: None,
11913 with_statistics: None,
11914 teradata_indexes: Vec::new(),
11915 with_cte: None,
11916 properties: hive_properties,
11917 partition_of: None,
11918 post_table_properties: Vec::new(),
11919 mysql_table_options: Vec::new(),
11920 inherits: Vec::new(),
11921 on_property: None,
11922 copy_grants,
11923 using_template: None,
11924 rollup: None,
11925 uuid: uuid.clone(),
11926 })));
11927 }
11928
11929 if self.check(TokenType::LParen) {
11931 let saved = self.current;
11932 self.skip(); let is_ctas = self.check(TokenType::Select) || self.check(TokenType::With);
11934 self.current = saved;
11935 if is_ctas {
11936 let subquery = self.parse_primary()?;
11938 let query = if let Expression::Subquery(sq) = subquery {
11939 sq.this
11940 } else if let Expression::Paren(p) = subquery {
11941 p.this
11942 } else {
11943 subquery
11944 };
11945 return Ok(Expression::CreateTable(Box::new(CreateTable {
11946 name,
11947 on_cluster: on_cluster.clone(),
11948 columns: Vec::new(),
11949 constraints: Vec::new(),
11950 if_not_exists,
11951 temporary,
11952 or_replace,
11953 table_modifier: table_modifier.map(|s| s.to_string()),
11954 as_select: Some(query),
11955 as_select_parenthesized: true,
11956 on_commit: None,
11957 clone_source: None,
11958 clone_at_clause: None,
11959 shallow_clone: false,
11960 is_copy: false,
11961 leading_comments,
11962 with_properties,
11963 teradata_post_name_options: teradata_post_name_options.clone(),
11964 with_data: None,
11965 with_statistics: None,
11966 teradata_indexes: Vec::new(),
11967 with_cte: None,
11968 properties: Vec::new(),
11969 partition_of: None,
11970 post_table_properties: Vec::new(),
11971 mysql_table_options: Vec::new(),
11972 inherits: Vec::new(),
11973 on_property: None,
11974 copy_grants,
11975 using_template: None,
11976 rollup: None,
11977 uuid: uuid.clone(),
11978 })));
11979 }
11980 }
11981
11982 let no_column_defs = !self.check(TokenType::LParen)
11985 && (self.check(TokenType::Partition)
11986 || self.check(TokenType::PartitionBy)
11987 || self.check(TokenType::Cluster)
11988 || self.check_identifier("OPTIONS")
11989 || self.check(TokenType::As));
11990
11991 if !no_column_defs {
11993 self.expect(TokenType::LParen)?;
11994 }
11995
11996 let (columns, constraints) = if no_column_defs {
11999 (Vec::new(), Vec::new())
12000 } else if table_modifier == Some("DYNAMIC") {
12001 let saved = self.current;
12004 let is_name_only_list =
12005 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
12006 self.skip();
12007 let result = self.check(TokenType::Comma) || self.check(TokenType::RParen);
12008 self.current = saved;
12009 result
12010 } else {
12011 false
12012 };
12013
12014 if is_name_only_list {
12015 let mut cols = Vec::new();
12017 loop {
12018 let name = self.expect_identifier_or_safe_keyword_with_quoted()?;
12019 let mut col_def = ColumnDef::new(
12021 name.name.clone(),
12022 DataType::Custom {
12023 name: String::new(),
12024 },
12025 );
12026 col_def.name = name;
12027 cols.push(col_def);
12028 if !self.match_token(TokenType::Comma) {
12029 break;
12030 }
12031 }
12032 (cols, Vec::new())
12033 } else {
12034 self.parse_column_definitions()?
12036 }
12037 } else {
12038 self.parse_column_definitions()?
12039 };
12040
12041 if !no_column_defs {
12042 self.expect(TokenType::RParen)?;
12043 }
12044
12045 let pre_with_comment = if self.check(TokenType::Comment) {
12047 let saved = self.current;
12048 self.skip(); if self.check(TokenType::String) {
12050 let comment_text = self.advance().text.clone();
12051 Some(comment_text)
12052 } else {
12053 self.current = saved;
12054 None
12055 }
12056 } else {
12057 None
12058 };
12059
12060 let with_properties_after = if self.check(TokenType::With) {
12063 let saved = self.current;
12065 self.skip(); let is_system_versioning = if self.check(TokenType::LParen) {
12067 let saved2 = self.current;
12068 self.skip(); let result = self.check_identifier("SYSTEM_VERSIONING");
12070 self.current = saved2; result
12072 } else {
12073 false
12074 };
12075 if is_system_versioning {
12076 self.current = saved;
12078 Vec::new()
12079 } else {
12080 self.parse_with_properties()?
12082 }
12083 } else {
12084 Vec::new()
12085 };
12086
12087 let mut all_with_properties = with_properties;
12089 all_with_properties.extend(with_properties_after);
12090
12091 if is_special_modifier {
12094 while !self.is_at_end()
12095 && !self.check(TokenType::As)
12096 && !self.check(TokenType::Semicolon)
12097 {
12098 let is_snowflake_option = self.check(TokenType::Warehouse)
12102 || self.check_identifier("TARGET_LAG")
12103 || self.check_identifier("CATALOG")
12104 || self.check_identifier("EXTERNAL_VOLUME")
12105 || self.check_identifier("BASE_LOCATION")
12106 || self.check_identifier("REFRESH_MODE")
12107 || self.check_identifier("INITIALIZE")
12108 || self.check_identifier("DATA_RETENTION_TIME_IN_DAYS")
12109 || self.check_identifier("LOCATION")
12110 || self.check_identifier("PARTITION")
12111 || self.check_identifier("FILE_FORMAT")
12112 || self.check_identifier("AUTO_REFRESH");
12113 if is_snowflake_option {
12114 let saved = self.current;
12116 let key = self.advance().text;
12117 if self.match_token(TokenType::Eq) {
12118 let value = if self.check(TokenType::LParen) {
12120 self.skip(); let mut options = String::from("(");
12123 let mut depth = 1;
12124 while !self.is_at_end() && depth > 0 {
12125 let tok = self.advance();
12126 if tok.token_type == TokenType::LParen {
12127 depth += 1;
12128 } else if tok.token_type == TokenType::RParen {
12129 depth -= 1;
12130 }
12131 if !options.ends_with('(')
12133 && !options.ends_with(' ')
12134 && tok.token_type != TokenType::RParen
12135 {
12136 options.push(' ');
12137 }
12138 options.push_str(&tok.text);
12139 }
12140 options
12141 } else if self.check(TokenType::String) {
12142 let v = format!("'{}'", self.peek().text);
12143 self.skip();
12144 v
12145 } else if self.check(TokenType::DAt) {
12146 self.skip(); let mut path = String::from("@");
12149 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
12150 path.push_str(&self.advance().text);
12151 }
12152 while self.check(TokenType::Slash) {
12154 if self.current + 1 < self.tokens.len() {
12156 let next = &self.tokens[self.current + 1];
12157 if next.text.eq_ignore_ascii_case("FILE_FORMAT")
12158 || next.text.eq_ignore_ascii_case("PARTITION_TYPE")
12159 || next.text.eq_ignore_ascii_case("AUTO_REFRESH")
12160 || next.text.eq_ignore_ascii_case("LOCATION")
12161 || next.text.eq_ignore_ascii_case("PARTITION")
12162 || next.text.eq_ignore_ascii_case("WAREHOUSE")
12163 {
12164 self.skip();
12166 path.push('/');
12167 break;
12168 }
12169 }
12170 self.skip();
12171 path.push('/');
12172 if self.is_identifier_token()
12173 || self.is_safe_keyword_as_identifier()
12174 {
12175 path.push_str(&self.advance().text);
12176 }
12177 }
12178 path
12179 } else if self.check(TokenType::Var) && self.peek().text.starts_with('@') {
12180 let mut path = self.advance().text;
12183 while self.check(TokenType::Slash) {
12185 if self.current + 1 < self.tokens.len() {
12187 let next = &self.tokens[self.current + 1];
12188 if next.text.eq_ignore_ascii_case("FILE_FORMAT")
12189 || next.text.eq_ignore_ascii_case("PARTITION_TYPE")
12190 || next.text.eq_ignore_ascii_case("AUTO_REFRESH")
12191 || next.text.eq_ignore_ascii_case("LOCATION")
12192 || next.text.eq_ignore_ascii_case("PARTITION")
12193 || next.text.eq_ignore_ascii_case("WAREHOUSE")
12194 {
12195 self.skip();
12197 path.push('/');
12198 break;
12199 }
12200 }
12201 self.skip();
12202 path.push('/');
12203 if self.is_identifier_token()
12204 || self.is_safe_keyword_as_identifier()
12205 {
12206 path.push_str(&self.advance().text);
12207 }
12208 }
12209 path
12210 } else if self.check(TokenType::Warehouse) {
12211 self.advance().text
12212 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier()
12213 {
12214 self.advance().text
12215 } else {
12216 self.current = saved;
12218 break;
12219 };
12220 all_with_properties.push((key, value));
12221 } else if self.is_identifier_token()
12222 || self.is_safe_keyword_as_identifier()
12223 || self.check(TokenType::Warehouse)
12224 {
12225 let value = self.advance().text;
12227 all_with_properties.push((key, value));
12228 } else {
12229 self.current = saved;
12232 break;
12233 }
12234 } else {
12235 break;
12236 }
12237 }
12238 }
12239
12240 let mysql_table_options = if is_clickhouse {
12242 Vec::new()
12243 } else {
12244 self.parse_mysql_table_options()
12245 };
12246
12247 let rollup = if self.match_token(TokenType::Rollup) {
12249 self.expect(TokenType::LParen)?;
12250 let mut indices = Vec::new();
12251 loop {
12252 let name = self.expect_identifier_or_keyword_with_quoted()?;
12253 let cols = if self.match_token(TokenType::LParen) {
12254 let mut col_list = Vec::new();
12255 loop {
12256 col_list.push(self.expect_identifier_or_keyword_with_quoted()?);
12257 if !self.match_token(TokenType::Comma) {
12258 break;
12259 }
12260 }
12261 self.expect(TokenType::RParen)?;
12262 col_list
12263 } else {
12264 Vec::new()
12265 };
12266 indices.push(crate::expressions::RollupIndex {
12267 name,
12268 expressions: cols,
12269 });
12270 if !self.match_token(TokenType::Comma) {
12271 break;
12272 }
12273 }
12274 self.expect(TokenType::RParen)?;
12275 Some(crate::expressions::RollupProperty {
12276 expressions: indices,
12277 })
12278 } else {
12279 None
12280 };
12281
12282 let hive_properties = self.parse_hive_table_properties()?;
12284 let is_teradata = matches!(
12285 self.config.dialect,
12286 Some(crate::dialects::DialectType::Teradata)
12287 );
12288
12289 let (mut on_commit, on_property) = if is_teradata {
12292 (None, None)
12293 } else if self.match_token(TokenType::On) {
12294 if self.match_token(TokenType::Commit) {
12295 if self.match_keywords(&[TokenType::Preserve, TokenType::Rows]) {
12296 (Some(OnCommit::PreserveRows), None)
12297 } else if self.match_keywords(&[TokenType::Delete, TokenType::Rows]) {
12298 (Some(OnCommit::DeleteRows), None)
12299 } else {
12300 return Err(
12301 self.parse_error("Expected PRESERVE ROWS or DELETE ROWS after ON COMMIT")
12302 );
12303 }
12304 } else {
12305 let filegroup = self.parse_schema_identifier()?;
12308 (
12309 None,
12310 Some(OnProperty {
12311 this: Box::new(filegroup),
12312 }),
12313 )
12314 }
12315 } else {
12316 (None, None)
12317 };
12318
12319 let mut table_properties = hive_properties;
12321
12322 if let Some(comment_text) = pre_with_comment {
12324 table_properties.push(Expression::SchemaCommentProperty(Box::new(
12325 SchemaCommentProperty {
12326 this: Box::new(Expression::Literal(Box::new(Literal::String(comment_text)))),
12327 },
12328 )));
12329 }
12330
12331 if self.match_token(TokenType::Default) && self.match_token(TokenType::Collate) {
12332 let collation = self.parse_primary()?;
12333 table_properties.push(Expression::CollateProperty(Box::new(CollateProperty {
12334 this: Box::new(collation),
12335 default: Some(Box::new(Expression::Boolean(BooleanLiteral {
12336 value: true,
12337 }))),
12338 })));
12339 }
12340
12341 if matches!(
12343 self.config.dialect,
12344 Some(crate::dialects::DialectType::BigQuery)
12345 ) {
12346 if let Some(options_property) = self.parse_bigquery_options_property()? {
12347 table_properties.push(options_property);
12348 }
12349 } else if self.match_identifier("OPTIONS") {
12350 let options = self.parse_options_list()?;
12351 table_properties.push(Expression::Properties(Box::new(Properties {
12352 expressions: options,
12353 })));
12354 }
12355
12356 let is_doris_starrocks = matches!(
12358 self.config.dialect,
12359 Some(crate::dialects::DialectType::Doris)
12360 | Some(crate::dialects::DialectType::StarRocks)
12361 );
12362 if is_doris_starrocks && self.match_identifier("PROPERTIES") {
12363 let props = self.parse_options_list()?;
12365 if !props.is_empty() {
12366 table_properties.push(Expression::Properties(Box::new(Properties {
12367 expressions: props,
12368 })));
12369 }
12370 }
12371
12372 loop {
12375 if self.match_identifier("DISTKEY") {
12376 if let Some(distkey) = self.parse_distkey()? {
12378 table_properties.push(distkey);
12379 }
12380 } else if self.match_text_seq(&["COMPOUND", "SORTKEY"]) {
12381 if let Some(sortkey) = self.parse_sortkey()? {
12383 if let Expression::SortKeyProperty(mut skp) = sortkey {
12385 skp.compound = Some(Box::new(Expression::Boolean(BooleanLiteral {
12386 value: true,
12387 })));
12388 table_properties.push(Expression::SortKeyProperty(skp));
12389 }
12390 }
12391 } else if self.match_identifier("SORTKEY") {
12392 if let Some(sortkey) = self.parse_sortkey()? {
12394 table_properties.push(sortkey);
12395 }
12396 } else if self.match_identifier("DISTSTYLE") {
12397 if self.match_texts(&["ALL", "EVEN", "AUTO", "KEY"]) {
12399 let style = self.previous().text.to_ascii_uppercase();
12400 table_properties.push(Expression::DistStyleProperty(Box::new(
12401 DistStyleProperty {
12402 this: Box::new(Expression::Var(Box::new(Var { this: style }))),
12403 },
12404 )));
12405 }
12406 } else if self.match_identifier("BACKUP") {
12407 if self.match_texts(&["YES", "NO"]) {
12409 let value = self.previous().text.to_ascii_uppercase();
12410 table_properties.push(Expression::BackupProperty(Box::new(BackupProperty {
12411 this: Box::new(Expression::Var(Box::new(Var { this: value }))),
12412 })));
12413 }
12414 } else {
12415 break;
12416 }
12417 }
12418
12419 if is_teradata {
12421 loop {
12422 if self.check(TokenType::Comma) {
12424 let saved_comma = self.current;
12425 self.skip(); let is_index_keyword = self.check(TokenType::Unique)
12427 || self.check(TokenType::PrimaryKey)
12428 || self.check(TokenType::Index)
12429 || self.check(TokenType::No);
12430 if !is_index_keyword {
12431 self.current = saved_comma; }
12433 }
12434 if self.match_token(TokenType::Unique) {
12435 let primary = self.match_token(TokenType::PrimaryKey);
12436 let amp = self.match_identifier("AMP");
12437 self.match_token(TokenType::Index);
12438 let params = if self.match_token(TokenType::LParen) {
12439 let cols = self.parse_identifier_list()?;
12440 self.expect(TokenType::RParen)?;
12441 cols.into_iter()
12442 .map(|id| {
12443 Expression::boxed_column(Column {
12444 name: id,
12445 table: None,
12446 join_mark: false,
12447 trailing_comments: Vec::new(),
12448 span: None,
12449 inferred_type: None,
12450 })
12451 })
12452 .collect()
12453 } else {
12454 Vec::new()
12455 };
12456 table_properties.push(Expression::Index(Box::new(Index {
12457 this: None,
12458 table: None,
12459 unique: true,
12460 primary: if primary {
12461 Some(Box::new(Expression::Boolean(BooleanLiteral {
12462 value: true,
12463 })))
12464 } else {
12465 None
12466 },
12467 amp: if amp {
12468 Some(Box::new(Expression::Boolean(BooleanLiteral {
12469 value: true,
12470 })))
12471 } else {
12472 None
12473 },
12474 params,
12475 })));
12476 continue;
12477 }
12478 if self.match_token(TokenType::PrimaryKey) {
12479 let amp = self.match_identifier("AMP");
12480 self.match_token(TokenType::Index);
12481 let params = if self.match_token(TokenType::LParen) {
12482 let cols = self.parse_identifier_list()?;
12483 self.expect(TokenType::RParen)?;
12484 cols.into_iter()
12485 .map(|id| {
12486 Expression::boxed_column(Column {
12487 name: id,
12488 table: None,
12489 join_mark: false,
12490 trailing_comments: Vec::new(),
12491 span: None,
12492 inferred_type: None,
12493 })
12494 })
12495 .collect()
12496 } else {
12497 Vec::new()
12498 };
12499 table_properties.push(Expression::Index(Box::new(Index {
12500 this: None,
12501 table: None,
12502 unique: false,
12503 primary: Some(Box::new(Expression::Boolean(BooleanLiteral {
12504 value: true,
12505 }))),
12506 amp: if amp {
12507 Some(Box::new(Expression::Boolean(BooleanLiteral {
12508 value: true,
12509 })))
12510 } else {
12511 None
12512 },
12513 params,
12514 })));
12515 continue;
12516 }
12517 if self.match_token(TokenType::Index) {
12518 let params = if self.match_token(TokenType::LParen) {
12519 let cols = self.parse_identifier_list()?;
12520 self.expect(TokenType::RParen)?;
12521 cols.into_iter()
12522 .map(|id| {
12523 Expression::boxed_column(Column {
12524 name: id,
12525 table: None,
12526 join_mark: false,
12527 trailing_comments: Vec::new(),
12528 span: None,
12529 inferred_type: None,
12530 })
12531 })
12532 .collect()
12533 } else {
12534 Vec::new()
12535 };
12536 table_properties.push(Expression::Index(Box::new(Index {
12537 this: None,
12538 table: None,
12539 unique: false,
12540 primary: None,
12541 amp: None,
12542 params,
12543 })));
12544 continue;
12545 }
12546 if self.match_keywords(&[TokenType::Partition, TokenType::By]) {
12547 let expr = self.parse_primary()?;
12548 table_properties.push(Expression::PartitionedByProperty(Box::new(
12549 PartitionedByProperty {
12550 this: Box::new(expr),
12551 },
12552 )));
12553 continue;
12554 }
12555 break;
12556 }
12557
12558 if on_commit.is_none()
12559 && self.check(TokenType::On)
12560 && self.check_next(TokenType::Commit)
12561 {
12562 self.skip(); self.skip(); if self.match_keywords(&[TokenType::Preserve, TokenType::Rows]) {
12565 on_commit = Some(OnCommit::PreserveRows);
12566 } else if self.match_keywords(&[TokenType::Delete, TokenType::Rows]) {
12567 on_commit = Some(OnCommit::DeleteRows);
12568 } else {
12569 return Err(
12570 self.parse_error("Expected PRESERVE ROWS or DELETE ROWS after ON COMMIT")
12571 );
12572 }
12573 }
12574 }
12575
12576 if is_clickhouse {
12578 self.parse_clickhouse_table_properties(&mut table_properties)?;
12579 }
12580
12581 if matches!(
12583 self.config.dialect,
12584 Some(crate::dialects::DialectType::ClickHouse)
12585 ) && self.match_identifier("EMPTY")
12586 {
12587 table_properties.push(Expression::Var(Box::new(Var {
12588 this: "EMPTY".to_string(),
12589 })));
12590 }
12591
12592 let as_select = if !no_column_defs && self.match_token(TokenType::As) {
12595 Some(self.parse_statement()?)
12596 } else {
12597 None
12598 };
12599
12600 if is_clickhouse && as_select.is_some() {
12601 self.parse_clickhouse_table_properties(&mut table_properties)?;
12602 }
12603
12604 let is_bigquery = matches!(
12606 self.config.dialect,
12607 Some(crate::dialects::DialectType::BigQuery)
12608 );
12609 if !is_teradata && (self.check(TokenType::Partition) || self.check(TokenType::PartitionBy))
12610 {
12611 let parsed_bigquery_partition = if is_bigquery {
12612 if let Some(partition_property) = self.parse_bigquery_partition_by_property()? {
12613 table_properties.push(partition_property);
12614 true
12615 } else {
12616 false
12617 }
12618 } else {
12619 false
12620 };
12621
12622 if !parsed_bigquery_partition {
12623 let saved = self.current;
12624 let is_partition_by = if self.match_token(TokenType::PartitionBy) {
12625 true
12626 } else if self.match_token(TokenType::Partition) {
12627 self.match_token(TokenType::By)
12628 } else {
12629 false
12630 };
12631 if is_partition_by {
12632 let partition_kind = if self.check(TokenType::Range) {
12633 self.skip();
12634 Some("RANGE".to_string())
12635 } else if self.check(TokenType::List) {
12636 self.skip();
12637 Some("LIST".to_string())
12638 } else if (self.check(TokenType::Identifier) || self.check(TokenType::Var))
12639 && self.check_next(TokenType::LParen)
12640 {
12641 Some(self.advance().text.to_ascii_uppercase())
12643 } else {
12644 None
12646 };
12647
12648 if is_doris_starrocks
12652 && partition_kind.is_some()
12653 && !matches!(
12654 partition_kind.as_deref(),
12655 Some("RANGE") | Some("LIST") | Some("HASH") | Some("KEY")
12656 )
12657 {
12658 let func_name = partition_kind.unwrap();
12660 let mut raw_sql = format!("PARTITION BY {}", func_name);
12661 fn consume_parens(parser: &mut Parser, raw_sql: &mut String) {
12663 if !parser.check(TokenType::LParen) {
12664 return;
12665 }
12666 parser.advance();
12667 raw_sql.push('(');
12668 let mut depth = 1;
12669 let mut last_type: Option<TokenType> = None;
12670 while !parser.is_at_end() && depth > 0 {
12671 let tok = parser.advance();
12672 if tok.token_type == TokenType::LParen {
12673 depth += 1;
12674 } else if tok.token_type == TokenType::RParen {
12675 depth -= 1;
12676 if depth == 0 {
12677 break;
12678 }
12679 }
12680 if matches!(last_type, Some(TokenType::Comma)) {
12682 raw_sql.push(' ');
12683 }
12684 if tok.token_type == TokenType::String {
12685 raw_sql.push('\'');
12686 raw_sql.push_str(&tok.text);
12687 raw_sql.push('\'');
12688 } else {
12689 raw_sql.push_str(&tok.text);
12690 }
12691 last_type = Some(tok.token_type.clone());
12692 }
12693 raw_sql.push(')');
12694 }
12695 consume_parens(self, &mut raw_sql);
12696 while self.match_token(TokenType::Comma) {
12698 raw_sql.push_str(", ");
12699 let tok = self.advance();
12700 raw_sql.push_str(&tok.text);
12701 consume_parens(self, &mut raw_sql);
12702 }
12703 table_properties.push(Expression::Raw(Raw { sql: raw_sql }));
12704 } else
12705 if (is_doris_starrocks
12707 || matches!(
12708 self.config.dialect,
12709 Some(crate::dialects::DialectType::MySQL)
12710 | Some(crate::dialects::DialectType::SingleStore)
12711 | Some(crate::dialects::DialectType::TiDB)
12712 ))
12713 && matches!(partition_kind.as_deref(), Some("RANGE") | Some("LIST"))
12714 {
12715 let partition_expr = self.parse_doris_partition_by_range_or_list(
12716 partition_kind
12717 .as_ref()
12718 .map(|s| s.as_str())
12719 .unwrap_or("RANGE"),
12720 )?;
12721 table_properties.push(partition_expr);
12722 } else {
12723 let no_partition_kind = partition_kind.is_none();
12725 let mut raw_sql = match partition_kind {
12726 Some(kind) => format!("PARTITION BY {}", kind),
12727 None => "PARTITION BY ".to_string(),
12728 };
12729 if self.check(TokenType::LParen) {
12730 self.skip();
12731 raw_sql.push('(');
12732 let mut depth = 1;
12733 let mut last_tok_type: Option<TokenType> = None;
12734 while !self.is_at_end() && depth > 0 {
12735 let tok = self.advance();
12736 if tok.token_type == TokenType::LParen {
12737 depth += 1;
12738 } else if tok.token_type == TokenType::RParen {
12739 depth -= 1;
12740 if depth == 0 {
12741 break;
12742 }
12743 }
12744 let needs_space = match (&last_tok_type, &tok.token_type) {
12746 (Some(TokenType::Comma), _) => true,
12748 (Some(TokenType::Identifier), TokenType::Identifier) => true,
12750 _ => false,
12751 };
12752 if needs_space {
12753 raw_sql.push(' ');
12754 }
12755 if tok.token_type == TokenType::String {
12757 raw_sql.push('\'');
12758 raw_sql.push_str(&tok.text);
12759 raw_sql.push('\'');
12760 } else {
12761 raw_sql.push_str(&tok.text);
12762 }
12763 last_tok_type = Some(tok.token_type.clone());
12764 }
12765 raw_sql.push(')');
12766 } else if no_partition_kind {
12767 let mut first = true;
12769 while !self.is_at_end()
12770 && !self.check(TokenType::Cluster)
12771 && !self.check(TokenType::As)
12772 && !self.check(TokenType::Semicolon)
12773 && !self.check(TokenType::RParen)
12774 && !self.check_identifier("OPTIONS")
12775 {
12776 if !first {
12777 raw_sql.push_str(", ");
12778 }
12779 first = false;
12780 let tok = self.advance();
12781 raw_sql.push_str(&tok.text);
12782 if self.check(TokenType::LParen) {
12784 self.skip();
12785 raw_sql.push('(');
12786 let mut depth = 1;
12787 while !self.is_at_end() && depth > 0 {
12788 let t = self.advance();
12789 if t.token_type == TokenType::LParen {
12790 depth += 1;
12791 } else if t.token_type == TokenType::RParen {
12792 depth -= 1;
12793 if depth == 0 {
12794 break;
12795 }
12796 }
12797 raw_sql.push_str(&t.text);
12798 }
12799 raw_sql.push(')');
12800 }
12801 if !self.match_token(TokenType::Comma) {
12802 break;
12803 }
12804 }
12805 }
12806 table_properties.push(Expression::Raw(Raw { sql: raw_sql }));
12807 }
12808 } else {
12809 self.current = saved;
12810 }
12811 }
12812 }
12813
12814 if is_bigquery {
12816 if let Some(cluster_property) = self.parse_bigquery_cluster_by_property()? {
12817 table_properties.push(cluster_property);
12818 }
12819 } else if self.match_keywords(&[TokenType::Cluster, TokenType::By]) {
12820 let mut cluster_names = Vec::new();
12821 loop {
12822 let name = self.expect_identifier_or_keyword()?;
12823 cluster_names.push(name);
12824 if !self.match_token(TokenType::Comma) {
12825 break;
12826 }
12827 }
12828 table_properties.push(Expression::Raw(Raw {
12829 sql: format!("CLUSTER BY {}", cluster_names.join(", ")),
12830 }));
12831 }
12832
12833 if no_column_defs {
12835 if matches!(
12836 self.config.dialect,
12837 Some(crate::dialects::DialectType::BigQuery)
12838 ) {
12839 if let Some(options_property) = self.parse_bigquery_options_property()? {
12840 table_properties.push(options_property);
12841 }
12842 } else if self.match_identifier("OPTIONS") {
12843 let options = self.parse_options_list()?;
12844 table_properties.push(Expression::Properties(Box::new(Properties {
12845 expressions: options,
12846 })));
12847 }
12848 }
12849
12850 let as_select = if no_column_defs && self.match_token(TokenType::As) {
12851 Some(self.parse_statement()?)
12852 } else {
12853 as_select
12854 };
12855
12856 if is_special_modifier {
12859 while !self.is_at_end()
12860 && !self.check(TokenType::As)
12861 && !self.check(TokenType::Semicolon)
12862 {
12863 let is_snowflake_option = self.check(TokenType::Warehouse)
12864 || self.check_identifier("TARGET_LAG")
12865 || self.check_identifier("CATALOG")
12866 || self.check_identifier("EXTERNAL_VOLUME")
12867 || self.check_identifier("BASE_LOCATION")
12868 || self.check_identifier("REFRESH_MODE")
12869 || self.check_identifier("INITIALIZE")
12870 || self.check_identifier("DATA_RETENTION_TIME_IN_DAYS")
12871 || self.check_identifier("LOCATION")
12872 || self.check_identifier("PARTITION_TYPE")
12873 || self.check_identifier("FILE_FORMAT")
12874 || self.check_identifier("AUTO_REFRESH");
12875 if is_snowflake_option {
12876 let key = self.advance().text;
12877 if self.match_token(TokenType::Eq) {
12878 let value = if self.check(TokenType::LParen) {
12879 self.skip();
12881 let mut options = String::from("(");
12882 let mut depth = 1;
12883 while !self.is_at_end() && depth > 0 {
12884 let tok = self.advance();
12885 if tok.token_type == TokenType::LParen {
12886 depth += 1;
12887 } else if tok.token_type == TokenType::RParen {
12888 depth -= 1;
12889 }
12890 if !options.ends_with('(')
12891 && !options.ends_with(' ')
12892 && tok.token_type != TokenType::RParen
12893 {
12894 options.push(' ');
12895 }
12896 options.push_str(&tok.text);
12897 }
12898 options
12899 } else if self.check(TokenType::String) {
12900 let v = format!("'{}'", self.peek().text);
12901 self.skip();
12902 v
12903 } else if self.check(TokenType::DAt) {
12904 self.skip();
12906 let mut path = String::from("@");
12907 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
12908 path.push_str(&self.advance().text);
12909 }
12910 while self.check(TokenType::Slash) {
12911 if self.current + 1 < self.tokens.len() {
12912 let next = &self.tokens[self.current + 1];
12913 if next.text.eq_ignore_ascii_case("FILE_FORMAT")
12914 || next.text.eq_ignore_ascii_case("PARTITION_TYPE")
12915 || next.text.eq_ignore_ascii_case("AUTO_REFRESH")
12916 || next.text.eq_ignore_ascii_case("LOCATION")
12917 || next.text.eq_ignore_ascii_case("PARTITION")
12918 || next.text.eq_ignore_ascii_case("WAREHOUSE")
12919 {
12920 self.skip();
12921 path.push('/');
12922 break;
12923 }
12924 }
12925 self.skip();
12926 path.push('/');
12927 if self.is_identifier_token()
12928 || self.is_safe_keyword_as_identifier()
12929 {
12930 path.push_str(&self.advance().text);
12931 }
12932 }
12933 path
12934 } else if self.check(TokenType::Var) && self.peek().text.starts_with('@') {
12935 let mut path = self.advance().text;
12936 while self.check(TokenType::Slash) {
12937 if self.current + 1 < self.tokens.len() {
12938 let next = &self.tokens[self.current + 1];
12939 if next.text.eq_ignore_ascii_case("FILE_FORMAT")
12940 || next.text.eq_ignore_ascii_case("PARTITION_TYPE")
12941 || next.text.eq_ignore_ascii_case("AUTO_REFRESH")
12942 || next.text.eq_ignore_ascii_case("LOCATION")
12943 || next.text.eq_ignore_ascii_case("PARTITION")
12944 || next.text.eq_ignore_ascii_case("WAREHOUSE")
12945 {
12946 self.skip();
12947 path.push('/');
12948 break;
12949 }
12950 }
12951 self.skip();
12952 path.push('/');
12953 if self.is_identifier_token()
12954 || self.is_safe_keyword_as_identifier()
12955 {
12956 path.push_str(&self.advance().text);
12957 }
12958 }
12959 path
12960 } else if self.check(TokenType::Warehouse) {
12961 self.advance().text
12962 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier()
12963 {
12964 self.advance().text
12965 } else {
12966 break;
12967 };
12968 all_with_properties.push((key, value));
12969 } else if self.is_identifier_token()
12970 || self.is_safe_keyword_as_identifier()
12971 || self.check(TokenType::Warehouse)
12972 {
12973 let value = self.advance().text;
12974 all_with_properties.push((key, value));
12975 }
12976 } else {
12977 break;
12978 }
12979 }
12980 }
12981
12982 let post_table_properties = self.parse_post_table_properties()?;
12986
12987 let inherits = if self.match_identifier("INHERITS") {
12989 self.expect(TokenType::LParen)?;
12990 let mut parents = Vec::new();
12991 loop {
12992 parents.push(self.parse_table_ref()?);
12993 if !self.match_token(TokenType::Comma) {
12994 break;
12995 }
12996 }
12997 self.expect(TokenType::RParen)?;
12998 parents
12999 } else {
13000 Vec::new()
13001 };
13002
13003 Ok(Expression::CreateTable(Box::new(CreateTable {
13004 name,
13005 on_cluster,
13006 columns,
13007 constraints,
13008 if_not_exists,
13009 temporary,
13010 or_replace,
13011 table_modifier: table_modifier.map(|s| s.to_string()),
13012 as_select,
13013 as_select_parenthesized: false,
13014 on_commit,
13015 clone_source: None,
13016 clone_at_clause: None,
13017 shallow_clone: false,
13018 is_copy: false,
13019 leading_comments,
13020 with_properties: all_with_properties,
13021 teradata_post_name_options: teradata_post_name_options.clone(),
13022 with_data: None,
13023 with_statistics: None,
13024 teradata_indexes: Vec::new(),
13025 with_cte: None,
13026 properties: table_properties,
13027 partition_of: None,
13028 post_table_properties,
13029 mysql_table_options,
13030 inherits,
13031 on_property,
13032 copy_grants,
13033 using_template: None,
13034 rollup,
13035 uuid,
13036 })))
13037 }
13038
13039 fn parse_create_table_partition_of(
13041 &mut self,
13042 name: TableRef,
13043 if_not_exists: bool,
13044 temporary: bool,
13045 or_replace: bool,
13046 table_modifier: Option<&str>,
13047 leading_comments: Vec<String>,
13048 ) -> Result<Expression> {
13049 let parent_table = self.parse_table_ref()?;
13051
13052 let (columns, constraints) = if self.check(TokenType::LParen) {
13057 let first_inside = self.current + 1;
13059 let is_column_defs = first_inside < self.tokens.len()
13062 && (self.tokens[first_inside].token_type == TokenType::Constraint
13063 || ((self.tokens[first_inside].token_type == TokenType::Var
13064 || self.tokens[first_inside].token_type == TokenType::QuotedIdentifier
13065 || self.tokens[first_inside].token_type == TokenType::Identifier)
13066 && first_inside + 1 < self.tokens.len()
13067 && self.tokens[first_inside + 1].token_type == TokenType::Default));
13068
13069 if is_column_defs {
13070 self.skip(); let (cols, constrs) = self.parse_partition_column_specs()?;
13074 self.expect(TokenType::RParen)?;
13075 (cols, constrs)
13076 } else {
13077 (Vec::new(), Vec::new())
13078 }
13079 } else {
13080 (Vec::new(), Vec::new())
13081 };
13082
13083 let partition_bound: Expression = if self.match_token(TokenType::Default) {
13085 Expression::Var(Box::new(Var {
13087 this: "DEFAULT".to_string(),
13088 }))
13089 } else if self.match_token(TokenType::For) {
13090 self.expect(TokenType::Values)?;
13092 self.parse_partition_bound_spec()?
13093 } else {
13094 Expression::Var(Box::new(Var {
13097 this: "DEFAULT".to_string(),
13098 }))
13099 };
13100
13101 let partition_of_expr =
13102 Expression::PartitionedOfProperty(Box::new(PartitionedOfProperty {
13103 this: Box::new(Expression::Table(Box::new(parent_table))),
13104 expression: Box::new(partition_bound),
13105 }));
13106
13107 let mut table_properties: Vec<Expression> = Vec::new();
13109 if self.match_token(TokenType::Partition) || self.match_token(TokenType::PartitionBy) {
13110 if self.previous().token_type == TokenType::Partition {
13112 self.expect(TokenType::By)?;
13113 }
13114 let partition_kind = if self.check(TokenType::Identifier) || self.check(TokenType::Var)
13116 {
13117 let kind_text = self.advance().text.to_ascii_uppercase();
13118 kind_text
13119 } else if self.check(TokenType::Range) {
13120 self.skip();
13121 "RANGE".to_string()
13122 } else if self.check(TokenType::List) {
13123 self.skip();
13124 "LIST".to_string()
13125 } else {
13126 "RANGE".to_string()
13127 };
13128 let mut raw_sql = format!("PARTITION BY {}", partition_kind);
13130 if self.check(TokenType::LParen) {
13131 self.skip(); raw_sql.push('(');
13133 let mut depth = 1;
13134 while !self.is_at_end() && depth > 0 {
13135 let tok = self.advance();
13136 if tok.token_type == TokenType::LParen {
13137 depth += 1;
13138 } else if tok.token_type == TokenType::RParen {
13139 depth -= 1;
13140 if depth == 0 {
13141 break;
13142 }
13143 }
13144 raw_sql.push_str(&tok.text);
13145 }
13146 raw_sql.push(')');
13147 }
13148 table_properties.push(Expression::Raw(Raw { sql: raw_sql }));
13149 }
13150
13151 Ok(Expression::CreateTable(Box::new(CreateTable {
13152 name,
13153 on_cluster: None,
13154 columns,
13155 constraints,
13156 if_not_exists,
13157 temporary,
13158 or_replace,
13159 table_modifier: table_modifier.map(|s| s.to_string()),
13160 as_select: None,
13161 as_select_parenthesized: false,
13162 on_commit: None,
13163 clone_source: None,
13164 clone_at_clause: None,
13165 shallow_clone: false,
13166 is_copy: false,
13167 leading_comments,
13168 with_properties: Vec::new(),
13169 teradata_post_name_options: Vec::new(),
13170 with_data: None,
13171 with_statistics: None,
13172 teradata_indexes: Vec::new(),
13173 with_cte: None,
13174 properties: table_properties,
13175 partition_of: Some(partition_of_expr),
13176 post_table_properties: Vec::new(),
13177 mysql_table_options: Vec::new(),
13178 inherits: Vec::new(),
13179 on_property: None,
13180 copy_grants: false,
13181 using_template: None,
13182 rollup: None,
13183 uuid: None,
13184 })))
13185 }
13186
13187 fn parse_partition_bound_spec(&mut self) -> Result<Expression> {
13189 if self.match_token(TokenType::In) {
13190 self.expect(TokenType::LParen)?;
13192 let mut values = Vec::new();
13193 loop {
13194 let val = self.parse_expression()?;
13195 values.push(val);
13196 if !self.match_token(TokenType::Comma) {
13197 break;
13198 }
13199 }
13200 self.expect(TokenType::RParen)?;
13201 let this_expr = if values.len() == 1 {
13203 values.into_iter().next().unwrap()
13204 } else {
13205 Expression::Tuple(Box::new(Tuple {
13206 expressions: values,
13207 }))
13208 };
13209 Ok(Expression::PartitionBoundSpec(Box::new(
13210 PartitionBoundSpec {
13211 this: Some(Box::new(this_expr)),
13212 expression: None,
13213 from_expressions: None,
13214 to_expressions: None,
13215 },
13216 )))
13217 } else if self.match_token(TokenType::From) {
13218 self.expect(TokenType::LParen)?;
13220 let mut from_vals = Vec::new();
13221 loop {
13222 let val = self.parse_partition_bound_value()?;
13223 from_vals.push(val);
13224 if !self.match_token(TokenType::Comma) {
13225 break;
13226 }
13227 }
13228 self.expect(TokenType::RParen)?;
13229
13230 self.expect(TokenType::To)?;
13231 self.expect(TokenType::LParen)?;
13232 let mut to_vals = Vec::new();
13233 loop {
13234 let val = self.parse_partition_bound_value()?;
13235 to_vals.push(val);
13236 if !self.match_token(TokenType::Comma) {
13237 break;
13238 }
13239 }
13240 self.expect(TokenType::RParen)?;
13241
13242 let from_expr = if from_vals.len() == 1 {
13243 from_vals.into_iter().next().unwrap()
13244 } else {
13245 Expression::Tuple(Box::new(Tuple {
13246 expressions: from_vals,
13247 }))
13248 };
13249 let to_expr = if to_vals.len() == 1 {
13250 to_vals.into_iter().next().unwrap()
13251 } else {
13252 Expression::Tuple(Box::new(Tuple {
13253 expressions: to_vals,
13254 }))
13255 };
13256
13257 Ok(Expression::PartitionBoundSpec(Box::new(
13258 PartitionBoundSpec {
13259 this: None,
13260 expression: None,
13261 from_expressions: Some(Box::new(from_expr)),
13262 to_expressions: Some(Box::new(to_expr)),
13263 },
13264 )))
13265 } else if self.match_token(TokenType::With) {
13266 self.expect(TokenType::LParen)?;
13268 self.match_text_seq(&["MODULUS"]);
13269 let modulus = self.parse_expression()?;
13270 self.expect(TokenType::Comma)?;
13271 self.match_text_seq(&["REMAINDER"]);
13272 let remainder = self.parse_expression()?;
13273 self.expect(TokenType::RParen)?;
13274
13275 Ok(Expression::PartitionBoundSpec(Box::new(
13276 PartitionBoundSpec {
13277 this: Some(Box::new(modulus)),
13278 expression: Some(Box::new(remainder)),
13279 from_expressions: None,
13280 to_expressions: None,
13281 },
13282 )))
13283 } else {
13284 Err(self.parse_error("Expected IN, FROM, or WITH after FOR VALUES in PARTITION OF"))
13285 }
13286 }
13287
13288 fn parse_partition_bound_value(&mut self) -> Result<Expression> {
13290 if self.match_token(TokenType::Minvalue) {
13291 Ok(Expression::Var(Box::new(Var {
13292 this: "MINVALUE".to_string(),
13293 })))
13294 } else if self.match_token(TokenType::Maxvalue) {
13295 Ok(Expression::Var(Box::new(Var {
13296 this: "MAXVALUE".to_string(),
13297 })))
13298 } else {
13299 self.parse_expression()
13300 }
13301 }
13302
13303 fn parse_partition_column_specs(&mut self) -> Result<(Vec<ColumnDef>, Vec<TableConstraint>)> {
13308 let mut columns = Vec::new();
13309 let mut constraints = Vec::new();
13310
13311 loop {
13312 if self.check(TokenType::Constraint) {
13314 constraints.push(self.parse_table_constraint()?);
13315 } else if self.check(TokenType::PrimaryKey)
13316 || self.check(TokenType::ForeignKey)
13317 || self.check(TokenType::Unique)
13318 || self.check(TokenType::Check)
13319 || self.check(TokenType::Exclude)
13320 {
13321 constraints.push(self.parse_table_constraint()?);
13322 } else {
13323 columns.push(self.parse_partition_column_spec()?);
13325 }
13326
13327 if !self.match_token(TokenType::Comma) {
13328 break;
13329 }
13330 if matches!(
13332 self.config.dialect,
13333 Some(crate::dialects::DialectType::ClickHouse)
13334 ) && self.check(TokenType::RParen)
13335 {
13336 break;
13337 }
13338 }
13339
13340 Ok((columns, constraints))
13341 }
13342
13343 fn parse_partition_column_spec(&mut self) -> Result<ColumnDef> {
13345 let name = self.expect_identifier_or_safe_keyword_with_quoted()?;
13347
13348 let mut col_def = ColumnDef::new(name.name.clone(), DataType::Unknown);
13350 col_def.name = name;
13351
13352 loop {
13354 if self.match_token(TokenType::Default) {
13355 let default_val = self.parse_expression()?;
13357 col_def.default = Some(default_val.clone());
13358 col_def
13359 .constraints
13360 .push(ColumnConstraint::Default(default_val));
13361 col_def.constraint_order.push(ConstraintType::Default);
13362 } else if self.match_keywords(&[TokenType::Not, TokenType::Null]) {
13363 col_def.nullable = Some(false);
13364 col_def.constraint_order.push(ConstraintType::NotNull);
13365 } else if self.match_token(TokenType::Null) {
13366 col_def.nullable = Some(true);
13367 col_def.constraint_order.push(ConstraintType::Null);
13368 } else if self.match_token(TokenType::Constraint) {
13369 let constraint_name = self.expect_identifier_or_safe_keyword()?;
13371 if self.match_keywords(&[TokenType::Not, TokenType::Null]) {
13372 col_def.nullable = Some(false);
13373 col_def.not_null_constraint_name = Some(constraint_name);
13374 col_def.constraint_order.push(ConstraintType::NotNull);
13375 } else if self.match_token(TokenType::Check) {
13376 col_def.check_constraint_name = Some(constraint_name);
13377 if self.match_token(TokenType::LParen) {
13378 let check_expr = self.parse_expression()?;
13379 self.expect(TokenType::RParen)?;
13380 col_def
13381 .constraints
13382 .push(ColumnConstraint::Check(check_expr));
13383 }
13384 col_def.constraint_order.push(ConstraintType::Check);
13385 } else if self.match_token(TokenType::Default) {
13386 let default_val = self.parse_expression()?;
13387 col_def.default = Some(default_val.clone());
13388 col_def
13389 .constraints
13390 .push(ColumnConstraint::Default(default_val));
13391 col_def.constraint_order.push(ConstraintType::Default);
13392 }
13393 } else if self.match_text_seq(&["WITH", "OPTIONS"]) {
13394 break;
13397 } else {
13398 break;
13399 }
13400 }
13401
13402 Ok(col_def)
13403 }
13404
13405 fn parse_with_properties(&mut self) -> Result<Vec<(String, String)>> {
13408 self.expect(TokenType::LParen)?;
13409 let mut properties = Vec::new();
13410
13411 loop {
13412 if self.check(TokenType::RParen) {
13413 break;
13414 }
13415
13416 let mut key = self.expect_identifier_or_keyword()?;
13418
13419 if key.eq_ignore_ascii_case("PARTITIONED") && self.check(TokenType::By) {
13421 self.skip(); key = "PARTITIONED_BY".to_string();
13423 }
13424
13425 self.expect(TokenType::Eq)?;
13427
13428 let value = if self.check(TokenType::String) {
13430 let val = format!("'{}'", self.peek().text);
13432 self.skip();
13433 val
13434 } else if self.match_token(TokenType::LParen) {
13435 let mut depth = 1;
13437 let mut result = String::from("(");
13438 let mut need_space = false;
13439 while !self.is_at_end() && depth > 0 {
13440 if self.check(TokenType::LParen) {
13441 depth += 1;
13442 } else if self.check(TokenType::RParen) {
13443 depth -= 1;
13444 if depth == 0 {
13445 break;
13446 }
13447 }
13448 let token = self.peek();
13449 let text = &token.text;
13450 let token_type = token.token_type;
13451
13452 let is_punctuation = matches!(
13454 token_type,
13455 TokenType::Comma | TokenType::LParen | TokenType::RParen
13456 );
13457 if need_space && !is_punctuation {
13458 result.push(' ');
13459 }
13460
13461 result.push_str(text);
13462
13463 need_space = token_type == TokenType::Comma
13465 || (!is_punctuation
13466 && !matches!(
13467 token_type,
13468 TokenType::LParen | TokenType::RParen | TokenType::Comma
13469 ));
13470 self.skip();
13471 }
13472 self.expect(TokenType::RParen)?;
13473 result.push(')');
13474 result
13475 } else if self.check_identifier("ARRAY")
13476 && self
13477 .peek_nth(1)
13478 .is_some_and(|t| t.token_type == TokenType::LBracket)
13479 {
13480 let mut result = self.advance().text.clone(); self.expect(TokenType::LBracket)?;
13483 result.push('[');
13484 let mut first = true;
13485 while !self.is_at_end() && !self.check(TokenType::RBracket) {
13486 if !first {
13487 if self.match_token(TokenType::Comma) {
13488 result.push_str(", ");
13489 } else {
13490 break;
13491 }
13492 }
13493 first = false;
13494 if self.check(TokenType::String) {
13496 result.push('\'');
13497 result.push_str(&self.advance().text);
13498 result.push('\'');
13499 } else if self.is_identifier_token() {
13500 result.push_str(&self.advance().text);
13501 } else {
13502 break;
13503 }
13504 }
13505 self.expect(TokenType::RBracket)?;
13506 result.push(']');
13507 result
13508 } else if self.check(TokenType::Number) {
13509 self.advance().text.clone()
13511 } else {
13512 self.expect_identifier_or_keyword()?
13514 };
13515
13516 properties.push((key, value));
13517
13518 if !self.match_token(TokenType::Comma) {
13519 break;
13520 }
13521 }
13522
13523 self.expect(TokenType::RParen)?;
13524 Ok(properties)
13525 }
13526
13527 fn parse_column_definitions(&mut self) -> Result<(Vec<ColumnDef>, Vec<TableConstraint>)> {
13529 let mut columns = Vec::new();
13530 let mut constraints = Vec::new();
13531
13532 loop {
13533 if self.check(TokenType::RParen) {
13534 break;
13535 }
13536 if self.check(TokenType::Like) {
13538 constraints.push(self.parse_like_clause()?);
13539 }
13540 else if self.check(TokenType::Constraint)
13545 || self.check(TokenType::PrimaryKey)
13546 || self.check(TokenType::ForeignKey)
13547 || self.check(TokenType::Unique)
13548 || (self.check(TokenType::Check)
13549 && !matches!(
13550 self.config.dialect,
13551 Some(crate::dialects::DialectType::ClickHouse)
13552 )
13553 && self
13554 .peek_nth(1)
13555 .map_or(false, |t| t.token_type == TokenType::LParen))
13556 || self.check(TokenType::Exclude)
13557 {
13558 constraints.push(self.parse_table_constraint()?);
13559 } else if matches!(
13560 self.config.dialect,
13561 Some(crate::dialects::DialectType::ClickHouse)
13562 ) && self.check(TokenType::Index)
13563 {
13564 self.skip(); let name = self.expect_identifier_or_keyword_with_quoted()?;
13567 let expression = self.parse_conjunction()?.ok_or_else(|| {
13569 self.parse_error("Expected expression in ClickHouse INDEX definition")
13570 })?;
13571 let index_type = if self.match_token(TokenType::Type) {
13572 if let Some(func) = self.parse_function()? {
13575 Some(Box::new(func))
13576 } else if !self.check(TokenType::Identifier)
13577 && !self.check(TokenType::Var)
13578 && !self.is_at_end()
13579 {
13580 let type_name = self.advance().text.clone();
13582 if self.check(TokenType::LParen) {
13583 self.skip(); let mut args = Vec::new();
13586 if !self.check(TokenType::RParen) {
13587 args.push(self.parse_expression()?);
13588 while self.match_token(TokenType::Comma) {
13589 args.push(self.parse_expression()?);
13590 }
13591 }
13592 self.expect(TokenType::RParen)?;
13593 Some(Box::new(Expression::Function(Box::new(Function::new(
13594 type_name, args,
13595 )))))
13596 } else {
13597 Some(Box::new(Expression::Identifier(Identifier::new(type_name))))
13599 }
13600 } else if let Some(id) = self.parse_id_var()? {
13601 Some(Box::new(id))
13602 } else {
13603 None
13604 }
13605 } else {
13606 None
13607 };
13608 let granularity = if self.match_identifier("GRANULARITY") {
13609 let gran_val = self.parse_expression()?;
13610 Some(Box::new(gran_val))
13611 } else {
13612 None
13613 };
13614 constraints.push(TableConstraint::Index {
13615 name: Some(name),
13616 columns: Vec::new(),
13617 kind: None,
13618 modifiers: ConstraintModifiers::default(),
13619 use_key_keyword: false,
13620 expression: Some(Box::new(expression)),
13621 index_type,
13622 granularity,
13623 });
13624 } else if !matches!(
13625 self.config.dialect,
13626 Some(crate::dialects::DialectType::ClickHouse)
13627 ) && (self.check(TokenType::Index)
13628 || self.check(TokenType::Key)
13629 || self.check_identifier("FULLTEXT")
13630 || self.check_identifier("SPATIAL"))
13631 {
13632 let looks_like_key_constraint = if self.check(TokenType::Key) {
13635 self.check_next(TokenType::LParen)
13636 || ((self.check_next(TokenType::Identifier)
13637 || self.check_next(TokenType::Var)
13638 || self.check_next(TokenType::QuotedIdentifier))
13639 && self.current + 2 < self.tokens.len()
13640 && self.tokens[self.current + 2].token_type == TokenType::LParen)
13641 } else {
13642 true
13643 };
13644
13645 if looks_like_key_constraint {
13646 constraints.push(self.parse_index_table_constraint()?);
13647 } else {
13648 columns.push(self.parse_column_def()?);
13649 }
13650 } else if self.check_identifier("PERIOD") {
13651 if let Some(period_constraint) =
13653 self.parse_period_for_system_time_table_constraint()?
13654 {
13655 constraints.push(period_constraint);
13656 } else {
13657 columns.push(self.parse_column_def()?);
13659 }
13660 } else if self.check_identifier("INITIALLY") {
13661 self.skip(); if self.match_identifier("DEFERRED") {
13664 constraints.push(TableConstraint::InitiallyDeferred { deferred: true });
13665 } else if self.match_identifier("IMMEDIATE") {
13666 constraints.push(TableConstraint::InitiallyDeferred { deferred: false });
13667 } else {
13668 return Err(self.parse_error("Expected DEFERRED or IMMEDIATE after INITIALLY"));
13669 }
13670 } else if matches!(
13671 self.config.dialect,
13672 Some(crate::dialects::DialectType::ClickHouse)
13673 ) && self.check_identifier("PROJECTION")
13674 {
13675 self.skip(); let name = self.expect_identifier_or_keyword_with_quoted()?;
13678 if self.match_token(TokenType::LParen) {
13679 let expression = self.parse_statement()?;
13680 self.expect(TokenType::RParen)?;
13681 if self.check(TokenType::With)
13683 && self.current + 1 < self.tokens.len()
13684 && self.tokens[self.current + 1].token_type == TokenType::Settings
13685 {
13686 self.skip(); self.skip(); if self.match_token(TokenType::LParen) {
13689 loop {
13691 if self.check(TokenType::RParen) {
13692 break;
13693 }
13694 if self.is_identifier_token()
13695 || self.is_safe_keyword_as_identifier()
13696 {
13697 self.skip(); }
13699 if self.match_token(TokenType::Eq) {
13700 let _ = self.parse_primary()?; }
13702 if !self.match_token(TokenType::Comma) {
13703 break;
13704 }
13705 }
13706 self.expect(TokenType::RParen)?;
13707 }
13708 }
13709 constraints.push(TableConstraint::Projection { name, expression });
13710 } else if self.match_token(TokenType::Index) {
13711 let expr = self.parse_bitwise()?.ok_or_else(|| {
13713 self.parse_error(
13714 "Expected expression in ClickHouse PROJECTION INDEX definition",
13715 )
13716 })?;
13717 let type_str = if self.match_token(TokenType::Type) {
13718 if !self.is_at_end()
13719 && !self.check(TokenType::Comma)
13720 && !self.check(TokenType::RParen)
13721 {
13722 self.advance().text.clone()
13723 } else {
13724 String::new()
13725 }
13726 } else {
13727 String::new()
13728 };
13729 let raw_sql = if type_str.is_empty() {
13730 format!("INDEX {} ", expr)
13731 } else {
13732 format!("INDEX {} TYPE {}", expr, type_str)
13733 };
13734 constraints.push(TableConstraint::Projection {
13735 name,
13736 expression: Expression::Raw(Raw { sql: raw_sql }),
13737 });
13738 } else {
13739 constraints.push(TableConstraint::Projection {
13740 name,
13741 expression: Expression::Null(Null),
13742 });
13743 }
13744 } else {
13745 columns.push(self.parse_column_def()?);
13747 }
13748
13749 if !self.match_token(TokenType::Comma) {
13750 break;
13751 }
13752 if matches!(
13754 self.config.dialect,
13755 Some(crate::dialects::DialectType::ClickHouse)
13756 ) && self.check(TokenType::RParen)
13757 {
13758 break;
13759 }
13760 }
13761
13762 Ok((columns, constraints))
13763 }
13764
13765 fn parse_like_clause(&mut self) -> Result<TableConstraint> {
13767 self.expect(TokenType::Like)?;
13768 let source = self.parse_table_ref()?;
13769 let mut options = Vec::new();
13770
13771 loop {
13773 if self.match_identifier("INCLUDING") {
13774 let prop = self.expect_identifier_or_keyword()?.to_ascii_uppercase();
13775 options.push((LikeOptionAction::Including, prop));
13776 } else if self.match_identifier("EXCLUDING") {
13777 let prop = self.expect_identifier_or_keyword()?.to_ascii_uppercase();
13778 options.push((LikeOptionAction::Excluding, prop));
13779 } else {
13780 break;
13781 }
13782 }
13783
13784 Ok(TableConstraint::Like { source, options })
13785 }
13786
13787 fn parse_column_def(&mut self) -> Result<ColumnDef> {
13789 let mut name = if matches!(
13792 self.config.dialect,
13793 Some(crate::dialects::DialectType::ClickHouse)
13794 ) {
13795 self.expect_identifier_or_keyword_with_quoted()?
13796 } else {
13797 self.expect_identifier_or_safe_keyword_with_quoted()?
13798 };
13799 if matches!(
13801 self.config.dialect,
13802 Some(crate::dialects::DialectType::ClickHouse)
13803 ) {
13804 while self.match_token(TokenType::Dot) {
13805 let sub = self.expect_identifier_or_safe_keyword_with_quoted()?;
13806 name = Identifier {
13807 name: format!("{}.{}", name.name, sub.name),
13808 quoted: name.quoted,
13809 trailing_comments: sub.trailing_comments,
13810 span: None,
13811 };
13812 }
13813 }
13814
13815 if self.check(TokenType::As) {
13818 let mut col_def = ColumnDef::new(
13819 name.name.clone(),
13820 DataType::Custom {
13821 name: String::new(),
13822 },
13823 );
13824 col_def.name = name;
13825 self.skip(); if self.check(TokenType::LParen) {
13828 self.parse_as_computed_column(&mut col_def)?;
13829 }
13830 return Ok(col_def);
13831 }
13832
13833 let no_type = self.check(TokenType::Comma)
13837 || self.check(TokenType::RParen)
13838 || (matches!(
13839 self.config.dialect,
13840 Some(crate::dialects::DialectType::ClickHouse)
13841 ) && (self.check(TokenType::Default)
13842 || self.check(TokenType::Materialized)
13843 || self.check_identifier("ALIAS")
13844 || self.check_identifier("EPHEMERAL")));
13845 let data_type = if no_type {
13846 DataType::Custom {
13848 name: String::new(),
13849 }
13850 } else {
13851 self.parse_data_type()?
13852 };
13853
13854 let mut col_def = ColumnDef::new(name.name.clone(), data_type);
13855 col_def.name = name;
13856 col_def.no_type = no_type;
13857
13858 while self.match_identifier("UNSIGNED")
13861 || self.match_identifier("ZEROFILL")
13862 || self.match_identifier("SIGNED")
13863 {
13864 let modifier = self.previous().text.to_ascii_uppercase();
13865 if modifier == "UNSIGNED" {
13866 col_def.unsigned = true;
13867 } else if modifier == "ZEROFILL" {
13868 col_def.zerofill = true;
13869 }
13870 }
13872
13873 if self.match_identifier("OPTIONS") {
13875 col_def.options = self.parse_options_list()?;
13876 }
13877
13878 loop {
13880 if self.match_keywords(&[TokenType::Not, TokenType::Null]) {
13881 col_def.nullable = Some(false);
13882 col_def.constraint_order.push(ConstraintType::NotNull);
13883 } else if self.match_token(TokenType::Null) {
13884 col_def.nullable = Some(true);
13885 col_def.constraint_order.push(ConstraintType::Null);
13886 } else if self.match_keywords(&[TokenType::PrimaryKey, TokenType::Key]) {
13887 col_def.primary_key = true;
13889 if self.match_token(TokenType::Asc) {
13891 col_def.primary_key_order = Some(SortOrder::Asc);
13892 } else if self.match_token(TokenType::Desc) {
13893 col_def.primary_key_order = Some(SortOrder::Desc);
13894 }
13895 col_def.constraint_order.push(ConstraintType::PrimaryKey);
13896 } else if self.match_token(TokenType::Constraint) {
13897 let constraint_name = self.expect_identifier()?;
13899 if self.match_token(TokenType::References) {
13901 let mut fk_ref = self.parse_foreign_key_ref()?;
13902 fk_ref.constraint_name = Some(constraint_name);
13903 col_def
13904 .constraints
13905 .push(ColumnConstraint::References(fk_ref));
13906 col_def.constraint_order.push(ConstraintType::References);
13907 } else if self.match_keywords(&[TokenType::PrimaryKey, TokenType::Key]) {
13908 col_def.primary_key = true;
13909 col_def.primary_key_constraint_name = Some(constraint_name);
13910 col_def.constraint_order.push(ConstraintType::PrimaryKey);
13911 } else if self.match_token(TokenType::Unique) {
13912 col_def.unique = true;
13913 col_def.unique_constraint_name = Some(constraint_name);
13914 if self.match_text_seq(&["NULLS", "NOT", "DISTINCT"]) {
13916 col_def.unique_nulls_not_distinct = true;
13917 }
13918 col_def.constraint_order.push(ConstraintType::Unique);
13919 } else if self.match_keywords(&[TokenType::Not, TokenType::Null]) {
13920 col_def.nullable = Some(false);
13921 col_def.not_null_constraint_name = Some(constraint_name);
13922 col_def.constraint_order.push(ConstraintType::NotNull);
13923 } else if self.match_token(TokenType::Check) {
13924 col_def.check_constraint_name = Some(constraint_name);
13925 if self.match_token(TokenType::LParen) {
13927 let check_expr = self.parse_expression()?;
13928 self.expect(TokenType::RParen)?;
13929 col_def
13930 .constraints
13931 .push(ColumnConstraint::Check(check_expr));
13932 } else if matches!(
13933 self.config.dialect,
13934 Some(crate::dialects::DialectType::ClickHouse)
13935 ) {
13936 let check_expr = self.parse_or()?;
13938 col_def
13939 .constraints
13940 .push(ColumnConstraint::Check(check_expr));
13941 }
13942 col_def.constraint_order.push(ConstraintType::Check);
13943 }
13944 } else if self.match_token(TokenType::Unique) {
13945 col_def.unique = true;
13946 if self.match_text_seq(&["NULLS", "NOT", "DISTINCT"]) {
13948 col_def.unique_nulls_not_distinct = true;
13949 }
13950 col_def.constraint_order.push(ConstraintType::Unique);
13951 } else if self.match_token(TokenType::Check) {
13952 if self.match_token(TokenType::LParen) {
13954 let check_expr = self.parse_expression()?;
13955 self.expect(TokenType::RParen)?;
13956 col_def
13957 .constraints
13958 .push(ColumnConstraint::Check(check_expr));
13959 col_def.constraint_order.push(ConstraintType::Check);
13960 } else if matches!(
13961 self.config.dialect,
13962 Some(crate::dialects::DialectType::ClickHouse)
13963 ) {
13964 let check_expr = self.parse_or()?;
13966 col_def
13967 .constraints
13968 .push(ColumnConstraint::Check(check_expr));
13969 col_def.constraint_order.push(ConstraintType::Check);
13970 }
13971 } else if self.match_token(TokenType::AutoIncrement) || self.match_keyword("IDENTITY") {
13972 col_def.auto_increment = true;
13973 col_def.constraint_order.push(ConstraintType::AutoIncrement);
13974 if self.match_keyword("START") {
13976 col_def.auto_increment_start = Some(Box::new(self.parse_primary()?));
13977 if self.match_keyword("INCREMENT") {
13978 col_def.auto_increment_increment = Some(Box::new(self.parse_primary()?));
13979 }
13980 if self.match_token(TokenType::Order) {
13982 col_def.auto_increment_order = Some(true);
13983 } else if self.match_identifier("NOORDER") {
13984 col_def.auto_increment_order = Some(false);
13985 }
13986 } else if self.match_token(TokenType::LParen) {
13987 col_def.auto_increment_start = Some(Box::new(self.parse_primary()?));
13989 if self.match_token(TokenType::Comma) {
13990 col_def.auto_increment_increment = Some(Box::new(self.parse_primary()?));
13991 }
13992 self.expect(TokenType::RParen)?;
13993 }
13994 } else if self.match_token(TokenType::Default) {
13995 col_def.default = if matches!(
13997 self.config.dialect,
13998 Some(crate::dialects::DialectType::ClickHouse)
13999 ) {
14000 Some(self.parse_expression()?)
14001 } else {
14002 Some(self.parse_unary()?)
14003 };
14004 col_def.constraint_order.push(ConstraintType::Default);
14005 } else if self.match_keywords(&[TokenType::ForeignKey, TokenType::Key]) {
14006 self.expect(TokenType::References)?;
14009 let mut fk_ref = self.parse_foreign_key_ref()?;
14010 fk_ref.has_foreign_key_keywords = true;
14011 col_def
14012 .constraints
14013 .push(ColumnConstraint::References(fk_ref));
14014 col_def.constraint_order.push(ConstraintType::References);
14015 } else if self.match_token(TokenType::References) {
14016 let fk_ref = self.parse_foreign_key_ref()?;
14017 col_def
14018 .constraints
14019 .push(ColumnConstraint::References(fk_ref));
14020 col_def.constraint_order.push(ConstraintType::References);
14021 } else if self.match_token(TokenType::Generated) {
14022 self.parse_generated_column_constraint(&mut col_def)?;
14025 } else if self.match_token(TokenType::Collate) {
14026 let mut collation = self.expect_identifier_or_keyword_with_quoted()?;
14029 while self.match_token(TokenType::Dot) {
14031 let next = self.expect_identifier_or_keyword_with_quoted()?;
14032 let sep = if next.quoted {
14033 format!("{}.\"{}\"", collation.name, next.name)
14034 } else {
14035 format!("{}.{}", collation.name, next.name)
14036 };
14037 collation = Identifier {
14038 name: sep,
14039 quoted: false,
14040 trailing_comments: Vec::new(),
14041 span: None,
14042 };
14043 }
14044 col_def
14045 .constraints
14046 .push(ColumnConstraint::Collate(collation));
14047 col_def.constraint_order.push(ConstraintType::Collate);
14048 } else if self.match_token(TokenType::Comment) {
14049 let comment_text = self.expect_string()?;
14051 col_def
14052 .constraints
14053 .push(ColumnConstraint::Comment(comment_text));
14054 col_def.constraint_order.push(ConstraintType::Comment);
14055 } else if self.match_keywords(&[TokenType::On, TokenType::Update]) {
14056 let expr = self.parse_unary()?;
14058 col_def.on_update = Some(expr);
14059 col_def.constraint_order.push(ConstraintType::OnUpdate);
14060 } else if self.match_identifier("ENCODE") {
14061 let encoding = self.expect_identifier_or_keyword()?;
14063 col_def.encoding = Some(encoding);
14064 col_def.constraint_order.push(ConstraintType::Encode);
14065 } else if !matches!(
14066 self.config.dialect,
14067 Some(crate::dialects::DialectType::ClickHouse)
14068 ) && self.match_token(TokenType::Format)
14069 {
14070 let format_str = self.expect_string()?;
14072 col_def.format = Some(format_str);
14073 } else if self.match_identifier("TITLE") {
14074 let title_str = self.expect_string()?;
14076 col_def.title = Some(title_str);
14077 } else if self.match_identifier("INLINE") {
14078 self.match_identifier("LENGTH");
14080 let length = self.expect_number()?;
14081 col_def.inline_length = Some(length as u64);
14082 } else if self.match_identifier("COMPRESS") {
14083 if self.match_token(TokenType::LParen) {
14085 let values = self.parse_expression_list()?;
14086 self.expect(TokenType::RParen)?;
14087 col_def.compress = Some(values);
14088 } else if self.check(TokenType::String) {
14089 let value = self.parse_primary()?;
14091 col_def.compress = Some(vec![value]);
14092 } else {
14093 col_def.compress = Some(Vec::new());
14095 }
14096 } else if self.match_identifier("CHARACTER") {
14097 self.match_token(TokenType::Set);
14099 let charset = self.expect_identifier_or_keyword()?;
14100 col_def.character_set = Some(charset);
14101 } else if self.match_identifier("UPPERCASE") {
14102 col_def.uppercase = true;
14104 } else if self.match_identifier("CASESPECIFIC") {
14105 col_def.casespecific = Some(true);
14107 } else if self.match_text_seq(&["NOT", "FOR", "REPLICATION"]) {
14108 col_def.not_for_replication = true;
14110 } else if self.match_token(TokenType::Not) && self.match_identifier("CASESPECIFIC") {
14111 col_def.casespecific = Some(false);
14113 } else if self.match_keyword("TAG")
14114 || (self.match_token(TokenType::With) && self.match_keyword("TAG"))
14115 {
14116 let tags = self.parse_tags()?;
14118 col_def.constraints.push(ColumnConstraint::Tags(tags));
14119 col_def.constraint_order.push(ConstraintType::Tags);
14120 } else if self.match_token(TokenType::As) {
14121 if self.check(TokenType::LParen) {
14126 self.parse_as_computed_column(&mut col_def)?;
14127 }
14128 } else if self.match_identifier("CODEC") {
14129 self.expect(TokenType::LParen)?;
14131 let start = self.current;
14132 let mut depth = 1;
14133 while !self.is_at_end() && depth > 0 {
14134 if self.check(TokenType::LParen) {
14135 depth += 1;
14136 }
14137 if self.check(TokenType::RParen) {
14138 depth -= 1;
14139 if depth == 0 {
14140 break;
14141 }
14142 }
14143 self.skip();
14144 }
14145 let codec_text = self.tokens_to_sql(start, self.current);
14146 self.expect(TokenType::RParen)?;
14147 col_def.codec = Some(codec_text);
14148 } else if self.match_identifier("STATISTICS") {
14149 self.expect(TokenType::LParen)?;
14151 let mut depth = 1;
14152 while !self.is_at_end() && depth > 0 {
14153 if self.check(TokenType::LParen) {
14154 depth += 1;
14155 }
14156 if self.check(TokenType::RParen) {
14157 depth -= 1;
14158 if depth == 0 {
14159 break;
14160 }
14161 }
14162 self.skip();
14163 }
14164 self.expect(TokenType::RParen)?;
14165 } else if self.match_identifier("EPHEMERAL") {
14167 if !self.check(TokenType::Comma)
14170 && !self.check(TokenType::RParen)
14171 && !self.is_at_end()
14172 && !self.check_identifier("CODEC")
14173 && !self.check_identifier("TTL")
14174 && !self.check(TokenType::Comment)
14175 {
14176 let expr = self.parse_bitwise()?.unwrap_or(Expression::Null(Null));
14177 col_def.ephemeral = Some(Some(Box::new(expr)));
14178 if col_def.no_type
14180 && !self.check(TokenType::Comma)
14181 && !self.check(TokenType::RParen)
14182 && !self.is_at_end()
14183 && !self.check_identifier("CODEC")
14184 && !self.check_identifier("TTL")
14185 && !self.check(TokenType::Comment)
14186 {
14187 col_def.data_type = self.parse_data_type()?;
14188 col_def.no_type = false;
14189 }
14190 } else {
14191 col_def.ephemeral = Some(None);
14192 }
14193 } else if self.check(TokenType::Materialized) && !self.check_next(TokenType::View) {
14194 self.skip(); let expr = self.parse_or()?;
14197 col_def.materialized_expr = Some(Box::new(expr));
14198 } else if self.match_identifier("ALIAS") {
14199 let expr = self.parse_or()?;
14201 col_def.alias_expr = Some(Box::new(expr));
14202 } else if matches!(
14203 self.config.dialect,
14204 Some(crate::dialects::DialectType::ClickHouse)
14205 ) && self.check_identifier("EXPRESSION")
14206 {
14207 self.skip(); let expr = self.parse_or()?;
14210 col_def.materialized_expr = Some(Box::new(expr));
14211 } else if matches!(
14212 self.config.dialect,
14213 Some(crate::dialects::DialectType::ClickHouse)
14214 ) && (self.match_identifier("HIERARCHICAL")
14215 || self.match_identifier("IS_OBJECT_ID")
14216 || self.match_identifier("INJECTIVE")
14217 || self.match_identifier("BIDIRECTIONAL"))
14218 {
14219 } else if self.match_identifier("TTL") {
14222 let expr = self.parse_expression()?;
14224 col_def.ttl_expr = Some(Box::new(expr));
14225 } else if matches!(
14226 self.config.dialect,
14227 Some(crate::dialects::DialectType::ClickHouse)
14228 ) && self.check(TokenType::Settings)
14229 && self.check_next(TokenType::LParen)
14230 {
14231 self.skip(); self.expect(TokenType::LParen)?;
14235 let mut depth = 1i32;
14236 while !self.is_at_end() && depth > 0 {
14237 if self.check(TokenType::LParen) {
14238 depth += 1;
14239 }
14240 if self.check(TokenType::RParen) {
14241 depth -= 1;
14242 if depth == 0 {
14243 break;
14244 }
14245 }
14246 self.skip();
14247 }
14248 self.expect(TokenType::RParen)?;
14249 } else {
14250 if self.skip_column_modifier() {
14253 continue;
14254 }
14255 break;
14256 }
14257 }
14258
14259 Ok(col_def)
14260 }
14261
14262 fn skip_column_modifier(&mut self) -> bool {
14264 if self.check(TokenType::Not) {
14267 if self.check_next_identifier("DEFERRABLE")
14269 || self.check_next_identifier("CASESPECIFIC")
14270 {
14271 self.skip(); self.skip(); return true;
14274 }
14275 }
14276 if self.match_identifier("DEFERRABLE")
14278 || self.match_identifier("DEFERRED")
14279 || self.match_identifier("IMMEDIATE")
14280 {
14281 return true;
14282 }
14283 if self.match_identifier("CHARACTER") {
14285 self.match_token(TokenType::Set);
14286 let _ = self.match_token(TokenType::Var) || self.match_token(TokenType::Identifier);
14288 return true;
14289 }
14290 if self.match_identifier("UPPERCASE") || self.match_identifier("CASESPECIFIC") {
14292 return true;
14293 }
14294 false
14296 }
14297
14298 fn parse_teradata_table_options(&mut self) -> (Option<bool>, Option<bool>, Vec<TeradataIndex>) {
14301 let mut with_data = None;
14302 let mut with_statistics = None;
14303 let mut teradata_indexes = Vec::new();
14304
14305 loop {
14306 if self.match_token(TokenType::With) {
14308 let no = self.match_token(TokenType::No); self.match_identifier("DATA");
14310 with_data = Some(!no); if self.match_token(TokenType::And) {
14313 let no_stats = self.match_token(TokenType::No); self.match_identifier("STATISTICS");
14315 with_statistics = Some(!no_stats); }
14317 continue;
14318 }
14319 if self.match_token(TokenType::No) {
14321 self.match_token(TokenType::PrimaryKey);
14322 self.match_token(TokenType::Index);
14323 teradata_indexes.push(TeradataIndex {
14324 kind: TeradataIndexKind::NoPrimary,
14325 name: None,
14326 columns: Vec::new(),
14327 });
14328 self.match_token(TokenType::Comma);
14330 continue;
14331 }
14332 if self.match_token(TokenType::PrimaryKey) {
14334 let is_amp = self.match_identifier("AMP");
14335 self.match_token(TokenType::Index);
14336 let name = if self.is_identifier_token() && !self.check(TokenType::LParen) {
14338 Some(self.advance().text)
14339 } else {
14340 None
14341 };
14342 let columns = if self.match_token(TokenType::LParen) {
14344 let cols = self.parse_identifier_list_raw();
14345 self.match_token(TokenType::RParen);
14346 cols
14347 } else {
14348 Vec::new()
14349 };
14350 teradata_indexes.push(TeradataIndex {
14351 kind: if is_amp {
14352 TeradataIndexKind::PrimaryAmp
14353 } else {
14354 TeradataIndexKind::Primary
14355 },
14356 name,
14357 columns,
14358 });
14359 self.match_token(TokenType::Comma);
14361 continue;
14362 }
14363 if self.match_token(TokenType::Unique) {
14365 let is_primary = self.match_token(TokenType::PrimaryKey);
14366 self.match_token(TokenType::Index);
14367 let name = if self.is_identifier_token() {
14369 Some(self.advance().text)
14370 } else {
14371 None
14372 };
14373 let columns = if self.match_token(TokenType::LParen) {
14375 let cols = self.parse_identifier_list_raw();
14376 self.match_token(TokenType::RParen);
14377 cols
14378 } else {
14379 Vec::new()
14380 };
14381 teradata_indexes.push(TeradataIndex {
14382 kind: if is_primary {
14383 TeradataIndexKind::UniquePrimary
14384 } else {
14385 TeradataIndexKind::Unique
14386 },
14387 name,
14388 columns,
14389 });
14390 self.match_token(TokenType::Comma);
14392 continue;
14393 }
14394 if self.match_token(TokenType::Index) {
14396 let name = if self.is_identifier_token() && !self.check(TokenType::LParen) {
14398 Some(self.advance().text)
14399 } else {
14400 None
14401 };
14402 let columns = if self.match_token(TokenType::LParen) {
14404 let cols = self.parse_identifier_list_raw();
14405 self.match_token(TokenType::RParen);
14406 cols
14407 } else {
14408 Vec::new()
14409 };
14410 teradata_indexes.push(TeradataIndex {
14411 kind: TeradataIndexKind::Secondary,
14412 name,
14413 columns,
14414 });
14415 self.match_token(TokenType::Comma);
14417 continue;
14418 }
14419 break;
14420 }
14421
14422 (with_data, with_statistics, teradata_indexes)
14423 }
14424
14425 fn parse_teradata_post_name_options(&mut self) -> Vec<String> {
14427 if !self.match_token(TokenType::Comma) {
14429 return Vec::new();
14430 }
14431
14432 let mut options = Vec::new();
14433 let mut current_tokens: Vec<(String, TokenType)> = Vec::new();
14434 let mut paren_depth = 0;
14435 let mut in_value = false;
14436
14437 while !self.is_at_end() {
14438 if self.check(TokenType::LParen) && paren_depth == 0 {
14439 if !in_value {
14440 break;
14442 }
14443 let mut is_terminal = false;
14444 if let Some((last_text, last_type)) = current_tokens.last() {
14445 let last_upper = last_text.to_ascii_uppercase();
14446 is_terminal = matches!(last_type, TokenType::Number | TokenType::String)
14447 || matches!(
14448 last_upper.as_str(),
14449 "ON" | "OFF"
14450 | "DEFAULT"
14451 | "NEVER"
14452 | "ALWAYS"
14453 | "MINIMUM"
14454 | "MAXIMUM"
14455 | "BYTES"
14456 | "KBYTES"
14457 | "KILOBYTES"
14458 | "PERCENT"
14459 );
14460 }
14461 if is_terminal {
14462 break;
14463 }
14464 }
14465
14466 let token = self.advance();
14467
14468 match token.token_type {
14469 TokenType::LParen => {
14470 paren_depth += 1;
14471 }
14472 TokenType::RParen => {
14473 if paren_depth > 0 {
14474 paren_depth -= 1;
14475 if paren_depth == 0 && in_value {
14476 in_value = false;
14477 }
14478 }
14479 }
14480 TokenType::Eq => {
14481 if paren_depth == 0 {
14482 in_value = true;
14483 }
14484 }
14485 TokenType::Comma => {
14486 if paren_depth == 0 {
14487 let option = self.join_teradata_option_tokens(current_tokens);
14488 if !option.is_empty() {
14489 options.push(option);
14490 }
14491 current_tokens = Vec::new();
14492 in_value = false;
14493 continue;
14494 }
14495 }
14496 _ => {}
14497 }
14498
14499 let text = if token.token_type == TokenType::QuotedIdentifier {
14500 let quote_char = if self.config.dialect == Some(crate::dialects::DialectType::MySQL)
14501 || self.config.dialect == Some(crate::dialects::DialectType::SingleStore)
14502 || self.config.dialect == Some(crate::dialects::DialectType::Doris)
14503 || self.config.dialect == Some(crate::dialects::DialectType::StarRocks)
14504 {
14505 '`'
14506 } else {
14507 '"'
14508 };
14509 format!("{}{}{}", quote_char, token.text, quote_char)
14510 } else if token.token_type == TokenType::String {
14511 format!("'{}'", token.text)
14512 } else {
14513 token.text.clone()
14514 };
14515
14516 let mut join_type = token.token_type;
14517 if join_type == TokenType::Percent && token.text.eq_ignore_ascii_case("PERCENT") {
14518 join_type = TokenType::Identifier;
14520 }
14521 current_tokens.push((text, join_type));
14522 }
14523
14524 if !current_tokens.is_empty() {
14525 let option = self.join_teradata_option_tokens(current_tokens);
14526 if !option.is_empty() {
14527 options.push(option);
14528 }
14529 }
14530
14531 options
14532 }
14533
14534 fn parse_identifier_list_raw(&mut self) -> Vec<String> {
14536 let mut identifiers = Vec::new();
14537 loop {
14538 if self.is_identifier_token() || self.is_identifier_or_keyword_token() {
14539 identifiers.push(self.advance().text);
14540 }
14541 if !self.match_token(TokenType::Comma) {
14542 break;
14543 }
14544 }
14545 identifiers
14546 }
14547
14548 fn parse_generated_column_constraint(&mut self, col_def: &mut ColumnDef) -> Result<()> {
14554 let always;
14555 let mut on_null = false;
14556
14557 if self.match_token(TokenType::By) {
14559 self.expect(TokenType::Default)?;
14560 on_null = self.match_keywords(&[TokenType::On, TokenType::Null]);
14561 always = false;
14562 } else {
14563 self.expect(TokenType::Always)?;
14564 always = true;
14565 }
14566
14567 self.expect(TokenType::As)?;
14569
14570 if self.check(TokenType::Row) {
14572 self.skip(); let start = if self.match_token(TokenType::Start) {
14575 true
14576 } else {
14577 self.expect(TokenType::End)?;
14578 false
14579 };
14580 let hidden = self.match_identifier("HIDDEN");
14581 col_def
14582 .constraints
14583 .push(ColumnConstraint::GeneratedAsRow(GeneratedAsRow {
14584 start,
14585 hidden,
14586 }));
14587 col_def
14588 .constraint_order
14589 .push(ConstraintType::GeneratedAsRow);
14590 } else if self.check(TokenType::Identity) {
14591 self.skip(); let mut start = None;
14595 let mut increment = None;
14596 let mut minvalue = None;
14597 let mut maxvalue = None;
14598 let mut cycle = None;
14599
14600 if self.match_token(TokenType::LParen) {
14602 loop {
14603 if self.match_token(TokenType::Start) {
14604 self.match_token(TokenType::With);
14605 start = Some(Box::new(self.parse_unary()?));
14606 } else if self.match_token(TokenType::Increment) {
14607 self.match_token(TokenType::By);
14608 increment = Some(Box::new(self.parse_unary()?));
14609 } else if self.match_token(TokenType::Minvalue) {
14610 minvalue = Some(Box::new(self.parse_unary()?));
14611 } else if self.match_token(TokenType::Maxvalue) {
14612 maxvalue = Some(Box::new(self.parse_unary()?));
14613 } else if self.match_token(TokenType::Cycle) {
14614 cycle = Some(true);
14615 } else if self.match_keywords(&[TokenType::No, TokenType::Cycle]) {
14616 cycle = Some(false);
14617 } else if self.check(TokenType::RParen) {
14618 break;
14619 } else {
14620 self.skip();
14621 }
14622 }
14623 self.expect(TokenType::RParen)?;
14624 }
14625
14626 col_def
14627 .constraints
14628 .push(ColumnConstraint::GeneratedAsIdentity(GeneratedAsIdentity {
14629 always,
14630 on_null,
14631 start,
14632 increment,
14633 minvalue,
14634 maxvalue,
14635 cycle,
14636 }));
14637 col_def
14638 .constraint_order
14639 .push(ConstraintType::GeneratedAsIdentity);
14640 } else if self.check(TokenType::LParen) {
14641 self.skip(); let expr = self.parse_expression()?;
14644 self.expect(TokenType::RParen)?;
14645
14646 let (persisted, persistence_kind) = if self.match_identifier("STORED") {
14648 (true, Some("STORED".to_string()))
14649 } else if self.match_identifier("VIRTUAL") {
14650 (false, Some("VIRTUAL".to_string()))
14651 } else {
14652 (false, None)
14653 };
14654
14655 col_def
14656 .constraints
14657 .push(ColumnConstraint::ComputedColumn(ComputedColumn {
14658 expression: Box::new(expr),
14659 persisted,
14660 not_null: false,
14661 persistence_kind,
14662 data_type: None,
14663 }));
14664 col_def
14665 .constraint_order
14666 .push(ConstraintType::ComputedColumn);
14667 } else {
14668 col_def
14670 .constraints
14671 .push(ColumnConstraint::GeneratedAsIdentity(GeneratedAsIdentity {
14672 always,
14673 on_null,
14674 start: None,
14675 increment: None,
14676 minvalue: None,
14677 maxvalue: None,
14678 cycle: None,
14679 }));
14680 col_def
14681 .constraint_order
14682 .push(ConstraintType::GeneratedAsIdentity);
14683 }
14684 Ok(())
14685 }
14686
14687 fn parse_as_computed_column(&mut self, col_def: &mut ColumnDef) -> Result<()> {
14691 self.expect(TokenType::LParen)?;
14692 let expr = self.parse_expression()?;
14693 self.expect(TokenType::RParen)?;
14694
14695 let (persisted, persistence_kind) = if self.match_identifier("STORED") {
14697 (true, Some("STORED".to_string()))
14698 } else if self.match_identifier("VIRTUAL") {
14699 (false, Some("VIRTUAL".to_string()))
14700 } else if self.match_identifier("PERSISTED") {
14701 (true, Some("PERSISTED".to_string()))
14702 } else {
14703 (false, None)
14704 };
14705
14706 let data_type = if persistence_kind.as_deref() == Some("PERSISTED") {
14709 if !self.is_at_end()
14711 && !self.check(TokenType::Not)
14712 && !self.check(TokenType::Comma)
14713 && !self.check(TokenType::RParen)
14714 && !self.check(TokenType::Semicolon)
14715 {
14716 let tok = self.peek();
14717 if tok.text.eq_ignore_ascii_case("AUTO") {
14719 self.skip(); None } else if tok.token_type.is_keyword()
14722 || tok.token_type == TokenType::Identifier
14723 || tok.token_type == TokenType::Var
14724 {
14725 Some(self.parse_data_type()?)
14726 } else {
14727 None
14728 }
14729 } else {
14730 None
14731 }
14732 } else {
14733 None
14734 };
14735
14736 let not_null = if persistence_kind.as_deref() == Some("PERSISTED") {
14738 self.match_keywords(&[TokenType::Not, TokenType::Null])
14739 } else {
14740 false
14741 };
14742
14743 col_def
14744 .constraints
14745 .push(ColumnConstraint::ComputedColumn(ComputedColumn {
14746 expression: Box::new(expr),
14747 persisted,
14748 not_null,
14749 persistence_kind,
14750 data_type,
14751 }));
14752 col_def
14753 .constraint_order
14754 .push(ConstraintType::ComputedColumn);
14755 Ok(())
14756 }
14757
14758 fn parse_period_for_system_time_table_constraint(&mut self) -> Result<Option<TableConstraint>> {
14761 let saved = self.current;
14763
14764 if self.match_identifier("PERIOD") {
14765 if self.match_token(TokenType::For) {
14767 if self.match_identifier("SYSTEM_TIME") {
14768 self.expect(TokenType::LParen)?;
14770 let start_name = self.expect_identifier_or_safe_keyword_with_quoted()?;
14771 self.expect(TokenType::Comma)?;
14772 let end_name = self.expect_identifier_or_safe_keyword_with_quoted()?;
14773 self.expect(TokenType::RParen)?;
14774 return Ok(Some(TableConstraint::PeriodForSystemTime {
14775 start_col: start_name,
14776 end_col: end_name,
14777 }));
14778 }
14779 }
14780 }
14781
14782 self.current = saved;
14784 Ok(None)
14785 }
14786
14787 fn parse_mysql_table_options(&mut self) -> Vec<(String, String)> {
14791 let mut options = Vec::new();
14792 loop {
14793 self.match_token(TokenType::Comma);
14795
14796 if self.check(TokenType::Default) {
14798 let saved = self.current;
14799 self.skip(); if self.check_identifier("CHARSET") || self.check_identifier("CHARACTER") {
14801 let is_character = self.check_identifier("CHARACTER");
14802 let key_part = self.advance().text.to_ascii_uppercase();
14803 if is_character {
14804 self.match_token(TokenType::Set);
14806 }
14807 if self.match_token(TokenType::Eq) {
14808 let value = if self.check(TokenType::String) {
14809 let v = format!("'{}'", self.peek().text);
14810 self.skip();
14811 v
14812 } else if self.is_identifier_token()
14813 || self.is_safe_keyword_as_identifier()
14814 || self.check(TokenType::Number)
14815 {
14816 self.advance().text
14817 } else {
14818 self.current = saved;
14819 break;
14820 };
14821 let key = if is_character || key_part == "CHARSET" {
14823 "DEFAULT CHARACTER SET".to_string()
14824 } else {
14825 format!("DEFAULT {}", key_part)
14826 };
14827 options.push((key, value));
14828 continue;
14829 }
14830 }
14831 self.current = saved;
14832 break;
14833 }
14834
14835 let is_known_option = self.check_identifier("ENGINE")
14837 || self.check(TokenType::AutoIncrement)
14838 || self.check_identifier("ROW_FORMAT")
14839 || self.check(TokenType::Collate)
14840 || self.check_identifier("KEY_BLOCK_SIZE")
14841 || self.check_identifier("PACK_KEYS")
14842 || self.check_identifier("STATS_AUTO_RECALC")
14843 || self.check_identifier("STATS_PERSISTENT")
14844 || self.check_identifier("STATS_SAMPLE_PAGES")
14845 || self.check_identifier("MAX_ROWS")
14846 || self.check_identifier("MIN_ROWS")
14847 || self.check_identifier("CHECKSUM")
14848 || self.check_identifier("DELAY_KEY_WRITE")
14849 || self.check_identifier("COMPRESSION")
14850 || self.check_identifier("CONNECTION")
14851 || self.check_identifier("TABLESPACE")
14852 || self.check_identifier("ENCRYPTION");
14853
14854 if is_known_option {
14855 let key = self.advance().text.to_ascii_uppercase();
14856 if self.match_token(TokenType::Eq) {
14857 let value = if self.check(TokenType::String) {
14858 let v = format!("'{}'", self.peek().text);
14859 self.skip();
14860 v
14861 } else if self.check(TokenType::Number) {
14862 self.advance().text
14863 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
14864 self.advance().text
14865 } else {
14866 break;
14867 };
14868 options.push((key, value));
14869 continue;
14870 }
14871 break;
14872 }
14873
14874 if self.check(TokenType::Comment) {
14876 let saved = self.current;
14877 self.skip(); if self.match_token(TokenType::Eq) {
14879 if self.check(TokenType::String) {
14880 let v = format!("'{}'", self.peek().text);
14881 self.skip();
14882 options.push(("COMMENT".to_string(), v));
14883 continue;
14884 }
14885 } else if self.check(TokenType::String) {
14886 let v = format!("'{}'", self.peek().text);
14887 self.skip();
14888 options.push(("COMMENT".to_string(), v));
14889 continue;
14890 }
14891 self.current = saved;
14892 break;
14893 }
14894
14895 if self.check_identifier("CHARACTER") || self.check_identifier("CHARSET") {
14897 let saved = self.current;
14898 let is_character = self.check_identifier("CHARACTER");
14899 self.skip(); if is_character {
14901 if !self.match_token(TokenType::Set) {
14903 self.current = saved;
14904 break;
14905 }
14906 }
14907 if self.match_token(TokenType::Eq) {
14908 let value = if self.check(TokenType::String) {
14909 let v = format!("'{}'", self.peek().text);
14910 self.skip();
14911 v
14912 } else if self.is_identifier_token()
14913 || self.is_safe_keyword_as_identifier()
14914 || self.check(TokenType::Number)
14915 {
14916 self.advance().text
14917 } else {
14918 self.current = saved;
14919 break;
14920 };
14921 options.push(("CHARACTER SET".to_string(), value));
14922 continue;
14923 }
14924 self.current = saved;
14925 break;
14926 }
14927
14928 break;
14929 }
14930 options
14931 }
14932
14933 fn parse_hive_table_properties(&mut self) -> Result<Vec<Expression>> {
14936 let mut properties = Vec::new();
14937
14938 loop {
14939 if self.match_token(TokenType::Row) {
14942 if let Some(row_format) = self.parse_row()? {
14943 properties.push(row_format);
14944 continue;
14945 }
14946 }
14947
14948 if self.match_identifier("STORED") {
14952 if self.match_token(TokenType::By) {
14953 let handler = self.parse_string()?.unwrap_or(Expression::Null(Null));
14955 properties.push(Expression::StorageHandlerProperty(Box::new(
14956 StorageHandlerProperty {
14957 this: Box::new(handler),
14958 },
14959 )));
14960 continue;
14961 } else if self.match_token(TokenType::As) {
14962 if self.match_token(TokenType::InputFormat) {
14964 let input_format = self.parse_string()?;
14965 let output_format = if self.match_identifier("OUTPUTFORMAT") {
14966 self.parse_string()?
14967 } else {
14968 None
14969 };
14970 let io_format =
14972 Expression::InputOutputFormat(Box::new(InputOutputFormat {
14973 input_format: input_format.map(Box::new),
14974 output_format: output_format.map(Box::new),
14975 }));
14976 properties.push(Expression::FileFormatProperty(Box::new(
14977 FileFormatProperty {
14978 this: Some(Box::new(io_format)),
14979 expressions: vec![],
14980 hive_format: Some(Box::new(Expression::Boolean(BooleanLiteral {
14981 value: true,
14982 }))),
14983 },
14984 )));
14985 continue;
14986 } else {
14987 let format = if self.check(TokenType::String) {
14989 Expression::Literal(Box::new(Literal::String(
14990 self.advance().text.clone(),
14991 )))
14992 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier()
14993 {
14994 Expression::Identifier(Identifier::new(self.advance().text.clone()))
14995 } else {
14996 break;
14997 };
14998 properties.push(Expression::FileFormatProperty(Box::new(
14999 FileFormatProperty {
15000 this: Some(Box::new(format)),
15001 expressions: vec![],
15002 hive_format: Some(Box::new(Expression::Boolean(BooleanLiteral {
15003 value: true,
15004 }))),
15005 },
15006 )));
15007 continue;
15008 }
15009 }
15010 }
15011
15012 if self.match_token(TokenType::Using) {
15015 let format = if self.check(TokenType::String) {
15017 Expression::Literal(Box::new(Literal::String(self.advance().text.clone())))
15018 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
15019 Expression::Identifier(Identifier::new(self.advance().text.clone()))
15020 } else {
15021 break;
15022 };
15023 properties.push(Expression::FileFormatProperty(Box::new(
15025 FileFormatProperty {
15026 this: Some(Box::new(format)),
15027 expressions: vec![],
15028 hive_format: None, },
15030 )));
15031 continue;
15032 }
15033
15034 if self.match_identifier("LOCATION") {
15036 let path = self.parse_string()?.unwrap_or(Expression::Null(Null));
15037 properties.push(Expression::LocationProperty(Box::new(LocationProperty {
15038 this: Box::new(path),
15039 })));
15040 continue;
15041 }
15042
15043 if self.match_identifier("TBLPROPERTIES") {
15045 self.expect(TokenType::LParen)?;
15047 let mut prop_exprs = Vec::new();
15048 loop {
15049 if self.check(TokenType::RParen) {
15050 break;
15051 }
15052 let key = self.parse_primary()?;
15054 if self.match_token(TokenType::Eq) {
15055 let value = self.parse_primary()?;
15056 prop_exprs.push(Expression::Eq(Box::new(BinaryOp::new(key, value))));
15057 } else {
15058 prop_exprs.push(key);
15059 }
15060 if !self.match_token(TokenType::Comma) {
15061 break;
15062 }
15063 }
15064 self.expect(TokenType::RParen)?;
15065 properties.push(Expression::Properties(Box::new(Properties {
15066 expressions: prop_exprs,
15067 })));
15068 continue;
15069 }
15070
15071 if self.match_identifier("DISTRIBUTED") {
15073 if let Some(dist_prop) = self.parse_distributed_property()? {
15074 properties.push(dist_prop);
15075 continue;
15076 }
15077 }
15078
15079 if self.match_identifier("CLUSTERED") {
15081 self.expect(TokenType::By)?;
15082 self.expect(TokenType::LParen)?;
15083 let expressions = self.parse_expression_list()?;
15084 self.expect(TokenType::RParen)?;
15085
15086 let sorted_by = if self.match_identifier("SORTED") {
15088 self.expect(TokenType::By)?;
15089 self.expect(TokenType::LParen)?;
15090 let sorted_exprs = self.parse_expression_list()?;
15091 self.expect(TokenType::RParen)?;
15092 Some(Box::new(Expression::Tuple(Box::new(Tuple {
15093 expressions: sorted_exprs,
15094 }))))
15095 } else {
15096 None
15097 };
15098
15099 let buckets = if self.match_token(TokenType::Into) {
15101 let num = self.parse_expression()?;
15102 if !self.match_identifier("BUCKETS") {
15103 return Err(self.parse_error("Expected BUCKETS after INTO <n>"));
15104 }
15105 Some(Box::new(num))
15106 } else {
15107 None
15108 };
15109
15110 properties.push(Expression::ClusteredByProperty(Box::new(
15111 ClusteredByProperty {
15112 expressions,
15113 sorted_by,
15114 buckets,
15115 },
15116 )));
15117 continue;
15118 }
15119
15120 if self.match_identifier("PARTITIONED") {
15122 self.expect(TokenType::By)?;
15123 self.expect(TokenType::LParen)?;
15124
15125 let mut partition_exprs = Vec::new();
15126 loop {
15127 if self.check(TokenType::RParen) {
15128 break;
15129 }
15130
15131 if self.check_identifier("BUCKET") || self.check_identifier("TRUNCATE") {
15133 let func_name = self.advance().text.clone();
15134 self.expect(TokenType::LParen)?;
15135 let args = self.parse_expression_list()?;
15136 self.expect(TokenType::RParen)?;
15137
15138 partition_exprs.push(Expression::Function(Box::new(Function {
15140 name: func_name,
15141 args,
15142 distinct: false,
15143 trailing_comments: Vec::new(),
15144 use_bracket_syntax: false,
15145 no_parens: false,
15146 quoted: false,
15147 span: None,
15148 inferred_type: None,
15149 })));
15150 } else {
15151 let saved_pos = self.current;
15154 let mut parsed_as_column = false;
15155 if self.check(TokenType::Var)
15157 || self.check(TokenType::Identifier)
15158 || self.check(TokenType::Date)
15159 || self.check(TokenType::Timestamp)
15160 || self.check(TokenType::Int)
15161 || self.check(TokenType::BigInt)
15162 || self.check(TokenType::SmallInt)
15163 || self.check(TokenType::TinyInt)
15164 || self.check(TokenType::Float)
15165 || self.check(TokenType::Double)
15166 || self.check(TokenType::Boolean)
15167 {
15168 let col_name = self.advance().text.clone();
15169 if self.check(TokenType::Var)
15171 || self.check(TokenType::Identifier)
15172 || self.check(TokenType::Int)
15173 || self.check(TokenType::BigInt)
15174 || self.check(TokenType::SmallInt)
15175 || self.check(TokenType::TinyInt)
15176 || self.check(TokenType::Float)
15177 || self.check(TokenType::Double)
15178 || self.check(TokenType::Boolean)
15179 || self.check(TokenType::Date)
15180 || self.check(TokenType::Timestamp)
15181 {
15182 let type_text = self.peek().text.to_ascii_uppercase();
15183 let is_type = matches!(
15184 type_text.as_str(),
15185 "INT"
15186 | "INTEGER"
15187 | "BIGINT"
15188 | "SMALLINT"
15189 | "TINYINT"
15190 | "FLOAT"
15191 | "DOUBLE"
15192 | "DECIMAL"
15193 | "NUMERIC"
15194 | "STRING"
15195 | "VARCHAR"
15196 | "CHAR"
15197 | "BINARY"
15198 | "BOOLEAN"
15199 | "DATE"
15200 | "TIMESTAMP"
15201 | "DATETIME"
15202 | "ARRAY"
15203 | "MAP"
15204 | "STRUCT"
15205 );
15206 if is_type {
15207 let data_type = self.parse_data_type()?;
15209 partition_exprs.push(Expression::ColumnDef(Box::new(
15211 crate::expressions::ColumnDef::new(col_name, data_type),
15212 )));
15213 parsed_as_column = true;
15214 }
15215 }
15216 }
15217 if !parsed_as_column {
15218 self.current = saved_pos;
15220 partition_exprs.push(self.parse_expression()?);
15221 }
15222 }
15223
15224 if !self.match_token(TokenType::Comma) {
15225 break;
15226 }
15227 }
15228 self.expect(TokenType::RParen)?;
15229
15230 properties.push(Expression::PartitionedByProperty(Box::new(
15231 PartitionedByProperty {
15232 this: Box::new(Expression::Tuple(Box::new(Tuple {
15233 expressions: partition_exprs,
15234 }))),
15235 },
15236 )));
15237 continue;
15238 }
15239
15240 break;
15242 }
15243
15244 Ok(properties)
15245 }
15246
15247 fn parse_post_table_properties(&mut self) -> Result<Vec<Expression>> {
15250 let mut properties = Vec::new();
15251
15252 let is_doris_starrocks = matches!(
15255 self.config.dialect,
15256 Some(crate::dialects::DialectType::Doris)
15257 | Some(crate::dialects::DialectType::StarRocks)
15258 );
15259 if is_doris_starrocks {
15260 if self.match_text_seq(&["UNIQUE", "KEY"]) {
15262 let exprs = self.parse_composite_key_expressions()?;
15263 properties.push(Expression::UniqueKeyProperty(Box::new(
15264 crate::expressions::UniqueKeyProperty { expressions: exprs },
15265 )));
15266 }
15267 else if self.match_text_seq(&["DUPLICATE", "KEY"]) {
15269 let exprs = self.parse_composite_key_expressions()?;
15270 properties.push(Expression::DuplicateKeyProperty(Box::new(
15271 crate::expressions::DuplicateKeyProperty { expressions: exprs },
15272 )));
15273 }
15274
15275 if self.match_identifier("DISTRIBUTED") {
15277 if let Some(dist_prop) = self.parse_distributed_property()? {
15278 properties.push(dist_prop);
15279 }
15280 }
15281
15282 if self.match_identifier("PROPERTIES") {
15284 let props = self.parse_options_list()?;
15285 if !props.is_empty() {
15286 properties.push(Expression::Properties(Box::new(Properties {
15287 expressions: props,
15288 })));
15289 }
15290 }
15291 }
15292
15293 if self.check(TokenType::With) {
15297 let saved = self.current;
15299 if self.match_token(TokenType::With) {
15300 if self.match_token(TokenType::LParen) {
15301 if self.check_identifier("SYSTEM_VERSIONING") {
15302 self.skip(); self.expect(TokenType::Eq)?;
15304
15305 let on = if self.match_token(TokenType::On) {
15306 true
15307 } else if self.match_identifier("OFF") {
15308 false
15309 } else {
15310 return Err(
15311 self.parse_error("Expected ON or OFF after SYSTEM_VERSIONING=")
15312 );
15313 };
15314
15315 let mut history_table = None;
15316 let mut data_consistency = None;
15317
15318 if on && self.match_token(TokenType::LParen) {
15320 loop {
15321 if self.check(TokenType::RParen) {
15322 break;
15323 }
15324 if self.match_identifier("HISTORY_TABLE") {
15325 self.expect(TokenType::Eq)?;
15326 let table_ref = self.parse_table_ref()?;
15328 history_table = Some(Expression::Table(Box::new(table_ref)));
15329 } else if self.match_identifier("DATA_CONSISTENCY_CHECK") {
15330 self.expect(TokenType::Eq)?;
15331 let val = self.expect_identifier_or_keyword()?;
15332 data_consistency = Some(Expression::Identifier(
15333 crate::expressions::Identifier::new(val),
15334 ));
15335 } else if self.check(TokenType::RParen) {
15336 break;
15337 } else {
15338 self.skip();
15339 }
15340 self.match_token(TokenType::Comma);
15341 }
15342 self.expect(TokenType::RParen)?;
15343 }
15344
15345 self.expect(TokenType::RParen)?; properties.push(Expression::WithSystemVersioningProperty(Box::new(
15348 WithSystemVersioningProperty {
15349 on: if on {
15350 Some(Box::new(Expression::Boolean(
15351 crate::expressions::BooleanLiteral { value: true },
15352 )))
15353 } else {
15354 None
15355 },
15356 this: history_table.map(Box::new),
15357 data_consistency: data_consistency.map(Box::new),
15358 retention_period: None,
15359 with_: Some(Box::new(Expression::Boolean(
15360 crate::expressions::BooleanLiteral { value: true },
15361 ))),
15362 },
15363 )));
15364 } else {
15365 self.current = saved;
15367 }
15368 } else {
15369 self.current = saved;
15371 }
15372 }
15373 }
15374
15375 Ok(properties)
15376 }
15377
15378 fn parse_composite_key_expressions(&mut self) -> Result<Vec<Expression>> {
15381 self.expect(TokenType::LParen)?;
15382 let mut expressions = Vec::new();
15383 loop {
15384 if let Some(id) = self.parse_id_var()? {
15385 expressions.push(id);
15386 } else {
15387 break;
15388 }
15389 if !self.match_token(TokenType::Comma) {
15390 break;
15391 }
15392 }
15393 self.expect(TokenType::RParen)?;
15394 Ok(expressions)
15395 }
15396
15397 fn parse_table_constraint(&mut self) -> Result<TableConstraint> {
15399 let name = if self.match_token(TokenType::Constraint) {
15401 Some(self.expect_identifier_or_safe_keyword_with_quoted()?)
15403 } else {
15404 None
15405 };
15406
15407 self.parse_constraint_definition(name)
15408 }
15409
15410 fn parse_constraint_definition(&mut self, name: Option<Identifier>) -> Result<TableConstraint> {
15412 if self.match_keywords(&[TokenType::PrimaryKey, TokenType::Key]) {
15413 let clustered = if self.check_identifier("CLUSTERED") {
15419 self.skip();
15420 Some("CLUSTERED".to_string())
15421 } else if self.check_identifier("NONCLUSTERED") {
15422 self.skip();
15423 Some("NONCLUSTERED".to_string())
15424 } else {
15425 None
15426 };
15427
15428 let actual_name = if name.is_none() && !self.check(TokenType::LParen) {
15429 if matches!(
15430 self.config.dialect,
15431 Some(crate::dialects::DialectType::ClickHouse)
15432 ) {
15433 None
15435 } else if self.is_identifier_token() || self.check(TokenType::QuotedIdentifier) {
15436 Some(self.expect_identifier_with_quoted()?)
15437 } else if self.check(TokenType::String)
15438 && matches!(
15439 self.config.dialect,
15440 Some(crate::dialects::DialectType::MySQL)
15441 )
15442 {
15443 let s = self.advance().text.clone();
15446 Some(Identifier {
15447 name: s,
15448 quoted: true,
15449 trailing_comments: Vec::new(),
15450 span: None,
15451 })
15452 } else {
15453 None
15454 }
15455 } else {
15456 name.clone()
15457 };
15458 let columns = if matches!(
15460 self.config.dialect,
15461 Some(crate::dialects::DialectType::ClickHouse)
15462 ) && !self.check(TokenType::LParen)
15463 && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
15464 {
15465 let col_name = self.expect_identifier_or_keyword_with_quoted()?;
15466 vec![col_name]
15467 } else {
15468 self.expect(TokenType::LParen)?;
15469 let cols = if self.check(TokenType::RParen) {
15471 Vec::new()
15472 } else if matches!(
15473 self.config.dialect,
15474 Some(crate::dialects::DialectType::ClickHouse)
15475 ) {
15476 let mut exprs = Vec::new();
15478 loop {
15479 let expr = self.parse_expression()?;
15480 let name = self.expression_to_sql(&expr);
15481 exprs.push(Identifier::new(name));
15482 if !self.match_token(TokenType::Comma) {
15483 break;
15484 }
15485 }
15486 exprs
15487 } else {
15488 self.parse_index_identifier_list()?
15489 };
15490 self.expect(TokenType::RParen)?;
15491 cols
15492 };
15493 let include_columns = if self.match_identifier("INCLUDE") {
15495 self.expect(TokenType::LParen)?;
15496 let cols = self.parse_identifier_list()?;
15497 self.expect(TokenType::RParen)?;
15498 cols
15499 } else {
15500 Vec::new()
15501 };
15502 let mut modifiers = self.parse_constraint_modifiers();
15504 modifiers.clustered = clustered;
15505 let has_constraint_keyword = name.is_some();
15506 Ok(TableConstraint::PrimaryKey {
15507 name: actual_name.or(name),
15508 columns,
15509 include_columns,
15510 modifiers,
15511 has_constraint_keyword,
15512 })
15513 } else if self.match_token(TokenType::Unique) {
15514 let clustered = if self.check_identifier("CLUSTERED") {
15521 self.skip();
15522 Some("CLUSTERED".to_string())
15523 } else if self.check_identifier("NONCLUSTERED") {
15524 self.skip();
15525 Some("NONCLUSTERED".to_string())
15526 } else {
15527 None
15528 };
15529
15530 let use_key_keyword =
15531 self.match_token(TokenType::Key) || self.match_token(TokenType::Index);
15532
15533 let nulls_not_distinct = self.match_text_seq(&["NULLS", "NOT", "DISTINCT"]);
15535
15536 let actual_name = if name.is_none()
15538 && self.is_identifier_token()
15539 && !self.check_next(TokenType::Comma)
15540 {
15541 if self.check_next(TokenType::LParen) {
15543 Some(self.expect_identifier_with_quoted()?)
15544 } else {
15545 None
15546 }
15547 } else {
15548 name.clone()
15549 };
15550
15551 if self.match_token(TokenType::LParen) {
15552 let columns = self.parse_index_identifier_list()?;
15553 self.expect(TokenType::RParen)?;
15554 let mut modifiers = self.parse_constraint_modifiers();
15555 modifiers.clustered = clustered;
15556 if use_key_keyword {
15557 Ok(TableConstraint::Index {
15559 name: actual_name.or(name),
15560 columns,
15561 kind: Some("UNIQUE".to_string()),
15562 modifiers,
15563 use_key_keyword,
15564 expression: None,
15565 index_type: None,
15566 granularity: None,
15567 })
15568 } else {
15569 let has_constraint_keyword = name.is_some();
15570 Ok(TableConstraint::Unique {
15571 name: actual_name.or(name),
15572 columns,
15573 columns_parenthesized: true,
15574 modifiers,
15575 has_constraint_keyword,
15576 nulls_not_distinct,
15577 })
15578 }
15579 } else {
15580 let col_name = self.expect_identifier()?;
15582 let mut modifiers = self.parse_constraint_modifiers();
15583 modifiers.clustered = clustered;
15584 let has_constraint_keyword = name.is_some();
15585 Ok(TableConstraint::Unique {
15586 name: actual_name.or(name),
15587 columns: vec![Identifier::new(col_name)],
15588 columns_parenthesized: false,
15589 modifiers,
15590 has_constraint_keyword,
15591 nulls_not_distinct,
15592 })
15593 }
15594 } else if self.match_keywords(&[TokenType::ForeignKey, TokenType::Key]) {
15595 self.expect(TokenType::LParen)?;
15597 let columns = self.parse_identifier_list()?;
15598 self.expect(TokenType::RParen)?;
15599 if self.match_token(TokenType::References) {
15600 let references = self.parse_foreign_key_ref()?;
15601 let modifiers = self.parse_constraint_modifiers();
15602 Ok(TableConstraint::ForeignKey {
15603 name,
15604 columns,
15605 references: Some(references),
15606 on_delete: None,
15607 on_update: None,
15608 modifiers,
15609 })
15610 } else {
15611 let mut on_delete = None;
15613 let mut on_update = None;
15614 loop {
15615 if self.check(TokenType::On) {
15616 let saved = self.current;
15617 self.skip(); if self.match_token(TokenType::Delete) {
15619 on_delete = Some(self.parse_referential_action()?);
15620 } else if self.match_token(TokenType::Update) {
15621 on_update = Some(self.parse_referential_action()?);
15622 } else {
15623 self.current = saved;
15624 break;
15625 }
15626 } else {
15627 break;
15628 }
15629 }
15630 let modifiers = self.parse_constraint_modifiers();
15631 Ok(TableConstraint::ForeignKey {
15632 name,
15633 columns,
15634 references: None,
15635 on_delete,
15636 on_update,
15637 modifiers,
15638 })
15639 }
15640 } else if self.match_token(TokenType::Check) {
15641 let expression = if self.match_token(TokenType::LParen) {
15643 let expr = if self.check(TokenType::Select) || self.check(TokenType::With) {
15644 self.parse_statement()?
15647 } else {
15648 self.parse_expression()?
15649 };
15650 self.expect(TokenType::RParen)?;
15651 expr
15652 } else if matches!(
15653 self.config.dialect,
15654 Some(crate::dialects::DialectType::ClickHouse)
15655 ) {
15656 self.parse_or()?
15657 } else {
15658 self.expect(TokenType::LParen)?;
15659 unreachable!()
15660 };
15661 let modifiers = self.parse_constraint_modifiers();
15662 Ok(TableConstraint::Check {
15663 name,
15664 expression,
15665 modifiers,
15666 })
15667 } else if self.match_token(TokenType::Exclude) {
15668 let using = if self.match_token(TokenType::Using) {
15671 Some(self.expect_identifier()?)
15672 } else {
15673 None
15674 };
15675
15676 self.expect(TokenType::LParen)?;
15677 let mut elements = Vec::new();
15678 loop {
15679 let mut expr_parts = Vec::new();
15682 let mut paren_depth = 0;
15683 while !self.is_at_end() {
15684 if self.check(TokenType::LParen) {
15685 paren_depth += 1;
15686 expr_parts.push(self.advance().text);
15687 } else if self.check(TokenType::RParen) {
15688 if paren_depth == 0 {
15689 break;
15690 }
15691 paren_depth -= 1;
15692 expr_parts.push(self.advance().text);
15693 } else if paren_depth == 0 && self.check(TokenType::With) {
15694 break;
15695 } else if self.check(TokenType::String) {
15696 let token = self.advance();
15698 expr_parts.push(format!("'{}'", token.text));
15699 } else {
15700 expr_parts.push(self.advance().text);
15701 }
15702 }
15703 let expression = expr_parts
15704 .join(" ")
15705 .replace(" (", "(")
15706 .replace(" )", ")")
15707 .replace("( ", "(")
15708 .replace(" ,", ",");
15709
15710 self.expect(TokenType::With)?;
15712 let operator = self.advance().text.clone();
15713
15714 elements.push(ExcludeElement {
15715 expression,
15716 operator,
15717 });
15718
15719 if !self.match_token(TokenType::Comma) {
15720 break;
15721 }
15722 }
15723 self.expect(TokenType::RParen)?;
15724
15725 let include_columns = if self.match_identifier("INCLUDE") {
15727 self.expect(TokenType::LParen)?;
15728 let cols = self.parse_identifier_list()?;
15729 self.expect(TokenType::RParen)?;
15730 cols
15731 } else {
15732 Vec::new()
15733 };
15734
15735 let with_params = if self.match_token(TokenType::With) {
15737 self.expect(TokenType::LParen)?;
15738 let mut params = Vec::new();
15739 loop {
15740 let key = self.expect_identifier()?;
15741 self.expect(TokenType::Eq)?;
15742 let val = self.advance().text.clone();
15743 params.push((key, val));
15744 if !self.match_token(TokenType::Comma) {
15745 break;
15746 }
15747 }
15748 self.expect(TokenType::RParen)?;
15749 params
15750 } else {
15751 Vec::new()
15752 };
15753
15754 let using_index_tablespace =
15756 if self.check(TokenType::Using) && self.check_next(TokenType::Index) {
15757 self.skip(); self.skip(); if self.match_identifier("TABLESPACE") {
15760 Some(self.expect_identifier()?)
15761 } else {
15762 None
15763 }
15764 } else {
15765 None
15766 };
15767
15768 let where_clause = if self.match_token(TokenType::Where) {
15770 self.expect(TokenType::LParen)?;
15771 let expr = self.parse_expression()?;
15772 self.expect(TokenType::RParen)?;
15773 Some(Box::new(expr))
15774 } else {
15775 None
15776 };
15777
15778 let modifiers = self.parse_constraint_modifiers();
15779 Ok(TableConstraint::Exclude {
15780 name,
15781 using,
15782 elements,
15783 include_columns,
15784 where_clause,
15785 with_params,
15786 using_index_tablespace,
15787 modifiers,
15788 })
15789 } else if matches!(
15790 self.config.dialect,
15791 Some(crate::dialects::DialectType::ClickHouse)
15792 ) && self.check_identifier("ASSUME")
15793 {
15794 self.skip(); let expression = if self.match_token(TokenType::LParen) {
15798 let expr = if self.check(TokenType::Select) || self.check(TokenType::With) {
15800 self.parse_statement()?
15801 } else {
15802 self.parse_expression()?
15803 };
15804 self.expect(TokenType::RParen)?;
15805 expr
15806 } else {
15807 self.parse_expression()?
15808 };
15809 Ok(TableConstraint::Assume { name, expression })
15810 } else {
15811 Err(self.parse_error("Expected PRIMARY KEY, UNIQUE, FOREIGN KEY, CHECK, or EXCLUDE"))
15812 }
15813 }
15814
15815 fn parse_index_table_constraint(&mut self) -> Result<TableConstraint> {
15819 let kind = if self.match_identifier("FULLTEXT") {
15821 Some("FULLTEXT".to_string())
15822 } else if self.match_identifier("SPATIAL") {
15823 Some("SPATIAL".to_string())
15824 } else {
15825 None
15826 };
15827
15828 let use_key_keyword = if self.match_token(TokenType::Key) {
15830 true
15831 } else {
15832 self.match_token(TokenType::Index);
15833 false
15834 };
15835
15836 let early_using = if self.check(TokenType::Using) {
15838 self.match_token(TokenType::Using);
15839 if self.match_identifier("BTREE") {
15840 Some("BTREE".to_string())
15841 } else if self.match_identifier("HASH") {
15842 Some("HASH".to_string())
15843 } else {
15844 None
15845 }
15846 } else {
15847 None
15848 };
15849
15850 let name = if !self.check(TokenType::LParen)
15852 && !self.check(TokenType::Using)
15853 && self.is_identifier_token()
15854 {
15855 Some(Identifier::new(self.advance().text))
15856 } else {
15857 None
15858 };
15859
15860 let late_using = if early_using.is_none() && self.match_token(TokenType::Using) {
15862 if self.match_identifier("BTREE") {
15863 Some("BTREE".to_string())
15864 } else if self.match_identifier("HASH") {
15865 Some("HASH".to_string())
15866 } else {
15867 None
15868 }
15869 } else {
15870 None
15871 };
15872
15873 self.expect(TokenType::LParen)?;
15875 let columns = self.parse_index_identifier_list()?;
15876 self.expect(TokenType::RParen)?;
15877
15878 let mut modifiers = self.parse_constraint_modifiers();
15880
15881 if early_using.is_some() {
15884 modifiers.using = early_using;
15885 modifiers.using_before_columns = true;
15886 } else if late_using.is_some() {
15887 modifiers.using = late_using;
15888 modifiers.using_before_columns = true; }
15890 Ok(TableConstraint::Index {
15893 name,
15894 columns,
15895 kind,
15896 modifiers,
15897 use_key_keyword,
15898 expression: None,
15899 index_type: None,
15900 granularity: None,
15901 })
15902 }
15903
15904 fn parse_constraint_modifiers(&mut self) -> ConstraintModifiers {
15906 let mut modifiers = ConstraintModifiers::default();
15907 loop {
15908 if self.match_token(TokenType::Not) {
15909 if self.match_identifier("ENFORCED") {
15911 modifiers.enforced = Some(false);
15912 } else if self.match_identifier("DEFERRABLE") {
15913 modifiers.deferrable = Some(false);
15914 } else if self.match_identifier("VALID") {
15915 modifiers.not_valid = true;
15916 }
15917 } else if self.match_identifier("ENFORCED") {
15918 modifiers.enforced = Some(true);
15919 } else if self.match_identifier("DEFERRABLE") {
15920 modifiers.deferrable = Some(true);
15921 } else if self.match_identifier("INITIALLY") {
15922 if self.match_identifier("DEFERRED") {
15924 modifiers.initially_deferred = Some(true);
15925 } else if self.match_identifier("IMMEDIATE") {
15926 modifiers.initially_deferred = Some(false);
15927 }
15928 } else if self.match_identifier("NORELY") {
15929 modifiers.norely = true;
15930 } else if self.match_identifier("RELY") {
15931 modifiers.rely = true;
15932 } else if self.match_token(TokenType::Using) {
15933 if self.match_identifier("BTREE") {
15935 modifiers.using = Some("BTREE".to_string());
15936 } else if self.match_identifier("HASH") {
15937 modifiers.using = Some("HASH".to_string());
15938 }
15939 } else if self.match_token(TokenType::Comment) {
15940 if self.check(TokenType::String) {
15942 modifiers.comment = Some(self.advance().text);
15943 }
15944 } else if self.match_identifier("VISIBLE") {
15945 modifiers.visible = Some(true);
15946 } else if self.match_identifier("INVISIBLE") {
15947 modifiers.visible = Some(false);
15948 } else if self.match_identifier("ENGINE_ATTRIBUTE") {
15949 self.match_token(TokenType::Eq);
15951 if self.check(TokenType::String) {
15952 modifiers.engine_attribute = Some(self.advance().text);
15953 }
15954 } else if self.check(TokenType::With) {
15955 let saved_with = self.current;
15956 self.skip(); if self.match_identifier("PARSER") {
15958 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
15960 modifiers.with_parser = Some(self.advance().text);
15961 }
15962 } else if self.check(TokenType::LParen) {
15963 self.skip(); loop {
15967 if self.check(TokenType::RParen) || self.is_at_end() {
15968 break;
15969 }
15970 let key = self.advance().text.clone();
15972 if self.match_token(TokenType::Eq) {
15973 let value = self.advance().text.clone();
15974 modifiers.with_options.push((key, value));
15975 }
15976 if !self.match_token(TokenType::Comma) {
15977 break;
15978 }
15979 }
15980 let _ = self.match_token(TokenType::RParen);
15981 } else {
15982 self.current = saved_with;
15984 break;
15985 }
15986 } else if self.check(TokenType::On) {
15987 let saved_on = self.current;
15988 self.skip(); if self.match_identifier("CONFLICT") {
15990 if self.match_token(TokenType::Rollback) {
15992 modifiers.on_conflict = Some("ROLLBACK".to_string());
15993 } else if self.match_identifier("ABORT") {
15994 modifiers.on_conflict = Some("ABORT".to_string());
15995 } else if self.match_identifier("FAIL") {
15996 modifiers.on_conflict = Some("FAIL".to_string());
15997 } else if self.match_token(TokenType::Ignore) {
15998 modifiers.on_conflict = Some("IGNORE".to_string());
15999 } else if self.match_token(TokenType::Replace) {
16000 modifiers.on_conflict = Some("REPLACE".to_string());
16001 }
16002 } else if self.is_identifier_token() || self.check(TokenType::QuotedIdentifier) {
16003 let quoted = self.check(TokenType::QuotedIdentifier);
16005 let name = self.advance().text.clone();
16006 modifiers.on_filegroup = Some(Identifier {
16007 name,
16008 quoted,
16009 trailing_comments: Vec::new(),
16010 span: None,
16011 });
16012 } else {
16013 self.current = saved_on;
16015 break;
16016 }
16017 } else {
16018 break;
16019 }
16020 }
16021 modifiers
16022 }
16023
16024 fn parse_foreign_key_ref(&mut self) -> Result<ForeignKeyRef> {
16026 let table = self.parse_table_ref()?;
16027
16028 let columns = if self.match_token(TokenType::LParen) {
16029 let cols = self.parse_identifier_list()?;
16030 self.expect(TokenType::RParen)?;
16031 cols
16032 } else {
16033 Vec::new()
16034 };
16035
16036 let match_type = if self.match_token(TokenType::Match) {
16039 if self.check(TokenType::Full) {
16040 self.skip();
16041 Some(MatchType::Full)
16042 } else if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
16043 let text = self.advance().text.to_ascii_uppercase();
16044 match text.as_str() {
16045 "PARTIAL" => Some(MatchType::Partial),
16046 "SIMPLE" => Some(MatchType::Simple),
16047 _ => None,
16048 }
16049 } else {
16050 None
16051 }
16052 } else {
16053 None
16054 };
16055
16056 let mut on_delete = None;
16058 let mut on_update = None;
16059 let mut on_update_first = false;
16060 let mut first_clause = true;
16061
16062 for _ in 0..2 {
16064 if on_delete.is_none() && self.match_keywords(&[TokenType::On, TokenType::Delete]) {
16065 on_delete = Some(self.parse_referential_action()?);
16066 } else if on_update.is_none()
16067 && self.match_keywords(&[TokenType::On, TokenType::Update])
16068 {
16069 if first_clause {
16070 on_update_first = true;
16071 }
16072 on_update = Some(self.parse_referential_action()?);
16073 } else {
16074 break;
16075 }
16076 first_clause = false;
16077 }
16078
16079 let mut match_after_actions = false;
16081 let match_type = if match_type.is_none() && self.match_token(TokenType::Match) {
16082 match_after_actions = on_delete.is_some() || on_update.is_some();
16083 if self.check(TokenType::Full) {
16084 self.skip();
16085 Some(MatchType::Full)
16086 } else if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
16087 let text = self.advance().text.to_ascii_uppercase();
16088 match text.as_str() {
16089 "PARTIAL" => Some(MatchType::Partial),
16090 "SIMPLE" => Some(MatchType::Simple),
16091 _ => None,
16092 }
16093 } else {
16094 None
16095 }
16096 } else {
16097 match_type
16098 };
16099
16100 let deferrable = if self.match_identifier("DEFERRABLE") {
16102 Some(true)
16103 } else if self.match_token(TokenType::Not) && self.match_identifier("DEFERRABLE") {
16104 Some(false)
16105 } else {
16106 None
16107 };
16108
16109 Ok(ForeignKeyRef {
16110 table,
16111 columns,
16112 on_delete,
16113 on_update,
16114 on_update_first,
16115 match_type,
16116 match_after_actions,
16117 constraint_name: None, deferrable,
16119 has_foreign_key_keywords: false, })
16121 }
16122
16123 fn parse_referential_action(&mut self) -> Result<ReferentialAction> {
16125 if self.match_token(TokenType::Cascade) {
16126 Ok(ReferentialAction::Cascade)
16127 } else if self.match_keywords(&[TokenType::Set, TokenType::Null]) {
16128 Ok(ReferentialAction::SetNull)
16129 } else if self.match_keywords(&[TokenType::Set, TokenType::Default]) {
16130 Ok(ReferentialAction::SetDefault)
16131 } else if self.match_token(TokenType::Restrict) {
16132 Ok(ReferentialAction::Restrict)
16133 } else if self.match_token(TokenType::No) {
16134 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("ACTION") {
16136 self.skip();
16137 }
16138 Ok(ReferentialAction::NoAction)
16139 } else {
16140 Err(self.parse_error("Expected CASCADE, SET NULL, SET DEFAULT, RESTRICT, or NO ACTION"))
16141 }
16142 }
16143
16144 fn parse_tags(&mut self) -> Result<Tags> {
16146 self.expect(TokenType::LParen)?;
16147 let mut expressions = Vec::new();
16148
16149 loop {
16150 let key = self.expect_identifier_or_keyword()?;
16152 self.expect(TokenType::Eq)?;
16153 let value = self.parse_primary()?;
16154
16155 expressions.push(Expression::Property(Box::new(Property {
16157 this: Box::new(Expression::Identifier(Identifier::new(key))),
16158 value: Some(Box::new(value)),
16159 })));
16160
16161 if !self.match_token(TokenType::Comma) {
16162 break;
16163 }
16164 }
16165
16166 self.expect(TokenType::RParen)?;
16167
16168 Ok(Tags { expressions })
16169 }
16170
16171 fn parse_create_view(
16173 &mut self,
16174 or_replace: bool,
16175 or_alter: bool,
16176 materialized: bool,
16177 temporary: bool,
16178 algorithm: Option<String>,
16179 definer: Option<String>,
16180 security: Option<FunctionSecurity>,
16181 secure: bool,
16182 ) -> Result<Expression> {
16183 self.expect(TokenType::View)?;
16184
16185 let if_not_exists =
16187 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
16188
16189 let name = self.parse_table_ref()?;
16190
16191 if matches!(
16193 self.config.dialect,
16194 Some(crate::dialects::DialectType::ClickHouse)
16195 ) && self.check_identifier("UUID")
16196 {
16197 self.skip(); let _ = self.advance(); }
16200
16201 let on_cluster = self.parse_on_cluster_clause()?;
16203
16204 let to_table = if self.match_token(TokenType::To) {
16206 Some(self.parse_table_ref()?)
16207 } else {
16208 None
16209 };
16210
16211 let copy_grants = self.match_text_seq(&["COPY", "GRANTS"]);
16213
16214 let mut schema: Option<Schema> = None;
16219 let mut unique_key: Option<UniqueKeyProperty> = None;
16220
16221 let columns = if self.check(TokenType::LParen) {
16223 if materialized
16225 || matches!(
16226 self.config.dialect,
16227 Some(crate::dialects::DialectType::ClickHouse)
16228 )
16229 {
16230 let saved_pos = self.current;
16232
16233 if let Some(Expression::Schema(parsed_schema)) = self.parse_schema()? {
16235 schema = Some(*parsed_schema);
16236
16237 if self.match_text_seq(&["KEY"]) {
16239 let exprs = self.parse_composite_key_expressions()?;
16240 unique_key = Some(UniqueKeyProperty { expressions: exprs });
16241 }
16242
16243 Vec::new() } else {
16245 self.current = saved_pos;
16247 self.parse_view_columns()?
16248 }
16249 } else {
16250 self.parse_view_columns()?
16251 }
16252 } else {
16253 Vec::new()
16254 };
16255
16256 let copy_grants = copy_grants || self.match_text_seq(&["COPY", "GRANTS"]);
16258
16259 let (security, security_sql_style, security_after_name) = if security.is_some() {
16263 (security, true, false)
16265 } else if self.check_identifier("SQL")
16266 && self.current + 1 < self.tokens.len()
16267 && self.tokens[self.current + 1]
16268 .text
16269 .eq_ignore_ascii_case("SECURITY")
16270 {
16271 self.skip(); self.skip(); let sec = if self.match_identifier("DEFINER") {
16275 Some(FunctionSecurity::Definer)
16276 } else if self.match_identifier("INVOKER") {
16277 Some(FunctionSecurity::Invoker)
16278 } else if self.match_identifier("NONE") {
16279 Some(FunctionSecurity::None)
16280 } else {
16281 None
16282 };
16283 (sec, true, true)
16284 } else if self.match_identifier("SECURITY") {
16285 let sec = if self.match_identifier("DEFINER") {
16287 Some(FunctionSecurity::Definer)
16288 } else if self.match_identifier("INVOKER") {
16289 Some(FunctionSecurity::Invoker)
16290 } else if self.match_identifier("NONE") {
16291 Some(FunctionSecurity::None)
16292 } else {
16293 None
16294 };
16295 (sec, false, false)
16296 } else {
16297 (None, true, false)
16298 };
16299
16300 let view_comment = if self.match_token(TokenType::Comment) {
16302 let _ = self.match_token(TokenType::Eq);
16304 Some(self.expect_string()?)
16305 } else {
16306 None
16307 };
16308
16309 let tags = if self.match_identifier("TAG") {
16311 let mut tag_list = Vec::new();
16312 if self.match_token(TokenType::LParen) {
16313 loop {
16314 let tag_name = self.expect_identifier()?;
16315 let tag_value = if self.match_token(TokenType::Eq) {
16316 self.expect_string()?
16317 } else {
16318 String::new()
16319 };
16320 tag_list.push((tag_name, tag_value));
16321 if !self.match_token(TokenType::Comma) {
16322 break;
16323 }
16324 }
16325 self.expect(TokenType::RParen)?;
16326 }
16327 tag_list
16328 } else {
16329 Vec::new()
16330 };
16331
16332 let options = if self.match_identifier("OPTIONS") {
16334 self.parse_options_list()?
16335 } else {
16336 Vec::new()
16337 };
16338
16339 let build = if self.match_identifier("BUILD") {
16341 if self.match_identifier("IMMEDIATE") {
16342 Some("IMMEDIATE".to_string())
16343 } else if self.match_identifier("DEFERRED") {
16344 Some("DEFERRED".to_string())
16345 } else {
16346 let value = self.expect_identifier_or_keyword()?;
16348 Some(value.to_ascii_uppercase())
16349 }
16350 } else {
16351 None
16352 };
16353
16354 let refresh = if self.match_token(TokenType::Refresh) {
16357 if matches!(
16358 self.config.dialect,
16359 Some(crate::dialects::DialectType::ClickHouse)
16360 ) {
16361 while !self.is_at_end()
16363 && !self.check(TokenType::As)
16364 && !self.check_identifier("POPULATE")
16365 && !self.check_identifier("TO")
16366 && !self.check_identifier("APPEND")
16367 && !self.check_identifier("ENGINE")
16368 && !self.check(TokenType::Semicolon)
16369 {
16370 self.skip();
16371 }
16372 let _ = self.match_identifier("APPEND");
16374 None
16375 } else {
16376 Some(Box::new(self.parse_refresh_trigger_property()?))
16377 }
16378 } else {
16379 None
16380 };
16381
16382 let to_table = if to_table.is_none() && self.match_token(TokenType::To) {
16385 Some(self.parse_table_ref()?)
16386 } else {
16387 to_table
16388 };
16389
16390 if schema.is_none()
16392 && self.check(TokenType::LParen)
16393 && matches!(
16394 self.config.dialect,
16395 Some(crate::dialects::DialectType::ClickHouse)
16396 )
16397 {
16398 let saved_pos = self.current;
16399 if let Some(Expression::Schema(parsed_schema)) = self.parse_schema()? {
16400 schema = Some(*parsed_schema);
16401 } else {
16402 self.current = saved_pos;
16403 }
16404 }
16405
16406 let auto_refresh = if self.match_text_seq(&["AUTO", "REFRESH"]) {
16408 if self.match_identifier("YES") {
16409 Some(true)
16410 } else if self.match_identifier("NO") {
16411 Some(false)
16412 } else {
16413 None
16414 }
16415 } else {
16416 None
16417 };
16418
16419 let mut table_properties = Vec::new();
16422 if materialized
16423 && matches!(
16424 self.config.dialect,
16425 Some(crate::dialects::DialectType::ClickHouse)
16426 )
16427 {
16428 self.parse_clickhouse_table_properties(&mut table_properties)?;
16429 }
16430
16431 if materialized
16433 && matches!(
16434 self.config.dialect,
16435 Some(crate::dialects::DialectType::ClickHouse)
16436 )
16437 {
16438 let _ = self.match_identifier("POPULATE");
16439 let _ = self.match_identifier("EMPTY");
16440 }
16441
16442 let has_as = self.match_token(TokenType::As);
16444 if !has_as && !self.check(TokenType::Select) && !self.check(TokenType::With) {
16445 return Ok(Expression::CreateView(Box::new(CreateView {
16447 name,
16448 columns,
16449 query: Expression::Null(Null), or_replace,
16451 or_alter,
16452 if_not_exists,
16453 materialized,
16454 temporary,
16455 secure,
16456 algorithm,
16457 definer,
16458 security,
16459 security_sql_style,
16460 security_after_name,
16461 query_parenthesized: false,
16462 locking_mode: None,
16463 locking_access: None,
16464 copy_grants,
16465 comment: view_comment,
16466 tags,
16467 options,
16468 build,
16469 refresh,
16470 schema: schema.map(Box::new),
16471 unique_key: unique_key.map(Box::new),
16472 no_schema_binding: false,
16473 auto_refresh,
16474 on_cluster,
16475 to_table,
16476 table_properties,
16477 })));
16478 }
16479
16480 let mut locking_mode: Option<String> = None;
16482 let mut locking_access: Option<String> = None;
16483 if self.match_token(TokenType::Lock) || self.match_identifier("LOCKING") {
16484 if self.match_token(TokenType::Row) {
16486 locking_mode = Some("ROW".to_string());
16487 } else if self.match_token(TokenType::Table) {
16488 locking_mode = Some("TABLE".to_string());
16489 } else if self.match_token(TokenType::Database) || self.match_identifier("DATABASE") {
16490 locking_mode = Some("DATABASE".to_string());
16491 }
16492 if self.match_token(TokenType::For) {
16494 if self.match_identifier("ACCESS") {
16495 locking_access = Some("ACCESS".to_string());
16496 } else if self.match_identifier("READ") {
16497 locking_access = Some("READ".to_string());
16498 } else if self.match_identifier("WRITE") {
16499 locking_access = Some("WRITE".to_string());
16500 }
16501 }
16502 }
16503
16504 let query_parenthesized = self.check(TokenType::LParen);
16506 let query = if self.check(TokenType::With) {
16507 self.parse_statement()?
16508 } else if query_parenthesized {
16509 self.skip(); let inner = if self.check(TokenType::With) {
16512 self.parse_statement()?
16513 } else {
16514 self.parse_select()?
16515 };
16516 self.expect(TokenType::RParen)?;
16517 inner
16518 } else {
16519 self.parse_select()?
16520 };
16521
16522 let no_schema_binding = self.match_text_seq(&["WITH", "NO", "SCHEMA", "BINDING"]);
16524
16525 Ok(Expression::CreateView(Box::new(CreateView {
16526 name,
16527 columns,
16528 query,
16529 or_replace,
16530 or_alter,
16531 if_not_exists,
16532 materialized,
16533 temporary,
16534 secure,
16535 algorithm,
16536 definer,
16537 security,
16538 security_sql_style,
16539 security_after_name,
16540 query_parenthesized,
16541 locking_mode,
16542 locking_access,
16543 copy_grants,
16544 comment: view_comment,
16545 tags,
16546 options,
16547 build,
16548 refresh,
16549 schema: schema.map(Box::new),
16550 unique_key: unique_key.map(Box::new),
16551 no_schema_binding,
16552 auto_refresh,
16553 on_cluster,
16554 to_table,
16555 table_properties,
16556 })))
16557 }
16558
16559 fn parse_view_columns(&mut self) -> Result<Vec<ViewColumn>> {
16562 self.expect(TokenType::LParen)?;
16563 let mut cols = Vec::new();
16564 loop {
16565 let col_name = self.expect_identifier()?;
16566 let options = if self.match_identifier("OPTIONS") {
16568 self.parse_options_list()?
16569 } else {
16570 Vec::new()
16571 };
16572 let comment = if self.match_token(TokenType::Comment) {
16574 Some(self.expect_string()?)
16575 } else {
16576 None
16577 };
16578 cols.push(ViewColumn {
16579 name: Identifier::new(col_name),
16580 comment,
16581 options,
16582 });
16583 if !self.match_token(TokenType::Comma) {
16584 break;
16585 }
16586 }
16587 self.expect(TokenType::RParen)?;
16588 Ok(cols)
16589 }
16590
16591 fn parse_create_index_with_clustered(
16593 &mut self,
16594 unique: bool,
16595 clustered: Option<String>,
16596 ) -> Result<Expression> {
16597 self.expect(TokenType::Index)?;
16598
16599 let concurrently = self.match_identifier("CONCURRENTLY");
16601
16602 let if_not_exists =
16604 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
16605
16606 let name = if if_not_exists && self.check(TokenType::On) {
16608 Identifier::new("") } else {
16610 self.expect_identifier_with_quoted()?
16611 };
16612 self.expect(TokenType::On)?;
16613 let table = self.parse_table_ref()?;
16614
16615 let using = if self.match_token(TokenType::Using) {
16617 Some(self.expect_identifier()?)
16618 } else {
16619 None
16620 };
16621
16622 let columns = if self.match_token(TokenType::LParen) {
16624 let cols = self.parse_index_columns()?;
16625 self.expect(TokenType::RParen)?;
16626 cols
16627 } else if clustered
16628 .as_ref()
16629 .is_some_and(|c| c.contains("COLUMNSTORE"))
16630 {
16631 Vec::new()
16633 } else if matches!(
16634 self.config.dialect,
16635 Some(crate::dialects::DialectType::ClickHouse)
16636 ) {
16637 let mut parts = vec![
16640 "CREATE".to_string(),
16641 if unique {
16642 "UNIQUE INDEX".to_string()
16643 } else {
16644 "INDEX".to_string()
16645 },
16646 name.name.clone(),
16647 "ON".to_string(),
16648 ];
16649 if let Some(ref s) = table.schema {
16651 parts.push(format!("{}.{}", s.name, table.name.name));
16652 } else {
16653 parts.push(table.name.name.clone());
16654 }
16655 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
16656 let token = self.advance();
16657 if token.token_type == TokenType::String {
16658 parts.push(format!("'{}'", token.text));
16659 } else if token.token_type == TokenType::QuotedIdentifier {
16660 parts.push(format!("\"{}\"", token.text));
16661 } else {
16662 parts.push(token.text.clone());
16663 }
16664 }
16665 return Ok(Expression::Command(Box::new(crate::expressions::Command {
16666 this: parts.join(" "),
16667 })));
16668 } else {
16669 self.expect(TokenType::LParen)?;
16670 let cols = self.parse_index_columns()?;
16671 self.expect(TokenType::RParen)?;
16672 cols
16673 };
16674
16675 let include_columns = if self.match_identifier("INCLUDE") {
16677 self.expect(TokenType::LParen)?;
16678 let mut cols = Vec::new();
16679 loop {
16680 cols.push(self.expect_identifier_with_quoted()?);
16681 if !self.match_token(TokenType::Comma) {
16682 break;
16683 }
16684 }
16685 self.expect(TokenType::RParen)?;
16686 cols
16687 } else {
16688 Vec::new()
16689 };
16690
16691 let with_options = if self.check(TokenType::With) {
16693 if self
16696 .peek_nth(1)
16697 .is_some_and(|t| t.token_type == TokenType::LParen)
16698 {
16699 self.skip(); self.parse_with_properties()?
16701 } else {
16702 Vec::new()
16703 }
16704 } else {
16705 Vec::new()
16706 };
16707
16708 let where_clause = if self.match_token(TokenType::Where) {
16710 Some(Box::new(self.parse_expression()?))
16711 } else {
16712 None
16713 };
16714
16715 let on_filegroup = if self.match_token(TokenType::On) {
16718 let token = self.advance();
16720 let mut filegroup = token.text.clone();
16721 if self.match_token(TokenType::LParen) {
16723 filegroup.push('(');
16724 loop {
16726 let col_token = self.advance();
16727 if col_token.token_type == TokenType::QuotedIdentifier {
16729 filegroup.push('[');
16730 filegroup.push_str(&col_token.text);
16731 filegroup.push(']');
16732 } else {
16733 filegroup.push_str(&col_token.text);
16734 }
16735 if !self.match_token(TokenType::Comma) {
16736 break;
16737 }
16738 filegroup.push_str(", ");
16739 }
16740 self.expect(TokenType::RParen)?;
16741 filegroup.push(')');
16742 }
16743 Some(filegroup)
16744 } else {
16745 None
16746 };
16747
16748 Ok(Expression::CreateIndex(Box::new(CreateIndex {
16749 name,
16750 table,
16751 columns,
16752 unique,
16753 if_not_exists,
16754 using,
16755 clustered,
16756 concurrently,
16757 where_clause,
16758 include_columns,
16759 with_options,
16760 on_filegroup,
16761 })))
16762 }
16763
16764 fn parse_index_columns(&mut self) -> Result<Vec<IndexColumn>> {
16766 let mut columns = Vec::new();
16767 loop {
16768 let expr = self.parse_expression()?;
16770
16771 let column = match &expr {
16773 Expression::Identifier(ident) => ident.clone(),
16774 Expression::Column(col) => {
16775 col.name.clone()
16778 }
16779 Expression::Function(_func) => {
16780 Identifier::new(self.expression_to_sql(&expr))
16782 }
16783 _ => Identifier::new(self.expression_to_sql(&expr)),
16784 };
16785
16786 let opclass = if self.is_identifier_token()
16789 && !self.check(TokenType::Asc)
16790 && !self.check(TokenType::Desc)
16791 && !self.check(TokenType::Nulls)
16792 {
16793 let mut opclass_name = self.advance().text;
16794 while self.match_token(TokenType::Dot) {
16796 opclass_name.push('.');
16797 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
16798 opclass_name.push_str(&self.advance().text);
16799 }
16800 }
16801 Some(opclass_name)
16802 } else {
16803 None
16804 };
16805
16806 let desc = self.match_token(TokenType::Desc);
16807 let asc = if !desc {
16808 self.match_token(TokenType::Asc)
16809 } else {
16810 false
16811 };
16812 let nulls_first = if self.match_token(TokenType::Nulls) {
16813 if self.match_token(TokenType::First) {
16814 Some(true)
16815 } else if self.match_token(TokenType::Last) {
16816 Some(false)
16817 } else {
16818 None
16819 }
16820 } else {
16821 None
16822 };
16823 columns.push(IndexColumn {
16824 column,
16825 desc,
16826 asc,
16827 nulls_first,
16828 opclass,
16829 });
16830 if !self.match_token(TokenType::Comma) {
16831 break;
16832 }
16833 }
16834 Ok(columns)
16835 }
16836
16837 fn expression_to_sql(&self, expr: &Expression) -> String {
16839 match expr {
16840 Expression::Identifier(ident) => ident.name.clone(),
16841 Expression::Function(func) => {
16842 let args = func
16843 .args
16844 .iter()
16845 .map(|a| self.expression_to_sql(a))
16846 .collect::<Vec<_>>()
16847 .join(", ");
16848 format!("{}({})", func.name, args)
16849 }
16850 Expression::Column(col) => {
16851 if let Some(ref table) = col.table {
16852 format!("{}.{}", table, col.name)
16853 } else {
16854 col.name.to_string()
16855 }
16856 }
16857 Expression::Literal(lit) => match lit.as_ref() {
16858 Literal::String(s) => format!("'{}'", s),
16859 Literal::Number(n) => n.clone(),
16860 _ => "?".to_string(),
16861 },
16862 Expression::Null(_) => "NULL".to_string(),
16863 Expression::Boolean(b) => {
16864 if b.value {
16865 "TRUE".to_string()
16866 } else {
16867 "FALSE".to_string()
16868 }
16869 }
16870 _ => "?".to_string(),
16871 }
16872 }
16873
16874 fn parse_drop(&mut self) -> Result<Expression> {
16876 let leading_comments = self.current_leading_comments().to_vec();
16878 self.expect(TokenType::Drop)?;
16879
16880 if self.check(TokenType::Temporary)
16882 && matches!(
16883 self.config.dialect,
16884 Some(crate::dialects::DialectType::ClickHouse)
16885 )
16886 {
16887 self.skip(); if self.check(TokenType::View) {
16889 return self.parse_drop_view(false);
16890 }
16891 return self.parse_drop_table_with_iceberg(leading_comments.clone(), false);
16892 }
16893
16894 if self.check_identifier("ICEBERG")
16896 && self.current + 1 < self.tokens.len()
16897 && self.tokens[self.current + 1].token_type == TokenType::Table
16898 {
16899 self.skip(); return self.parse_drop_table_with_iceberg(leading_comments, true);
16901 }
16902
16903 match self.peek().token_type {
16904 TokenType::Table => self.parse_drop_table_with_iceberg(leading_comments, false),
16905 TokenType::View => self.parse_drop_view(false),
16906 TokenType::Materialized => {
16907 self.skip(); self.parse_drop_view(true)
16909 }
16910 TokenType::Index => self.parse_drop_index(),
16911 TokenType::Schema => self.parse_drop_schema(),
16912 TokenType::Database => self.parse_drop_database(),
16913 TokenType::Function => self.parse_drop_function(),
16914 TokenType::Procedure => self.parse_drop_procedure(),
16915 TokenType::Sequence => self.parse_drop_sequence(),
16916 TokenType::Trigger => self.parse_drop_trigger(),
16917 TokenType::Type => self.parse_drop_type(),
16918 TokenType::Domain => {
16919 self.skip();
16921 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
16922 let name = self.parse_table_ref()?;
16923 let cascade = self.match_token(TokenType::Cascade);
16924 if !cascade {
16925 self.match_token(TokenType::Restrict);
16926 }
16927 Ok(Expression::DropType(Box::new(DropType {
16928 name,
16929 if_exists,
16930 cascade,
16931 })))
16932 }
16933 TokenType::Namespace => {
16934 self.skip();
16936 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
16937 let mut name_parts = vec![self.expect_identifier()?];
16939 while self.match_token(TokenType::Dot) {
16940 name_parts.push(self.expect_identifier()?);
16941 }
16942 let name = Identifier::new(name_parts.join("."));
16943 let cascade = self.match_token(TokenType::Cascade);
16944 if !cascade {
16945 self.match_token(TokenType::Restrict);
16946 }
16947 Ok(Expression::DropNamespace(Box::new(DropNamespace {
16948 name,
16949 if_exists,
16950 cascade,
16951 })))
16952 }
16953 _ => {
16954 if matches!(
16957 self.config.dialect,
16958 Some(crate::dialects::DialectType::ClickHouse)
16959 ) {
16960 let text_upper = self.peek().text.to_ascii_uppercase();
16961 if matches!(
16962 text_upper.as_str(),
16963 "DICTIONARY"
16964 | "USER"
16965 | "QUOTA"
16966 | "ROLE"
16967 | "ROW"
16968 | "POLICY"
16969 | "NAMED"
16970 | "WORKLOAD"
16971 | "RESOURCE"
16972 | "PROFILE"
16973 ) || self.check(TokenType::Settings)
16974 || self.check(TokenType::Partition)
16975 {
16976 self.skip(); let mut tokens: Vec<(String, TokenType)> = vec![
16978 ("DROP".to_string(), TokenType::Var),
16979 (
16980 self.previous().text.to_ascii_uppercase(),
16981 self.previous().token_type,
16982 ),
16983 ];
16984 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
16985 let token = self.advance();
16986 let text = if token.token_type == TokenType::QuotedIdentifier {
16987 format!("\"{}\"", token.text)
16988 } else if token.token_type == TokenType::String {
16989 format!("'{}'", token.text)
16990 } else {
16991 token.text.clone()
16992 };
16993 tokens.push((text, token.token_type));
16994 }
16995 return Ok(Expression::Command(Box::new(Command {
16996 this: self.join_command_tokens(tokens),
16997 })));
16998 }
16999 }
17000 if matches!(
17002 self.config.dialect,
17003 Some(crate::dialects::DialectType::Snowflake)
17004 ) {
17005 let text_upper = self.peek().text.to_ascii_uppercase();
17006 let is_snowflake_drop = matches!(
17007 text_upper.as_str(),
17008 "STREAM"
17009 | "TASK"
17010 | "STAGE"
17011 | "WAREHOUSE"
17012 | "PIPE"
17013 | "INTEGRATION"
17014 | "TAG"
17015 | "NETWORK"
17016 | "SHARE"
17017 ) || (text_upper == "FILE"
17018 && self.current + 1 < self.tokens.len()
17019 && self.tokens[self.current + 1]
17020 .text
17021 .eq_ignore_ascii_case("FORMAT"));
17022 if is_snowflake_drop {
17023 self.skip(); let mut tokens: Vec<(String, TokenType)> = vec![
17025 ("DROP".to_string(), TokenType::Var),
17026 (
17027 self.previous().text.to_ascii_uppercase(),
17028 self.previous().token_type,
17029 ),
17030 ];
17031 if text_upper == "FILE" {
17033 let fmt = self.advance();
17034 tokens.push((fmt.text.to_ascii_uppercase(), fmt.token_type));
17035 }
17036 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
17037 let token = self.advance();
17038 let text = if token.token_type == TokenType::QuotedIdentifier {
17039 format!("\"{}\"", token.text)
17040 } else if token.token_type == TokenType::String {
17041 format!("'{}'", token.text)
17042 } else {
17043 token.text.clone()
17044 };
17045 tokens.push((text, token.token_type));
17046 }
17047 return Ok(Expression::Command(Box::new(Command {
17048 this: self.join_command_tokens(tokens),
17049 })));
17050 }
17051 }
17052 Err(self.parse_error(format!(
17053 "Expected TABLE, VIEW, INDEX, SCHEMA, DATABASE, FUNCTION, PROCEDURE, SEQUENCE, TRIGGER, TYPE, or NAMESPACE after DROP, got {:?}",
17054 self.peek().token_type
17055 )))
17056 }
17057 }
17058 }
17059
17060 fn parse_drop_table_with_iceberg(
17062 &mut self,
17063 leading_comments: Vec<String>,
17064 iceberg: bool,
17065 ) -> Result<Expression> {
17066 self.expect(TokenType::Table)?;
17067
17068 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
17069
17070 if !if_exists
17072 && matches!(
17073 self.config.dialect,
17074 Some(crate::dialects::DialectType::ClickHouse)
17075 )
17076 {
17077 if self.check(TokenType::If)
17078 && self.current + 1 < self.tokens.len()
17079 && self.tokens[self.current + 1]
17080 .text
17081 .eq_ignore_ascii_case("EMPTY")
17082 {
17083 self.skip(); self.skip(); }
17086 }
17087
17088 let mut names = Vec::new();
17090 loop {
17091 names.push(self.parse_table_ref()?);
17092 if !self.match_token(TokenType::Comma) {
17093 break;
17094 }
17095 }
17096
17097 let mut cascade = false;
17099 let mut cascade_constraints = false;
17100 let mut restrict = false;
17101 if self.match_token(TokenType::Cascade) {
17102 if self.match_identifier("CONSTRAINTS") {
17103 cascade_constraints = true;
17104 } else {
17105 cascade = true;
17106 }
17107 } else {
17108 restrict = self.match_token(TokenType::Restrict);
17109 }
17110
17111 let purge = self.match_identifier("PURGE");
17113
17114 if matches!(
17116 self.config.dialect,
17117 Some(crate::dialects::DialectType::ClickHouse)
17118 ) {
17119 let _ = self.parse_on_cluster_clause()?;
17120 }
17121
17122 let sync = if matches!(
17124 self.config.dialect,
17125 Some(crate::dialects::DialectType::ClickHouse)
17126 ) {
17127 let s = self.match_identifier("SYNC");
17128 self.match_identifier("NO");
17129 self.match_identifier("DELAY");
17130 s
17131 } else {
17132 false
17133 };
17134
17135 Ok(Expression::DropTable(Box::new(DropTable {
17136 names,
17137 if_exists,
17138 cascade,
17139 cascade_constraints,
17140 purge,
17141 leading_comments,
17142 object_id_args: None,
17143 sync,
17144 iceberg,
17145 restrict,
17146 })))
17147 }
17148
17149 fn parse_drop_view(&mut self, materialized: bool) -> Result<Expression> {
17151 self.expect(TokenType::View)?;
17152
17153 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
17154 let name = self.parse_table_ref()?;
17155
17156 if matches!(
17158 self.config.dialect,
17159 Some(crate::dialects::DialectType::ClickHouse)
17160 ) {
17161 let _ = self.parse_on_cluster_clause()?;
17162 self.match_identifier("SYNC");
17163 }
17164
17165 Ok(Expression::DropView(Box::new(DropView {
17166 name,
17167 if_exists,
17168 materialized,
17169 })))
17170 }
17171
17172 fn parse_drop_index(&mut self) -> Result<Expression> {
17174 self.expect(TokenType::Index)?;
17175
17176 let concurrently = self.match_identifier("CONCURRENTLY");
17178
17179 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
17180
17181 let mut name_parts = vec![self.expect_identifier()?];
17183 while self.match_token(TokenType::Dot) {
17184 name_parts.push(self.expect_identifier()?);
17185 }
17186 let name = Identifier::new(name_parts.join("."));
17187
17188 let table = if self.match_token(TokenType::On) {
17190 Some(self.parse_table_ref()?)
17191 } else {
17192 None
17193 };
17194
17195 Ok(Expression::DropIndex(Box::new(DropIndex {
17196 name,
17197 table,
17198 if_exists,
17199 concurrently,
17200 })))
17201 }
17202
17203 fn parse_alter(&mut self) -> Result<Expression> {
17205 self.expect(TokenType::Alter)?;
17206
17207 let alter_table_modifier = if self.check_identifier("ICEBERG") {
17209 self.skip();
17210 Some("ICEBERG".to_string())
17211 } else {
17212 None
17213 };
17214
17215 match self.peek().token_type {
17216 TokenType::Table => {
17217 self.skip();
17218 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
17220 let has_only = self.match_token(TokenType::Only);
17222 let mut name = self.parse_table_ref()?;
17223 if has_only {
17224 name.only = true;
17225 }
17226
17227 let on_cluster = self.parse_on_cluster_clause()?;
17229
17230 let partition = if self.match_token(TokenType::Partition) {
17232 self.expect(TokenType::LParen)?;
17233 let mut parts = Vec::new();
17234 loop {
17235 let key = self.expect_identifier()?;
17236 self.expect(TokenType::Eq)?;
17237 let value = self.parse_expression()?;
17238 parts.push((Identifier::new(key), value));
17239 if !self.match_token(TokenType::Comma) {
17240 break;
17241 }
17242 }
17243 self.expect(TokenType::RParen)?;
17244 Some(parts)
17245 } else {
17246 None
17247 };
17248
17249 let mut actions = Vec::new();
17250 let mut last_was_add_column = false;
17251 let mut with_check_modifier: Option<String> = None;
17252
17253 loop {
17254 if self.check_identifier("ALGORITHM") || self.check_identifier("LOCK") {
17258 break;
17259 }
17260
17261 if self.check(TokenType::With) {
17263 let saved = self.current;
17264 self.skip(); if self.check(TokenType::Check) {
17266 self.skip(); with_check_modifier = Some("WITH CHECK".to_string());
17268 } else if self.check_identifier("NOCHECK") {
17270 self.skip(); with_check_modifier = Some("WITH NOCHECK".to_string());
17272 } else {
17274 self.current = saved;
17276 }
17277 }
17278
17279 if last_was_add_column
17282 && !self.check(TokenType::Add)
17283 && !self.check(TokenType::Drop)
17284 && !self.check(TokenType::Alter)
17285 && !self.check(TokenType::Rename)
17286 && !self.check(TokenType::Set)
17287 && !self.check_identifier("MODIFY")
17288 && !self.check(TokenType::Delete)
17289 && !self.check(TokenType::Update)
17290 && !self.check_identifier("DETACH")
17291 && !self.check_identifier("ATTACH")
17292 && !self.check_identifier("FREEZE")
17293 && !self.check_identifier("CLEAR")
17294 && !self.check_identifier("MATERIALIZE")
17295 && !self.check(TokenType::Comment)
17296 && !self.check(TokenType::Replace)
17297 && !self.check_identifier("MOVE")
17298 && !self.check_identifier("REMOVE")
17299 && !self.check_identifier("APPLY")
17300 {
17301 self.match_token(TokenType::Column); let if_not_exists = self.match_keywords(&[
17304 TokenType::If,
17305 TokenType::Not,
17306 TokenType::Exists,
17307 ]);
17308 let col_def = self.parse_column_def()?;
17309 let position = if self.match_token(TokenType::First) {
17310 Some(ColumnPosition::First)
17311 } else if self.match_token(TokenType::After) {
17312 let after_col = self.expect_identifier()?;
17313 let after_name = if self.match_token(TokenType::Dot) {
17315 let field = self.expect_identifier()?;
17316 format!("{}.{}", after_col, field)
17317 } else {
17318 after_col
17319 };
17320 Some(ColumnPosition::After(Identifier::new(after_name)))
17321 } else {
17322 None
17323 };
17324 actions.push(AlterTableAction::AddColumn {
17325 column: col_def,
17326 if_not_exists,
17327 position,
17328 });
17329 } else {
17331 if self.check_identifier("ALGORITHM") || self.check_identifier("LOCK") {
17334 self.current -= 1; break;
17337 }
17338 let action = self.parse_alter_action()?;
17339 last_was_add_column = matches!(action, AlterTableAction::AddColumn { .. });
17340 actions.push(action);
17341 }
17342 if !self.match_token(TokenType::Comma) {
17343 break;
17344 }
17345 }
17346
17347 let mut algorithm = None;
17351 let mut lock = None;
17352 loop {
17353 if self.check_identifier("ALGORITHM") {
17355 self.skip();
17356 self.expect(TokenType::Eq)?;
17357 algorithm = Some(self.expect_identifier_or_keyword()?.to_ascii_uppercase());
17358 self.match_token(TokenType::Comma); } else if self.check_identifier("LOCK") {
17360 self.skip();
17361 self.expect(TokenType::Eq)?;
17362 lock = Some(self.expect_identifier_or_keyword()?.to_ascii_uppercase());
17363 self.match_token(TokenType::Comma); } else if self.match_token(TokenType::Comma) {
17365 if self.check_identifier("ALGORITHM") {
17367 self.skip();
17368 self.expect(TokenType::Eq)?;
17369 algorithm =
17370 Some(self.expect_identifier_or_keyword()?.to_ascii_uppercase());
17371 } else if self.check_identifier("LOCK") {
17372 self.skip();
17373 self.expect(TokenType::Eq)?;
17374 lock = Some(self.expect_identifier_or_keyword()?.to_ascii_uppercase());
17375 } else {
17376 self.current -= 1;
17377 break;
17378 }
17379 } else {
17380 break;
17381 }
17382 }
17383
17384 if matches!(
17387 self.config.dialect,
17388 Some(crate::dialects::DialectType::ClickHouse)
17389 ) && self.check(TokenType::Settings)
17390 {
17391 self.skip(); let _ = self.parse_settings_property()?;
17393 }
17394
17395 Ok(Expression::AlterTable(Box::new(AlterTable {
17396 name,
17397 actions,
17398 if_exists,
17399 algorithm,
17400 lock,
17401 with_check: with_check_modifier,
17402 partition,
17403 on_cluster,
17404 table_modifier: alter_table_modifier,
17405 })))
17406 }
17407 TokenType::View => self.parse_alter_view_with_modifiers(None, None, None),
17408 TokenType::Index => self.parse_alter_index(),
17409 TokenType::Sequence => self.parse_alter_sequence(),
17410 _ if self.check_identifier("SESSION") => {
17411 self.skip(); match self.parse_alter_session()? {
17414 Some(expr) => Ok(expr),
17415 None => {
17416 Ok(Expression::Command(Box::new(Command {
17418 this: "ALTER SESSION".to_string(),
17419 })))
17420 }
17421 }
17422 }
17423 _ => {
17424 let mut view_algorithm = None;
17427 let mut view_definer = None;
17428 let mut view_sql_security = None;
17429
17430 loop {
17431 if self.check_identifier("ALGORITHM") {
17432 self.skip();
17433 self.expect(TokenType::Eq)?;
17434 view_algorithm =
17435 Some(self.expect_identifier_or_keyword()?.to_ascii_uppercase());
17436 } else if self.check_identifier("DEFINER") {
17437 self.skip();
17438 self.expect(TokenType::Eq)?;
17439 let mut definer_str = String::new();
17441 if self.check(TokenType::String) {
17442 definer_str.push_str(&format!("'{}'", self.advance().text));
17443 } else {
17444 definer_str.push_str(&self.expect_identifier_or_keyword()?);
17445 }
17446 if !self.is_at_end() && self.peek().text == "@" {
17448 definer_str.push_str(&self.advance().text);
17449 if self.check(TokenType::String) {
17450 definer_str.push_str(&format!("'{}'", self.advance().text));
17451 } else if !self.is_at_end() {
17452 definer_str.push_str(&self.advance().text);
17453 }
17454 }
17455 view_definer = Some(definer_str);
17456 } else if self.check_identifier("SQL") {
17457 self.skip();
17458 if self.match_identifier("SECURITY") {
17459 self.match_token(TokenType::Eq);
17460 view_sql_security =
17461 Some(self.expect_identifier_or_keyword()?.to_ascii_uppercase());
17462 }
17463 } else {
17464 break;
17465 }
17466 }
17467
17468 if self.check(TokenType::View) {
17469 self.parse_alter_view_with_modifiers(
17470 view_algorithm,
17471 view_definer,
17472 view_sql_security,
17473 )
17474 } else {
17475 let start = self.current;
17477 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
17478 self.skip();
17479 }
17480 let sql = self.tokens_to_sql(start, self.current);
17481 Ok(Expression::Raw(Raw {
17482 sql: format!("ALTER {}", sql),
17483 }))
17484 }
17485 }
17486 }
17487 }
17488
17489 fn parse_alter_action(&mut self) -> Result<AlterTableAction> {
17491 if self.match_token(TokenType::Add) {
17492 if matches!(
17497 self.config.dialect,
17498 Some(crate::dialects::DialectType::ClickHouse)
17499 ) && (self.check(TokenType::Index)
17500 || self.check_identifier("PROJECTION")
17501 || self.check_identifier("STATISTICS"))
17502 {
17503 let is_statistics = self.check_identifier("STATISTICS");
17504 let mut tokens: Vec<(String, TokenType)> =
17505 vec![("ADD".to_string(), TokenType::Add)];
17506 let mut paren_depth = 0i32;
17507 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
17508 if self.check(TokenType::Comma) && paren_depth == 0 && !is_statistics {
17510 break;
17511 }
17512 let token = self.advance();
17513 if token.token_type == TokenType::LParen {
17514 paren_depth += 1;
17515 }
17516 if token.token_type == TokenType::RParen {
17517 paren_depth -= 1;
17518 }
17519 let text = if token.token_type == TokenType::QuotedIdentifier {
17520 format!("\"{}\"", token.text)
17521 } else if token.token_type == TokenType::String {
17522 format!("'{}'", token.text)
17523 } else {
17524 token.text.clone()
17525 };
17526 tokens.push((text, token.token_type));
17527 }
17528 return Ok(AlterTableAction::Raw {
17529 sql: self.join_command_tokens(tokens),
17530 });
17531 }
17532 if self.match_token(TokenType::Constraint) {
17534 let name = Some(self.expect_identifier_with_quoted()?);
17536 let constraint = self.parse_constraint_definition(name)?;
17537 Ok(AlterTableAction::AddConstraint(constraint))
17538 } else if self.check(TokenType::PrimaryKey)
17539 || self.check(TokenType::ForeignKey)
17540 || self.check(TokenType::Check)
17541 {
17542 let constraint = self.parse_table_constraint()?;
17544 Ok(AlterTableAction::AddConstraint(constraint))
17545 } else if self.check(TokenType::Index)
17546 || self.check(TokenType::Key)
17547 || self.check(TokenType::Unique)
17548 || self.check_identifier("FULLTEXT")
17549 || self.check_identifier("SPATIAL")
17550 {
17551 let kind = if self.match_token(TokenType::Unique) {
17553 Some("UNIQUE".to_string())
17554 } else if self.match_identifier("FULLTEXT") {
17555 Some("FULLTEXT".to_string())
17556 } else if self.match_identifier("SPATIAL") {
17557 Some("SPATIAL".to_string())
17558 } else {
17559 None
17560 };
17561 let use_key_keyword = if self.match_token(TokenType::Key) {
17563 true
17564 } else {
17565 self.match_token(TokenType::Index);
17566 false
17567 };
17568
17569 let name = if !self.check(TokenType::LParen) && !self.check(TokenType::Using) {
17571 Some(self.expect_identifier_with_quoted()?)
17572 } else {
17573 None
17574 };
17575
17576 self.expect(TokenType::LParen)?;
17578 let columns = self.parse_index_identifier_list()?;
17579 self.expect(TokenType::RParen)?;
17580
17581 let modifiers = self.parse_constraint_modifiers();
17583
17584 Ok(AlterTableAction::AddConstraint(TableConstraint::Index {
17585 name,
17586 columns,
17587 kind,
17588 modifiers,
17589 use_key_keyword,
17590 expression: None,
17591 index_type: None,
17592 granularity: None,
17593 }))
17594 } else if self.match_identifier("COLUMNS") {
17595 self.expect(TokenType::LParen)?;
17597 let mut columns = Vec::new();
17598 loop {
17599 let col_def = self.parse_column_def()?;
17600 columns.push(col_def);
17601 if !self.match_token(TokenType::Comma) {
17602 break;
17603 }
17604 }
17605 self.expect(TokenType::RParen)?;
17606 let cascade = self.match_token(TokenType::Cascade);
17607 Ok(AlterTableAction::AddColumns { columns, cascade })
17608 } else if self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]) {
17609 if self.match_token(TokenType::Partition) {
17612 self.expect(TokenType::LParen)?;
17613 let mut partition_exprs = Vec::new();
17614 loop {
17615 if let Some(expr) = self.parse_conjunction()? {
17616 partition_exprs.push(expr);
17617 }
17618 if !self.match_token(TokenType::Comma) {
17619 break;
17620 }
17621 }
17622 self.expect(TokenType::RParen)?;
17623 let partition =
17624 Expression::Partition(Box::new(crate::expressions::Partition {
17625 expressions: partition_exprs,
17626 subpartition: false,
17627 }));
17628 let location = if self.match_text_seq(&["LOCATION"]) {
17629 self.parse_property()?
17630 } else {
17631 None
17632 };
17633 return Ok(AlterTableAction::AddPartition {
17634 partition,
17635 if_not_exists: true,
17636 location,
17637 });
17638 } else {
17639 let col_def = self.parse_column_def()?;
17642 return Ok(AlterTableAction::AddColumn {
17643 column: col_def,
17644 if_not_exists: true,
17645 position: None,
17646 });
17647 }
17648 } else if self.check(TokenType::Partition) {
17649 self.skip(); self.expect(TokenType::LParen)?;
17652 let mut partition_exprs = Vec::new();
17653 loop {
17654 if let Some(expr) = self.parse_conjunction()? {
17655 partition_exprs.push(expr);
17656 }
17657 if !self.match_token(TokenType::Comma) {
17658 break;
17659 }
17660 }
17661 self.expect(TokenType::RParen)?;
17662 let partition = Expression::Partition(Box::new(crate::expressions::Partition {
17663 expressions: partition_exprs,
17664 subpartition: false,
17665 }));
17666 let location = if self.match_text_seq(&["LOCATION"]) {
17667 Some(self.parse_primary()?)
17669 } else {
17670 None
17671 };
17672 Ok(AlterTableAction::AddPartition {
17673 partition,
17674 if_not_exists: false,
17675 location,
17676 })
17677 } else {
17678 let has_column_keyword = self.match_token(TokenType::Column); if !has_column_keyword && self.check(TokenType::LParen) {
17683 self.skip(); let mut columns = Vec::new();
17686 loop {
17687 let col_def = self.parse_column_def()?;
17688 columns.push(col_def);
17689 if !self.match_token(TokenType::Comma) {
17690 break;
17691 }
17692 }
17693 self.expect(TokenType::RParen)?;
17694 Ok(AlterTableAction::AddColumns {
17696 columns,
17697 cascade: false,
17698 })
17699 } else {
17700 let if_not_exists =
17702 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
17703 let col_def = self.parse_column_def()?;
17704 let position = if self.match_token(TokenType::First) {
17706 Some(ColumnPosition::First)
17707 } else if self.match_token(TokenType::After) {
17708 let after_col = self.expect_identifier()?;
17709 let after_name = if self.match_token(TokenType::Dot) {
17711 let field = self.expect_identifier()?;
17712 format!("{}.{}", after_col, field)
17713 } else {
17714 after_col
17715 };
17716 Some(ColumnPosition::After(Identifier::new(after_name)))
17717 } else {
17718 None
17719 };
17720 Ok(AlterTableAction::AddColumn {
17721 column: col_def,
17722 if_not_exists,
17723 position,
17724 })
17725 }
17726 }
17727 } else if self.match_token(TokenType::Drop) {
17728 if matches!(
17731 self.config.dialect,
17732 Some(crate::dialects::DialectType::ClickHouse)
17733 ) && (self.check(TokenType::Index)
17734 || self.check_identifier("PROJECTION")
17735 || self.check_identifier("STATISTICS")
17736 || self.check_identifier("DETACHED")
17737 || self.check_identifier("PART"))
17738 {
17739 let is_statistics = self.check_identifier("STATISTICS");
17740 let mut tokens: Vec<(String, TokenType)> =
17741 vec![("DROP".to_string(), TokenType::Drop)];
17742 let mut paren_depth = 0i32;
17743 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
17744 if self.check(TokenType::Comma) && paren_depth == 0 && !is_statistics {
17745 break;
17746 }
17747 let token = self.advance();
17748 if token.token_type == TokenType::LParen {
17749 paren_depth += 1;
17750 }
17751 if token.token_type == TokenType::RParen {
17752 paren_depth -= 1;
17753 }
17754 let text = if token.token_type == TokenType::QuotedIdentifier {
17755 format!("\"{}\"", token.text)
17756 } else if token.token_type == TokenType::String {
17757 format!("'{}'", token.text)
17758 } else {
17759 token.text.clone()
17760 };
17761 tokens.push((text, token.token_type));
17762 }
17763 return Ok(AlterTableAction::Raw {
17764 sql: self.join_command_tokens(tokens),
17765 });
17766 }
17767 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
17769
17770 if self.match_token(TokenType::Partition) {
17771 let mut partitions = Vec::new();
17775 loop {
17776 if self.check(TokenType::LParen) {
17777 let is_ch_expr = matches!(
17782 self.config.dialect,
17783 Some(crate::dialects::DialectType::ClickHouse)
17784 ) && self.current + 1 < self.tokens.len()
17785 && (self.tokens[self.current + 1].token_type == TokenType::String
17786 || self.tokens[self.current + 1].token_type == TokenType::Number
17787 || self.tokens[self.current + 1].token_type == TokenType::LParen
17788 || (self.current + 2 < self.tokens.len()
17789 && self.tokens[self.current + 2].token_type != TokenType::Eq));
17790 if is_ch_expr {
17791 let expr = self.parse_expression()?;
17793 partitions.push(vec![(Identifier::new("__expr__".to_string()), expr)]);
17794 } else {
17795 self.skip(); let mut parts = Vec::new();
17797 loop {
17798 let key = self.expect_identifier()?;
17799 self.expect(TokenType::Eq)?;
17800 let value = self.parse_expression()?;
17801 parts.push((Identifier::new(key), value));
17802 if !self.match_token(TokenType::Comma) {
17803 break;
17804 }
17805 }
17806 self.expect(TokenType::RParen)?;
17807 partitions.push(parts);
17808 }
17809 } else if self.match_text_seq(&["ALL"]) {
17810 partitions.push(vec![(
17812 Identifier::new("ALL".to_string()),
17813 Expression::Boolean(BooleanLiteral { value: true }),
17814 )]);
17815 } else if self.match_text_seq(&["ID"]) {
17816 let id_val = self.parse_expression()?;
17818 partitions.push(vec![(Identifier::new("ID".to_string()), id_val)]);
17819 } else {
17820 let expr = self.parse_expression()?;
17822 partitions.push(vec![(Identifier::new("__expr__".to_string()), expr)]);
17823 }
17824 if self.match_token(TokenType::Comma) {
17826 if !self.match_token(TokenType::Partition) {
17827 break;
17828 }
17829 } else {
17830 break;
17831 }
17832 }
17833 Ok(AlterTableAction::DropPartition {
17834 partitions,
17835 if_exists,
17836 })
17837 } else if self.match_token(TokenType::Column) {
17838 let if_exists =
17841 if_exists || self.match_keywords(&[TokenType::If, TokenType::Exists]);
17842 let mut name = self.expect_identifier_with_quoted()?;
17843 if matches!(
17845 self.config.dialect,
17846 Some(crate::dialects::DialectType::ClickHouse)
17847 ) && self.match_token(TokenType::Dot)
17848 {
17849 let sub = self.expect_identifier_with_quoted()?;
17850 name.name = format!("{}.{}", name.name, sub.name);
17851 }
17852 let cascade = self.match_token(TokenType::Cascade);
17853 Ok(AlterTableAction::DropColumn {
17854 name,
17855 if_exists,
17856 cascade,
17857 })
17858 } else if self.match_token(TokenType::Constraint) {
17859 let name = self.expect_identifier_with_quoted()?;
17861 Ok(AlterTableAction::DropConstraint { name, if_exists })
17862 } else if self.match_keywords(&[TokenType::ForeignKey, TokenType::Key]) {
17863 let name = self.expect_identifier_with_quoted()?;
17865 Ok(AlterTableAction::DropForeignKey { name })
17866 } else if self.check_identifier("COLUMNS") && self.check_next(TokenType::LParen) {
17867 self.skip(); self.expect(TokenType::LParen)?;
17870 let mut names = Vec::new();
17871 loop {
17872 let name = self.expect_identifier_with_quoted()?;
17873 names.push(name);
17874 if !self.match_token(TokenType::Comma) {
17875 break;
17876 }
17877 }
17878 self.expect(TokenType::RParen)?;
17879 Ok(AlterTableAction::DropColumns { names })
17880 } else {
17881 let mut name = self.expect_identifier_with_quoted()?;
17883 if matches!(
17885 self.config.dialect,
17886 Some(crate::dialects::DialectType::ClickHouse)
17887 ) && self.match_token(TokenType::Dot)
17888 {
17889 let sub = self.expect_identifier_with_quoted()?;
17890 name.name = format!("{}.{}", name.name, sub.name);
17891 }
17892 let cascade = self.match_token(TokenType::Cascade);
17893 Ok(AlterTableAction::DropColumn {
17894 name,
17895 if_exists,
17896 cascade,
17897 })
17898 }
17899 } else if self.match_token(TokenType::Rename) {
17900 if self.match_token(TokenType::Column) {
17901 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
17903 let mut old_name = self.expect_identifier_or_safe_keyword_with_quoted()?;
17904 if matches!(
17906 self.config.dialect,
17907 Some(crate::dialects::DialectType::ClickHouse)
17908 ) && self.match_token(TokenType::Dot)
17909 {
17910 let field = self.expect_identifier_with_quoted()?;
17911 old_name = Identifier {
17912 name: format!("{}.{}", old_name.name, field.name),
17913 quoted: false,
17914 trailing_comments: Vec::new(),
17915 span: None,
17916 };
17917 }
17918 self.expect(TokenType::To)?;
17919 let mut new_name = self.expect_identifier_or_safe_keyword_with_quoted()?;
17920 if matches!(
17922 self.config.dialect,
17923 Some(crate::dialects::DialectType::ClickHouse)
17924 ) && self.match_token(TokenType::Dot)
17925 {
17926 let field = self.expect_identifier_or_safe_keyword_with_quoted()?;
17927 new_name = Identifier {
17928 name: format!("{}.{}", new_name.name, field.name),
17929 quoted: false,
17930 trailing_comments: Vec::new(),
17931 span: None,
17932 };
17933 }
17934 Ok(AlterTableAction::RenameColumn {
17935 old_name,
17936 new_name,
17937 if_exists,
17938 })
17939 } else if self.match_token(TokenType::To) {
17940 let new_name = self.parse_table_ref()?;
17942 Ok(AlterTableAction::RenameTable(new_name))
17943 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
17944 let first_name = self.expect_identifier_with_quoted()?;
17947 if self.match_token(TokenType::To) {
17948 let new_name = self.expect_identifier_with_quoted()?;
17949 Ok(AlterTableAction::RenameColumn {
17950 old_name: first_name,
17951 new_name,
17952 if_exists: false,
17953 })
17954 } else {
17955 Ok(AlterTableAction::RenameTable(TableRef::new(
17957 first_name.name,
17958 )))
17959 }
17960 } else {
17961 Err(self.parse_error("Expected COLUMN or TO after RENAME"))
17962 }
17963 } else if self.match_token(TokenType::Alter) {
17964 if self.match_token(TokenType::Index) {
17966 let name = self.expect_identifier_with_quoted()?;
17967 let visible = if self.match_identifier("VISIBLE") {
17968 true
17969 } else if self.match_identifier("INVISIBLE") {
17970 false
17971 } else {
17972 return Err(
17973 self.parse_error("Expected VISIBLE or INVISIBLE after ALTER INDEX name")
17974 );
17975 };
17976 Ok(AlterTableAction::AlterIndex { name, visible })
17977 } else if self.check_identifier("SORTKEY") {
17978 self.skip(); if self.match_texts(&["AUTO", "NONE"]) {
17981 let style = self.previous().text.to_ascii_uppercase();
17982 Ok(AlterTableAction::AlterSortKey {
17983 this: Some(style),
17984 expressions: Vec::new(),
17985 compound: false,
17986 })
17987 } else if self.check(TokenType::LParen) {
17988 let wrapped = self.parse_wrapped_id_vars()?;
17990 let expressions = if let Some(Expression::Tuple(t)) = wrapped {
17991 t.expressions
17992 } else {
17993 Vec::new()
17994 };
17995 Ok(AlterTableAction::AlterSortKey {
17996 this: None,
17997 expressions,
17998 compound: false,
17999 })
18000 } else {
18001 Err(self.parse_error("Expected AUTO, NONE, or (columns) after SORTKEY"))
18002 }
18003 } else if self.check_identifier("COMPOUND") {
18004 self.skip(); if !self.match_identifier("SORTKEY") {
18007 return Err(self.parse_error("Expected SORTKEY after COMPOUND"));
18008 }
18009 if self.check(TokenType::LParen) {
18010 let wrapped = self.parse_wrapped_id_vars()?;
18011 let expressions = if let Some(Expression::Tuple(t)) = wrapped {
18012 t.expressions
18013 } else {
18014 Vec::new()
18015 };
18016 Ok(AlterTableAction::AlterSortKey {
18017 this: None,
18018 expressions,
18019 compound: true,
18020 })
18021 } else {
18022 Err(self.parse_error("Expected (columns) after COMPOUND SORTKEY"))
18023 }
18024 } else if self.check_identifier("DISTSTYLE") {
18025 self.skip(); if self.match_texts(&["ALL", "EVEN", "AUTO"]) {
18028 let style = self.previous().text.to_ascii_uppercase();
18029 Ok(AlterTableAction::AlterDistStyle {
18030 style,
18031 distkey: None,
18032 })
18033 } else if self.match_token(TokenType::Key) || self.match_identifier("KEY") {
18034 if !self.match_identifier("DISTKEY") {
18036 return Err(self.parse_error("Expected DISTKEY after DISTSTYLE KEY"));
18037 }
18038 let col = self.expect_identifier_with_quoted()?;
18039 Ok(AlterTableAction::AlterDistStyle {
18040 style: "KEY".to_string(),
18041 distkey: Some(col),
18042 })
18043 } else {
18044 Err(self.parse_error("Expected ALL, EVEN, AUTO, or KEY after DISTSTYLE"))
18045 }
18046 } else if self.check_identifier("DISTKEY") {
18047 self.skip(); let col = self.expect_identifier_with_quoted()?;
18050 Ok(AlterTableAction::AlterDistStyle {
18051 style: "KEY".to_string(),
18052 distkey: Some(col),
18053 })
18054 } else {
18055 self.match_token(TokenType::Column); let name = self.expect_identifier_with_quoted()?;
18058 let action = self.parse_alter_column_action()?;
18059 Ok(AlterTableAction::AlterColumn {
18060 name,
18061 action,
18062 use_modify_keyword: false,
18063 })
18064 }
18065 } else if self.match_identifier("MODIFY") {
18066 if matches!(
18071 self.config.dialect,
18072 Some(crate::dialects::DialectType::ClickHouse)
18073 ) {
18074 let is_setting =
18076 self.check(TokenType::Settings) || self.check_identifier("SETTING");
18077 let mut tokens: Vec<(String, TokenType)> =
18078 vec![("MODIFY".to_string(), TokenType::Var)];
18079 let mut paren_depth = 0i32;
18080 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
18081 if self.check(TokenType::Comma) && paren_depth == 0 && !is_setting {
18082 break;
18083 }
18084 let token = self.advance();
18085 if token.token_type == TokenType::LParen {
18086 paren_depth += 1;
18087 }
18088 if token.token_type == TokenType::RParen {
18089 paren_depth -= 1;
18090 }
18091 let text = if token.token_type == TokenType::QuotedIdentifier {
18092 format!("\"{}\"", token.text)
18093 } else if token.token_type == TokenType::String {
18094 format!("'{}'", token.text)
18095 } else {
18096 token.text.clone()
18097 };
18098 tokens.push((text, token.token_type));
18099 }
18100 return Ok(AlterTableAction::Raw {
18101 sql: self.join_command_tokens(tokens),
18102 });
18103 }
18104 self.match_token(TokenType::Column); let name = Identifier::new(self.expect_identifier()?);
18107 let data_type = self.parse_data_type()?;
18109 let collate = if self.match_token(TokenType::Collate) {
18111 if self.check(TokenType::String) {
18112 Some(self.advance().text)
18113 } else if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
18114 Some(self.advance().text)
18115 } else {
18116 None
18117 }
18118 } else {
18119 None
18120 };
18121 Ok(AlterTableAction::AlterColumn {
18122 name,
18123 action: AlterColumnAction::SetDataType {
18124 data_type,
18125 using: None,
18126 collate,
18127 },
18128 use_modify_keyword: true,
18129 })
18130 } else if self.match_identifier("CHANGE") {
18131 self.match_token(TokenType::Column); let old_name = Identifier::new(self.expect_identifier()?);
18135 let new_name = Identifier::new(self.expect_identifier()?);
18136 let data_type = if !self.is_at_end()
18138 && !self.check(TokenType::Comment)
18139 && !self.check(TokenType::Comma)
18140 && !self.check(TokenType::Semicolon)
18141 {
18142 let tok = self.peek();
18144 if tok.token_type.is_keyword()
18145 || tok.token_type == TokenType::Identifier
18146 || tok.token_type == TokenType::Var
18147 {
18148 Some(self.parse_data_type()?)
18149 } else {
18150 None
18151 }
18152 } else {
18153 None
18154 };
18155 let comment = if self.match_token(TokenType::Comment) {
18156 Some(self.expect_string()?)
18157 } else {
18158 None
18159 };
18160 let cascade = self.match_text_seq(&["CASCADE"]);
18161 if !cascade {
18163 self.match_text_seq(&["RESTRICT"]);
18164 }
18165 Ok(AlterTableAction::ChangeColumn {
18166 old_name,
18167 new_name,
18168 data_type,
18169 comment,
18170 cascade,
18171 })
18172 } else if self.match_token(TokenType::Constraint) {
18173 let name = Some(self.expect_identifier_with_quoted()?);
18176 let constraint = self.parse_constraint_definition(name)?;
18177 Ok(AlterTableAction::AddConstraint(constraint))
18178 } else if self.check(TokenType::PrimaryKey)
18179 || self.check(TokenType::ForeignKey)
18180 || self.check(TokenType::Unique)
18181 {
18182 let constraint = self.parse_table_constraint()?;
18184 Ok(AlterTableAction::AddConstraint(constraint))
18185 } else if self.match_token(TokenType::Delete) {
18186 self.expect(TokenType::Where)?;
18188 let where_clause = self.parse_expression()?;
18189 Ok(AlterTableAction::Delete { where_clause })
18190 } else if self.match_keyword("SWAP") {
18191 self.expect(TokenType::With)?;
18193 let target = self.parse_table_ref()?;
18194 Ok(AlterTableAction::SwapWith(target))
18195 } else if self.match_token(TokenType::Set) {
18196 if self.check(TokenType::LParen) {
18198 self.skip(); let mut expressions = Vec::new();
18200 loop {
18201 if self.check(TokenType::RParen) {
18202 break;
18203 }
18204 if self.check_identifier("SYSTEM_VERSIONING") {
18205 let expr = self.parse_system_versioning_option()?;
18206 expressions.push(expr);
18207 } else if self.check_identifier("DATA_DELETION") {
18208 let expr = self.parse_data_deletion_option()?;
18209 expressions.push(expr);
18210 } else {
18211 let expr = self.parse_expression()?;
18213 expressions.push(expr);
18214 }
18215 if !self.match_token(TokenType::Comma) {
18216 break;
18217 }
18218 }
18219 self.expect(TokenType::RParen)?;
18220 Ok(AlterTableAction::SetOptions { expressions })
18221 } else if self.match_keyword("TAG") {
18222 let mut tags = Vec::new();
18224 loop {
18225 let mut key = self.expect_identifier_or_keyword()?;
18227 while self.match_token(TokenType::Dot) {
18228 let next = self.expect_identifier_or_keyword()?;
18229 key = format!("{}.{}", key, next);
18230 }
18231 self.expect(TokenType::Eq)?;
18232 let value = self.parse_primary()?;
18233 tags.push((key, value));
18234 if !self.match_token(TokenType::Comma) {
18235 break;
18236 }
18237 }
18238 Ok(AlterTableAction::SetTag { expressions: tags })
18239 } else if self.check_identifier("LOGGED") {
18240 self.skip();
18242 Ok(AlterTableAction::SetAttribute {
18243 attribute: "LOGGED".to_string(),
18244 })
18245 } else if self.check_identifier("UNLOGGED") {
18246 self.skip();
18248 Ok(AlterTableAction::SetAttribute {
18249 attribute: "UNLOGGED".to_string(),
18250 })
18251 } else if self.match_identifier("WITHOUT") {
18252 let what = self.expect_identifier_or_keyword()?;
18254 Ok(AlterTableAction::SetAttribute {
18255 attribute: format!("WITHOUT {}", what),
18256 })
18257 } else if self.check_identifier("ACCESS") {
18258 self.skip();
18260 if !self.match_identifier("METHOD") {
18262 return Err(self.parse_error("Expected METHOD after ACCESS"));
18263 }
18264 let method = self.expect_identifier_or_keyword()?;
18265 Ok(AlterTableAction::SetAttribute {
18266 attribute: format!("ACCESS METHOD {}", method),
18267 })
18268 } else if self.check_identifier("TABLESPACE") {
18269 self.skip();
18271 let name = self.expect_identifier_or_keyword()?;
18272 Ok(AlterTableAction::SetAttribute {
18273 attribute: format!("TABLESPACE {}", name),
18274 })
18275 } else if self.check_identifier("STAGE_FILE_FORMAT") {
18276 self.skip();
18278 let options = self.parse_wrapped_options()?;
18279 Ok(AlterTableAction::SetStageFileFormat { options })
18280 } else if self.check_identifier("STAGE_COPY_OPTIONS") {
18281 self.skip();
18283 let options = self.parse_wrapped_options()?;
18284 Ok(AlterTableAction::SetStageCopyOptions { options })
18285 } else if self.match_token(TokenType::Authorization) {
18286 let mut auth_text = String::new();
18288 if self.match_texts(&["ROLE"]) {
18289 auth_text.push_str("ROLE ");
18290 }
18291 let user = self.expect_identifier_or_keyword()?;
18292 auth_text.push_str(&user);
18293 Ok(AlterTableAction::SetAttribute {
18294 attribute: format!("AUTHORIZATION {}", auth_text),
18295 })
18296 } else if self.match_identifier("PROPERTIES") {
18297 let mut properties = Vec::new();
18299 loop {
18300 let key = if self.check(TokenType::String) {
18302 self.expect_string()?
18303 } else {
18304 self.expect_identifier_or_keyword()?
18305 };
18306 self.expect(TokenType::Eq)?;
18307 let value = if self.match_token(TokenType::Default) {
18309 Expression::Var(Box::new(crate::expressions::Var {
18311 this: "DEFAULT".to_string(),
18312 }))
18313 } else {
18314 self.parse_expression()?
18315 };
18316 properties.push((key, value));
18317 if !self.match_token(TokenType::Comma) {
18318 break;
18319 }
18320 }
18321 Ok(AlterTableAction::SetProperty { properties })
18322 } else if self.match_text_seq(&["TABLE", "PROPERTIES"]) {
18323 self.expect(TokenType::LParen)?;
18325 let mut properties = Vec::new();
18326 loop {
18327 if self.check(TokenType::RParen) {
18328 break;
18329 }
18330 let key = self.parse_primary()?;
18332 self.expect(TokenType::Eq)?;
18333 let value = self.parse_primary()?;
18335 properties.push((key, value));
18336 if !self.match_token(TokenType::Comma) {
18337 break;
18338 }
18339 }
18340 self.expect(TokenType::RParen)?;
18341 Ok(AlterTableAction::SetTableProperties { properties })
18342 } else if self.match_text_seq(&["LOCATION"]) {
18343 let location = self.expect_string()?;
18345 Ok(AlterTableAction::SetLocation { location })
18346 } else if self.match_text_seq(&["FILE", "FORMAT"]) {
18347 let format = self.expect_identifier_or_keyword()?;
18349 Ok(AlterTableAction::SetFileFormat { format })
18350 } else {
18351 let mut properties = Vec::new();
18353 loop {
18354 let key = self.expect_identifier_or_keyword()?;
18355 self.expect(TokenType::Eq)?;
18356 let value = self.parse_expression()?;
18357 properties.push((key, value));
18358 if !self.match_token(TokenType::Comma) {
18359 break;
18360 }
18361 }
18362 Ok(AlterTableAction::SetProperty { properties })
18363 }
18364 } else if self.match_keyword("UNSET") {
18365 if self.match_keyword("TAG") {
18367 let mut names = Vec::new();
18369 loop {
18370 let mut name = self.expect_identifier_or_keyword()?;
18371 while self.match_token(TokenType::Dot) {
18372 let next = self.expect_identifier_or_keyword()?;
18373 name = format!("{}.{}", name, next);
18374 }
18375 names.push(name);
18376 if !self.match_token(TokenType::Comma) {
18377 break;
18378 }
18379 }
18380 Ok(AlterTableAction::UnsetTag { names })
18381 } else {
18382 let mut properties = Vec::new();
18384 loop {
18385 let name = self.expect_identifier_or_keyword()?;
18386 properties.push(name);
18387 if !self.match_token(TokenType::Comma) {
18388 break;
18389 }
18390 }
18391 Ok(AlterTableAction::UnsetProperty { properties })
18392 }
18393 } else if self.match_keyword("CLUSTER") {
18394 self.expect(TokenType::By)?;
18396 self.expect(TokenType::LParen)?;
18397 let ordered = self.parse_order_by_list()?;
18399 let expressions: Vec<Expression> = ordered
18401 .into_iter()
18402 .map(|o| Expression::Ordered(Box::new(o)))
18403 .collect();
18404 self.expect(TokenType::RParen)?;
18405 Ok(AlterTableAction::ClusterBy { expressions })
18406 } else if self.match_token(TokenType::Replace) {
18407 if self.match_token(TokenType::Partition) {
18409 let partition_expr = if self.match_text_seq(&["ALL"]) {
18410 Expression::Identifier(Identifier::new("ALL".to_string()))
18411 } else if self.match_text_seq(&["ID"]) {
18412 let id_val = self.parse_expression()?;
18413 let id_str = match &id_val {
18415 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
18416 let Literal::String(s) = lit.as_ref() else {
18417 unreachable!()
18418 };
18419 format!("ID '{}'", s)
18420 }
18421 _ => format!("ID {}", "?"),
18422 };
18423 Expression::Raw(Raw { sql: id_str })
18424 } else {
18425 self.parse_expression()?
18426 };
18427 let source = if self.match_token(TokenType::From) {
18428 let tref = self.parse_table_ref()?;
18429 Some(Box::new(Expression::Table(Box::new(tref))))
18430 } else {
18431 None
18432 };
18433 Ok(AlterTableAction::ReplacePartition {
18434 partition: partition_expr,
18435 source,
18436 })
18437 } else {
18438 Err(self.parse_error("Expected PARTITION after REPLACE in ALTER TABLE"))
18439 }
18440 } else if matches!(
18441 self.config.dialect,
18442 Some(crate::dialects::DialectType::ClickHouse)
18443 ) {
18444 {
18450 let keyword = self.advance().text.clone();
18451 let mut tokens: Vec<(String, TokenType)> = vec![(keyword, TokenType::Var)];
18452 let mut paren_depth = 0i32;
18453 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
18454 if self.check(TokenType::Comma) && paren_depth == 0 {
18456 break;
18457 }
18458 let token = self.advance();
18459 if token.token_type == TokenType::LParen {
18460 paren_depth += 1;
18461 }
18462 if token.token_type == TokenType::RParen {
18463 paren_depth -= 1;
18464 }
18465 let text = if token.token_type == TokenType::QuotedIdentifier {
18466 format!("\"{}\"", token.text)
18467 } else if token.token_type == TokenType::String {
18468 format!("'{}'", token.text)
18469 } else {
18470 token.text.clone()
18471 };
18472 tokens.push((text, token.token_type));
18473 }
18474 Ok(AlterTableAction::Raw {
18475 sql: self.join_command_tokens(tokens),
18476 })
18477 }
18478 } else if self.check_identifier("REORGANIZE")
18479 || self.check_identifier("COALESCE")
18480 || self.check_identifier("EXCHANGE")
18481 || self.check_identifier("ANALYZE")
18482 || self.check_identifier("OPTIMIZE")
18483 || self.check_identifier("REBUILD")
18484 || self.check_identifier("REPAIR")
18485 || self.check_identifier("DISCARD")
18486 || self.check_identifier("IMPORT")
18487 {
18488 let keyword = self.advance().text.clone();
18491 let mut tokens: Vec<(String, TokenType)> = vec![(keyword, TokenType::Var)];
18492 let mut paren_depth = 0i32;
18493 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
18494 if self.check(TokenType::Comma) && paren_depth == 0 {
18495 break;
18496 }
18497 let token = self.advance();
18498 if token.token_type == TokenType::LParen {
18499 paren_depth += 1;
18500 }
18501 if token.token_type == TokenType::RParen {
18502 paren_depth -= 1;
18503 if paren_depth < 0 {
18504 break;
18505 }
18506 }
18507 let text = if token.token_type == TokenType::QuotedIdentifier {
18508 format!("\"{}\"", token.text)
18509 } else if token.token_type == TokenType::String {
18510 format!("'{}'", token.text)
18511 } else {
18512 token.text.clone()
18513 };
18514 tokens.push((text, token.token_type));
18515 }
18516 Ok(AlterTableAction::Raw {
18517 sql: self.join_command_tokens(tokens),
18518 })
18519 } else {
18520 Err(self.parse_error(format!(
18521 "Expected ADD, DROP, RENAME, ALTER, SET, UNSET, SWAP, CLUSTER, or REPLACE in ALTER TABLE, got {:?}",
18522 self.peek().token_type
18523 )))
18524 }
18525 }
18526
18527 fn parse_system_versioning_option(&mut self) -> Result<Expression> {
18530 self.skip(); self.expect(TokenType::Eq)?;
18532
18533 let mut prop = WithSystemVersioningProperty {
18534 on: None,
18535 this: None,
18536 data_consistency: None,
18537 retention_period: None,
18538 with_: None,
18539 };
18540
18541 if self.match_identifier("OFF") {
18542 return Ok(Expression::WithSystemVersioningProperty(Box::new(prop)));
18545 }
18546
18547 if self.match_token(TokenType::On) || self.match_identifier("ON") {
18549 prop.on = Some(Box::new(Expression::Boolean(BooleanLiteral {
18550 value: true,
18551 })));
18552 }
18553
18554 if self.match_token(TokenType::LParen) {
18555 loop {
18557 if self.check(TokenType::RParen) {
18558 break;
18559 }
18560 if self.match_identifier("HISTORY_TABLE") {
18561 self.expect(TokenType::Eq)?;
18562 let table = self.parse_table_ref()?;
18563 prop.this = Some(Box::new(Expression::Table(Box::new(table))));
18564 } else if self.match_identifier("DATA_CONSISTENCY_CHECK") {
18565 self.expect(TokenType::Eq)?;
18566 let val = self.expect_identifier_or_keyword()?;
18567 prop.data_consistency = Some(Box::new(Expression::Identifier(
18568 Identifier::new(val.to_ascii_uppercase()),
18569 )));
18570 } else if self.match_identifier("HISTORY_RETENTION_PERIOD") {
18571 self.expect(TokenType::Eq)?;
18572 if let Some(rp) = self.parse_retention_period()? {
18573 prop.retention_period = Some(Box::new(rp));
18574 }
18575 } else {
18576 self.skip();
18578 }
18579 if !self.match_token(TokenType::Comma) {
18580 break;
18581 }
18582 }
18583 self.expect(TokenType::RParen)?;
18584 }
18585
18586 Ok(Expression::WithSystemVersioningProperty(Box::new(prop)))
18587 }
18588
18589 fn parse_data_deletion_option(&mut self) -> Result<Expression> {
18592 self.skip(); self.expect(TokenType::Eq)?;
18594
18595 let on = if self.match_identifier("ON") || self.match_token(TokenType::On) {
18596 true
18597 } else if self.match_identifier("OFF") {
18598 false
18599 } else {
18600 false
18601 };
18602
18603 let on_expr = Box::new(Expression::Boolean(BooleanLiteral { value: on }));
18604 let mut filter_column = None;
18605 let mut retention_period = None;
18606
18607 if self.match_token(TokenType::LParen) {
18608 loop {
18609 if self.check(TokenType::RParen) {
18610 break;
18611 }
18612 if self.match_identifier("FILTER_COLUMN") {
18613 self.expect(TokenType::Eq)?;
18614 let col = self.expect_identifier_or_keyword()?;
18615 filter_column = Some(Box::new(Expression::boxed_column(Column {
18616 name: Identifier::new(col),
18617 table: None,
18618 join_mark: false,
18619 trailing_comments: Vec::new(),
18620 span: None,
18621 inferred_type: None,
18622 })));
18623 } else if self.match_identifier("RETENTION_PERIOD") {
18624 self.expect(TokenType::Eq)?;
18625 if let Some(rp) = self.parse_retention_period()? {
18626 retention_period = Some(Box::new(rp));
18627 }
18628 } else {
18629 self.skip();
18630 }
18631 if !self.match_token(TokenType::Comma) {
18632 break;
18633 }
18634 }
18635 self.expect(TokenType::RParen)?;
18636 }
18637
18638 Ok(Expression::DataDeletionProperty(Box::new(
18639 DataDeletionProperty {
18640 on: on_expr,
18641 filter_column,
18642 retention_period,
18643 },
18644 )))
18645 }
18646
18647 fn parse_alter_column_action(&mut self) -> Result<AlterColumnAction> {
18649 if self.match_token(TokenType::Set) {
18650 if self.match_keywords(&[TokenType::Not, TokenType::Null]) {
18651 Ok(AlterColumnAction::SetNotNull)
18652 } else if self.match_token(TokenType::Default) {
18653 let expr = self.parse_primary()?;
18654 Ok(AlterColumnAction::SetDefault(expr))
18655 } else if self.match_identifier("DATA") {
18656 let _ = self.match_token(TokenType::Type) || self.match_identifier("TYPE");
18659 let data_type = self.parse_data_type()?;
18660 let collate = if self.match_token(TokenType::Collate) {
18662 Some(self.expect_identifier_or_keyword()?)
18663 } else {
18664 None
18665 };
18666 let using = if self.match_token(TokenType::Using) {
18668 Some(self.parse_expression()?)
18669 } else {
18670 None
18671 };
18672 Ok(AlterColumnAction::SetDataType {
18673 data_type,
18674 using,
18675 collate,
18676 })
18677 } else if self.match_identifier("VISIBLE") {
18678 Ok(AlterColumnAction::SetVisible)
18679 } else if self.match_identifier("INVISIBLE") {
18680 Ok(AlterColumnAction::SetInvisible)
18681 } else {
18682 Err(self.parse_error("Expected NOT NULL, DEFAULT, VISIBLE, or INVISIBLE after SET"))
18683 }
18684 } else if self.match_token(TokenType::Drop) {
18685 if self.match_keywords(&[TokenType::Not, TokenType::Null]) {
18686 Ok(AlterColumnAction::DropNotNull)
18687 } else if self.match_token(TokenType::Default) {
18688 Ok(AlterColumnAction::DropDefault)
18689 } else {
18690 Err(self.parse_error("Expected NOT NULL or DEFAULT after DROP"))
18691 }
18692 } else if self.match_token(TokenType::Comment) {
18693 let comment = self.expect_string()?;
18695 Ok(AlterColumnAction::Comment(comment))
18696 } else if self.match_token(TokenType::Type)
18697 || self.match_identifier("TYPE")
18698 || self.is_identifier_token()
18699 {
18700 let data_type = self.parse_data_type()?;
18702 let collate = if self.match_token(TokenType::Collate) {
18704 Some(self.expect_identifier_or_keyword()?)
18705 } else {
18706 None
18707 };
18708 let using = if self.match_token(TokenType::Using) {
18710 Some(self.parse_expression()?)
18711 } else {
18712 None
18713 };
18714 Ok(AlterColumnAction::SetDataType {
18715 data_type,
18716 using,
18717 collate,
18718 })
18719 } else {
18720 Err(self.parse_error("Expected SET, DROP, or TYPE in ALTER COLUMN"))
18721 }
18722 }
18723
18724 fn parse_truncate(&mut self) -> Result<Expression> {
18726 self.expect(TokenType::Truncate)?;
18727
18728 if matches!(
18730 self.config.dialect,
18731 Some(crate::dialects::DialectType::ClickHouse)
18732 ) && self.check_identifier("ALL")
18733 && self.current + 1 < self.tokens.len()
18734 && self.tokens[self.current + 1]
18735 .text
18736 .eq_ignore_ascii_case("TABLES")
18737 {
18738 let mut parts = vec!["TRUNCATE".to_string()];
18740 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
18741 let token = self.advance();
18742 if token.token_type == TokenType::String {
18743 parts.push(format!("'{}'", token.text));
18744 } else {
18745 parts.push(token.text.clone());
18746 }
18747 }
18748 return Ok(Expression::Command(Box::new(crate::expressions::Command {
18749 this: parts.join(" "),
18750 })));
18751 }
18752
18753 let target = if self.match_token(TokenType::Database) {
18754 TruncateTarget::Database
18755 } else {
18756 self.match_token(TokenType::Temporary);
18758 self.match_token(TokenType::Table); TruncateTarget::Table
18760 };
18761
18762 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
18764
18765 let has_only = self.match_token(TokenType::Only);
18767 let mut table = self.parse_table_ref()?;
18768 if has_only {
18769 table.only = true;
18770 }
18771
18772 let first_star = self.match_token(TokenType::Star);
18774
18775 if self.check(TokenType::With) && self.check_next(TokenType::LParen) {
18777 if let Some(hint_expr) = self.parse_truncate_table_hints()? {
18778 match hint_expr {
18779 Expression::Tuple(tuple) => {
18780 table.hints = tuple.expressions;
18781 }
18782 other => {
18783 table.hints = vec![other];
18784 }
18785 }
18786 }
18787 }
18788
18789 let on_cluster = self.parse_on_cluster_clause()?;
18791
18792 let mut extra_tables = Vec::new();
18794 if first_star {
18795 extra_tables.push(TruncateTableEntry {
18797 table: table.clone(),
18798 star: true,
18799 });
18800 }
18801 while self.match_token(TokenType::Comma) {
18802 let extra_only = self.match_token(TokenType::Only);
18803 let mut extra_table = self.parse_table_ref()?;
18804 if extra_only {
18805 extra_table.only = true;
18806 }
18807 let extra_star = self.match_token(TokenType::Star);
18808 extra_tables.push(TruncateTableEntry {
18809 table: extra_table,
18810 star: extra_star,
18811 });
18812 }
18813
18814 let identity = if self.match_token(TokenType::Restart) {
18817 self.match_token(TokenType::Identity);
18818 Some(TruncateIdentity::Restart)
18819 } else if self.match_identifier("CONTINUE") {
18820 self.match_token(TokenType::Identity);
18821 Some(TruncateIdentity::Continue)
18822 } else {
18823 None
18824 };
18825
18826 let cascade = self.match_token(TokenType::Cascade);
18829 let restrict = if !cascade {
18830 self.match_token(TokenType::Restrict)
18831 } else {
18832 false
18833 };
18834
18835 let partition = self.parse_partition()?;
18838
18839 if matches!(
18841 self.config.dialect,
18842 Some(crate::dialects::DialectType::ClickHouse)
18843 ) && self.match_token(TokenType::Settings)
18844 {
18845 loop {
18847 let _ = self.parse_expression()?;
18848 if !self.match_token(TokenType::Comma) {
18849 break;
18850 }
18851 }
18852 }
18853
18854 Ok(Expression::Truncate(Box::new(Truncate {
18855 target,
18856 if_exists,
18857 table,
18858 on_cluster,
18859 cascade,
18860 extra_tables,
18861 identity,
18862 restrict,
18863 partition: partition.map(Box::new),
18864 })))
18865 }
18866
18867 fn parse_values(&mut self) -> Result<Expression> {
18869 self.expect(TokenType::Values)?;
18870
18871 let mut expressions = Vec::new();
18872
18873 if !self.check(TokenType::LParen) {
18875 loop {
18876 let val = self.parse_expression()?;
18877 expressions.push(Tuple {
18878 expressions: vec![val],
18879 });
18880 if !self.match_token(TokenType::Comma) {
18881 break;
18882 }
18883 }
18884 } else {
18885 loop {
18886 self.expect(TokenType::LParen)?;
18887 let row_values = self.parse_values_expression_list()?;
18889 self.expect(TokenType::RParen)?;
18890
18891 expressions.push(Tuple {
18892 expressions: row_values,
18893 });
18894
18895 if !self.match_token(TokenType::Comma) {
18896 break;
18897 }
18898 if matches!(
18900 self.config.dialect,
18901 Some(crate::dialects::DialectType::ClickHouse)
18902 ) && !self.check(TokenType::LParen)
18903 {
18904 break;
18905 }
18906 }
18907 }
18908
18909 let (alias, column_aliases) = if self.match_token(TokenType::As) {
18911 let alias_name = self.expect_identifier()?;
18912 let alias = Some(Identifier::new(alias_name));
18913
18914 let col_aliases = if self.match_token(TokenType::LParen) {
18916 let aliases = self.parse_identifier_list()?;
18917 self.expect(TokenType::RParen)?;
18918 aliases
18919 } else {
18920 Vec::new()
18921 };
18922 (alias, col_aliases)
18923 } else if self.check(TokenType::Var) && !self.check_keyword() {
18924 let alias_name = self.advance().text.clone();
18926 let alias = Some(Identifier::new(alias_name));
18927 let col_aliases = if self.match_token(TokenType::LParen) {
18928 let aliases = self.parse_identifier_list()?;
18929 self.expect(TokenType::RParen)?;
18930 aliases
18931 } else {
18932 Vec::new()
18933 };
18934 (alias, col_aliases)
18935 } else {
18936 (None, Vec::new())
18937 };
18938
18939 let values_expr = Expression::Values(Box::new(Values {
18941 expressions,
18942 alias,
18943 column_aliases,
18944 }));
18945
18946 self.parse_set_operation(values_expr)
18948 }
18949
18950 fn parse_use(&mut self) -> Result<Expression> {
18952 self.expect(TokenType::Use)?;
18953
18954 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("SECONDARY") {
18956 self.skip(); if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("ROLES") {
18959 self.skip(); let mut roles = Vec::new();
18962 loop {
18963 if self.check(TokenType::Var)
18964 || self.check(TokenType::All)
18965 || self.check(TokenType::Identifier)
18966 {
18967 let role = self.advance().text.clone();
18968 roles.push(role);
18969 if !self.match_token(TokenType::Comma) {
18970 break;
18971 }
18972 } else {
18973 break;
18974 }
18975 }
18976 let name = if roles.is_empty() {
18977 "ALL".to_string()
18978 } else {
18979 roles.join(", ")
18980 };
18981 return Ok(Expression::Use(Box::new(Use {
18982 kind: Some(UseKind::SecondaryRoles),
18983 this: Identifier::new(name),
18984 })));
18985 }
18986 }
18987
18988 let kind = if self.match_token(TokenType::Database) {
18991 Some(UseKind::Database)
18992 } else if self.match_token(TokenType::Schema) {
18993 Some(UseKind::Schema)
18994 } else if self.match_token(TokenType::Warehouse) {
18995 Some(UseKind::Warehouse)
18996 } else if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("ROLE") {
18997 self.skip();
18998 Some(UseKind::Role)
18999 } else if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("CATALOG") {
19000 self.skip();
19001 Some(UseKind::Catalog)
19002 } else {
19003 None
19004 };
19005
19006 let mut ident = self.expect_identifier_or_keyword_with_quoted()?;
19009
19010 if self.match_token(TokenType::Dot) {
19012 let second_part = self.expect_identifier_or_keyword_with_quoted()?;
19013 ident.name = format!("{}.{}", ident.name, second_part.name);
19014 }
19015
19016 Ok(Expression::Use(Box::new(Use { kind, this: ident })))
19017 }
19018
19019 fn parse_export_data(&mut self) -> Result<Expression> {
19022 self.skip(); if !self.match_identifier("DATA") {
19026 return Err(self.parse_error("Expected DATA after EXPORT"));
19027 }
19028
19029 let connection = if self.match_text_seq(&["WITH", "CONNECTION"]) {
19031 let first = self.expect_identifier()?;
19033 let connection_name = if self.match_token(TokenType::Dot) {
19034 let second = self.expect_identifier()?;
19035 if self.match_token(TokenType::Dot) {
19036 let third = self.expect_identifier()?;
19037 format!("{}.{}.{}", first, second, third)
19038 } else {
19039 format!("{}.{}", first, second)
19040 }
19041 } else {
19042 first
19043 };
19044 Some(Box::new(Expression::Identifier(Identifier::new(
19045 connection_name,
19046 ))))
19047 } else {
19048 None
19049 };
19050
19051 let options = if self.match_identifier("OPTIONS") {
19053 self.parse_options_list()?
19054 } else {
19055 Vec::new()
19056 };
19057
19058 self.expect(TokenType::As)?;
19060
19061 let query = self.parse_statement()?;
19063
19064 Ok(Expression::Export(Box::new(Export {
19065 this: Box::new(query),
19066 connection,
19067 options,
19068 })))
19069 }
19070
19071 fn parse_cache(&mut self) -> Result<Expression> {
19074 self.expect(TokenType::Cache)?;
19075
19076 let lazy = self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("LAZY");
19078 if lazy {
19079 self.skip();
19080 }
19081
19082 self.expect(TokenType::Table)?;
19083 let table = Identifier::new(self.expect_identifier()?);
19084
19085 let options =
19087 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("OPTIONS") {
19088 self.skip();
19089 self.expect(TokenType::LParen)?;
19090 let mut opts = Vec::new();
19091 loop {
19092 let key = if self.check(TokenType::NationalString) {
19094 let token = self.advance();
19095 Expression::Literal(Box::new(Literal::NationalString(token.text)))
19096 } else if self.check(TokenType::String) {
19097 let token = self.advance();
19098 Expression::Literal(Box::new(Literal::String(token.text)))
19099 } else {
19100 Expression::Identifier(Identifier::new(self.expect_identifier()?))
19101 };
19102 let _ = self.match_token(TokenType::Eq);
19105 let value = self.parse_expression()?;
19106 opts.push((key, value));
19107 if !self.match_token(TokenType::Comma) {
19108 break;
19109 }
19110 }
19111 self.expect(TokenType::RParen)?;
19112 opts
19113 } else {
19114 Vec::new()
19115 };
19116
19117 let query = if self.match_token(TokenType::As) {
19119 Some(self.parse_statement()?)
19120 } else if self.check(TokenType::Select) || self.check(TokenType::With) {
19121 Some(self.parse_statement()?)
19123 } else {
19124 None
19125 };
19126
19127 Ok(Expression::Cache(Box::new(Cache {
19128 table,
19129 lazy,
19130 options,
19131 query,
19132 })))
19133 }
19134
19135 fn parse_uncache(&mut self) -> Result<Expression> {
19138 self.expect(TokenType::Uncache)?;
19139 self.expect(TokenType::Table)?;
19140
19141 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
19142 let table = Identifier::new(self.expect_identifier()?);
19143
19144 Ok(Expression::Uncache(Box::new(Uncache { table, if_exists })))
19145 }
19146
19147 fn parse_load_data(&mut self) -> Result<Expression> {
19151 self.expect(TokenType::Load)?;
19152
19153 let data_token = self.advance();
19155 if !data_token.text.eq_ignore_ascii_case("DATA") {
19156 return Err(self.parse_error("Expected DATA after LOAD"));
19157 }
19158
19159 let local = self.match_token(TokenType::Local);
19161
19162 self.expect(TokenType::Inpath)?;
19164
19165 let inpath = if self.check(TokenType::String) {
19167 self.advance().text
19168 } else {
19169 return Err(self.parse_error("Expected string literal after INPATH"));
19170 };
19171
19172 let overwrite = self.match_token(TokenType::Overwrite);
19174
19175 self.expect(TokenType::Into)?;
19177 self.expect(TokenType::Table)?;
19178
19179 let table = Expression::Table(Box::new(self.parse_table_ref()?));
19181
19182 let partition = if self.match_token(TokenType::Partition) {
19184 self.expect(TokenType::LParen)?;
19185 let mut partitions = Vec::new();
19186 loop {
19187 let col = Identifier::new(self.expect_identifier_or_keyword()?);
19188 self.expect(TokenType::Eq)?;
19189 let val = self.parse_expression()?;
19190 partitions.push((col, val));
19191 if !self.match_token(TokenType::Comma) {
19192 break;
19193 }
19194 }
19195 self.expect(TokenType::RParen)?;
19196 partitions
19197 } else {
19198 Vec::new()
19199 };
19200
19201 let input_format = if self.match_token(TokenType::InputFormat) {
19203 if self.check(TokenType::String) {
19204 Some(self.advance().text)
19205 } else {
19206 return Err(self.parse_error("Expected string literal after INPUTFORMAT"));
19207 }
19208 } else {
19209 None
19210 };
19211
19212 let serde = if self.match_token(TokenType::Serde) {
19214 if self.check(TokenType::String) {
19215 Some(self.advance().text)
19216 } else {
19217 return Err(self.parse_error("Expected string literal after SERDE"));
19218 }
19219 } else {
19220 None
19221 };
19222
19223 Ok(Expression::LoadData(Box::new(LoadData {
19224 local,
19225 inpath,
19226 overwrite,
19227 table,
19228 partition,
19229 input_format,
19230 serde,
19231 })))
19232 }
19233
19234 fn parse_pragma(&mut self) -> Result<Expression> {
19237 self.expect(TokenType::Pragma)?;
19238
19239 let first_name = self.expect_identifier_or_keyword()?;
19241
19242 let (schema, name) = if self.match_token(TokenType::Dot) {
19243 let pragma_name = self.expect_identifier_or_keyword()?;
19245 (
19246 Some(Identifier::new(first_name)),
19247 Identifier::new(pragma_name),
19248 )
19249 } else {
19250 (None, Identifier::new(first_name))
19251 };
19252
19253 let (value, args) = if self.match_token(TokenType::Eq) {
19255 let val = self.parse_expression()?;
19257 (Some(val), Vec::new())
19258 } else if self.match_token(TokenType::LParen) {
19259 let mut arguments = Vec::new();
19261 if !self.check(TokenType::RParen) {
19262 loop {
19263 arguments.push(self.parse_expression()?);
19264 if !self.match_token(TokenType::Comma) {
19265 break;
19266 }
19267 }
19268 }
19269 self.expect(TokenType::RParen)?;
19270 (None, arguments)
19271 } else {
19272 (None, Vec::new())
19273 };
19274
19275 Ok(Expression::Pragma(Box::new(Pragma {
19276 schema,
19277 name,
19278 value,
19279 args,
19280 })))
19281 }
19282
19283 fn parse_rollback(&mut self) -> Result<Expression> {
19286 self.expect(TokenType::Rollback)?;
19287
19288 let has_transaction = self.match_token(TokenType::Transaction)
19290 || self.match_identifier("TRAN")
19291 || self.match_identifier("WORK");
19292
19293 let (savepoint, this) = if self.match_token(TokenType::To) {
19295 self.match_token(TokenType::Savepoint);
19297 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
19299 let name = self.advance().text;
19300 (
19301 Some(Box::new(Expression::Identifier(Identifier::new(name)))),
19302 None,
19303 )
19304 } else {
19305 (None, None)
19306 }
19307 } else if has_transaction
19308 && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
19309 {
19310 let name = self.advance().text;
19312 (
19313 None,
19314 Some(Box::new(Expression::Identifier(Identifier::new(name)))),
19315 )
19316 } else if has_transaction {
19317 (
19319 None,
19320 Some(Box::new(Expression::Identifier(Identifier::new(
19321 "TRANSACTION".to_string(),
19322 )))),
19323 )
19324 } else {
19325 (None, None)
19326 };
19327
19328 Ok(Expression::Rollback(Box::new(Rollback { savepoint, this })))
19329 }
19330
19331 fn parse_commit(&mut self) -> Result<Expression> {
19334 self.expect(TokenType::Commit)?;
19335
19336 let has_transaction = self.match_token(TokenType::Transaction)
19338 || self.match_identifier("TRAN")
19339 || self.match_identifier("WORK");
19340
19341 let this = if has_transaction
19343 && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
19344 && !self.check(TokenType::With)
19345 && !self.check(TokenType::And)
19346 {
19347 let name = self.advance().text;
19348 Some(Box::new(Expression::Identifier(Identifier::new(name))))
19349 } else if has_transaction {
19350 Some(Box::new(Expression::Identifier(Identifier::new(
19352 "TRANSACTION".to_string(),
19353 ))))
19354 } else {
19355 None
19356 };
19357
19358 let durability = if self.match_token(TokenType::With) && self.match_token(TokenType::LParen)
19360 {
19361 if self.match_identifier("DELAYED_DURABILITY") && self.match_token(TokenType::Eq) {
19363 let on = self.match_token(TokenType::On) || self.match_identifier("ON");
19365 if !on {
19366 self.match_identifier("OFF");
19367 }
19368 self.expect(TokenType::RParen)?;
19369 Some(Box::new(Expression::Boolean(BooleanLiteral { value: on })))
19370 } else {
19371 while !self.check(TokenType::RParen) && !self.is_at_end() {
19373 self.skip();
19374 }
19375 self.match_token(TokenType::RParen);
19376 None
19377 }
19378 } else {
19379 None
19380 };
19381
19382 let chain = if self.match_token(TokenType::And) {
19384 let no_chain = self.match_token(TokenType::No);
19385 self.match_identifier("CHAIN");
19386 if no_chain {
19387 Some(Box::new(Expression::Boolean(BooleanLiteral {
19389 value: false,
19390 })))
19391 } else {
19392 Some(Box::new(Expression::Boolean(BooleanLiteral {
19394 value: true,
19395 })))
19396 }
19397 } else {
19398 None
19399 };
19400
19401 Ok(Expression::Commit(Box::new(Commit {
19402 chain,
19403 this,
19404 durability,
19405 })))
19406 }
19407
19408 fn parse_end_transaction(&mut self) -> Result<Expression> {
19411 self.expect(TokenType::End)?;
19412
19413 let _has_work = self.match_identifier("WORK") || self.match_token(TokenType::Transaction);
19415
19416 let chain = if self.match_token(TokenType::And) {
19418 let no_chain = self.match_token(TokenType::No);
19419 self.match_identifier("CHAIN");
19420 if no_chain {
19421 Some(Box::new(Expression::Boolean(BooleanLiteral {
19423 value: false,
19424 })))
19425 } else {
19426 Some(Box::new(Expression::Boolean(BooleanLiteral {
19428 value: true,
19429 })))
19430 }
19431 } else {
19432 None
19433 };
19434
19435 Ok(Expression::Commit(Box::new(Commit {
19437 chain,
19438 this: None,
19439 durability: None,
19440 })))
19441 }
19442
19443 fn parse_transaction(&mut self) -> Result<Expression> {
19447 self.expect(TokenType::Begin)?;
19448
19449 let is_transaction = self.is_at_end()
19452 || self.check(TokenType::Semicolon)
19453 || self.check(TokenType::Transaction)
19454 || self.check_identifier("TRAN")
19455 || self.check_identifier("WORK")
19456 || self.check_identifier("DEFERRED")
19457 || self.check_identifier("IMMEDIATE")
19458 || self.check_identifier("EXCLUSIVE");
19459
19460 if !is_transaction {
19461 let is_try = self.check_identifier("TRY");
19465 let is_catch = self.check_identifier("CATCH");
19466 if is_try || is_catch {
19467 let block_kind = if is_try { "TRY" } else { "CATCH" };
19468 self.skip(); let mut tokens: Vec<(String, TokenType)> = vec![
19470 ("BEGIN".to_string(), TokenType::Begin),
19471 (block_kind.to_string(), TokenType::Var),
19472 ];
19473 while !self.is_at_end() {
19475 if self.check(TokenType::End)
19476 && self.current + 1 < self.tokens.len()
19477 && self.tokens[self.current + 1]
19478 .text
19479 .eq_ignore_ascii_case(block_kind)
19480 {
19481 tokens.push(("END".to_string(), TokenType::End));
19482 self.skip(); tokens.push((block_kind.to_string(), TokenType::Var));
19484 self.skip(); break;
19486 }
19487 let token = self.advance();
19488 let text = if token.token_type == TokenType::String {
19489 format!("'{}'", token.text)
19490 } else if token.token_type == TokenType::QuotedIdentifier {
19491 format!("\"{}\"", token.text)
19492 } else {
19493 token.text.clone()
19494 };
19495 tokens.push((text, token.token_type));
19496 }
19497 let mut result = Expression::Command(Box::new(Command {
19498 this: self.join_command_tokens(tokens),
19499 }));
19500
19501 if is_try
19503 && self.check(TokenType::Begin)
19504 && self.current + 1 < self.tokens.len()
19505 && self.tokens[self.current + 1]
19506 .text
19507 .eq_ignore_ascii_case("CATCH")
19508 {
19509 let catch_block = self.parse_transaction()?;
19511 if let (Expression::Command(try_cmd), Expression::Command(catch_cmd)) =
19513 (&result, &catch_block)
19514 {
19515 result = Expression::Command(Box::new(Command {
19516 this: format!("{} {}", try_cmd.this, catch_cmd.this),
19517 }));
19518 }
19519 }
19520
19521 return Ok(result);
19522 }
19523
19524 return self
19527 .parse_command()?
19528 .ok_or_else(|| self.parse_error("Failed to parse BEGIN block"));
19529 }
19530
19531 let kind = if self.match_identifier("DEFERRED")
19533 || self.match_identifier("IMMEDIATE")
19534 || self.match_identifier("EXCLUSIVE")
19535 {
19536 Some(self.previous().text.clone())
19537 } else {
19538 None
19539 };
19540
19541 let has_transaction_keyword = self.match_token(TokenType::Transaction)
19543 || self.match_identifier("TRAN")
19544 || self.match_identifier("WORK");
19545
19546 let trans_name = if has_transaction_keyword
19548 && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
19549 && !self.check(TokenType::With)
19550 {
19551 let name = self.advance().text;
19553 Some(name)
19554 } else {
19555 None
19556 };
19557
19558 let this = if let Some(name) = trans_name {
19560 Some(Box::new(Expression::Identifier(Identifier::new(name))))
19561 } else if let Some(k) = kind {
19562 Some(Box::new(Expression::Identifier(Identifier::new(k))))
19563 } else {
19564 None
19565 };
19566
19567 let mark = if self.match_token(TokenType::With) && self.match_identifier("MARK") {
19569 if self.check(TokenType::String) {
19570 let desc = self.advance().text;
19571 Some(Box::new(Expression::Literal(Box::new(Literal::String(
19572 desc,
19573 )))))
19574 } else {
19575 Some(Box::new(Expression::Literal(Box::new(Literal::String(
19576 "".to_string(),
19577 )))))
19578 }
19579 } else if has_transaction_keyword {
19580 Some(Box::new(Expression::Identifier(Identifier::new(
19582 "TRANSACTION".to_string(),
19583 ))))
19584 } else {
19585 None
19586 };
19587
19588 let mut mode_parts: Vec<String> = Vec::new();
19590 while self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
19591 let mut mode_tokens: Vec<String> = Vec::new();
19592 while (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
19593 && !self.check(TokenType::Comma)
19594 {
19595 mode_tokens.push(self.advance().text);
19596 }
19597 if !mode_tokens.is_empty() {
19598 mode_parts.push(mode_tokens.join(" "));
19599 }
19600 if !self.match_token(TokenType::Comma) {
19601 break;
19602 }
19603 }
19604
19605 let modes = if !mode_parts.is_empty() {
19606 Some(Box::new(Expression::Identifier(Identifier::new(
19607 mode_parts.join(", "),
19608 ))))
19609 } else {
19610 None
19611 };
19612
19613 Ok(Expression::Transaction(Box::new(Transaction {
19614 this,
19615 modes,
19616 mark,
19617 })))
19618 }
19619
19620 fn parse_start_transaction(&mut self) -> Result<Expression> {
19623 self.expect(TokenType::Start)?;
19624
19625 self.expect(TokenType::Transaction)?;
19627
19628 let mut mode_parts: Vec<String> = Vec::new();
19630 while self.is_identifier_token()
19631 || self.is_safe_keyword_as_identifier()
19632 || self.match_identifier("READ")
19633 {
19634 let read_matched = if self.previous().text.eq_ignore_ascii_case("READ") {
19636 true
19637 } else {
19638 false
19639 };
19640 let mut mode_tokens: Vec<String> = Vec::new();
19641 if read_matched {
19642 mode_tokens.push("READ".to_string());
19643 }
19644 while (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
19645 && !self.check(TokenType::Comma)
19646 {
19647 mode_tokens.push(self.advance().text);
19648 }
19649 if !mode_tokens.is_empty() {
19650 mode_parts.push(mode_tokens.join(" "));
19651 }
19652 if !self.match_token(TokenType::Comma) {
19653 break;
19654 }
19655 }
19656
19657 let modes = if !mode_parts.is_empty() {
19658 Some(Box::new(Expression::Identifier(Identifier::new(
19659 mode_parts.join(", "),
19660 ))))
19661 } else {
19662 None
19663 };
19664
19665 Ok(Expression::Transaction(Box::new(Transaction {
19666 this: None, modes,
19668 mark: Some(Box::new(Expression::Identifier(Identifier::new(
19670 "START".to_string(),
19671 )))),
19672 })))
19673 }
19674
19675 fn parse_describe(&mut self) -> Result<Expression> {
19679 let leading_comments = if self.check(TokenType::Describe) {
19682 let token = self.advance();
19683 token.comments
19684 } else if self.check(TokenType::Desc) {
19685 let token = self.advance();
19686 token.comments
19687 } else if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("EXPLAIN") {
19688 let token = self.advance(); token.comments
19690 } else {
19691 return Err(self.parse_error("Expected DESCRIBE, DESC, or EXPLAIN"));
19692 };
19693
19694 let extended = self.match_identifier("EXTENDED");
19696 let formatted = if !extended {
19697 self.match_identifier("FORMATTED")
19698 } else {
19699 false
19700 };
19701
19702 let style = if !extended && !formatted && self.match_identifier("ANALYZE") {
19707 Some("ANALYZE".to_string())
19708 } else if !extended
19709 && !formatted
19710 && matches!(
19711 self.config.dialect,
19712 Some(crate::dialects::DialectType::ClickHouse)
19713 )
19714 {
19715 let text_upper = if !self.is_at_end() {
19717 self.peek().text.to_ascii_uppercase()
19718 } else {
19719 String::new()
19720 };
19721 match text_upper.as_str() {
19722 "SYNTAX" | "AST" | "PLAN" | "PIPELINE" | "ESTIMATE" | "QUERY" | "CURRENT" => {
19723 self.skip();
19724 let mut style_str = text_upper;
19725 if style_str == "CURRENT" && self.check_identifier("TRANSACTION") {
19727 style_str.push_str(" TRANSACTION");
19728 self.skip();
19729 }
19730 if style_str == "QUERY" && self.check_identifier("TREE") {
19731 style_str.push_str(" TREE");
19732 self.skip();
19733 }
19734 Some(style_str)
19735 }
19736 _ if self.check(TokenType::Table) => {
19737 self.skip(); if self.check_identifier("OVERRIDE") {
19740 self.skip();
19741 Some("TABLE OVERRIDE".to_string())
19742 } else {
19743 self.current -= 1;
19745 None
19746 }
19747 }
19748 _ => None,
19749 }
19750 } else if !extended
19751 && !formatted
19752 && (self.check(TokenType::Identifier)
19753 || self.check(TokenType::Var)
19754 || self.check(TokenType::QuotedIdentifier))
19755 && self.peek().text.eq_ignore_ascii_case("HISTORY")
19756 && self.peek_nth(1).map(|t| t.token_type) != Some(TokenType::Dot)
19757 {
19758 self.skip(); Some("HISTORY".to_string())
19760 } else {
19761 None
19762 };
19763
19764 let kind = if self.match_identifier("SEMANTIC") {
19766 if self.match_token(TokenType::View) {
19767 Some("SEMANTIC VIEW".to_string())
19768 } else {
19769 Some("SEMANTIC".to_string())
19770 }
19771 } else if self.match_token(TokenType::Table) {
19772 Some("TABLE".to_string())
19773 } else if self.match_token(TokenType::View) {
19774 Some("VIEW".to_string())
19775 } else if self.match_identifier("DATABASE") {
19776 Some("DATABASE".to_string())
19777 } else if self.match_identifier("SCHEMA") {
19778 Some("SCHEMA".to_string())
19779 } else if self.match_token(TokenType::Input) {
19780 Some("INPUT".to_string())
19781 } else if self.match_token(TokenType::Output) {
19782 Some("OUTPUT".to_string())
19783 } else {
19784 None
19785 };
19786
19787 let mut properties = Vec::new();
19791 if matches!(
19792 self.config.dialect,
19793 Some(crate::dialects::DialectType::ClickHouse)
19794 ) {
19795 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
19796 if (self.is_identifier_token()
19798 || self.is_safe_keyword_as_identifier()
19799 || self.check(TokenType::Type))
19800 && self.current + 1 < self.tokens.len()
19801 && self.tokens[self.current + 1].token_type == TokenType::Eq
19802 {
19803 let name = self.advance().text.to_lowercase();
19804 self.skip(); let value = self.advance().text.clone();
19806 properties.push((name, value));
19807 self.match_token(TokenType::Comma); } else {
19809 break;
19810 }
19811 }
19812 }
19813
19814 let target = if self.check(TokenType::Select) || self.check(TokenType::With) {
19817 self.parse_statement()?
19818 } else if self.check(TokenType::LParen) && {
19819 let mut depth = 0usize;
19821 let mut found_select = false;
19822 for i in 0..100 {
19823 match self.peek_nth(i).map(|t| t.token_type) {
19824 Some(TokenType::LParen) => depth += 1,
19825 Some(TokenType::Select) | Some(TokenType::With) if depth > 0 => {
19826 found_select = true;
19827 break;
19828 }
19829 _ => break,
19830 }
19831 }
19832 found_select
19833 } {
19834 self.parse_statement()?
19836 } else if matches!(
19837 self.config.dialect,
19838 Some(crate::dialects::DialectType::ClickHouse)
19839 ) && (self.check(TokenType::Insert)
19840 || self.check(TokenType::Create)
19841 || self.check(TokenType::Alter)
19842 || self.check(TokenType::Drop)
19843 || self.check(TokenType::Set)
19844 || self.check(TokenType::System))
19845 {
19846 self.parse_statement()?
19847 } else if matches!(
19848 self.config.dialect,
19849 Some(crate::dialects::DialectType::ClickHouse)
19850 ) && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
19851 && self.peek_nth(1).map(|t| t.token_type) == Some(TokenType::LParen)
19852 {
19853 self.parse_expression()?
19855 } else {
19856 let table = self.parse_table_ref()?;
19858 Expression::Table(Box::new(table))
19859 };
19860
19861 let partition = if self.match_token(TokenType::Partition) {
19863 self.expect(TokenType::LParen)?;
19865 let mut partition_exprs = Vec::new();
19867 loop {
19868 if let Some(expr) = self.parse_conjunction()? {
19869 partition_exprs.push(expr);
19870 }
19871 if !self.match_token(TokenType::Comma) {
19872 break;
19873 }
19874 }
19875 self.expect(TokenType::RParen)?;
19876 let partition = Expression::Partition(Box::new(crate::expressions::Partition {
19877 expressions: partition_exprs,
19878 subpartition: false,
19879 }));
19880 Some(Box::new(partition))
19881 } else {
19882 None
19883 };
19884
19885 if matches!(
19888 self.config.dialect,
19889 Some(crate::dialects::DialectType::ClickHouse)
19890 ) && self.check(TokenType::Settings)
19891 {
19892 self.skip(); let _ = self.parse_settings_property()?;
19894 }
19895
19896 let as_json = if self.check(TokenType::As)
19898 && self
19899 .peek_nth(1)
19900 .map(|t| t.text.eq_ignore_ascii_case("JSON"))
19901 == Some(true)
19902 {
19903 self.skip(); self.skip(); true
19906 } else {
19907 false
19908 };
19909
19910 if properties.is_empty() {
19912 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
19913 if self.check(TokenType::Var) || self.check(TokenType::Type) || self.check_keyword()
19915 {
19916 let name = self.advance().text.to_lowercase();
19917 if self.match_token(TokenType::Eq) {
19918 let value = self.advance().text.clone();
19919 properties.push((name, value));
19920 } else {
19921 break;
19923 }
19924 } else {
19925 break;
19926 }
19927 }
19928 }
19929
19930 Ok(Expression::Describe(Box::new(Describe {
19931 target,
19932 extended,
19933 formatted,
19934 kind,
19935 properties,
19936 style,
19937 partition,
19938 leading_comments,
19939 as_json,
19940 })))
19941 }
19942
19943 fn parse_show(&mut self) -> Result<Expression> {
19946 self.expect(TokenType::Show)?;
19947
19948 let terse = self.match_identifier("TERSE");
19950
19951 let mut this_parts = Vec::new();
19954 let mut target: Option<Expression> = None;
19955 let mut mutex: Option<bool> = None;
19956
19957 while !self.is_at_end() {
19960 let current = self.peek();
19961 if matches!(
19963 current.token_type,
19964 TokenType::Like
19965 | TokenType::In
19966 | TokenType::From
19967 | TokenType::Limit
19968 | TokenType::Semicolon
19969 | TokenType::Eof
19970 | TokenType::Where
19971 | TokenType::For
19972 | TokenType::Offset
19973 | TokenType::Settings
19974 ) {
19975 if current.token_type == TokenType::Settings
19977 && matches!(
19978 self.config.dialect,
19979 Some(crate::dialects::DialectType::ClickHouse)
19980 )
19981 && this_parts.join(" ") == "CREATE"
19982 {
19983 } else {
19985 break;
19986 }
19987 }
19988 if current.token_type == TokenType::Comma {
19991 if !this_parts.is_empty() {
19992 let last = this_parts.pop().unwrap();
19993 this_parts.push(format!("{},", last));
19994 }
19995 self.skip();
19996 continue;
19997 }
19998 if !this_parts.is_empty() && current.text.eq_ignore_ascii_case("HISTORY") {
20000 break;
20001 }
20002 if current.text.eq_ignore_ascii_case("STARTS") {
20004 break;
20005 }
20006 let joined_check = this_parts.join(" ");
20009 if joined_check == "PLAN" && current.token_type == TokenType::Number {
20010 let id = self.advance().text;
20011 target = Some(Expression::Literal(Box::new(Literal::Number(id))));
20012 break;
20013 }
20014 if current.token_type == TokenType::Var || current.token_type.is_keyword() {
20016 let joined = this_parts.join(" ");
20017
20018 if matches!(
20021 joined.as_str(),
20022 "CREATE AGGREGATE" | "CREATE PIPELINE" | "CREATE PROJECTION"
20023 ) {
20024 let name = self.advance().text;
20025 target = Some(Expression::Identifier(Identifier::new(name)));
20026 break;
20027 }
20028
20029 if current.text.eq_ignore_ascii_case("ON") && !this_parts.is_empty() {
20032 this_parts.push("ON".to_string());
20033 self.skip();
20034 if !self.is_at_end() {
20036 let next = self.peek();
20037 if next.text.eq_ignore_ascii_case("TABLE") {
20039 this_parts.push("TABLE".to_string());
20040 self.skip();
20041 }
20042 if !self.is_at_end() {
20044 let name_tok = self.peek();
20045 if name_tok.token_type == TokenType::Var
20046 || name_tok.token_type.is_keyword()
20047 {
20048 let name = self.advance().text;
20049 target = Some(Expression::Identifier(Identifier::new(name)));
20050 }
20051 }
20052 }
20053 break;
20054 }
20055
20056 if current.text.eq_ignore_ascii_case("INTO") && joined == "REPRODUCTION" {
20058 this_parts.push("INTO".to_string());
20059 self.skip();
20060 if !self.is_at_end() && self.peek().text.eq_ignore_ascii_case("OUTFILE") {
20061 this_parts.push("OUTFILE".to_string());
20062 self.skip();
20063 if !self.is_at_end() && self.check(TokenType::String) {
20065 let filename = self.advance().text;
20066 target = Some(Expression::Literal(Box::new(Literal::String(filename))));
20067 }
20068 }
20069 break;
20070 }
20071
20072 if joined == "PLAN" {
20074 if current.text.eq_ignore_ascii_case("JSON") {
20076 this_parts.push("JSON".to_string());
20077 self.skip();
20078 if !self.is_at_end() && self.check(TokenType::Number) {
20080 let id = self.advance().text;
20081 target = Some(Expression::Literal(Box::new(Literal::Number(id))));
20082 }
20083 break;
20084 }
20085 if current.token_type == TokenType::Number {
20087 let id = self.advance().text;
20088 target = Some(Expression::Literal(Box::new(Literal::Number(id))));
20089 break;
20090 }
20091 }
20092
20093 this_parts.push(current.text.to_ascii_uppercase());
20094 self.skip();
20095
20096 let joined = this_parts.join(" ");
20099 if matches!(
20100 joined.as_str(),
20101 "CREATE TABLE"
20102 | "CREATE VIEW"
20103 | "CREATE DICTIONARY"
20104 | "CREATE DATABASE"
20105 | "CREATE MATERIALIZED VIEW"
20106 | "CREATE LIVE VIEW"
20107 ) {
20108 if !self.is_at_end()
20109 && (self.check(TokenType::Var)
20110 || self.check(TokenType::QuotedIdentifier)
20111 || self.is_safe_keyword_as_identifier())
20112 {
20113 let table = self.parse_table_ref()?;
20114 target = Some(Expression::Table(Box::new(table)));
20115 }
20116 break;
20117 }
20118
20119 if matches!(
20122 self.config.dialect,
20123 Some(crate::dialects::DialectType::ClickHouse)
20124 ) && (matches!(
20125 joined.as_str(),
20126 "CREATE ROLE"
20127 | "CREATE QUOTA"
20128 | "CREATE SETTINGS PROFILE"
20129 | "CREATE PROFILE"
20130 | "CREATE ROW POLICY"
20131 | "CREATE POLICY"
20132 | "CREATE USER"
20133 ) || matches!(
20134 joined.as_str(),
20135 "SHOW CREATE ROLE"
20136 | "SHOW CREATE QUOTA"
20137 | "SHOW CREATE SETTINGS PROFILE"
20138 | "SHOW CREATE PROFILE"
20139 | "SHOW CREATE ROW POLICY"
20140 | "SHOW CREATE POLICY"
20141 | "SHOW CREATE USER"
20142 )) {
20143 let mut parts = Vec::new();
20144 while !self.is_at_end() && self.peek().token_type != TokenType::Semicolon {
20145 parts.push(self.advance().text.clone());
20146 }
20147 target = Some(Expression::Identifier(Identifier::new(parts.join(" "))));
20148 break;
20149 }
20150
20151 if joined == "CREATE"
20154 && matches!(
20155 self.config.dialect,
20156 Some(crate::dialects::DialectType::ClickHouse)
20157 )
20158 && !self.is_at_end()
20159 && (self.check(TokenType::Var) || self.check(TokenType::QuotedIdentifier))
20160 && !matches!(
20161 self.peek().text.to_ascii_uppercase().as_str(),
20162 "TABLE"
20163 | "VIEW"
20164 | "DICTIONARY"
20165 | "DATABASE"
20166 | "MATERIALIZED"
20167 | "LIVE"
20168 | "TEMPORARY"
20169 | "ROLE"
20170 | "QUOTA"
20171 | "POLICY"
20172 | "PROFILE"
20173 | "USER"
20174 | "ROW"
20175 | "SETTINGS"
20176 )
20177 {
20178 let table = self.parse_table_ref()?;
20179 target = Some(Expression::Table(Box::new(table)));
20180 break;
20181 }
20182
20183 if joined == "ENGINE" {
20186 if !self.is_at_end() {
20188 let engine_tok = self.peek();
20189 if engine_tok.token_type == TokenType::Var
20190 || engine_tok.token_type.is_keyword()
20191 {
20192 let engine_name = self.advance().text;
20193 target = Some(Expression::Identifier(Identifier::new(engine_name)));
20194 if !self.is_at_end() {
20196 let next = self.peek();
20197 let next_upper = next.text.to_ascii_uppercase();
20198 if next_upper == "STATUS" {
20199 self.skip();
20200 mutex = Some(false);
20201 } else if next_upper == "MUTEX" {
20202 self.skip();
20203 mutex = Some(true);
20204 }
20205 }
20206 }
20207 }
20208 break;
20209 }
20210 } else {
20211 break;
20212 }
20213 }
20214
20215 let this = this_parts.join(" ");
20216
20217 let history = self.match_identifier("HISTORY");
20219
20220 let for_target = if self.match_token(TokenType::For) {
20223 let mut parts = Vec::new();
20225 while !self.is_at_end() {
20226 let tok = self.peek();
20227 if matches!(
20228 tok.token_type,
20229 TokenType::Like
20230 | TokenType::In
20231 | TokenType::From
20232 | TokenType::Limit
20233 | TokenType::Semicolon
20234 | TokenType::Eof
20235 | TokenType::Where
20236 ) {
20237 break;
20238 }
20239 if tok.token_type == TokenType::Var
20240 || tok.token_type.is_keyword()
20241 || tok.token_type == TokenType::Number
20242 {
20243 parts.push(self.advance().text);
20244 } else if tok.token_type == TokenType::String {
20245 let text = self.advance().text;
20247 parts.push(format!("'{}'", text));
20248 } else {
20249 break;
20250 }
20251 }
20252 if parts.is_empty() {
20253 None
20254 } else {
20255 Some(Expression::Identifier(Identifier::new(parts.join(" "))))
20256 }
20257 } else {
20258 None
20259 };
20260
20261 let like = if self.match_token(TokenType::Like) {
20263 Some(self.parse_primary()?)
20264 } else {
20265 None
20266 };
20267
20268 let (scope_kind, scope) = if self.match_token(TokenType::In) {
20270 let (kind, scope_obj) = if self.match_keyword("ACCOUNT") {
20273 (Some("ACCOUNT".to_string()), None)
20274 } else if self.match_token(TokenType::Database) {
20275 let scope_obj = if !self.is_at_end()
20277 && !self.check(TokenType::Like)
20278 && !self.check(TokenType::Limit)
20279 && !self.check(TokenType::Semicolon)
20280 && !self.check_keyword_text("STARTS")
20281 {
20282 let table = self.parse_table_ref()?;
20283 Some(Expression::Table(Box::new(table)))
20284 } else {
20285 None
20286 };
20287 (Some("DATABASE".to_string()), scope_obj)
20288 } else if self.match_token(TokenType::Schema) {
20289 let scope_obj = if !self.is_at_end()
20291 && !self.check(TokenType::Like)
20292 && !self.check(TokenType::Limit)
20293 && !self.check(TokenType::Semicolon)
20294 && !self.check_keyword_text("STARTS")
20295 {
20296 let table = self.parse_table_ref()?;
20297 Some(Expression::Table(Box::new(table)))
20298 } else {
20299 None
20300 };
20301 (Some("SCHEMA".to_string()), scope_obj)
20302 } else if self.match_token(TokenType::Table) {
20303 let scope_obj = if !self.is_at_end()
20305 && !self.check(TokenType::Like)
20306 && !self.check(TokenType::Limit)
20307 && !self.check(TokenType::Semicolon)
20308 && !self.check_keyword_text("STARTS")
20309 {
20310 let table = self.parse_table_ref()?;
20311 Some(Expression::Table(Box::new(table)))
20312 } else {
20313 None
20314 };
20315 (Some("TABLE".to_string()), scope_obj)
20316 } else if self.match_token(TokenType::View) {
20317 let scope_obj = if !self.is_at_end()
20319 && !self.check(TokenType::Like)
20320 && !self.check(TokenType::Limit)
20321 && !self.check(TokenType::Semicolon)
20322 && !self.check_keyword_text("STARTS")
20323 {
20324 let table = self.parse_table_ref()?;
20325 Some(Expression::Table(Box::new(table)))
20326 } else {
20327 None
20328 };
20329 (Some("VIEW".to_string()), scope_obj)
20330 } else if self.match_keyword("CLASS") {
20331 let scope_obj = if !self.is_at_end() {
20333 let table = self.parse_table_ref()?;
20334 Some(Expression::Table(Box::new(table)))
20335 } else {
20336 None
20337 };
20338 (Some("CLASS".to_string()), scope_obj)
20339 } else if self.match_keyword("APPLICATION") {
20340 let kind = if self.match_keyword("PACKAGE") {
20342 "APPLICATION PACKAGE".to_string()
20343 } else {
20344 "APPLICATION".to_string()
20345 };
20346 let scope_obj = if !self.is_at_end() {
20347 let table = self.parse_table_ref()?;
20348 Some(Expression::Table(Box::new(table)))
20349 } else {
20350 None
20351 };
20352 (Some(kind), scope_obj)
20353 } else {
20354 let table = self.parse_table_ref()?;
20357 let inferred_kind = match this.as_str() {
20358 "OBJECTS" | "TABLES" | "VIEWS" | "SEQUENCES" | "UNIQUE KEYS"
20359 | "IMPORTED KEYS" => "SCHEMA",
20360 "PRIMARY KEYS" => "TABLE",
20361 _ => "SCHEMA", };
20363 (
20364 Some(inferred_kind.to_string()),
20365 Some(Expression::Table(Box::new(table))),
20366 )
20367 };
20368 (kind, scope_obj)
20369 } else {
20370 (None, None)
20371 };
20372
20373 let starts_with = if self.match_keyword("STARTS") {
20375 self.match_token(TokenType::With); Some(self.parse_primary()?)
20377 } else {
20378 None
20379 };
20380
20381 let limit = if self.match_token(TokenType::Limit) {
20383 Some(Box::new(Limit {
20384 this: self.parse_expression()?,
20385 percent: false,
20386 comments: Vec::new(),
20387 }))
20388 } else {
20389 None
20390 };
20391
20392 let mut from = if self.match_token(TokenType::From) {
20396 Some(self.parse_primary()?)
20397 } else {
20398 None
20399 };
20400
20401 let mut db = if from.is_some() && self.match_token(TokenType::From) {
20403 Some(self.parse_primary()?)
20404 } else {
20405 None
20406 };
20407
20408 if matches!(this.as_str(), "INDEX" | "COLUMNS") && db.is_none() {
20410 if let Some(from_expr) = from.take() {
20411 match from_expr {
20412 Expression::Table(mut t) => {
20413 if let Some(db_ident) = t.schema.take().or(t.catalog.take()) {
20414 db = Some(Expression::Identifier(db_ident));
20415 from = Some(Expression::Identifier(t.name));
20416 } else {
20417 from = Some(Expression::Table(t));
20418 }
20419 }
20420 Expression::Column(c) => {
20421 if let Some(table_ident) = c.table {
20422 db = Some(Expression::Identifier(table_ident));
20423 from = Some(Expression::Identifier(c.name));
20424 } else {
20425 from = Some(Expression::Column(c));
20426 }
20427 }
20428 Expression::Identifier(id) => {
20429 if let Some((db_name, table_name)) = id.name.split_once('.') {
20430 db = Some(Expression::Identifier(Identifier::new(db_name)));
20431 from = Some(Expression::Identifier(Identifier {
20432 name: table_name.to_string(),
20433 quoted: id.quoted,
20434 trailing_comments: id.trailing_comments,
20435 span: None,
20436 }));
20437 } else {
20438 from = Some(Expression::Identifier(id));
20439 }
20440 }
20441 other => {
20442 from = Some(other);
20443 }
20444 }
20445 }
20446 }
20447
20448 let like = if like.is_none() && self.match_token(TokenType::Like) {
20450 Some(self.parse_primary()?)
20451 } else {
20452 like
20453 };
20454
20455 if matches!(
20457 self.config.dialect,
20458 Some(crate::dialects::DialectType::ClickHouse)
20459 ) && self.check(TokenType::Not)
20460 {
20461 if self.current + 1 < self.tokens.len()
20462 && matches!(
20463 self.tokens[self.current + 1].token_type,
20464 TokenType::Like | TokenType::ILike
20465 )
20466 {
20467 self.skip(); self.skip(); let _ = self.parse_primary()?; }
20471 }
20472
20473 if matches!(
20475 self.config.dialect,
20476 Some(crate::dialects::DialectType::ClickHouse)
20477 ) && self.match_token(TokenType::ILike)
20478 {
20479 let _ = self.parse_primary()?; }
20481
20482 let where_clause = if self.match_token(TokenType::Where) {
20484 Some(self.parse_expression()?)
20485 } else {
20486 None
20487 };
20488
20489 let privileges = if self.match_token(TokenType::With) && self.match_keyword("PRIVILEGES") {
20491 let mut privs = Vec::new();
20493 loop {
20494 if self.is_at_end() || self.check(TokenType::Semicolon) {
20495 break;
20496 }
20497 let tok = self.peek();
20498 if tok.token_type == TokenType::Var || tok.token_type.is_keyword() {
20499 privs.push(self.advance().text.to_ascii_uppercase());
20500 if !self.match_token(TokenType::Comma) {
20502 break;
20503 }
20504 } else {
20505 break;
20506 }
20507 }
20508 privs
20509 } else {
20510 Vec::new()
20511 };
20512
20513 if matches!(
20515 self.config.dialect,
20516 Some(crate::dialects::DialectType::ClickHouse)
20517 ) {
20518 self.parse_clickhouse_settings_clause()?;
20519 }
20520
20521 Ok(Expression::Show(Box::new(Show {
20522 this,
20523 terse,
20524 history,
20525 like,
20526 scope_kind,
20527 scope,
20528 starts_with,
20529 limit,
20530 from,
20531 where_clause,
20532 for_target,
20533 db,
20534 target,
20535 mutex,
20536 privileges,
20537 })))
20538 }
20539
20540 fn parse_copy(&mut self) -> Result<Expression> {
20544 self.expect(TokenType::Copy)?;
20545
20546 let is_into = self.match_token(TokenType::Into);
20548
20549 let this = if self.check(TokenType::LParen) {
20551 self.parse_primary()?
20553 } else if self.check(TokenType::DAt)
20554 || self.check(TokenType::String)
20555 || self.is_stage_reference()
20556 {
20557 self.parse_file_location()?
20559 } else {
20560 let table = self.parse_table_ref()?;
20562 if self.check(TokenType::LParen) {
20564 let has_column_list = {
20567 let start = self.current;
20568 self.skip(); let is_select = self.check(TokenType::Select);
20570 self.current = start; !is_select
20572 };
20573 if has_column_list {
20574 self.skip(); let mut columns = Vec::new();
20576 loop {
20577 let col_name = self.expect_identifier_or_keyword()?;
20578 columns.push(col_name);
20579 if !self.match_token(TokenType::Comma) {
20580 break;
20581 }
20582 }
20583 self.expect(TokenType::RParen)?;
20584 Expression::Schema(Box::new(Schema {
20586 this: Some(Box::new(Expression::Table(Box::new(table)))),
20587 expressions: columns
20588 .into_iter()
20589 .map(|c| {
20590 Expression::boxed_column(Column {
20591 name: Identifier::new(c),
20592 table: None,
20593 join_mark: false,
20594 trailing_comments: Vec::new(),
20595 span: None,
20596 inferred_type: None,
20597 })
20598 })
20599 .collect(),
20600 }))
20601 } else {
20602 Expression::Table(Box::new(table))
20603 }
20604 } else {
20605 Expression::Table(Box::new(table))
20606 }
20607 };
20608
20609 let kind = self.match_token(TokenType::From);
20611 let has_to = if !kind {
20612 self.match_token(TokenType::To)
20614 } else {
20615 false
20616 };
20617
20618 let mut files = Vec::new();
20621 if kind
20622 || has_to
20623 || self.check(TokenType::String)
20624 || self.is_stage_reference()
20625 || self.check(TokenType::LParen)
20626 {
20627 if self.check(TokenType::LParen) {
20629 let start = self.current;
20631 self.skip(); let is_select = self.check(TokenType::Select);
20633 self.current = start; if is_select {
20635 let subquery = self.parse_primary()?;
20637 files.push(subquery);
20638 }
20639 }
20640 while !self.is_at_end() && !self.check(TokenType::Semicolon) && files.is_empty()
20642 || (self.check(TokenType::Comma) && !files.is_empty())
20643 {
20644 if !files.is_empty() && !self.match_token(TokenType::Comma) {
20646 break;
20647 }
20648 if (self.check(TokenType::Var) || self.check_keyword())
20651 && !self.is_stage_reference()
20652 {
20653 let lookahead = self.current + 1;
20654 if lookahead < self.tokens.len()
20655 && self.tokens[lookahead].token_type == TokenType::Eq
20656 {
20657 break; }
20659 }
20660 if self.check(TokenType::With) {
20662 break;
20663 }
20664 if !self.check(TokenType::String)
20667 && !self.is_stage_reference()
20668 && !self.check(TokenType::Var)
20669 && !self.check_keyword()
20670 && !self.check(TokenType::QuotedIdentifier)
20671 {
20672 break;
20673 }
20674 if (self.check(TokenType::Var) || self.is_identifier_token())
20677 && !self.is_stage_reference()
20678 {
20679 let lookahead = self.current + 1;
20680 let has_dot = lookahead < self.tokens.len()
20681 && self.tokens[lookahead].token_type == TokenType::Dot;
20682 if has_dot {
20683 let table = self.parse_table_ref()?;
20684 files.push(Expression::Table(Box::new(table)));
20685 continue;
20686 }
20687 }
20688 let location = self.parse_file_location()?;
20689 files.push(location);
20690 }
20691 }
20692
20693 let mut params = Vec::new();
20695 let mut credentials = None;
20696 let mut with_wrapped = false;
20697
20698 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
20701 let had_with = self.match_token(TokenType::With);
20703
20704 if self.match_token(TokenType::LParen) {
20706 if had_with {
20707 with_wrapped = true;
20708 }
20709 while !self.check(TokenType::RParen) && !self.is_at_end() {
20710 let param = self.parse_copy_parameter()?;
20711 params.push(param);
20712 self.match_token(TokenType::Comma);
20714 }
20715 self.expect(TokenType::RParen)?;
20716 break;
20717 }
20718
20719 if self.check(TokenType::Var) || self.check_keyword() {
20721 let param = self.parse_copy_parameter()?;
20722
20723 if param.name.eq_ignore_ascii_case("CREDENTIALS") {
20725 if let Some(Expression::Literal(lit)) = ¶m.value {
20728 if let Literal::String(s) = lit.as_ref() {
20729 let creds = Credentials {
20731 credentials: vec![("".to_string(), s.clone())],
20732 storage: None,
20733 encryption: None,
20734 };
20735 credentials = Some(Box::new(creds));
20736 }
20737 } else {
20738 let creds = Credentials {
20740 credentials: param
20741 .values
20742 .iter()
20743 .filter_map(|v| {
20744 if let Expression::Eq(eq) = v {
20745 let key = if let Expression::Column(c) = &eq.left {
20746 c.name.name.clone()
20747 } else {
20748 return None;
20749 };
20750 let val = if let Expression::Literal(lit) = &eq.right {
20751 if let Literal::String(s) = lit.as_ref() {
20752 s.clone()
20753 } else {
20754 String::new()
20755 }
20756 } else {
20757 return None;
20758 };
20759 Some((key, val))
20760 } else {
20761 None
20762 }
20763 })
20764 .collect(),
20765 storage: None,
20766 encryption: None,
20767 };
20768 credentials = Some(Box::new(creds));
20769 }
20770 } else if param.name.eq_ignore_ascii_case("STORAGE_INTEGRATION") {
20771 params.push(param);
20774 } else {
20775 params.push(param);
20776 }
20777 } else {
20778 break;
20779 }
20780 }
20781
20782 Ok(Expression::Copy(Box::new(CopyStmt {
20783 this,
20784 kind,
20785 files,
20786 params,
20787 credentials,
20788 is_into,
20789 with_wrapped,
20790 })))
20791 }
20792
20793 fn parse_copy_parameter(&mut self) -> Result<CopyParameter> {
20795 let name = self.expect_identifier_or_keyword()?;
20797
20798 let mut value = None;
20799 let mut values = Vec::new();
20800
20801 let has_eq = self.match_token(TokenType::Eq);
20802
20803 if has_eq {
20804 if self.match_token(TokenType::LParen) {
20805 if self.check(TokenType::String) || self.check(TokenType::Number) {
20809 while !self.check(TokenType::RParen) && !self.is_at_end() {
20811 values.push(self.parse_primary()?);
20812 if !self.match_token(TokenType::Comma) {
20813 break;
20814 }
20815 }
20816 } else {
20817 while !self.check(TokenType::RParen) && !self.is_at_end() {
20819 let nested_key = self.expect_identifier_or_keyword()?.to_ascii_uppercase();
20821 if self.match_token(TokenType::Eq) {
20822 let nested_value = self.parse_copy_param_value()?;
20823 values.push(Expression::Eq(Box::new(BinaryOp {
20825 left: Expression::boxed_column(Column {
20826 name: Identifier::new(nested_key),
20827 table: None,
20828 join_mark: false,
20829 trailing_comments: Vec::new(),
20830 span: None,
20831 inferred_type: None,
20832 }),
20833 right: nested_value,
20834 left_comments: Vec::new(),
20835 operator_comments: Vec::new(),
20836 trailing_comments: Vec::new(),
20837 inferred_type: None,
20838 })));
20839 } else {
20840 values.push(Expression::boxed_column(Column {
20842 name: Identifier::new(nested_key),
20843 table: None,
20844 join_mark: false,
20845 trailing_comments: Vec::new(),
20846 span: None,
20847 inferred_type: None,
20848 }));
20849 }
20850 self.match_token(TokenType::Comma);
20852 }
20853 }
20854 self.expect(TokenType::RParen)?;
20855 } else {
20856 value = Some(self.parse_copy_param_value()?);
20858 }
20859 } else {
20860 if self.check(TokenType::LParen) {
20863 let is_varlen_option = matches!(
20866 name.as_str(),
20867 "FORMAT_OPTIONS" | "COPY_OPTIONS" | "FILE_FORMAT" | "CREDENTIAL"
20868 );
20869
20870 self.skip(); if is_varlen_option {
20873 while !self.check(TokenType::RParen) && !self.is_at_end() {
20875 if self.check(TokenType::String) {
20876 let key_token = self.advance();
20878 let key = key_token.text.clone();
20879 if self.match_token(TokenType::Eq) {
20880 let val = self.parse_copy_param_value()?;
20881 values.push(Expression::Eq(Box::new(BinaryOp {
20882 left: Expression::Literal(Box::new(Literal::String(key))),
20883 right: val,
20884 left_comments: Vec::new(),
20885 operator_comments: Vec::new(),
20886 trailing_comments: Vec::new(),
20887 inferred_type: None,
20888 })));
20889 } else {
20890 values.push(Expression::Literal(Box::new(Literal::String(key))));
20892 }
20893 } else if self.check(TokenType::Var)
20894 || self.check_keyword()
20895 || self.is_identifier_token()
20896 {
20897 let key = self.advance().text.clone();
20899 if self.match_token(TokenType::Eq) {
20900 let val = self.parse_copy_param_value()?;
20901 values.push(Expression::Eq(Box::new(BinaryOp {
20902 left: Expression::boxed_column(Column {
20903 name: Identifier::new(key),
20904 table: None,
20905 join_mark: false,
20906 trailing_comments: Vec::new(),
20907 span: None,
20908 inferred_type: None,
20909 }),
20910 right: val,
20911 left_comments: Vec::new(),
20912 operator_comments: Vec::new(),
20913 trailing_comments: Vec::new(),
20914 inferred_type: None,
20915 })));
20916 } else {
20917 values.push(Expression::boxed_column(Column {
20919 name: Identifier::new(key),
20920 table: None,
20921 join_mark: false,
20922 trailing_comments: Vec::new(),
20923 span: None,
20924 inferred_type: None,
20925 }));
20926 }
20927 } else {
20928 break;
20929 }
20930 self.match_token(TokenType::Comma);
20931 }
20932 } else {
20933 let mut items = Vec::new();
20935 while !self.check(TokenType::RParen) && !self.is_at_end() {
20936 items.push(self.parse_primary()?);
20937 if !self.match_token(TokenType::Comma) {
20938 break;
20939 }
20940 }
20941 value = Some(Expression::Tuple(Box::new(Tuple { expressions: items })));
20942 }
20943 self.expect(TokenType::RParen)?;
20944 } else if self.check(TokenType::LBrace) {
20945 value = Some(self.parse_primary()?);
20947 } else if self.check(TokenType::String) || self.check(TokenType::Number) {
20948 value = Some(self.parse_copy_param_value()?);
20950 } else if self.check(TokenType::True) || self.check(TokenType::False) {
20951 value = Some(self.parse_copy_param_value()?);
20953 } else if !self.check(TokenType::Comma)
20954 && !self.check(TokenType::RParen)
20955 && !self.is_at_end()
20956 && !self.check(TokenType::Semicolon)
20957 {
20958 let name_upper = name.to_ascii_uppercase();
20961 let is_flag_param = matches!(
20962 name_upper.as_str(),
20963 "EMPTYASNULL"
20964 | "BLANKSASNULL"
20965 | "ACCEPTINVCHARS"
20966 | "COMPUPDATE"
20967 | "STATUPDATE"
20968 | "NOLOAD"
20969 | "ESCAPE"
20970 | "REMOVEQUOTES"
20971 | "EXPLICIT_IDS"
20972 | "FILLRECORD"
20973 | "TRIMBLANKS"
20974 | "TRUNCATECOLUMNS"
20975 | "ROUNDEC"
20976 | "IGNOREHEADER"
20977 | "IGNOREBLANKLINES"
20978 | "ACCEPTANYDATE"
20979 );
20980 if !is_flag_param && (self.check(TokenType::Var) || self.check_keyword()) {
20981 value = Some(self.parse_copy_param_value()?);
20982 }
20983 }
20984 }
20986
20987 Ok(CopyParameter {
20988 name,
20989 value,
20990 values,
20991 eq: has_eq,
20992 })
20993 }
20994
20995 fn parse_copy_param_value(&mut self) -> Result<Expression> {
20997 if self.match_token(TokenType::LParen) {
20999 let mut items = Vec::new();
21000 while !self.check(TokenType::RParen) && !self.is_at_end() {
21001 items.push(self.parse_primary()?);
21002 if !self.match_token(TokenType::Comma) {
21003 break;
21004 }
21005 }
21006 self.expect(TokenType::RParen)?;
21007 return Ok(Expression::Tuple(Box::new(Tuple { expressions: items })));
21008 }
21009
21010 if self.check(TokenType::String) {
21012 let token = self.advance();
21013 return Ok(Expression::Literal(Box::new(Literal::String(
21014 token.text.clone(),
21015 ))));
21016 }
21017 if self.check(TokenType::QuotedIdentifier) {
21019 let token = self.advance();
21020 return Ok(Expression::boxed_column(Column {
21021 name: Identifier::quoted(token.text.clone()),
21022 table: None,
21023 join_mark: false,
21024 trailing_comments: Vec::new(),
21025 span: None,
21026 inferred_type: None,
21027 }));
21028 }
21029 if self.check(TokenType::Number) {
21030 let token = self.advance();
21031 return Ok(Expression::Literal(Box::new(Literal::Number(
21032 token.text.clone(),
21033 ))));
21034 }
21035 if self.match_token(TokenType::True) {
21036 return Ok(Expression::Boolean(BooleanLiteral { value: true }));
21037 }
21038 if self.match_token(TokenType::False) {
21039 return Ok(Expression::Boolean(BooleanLiteral { value: false }));
21040 }
21041 if self.check(TokenType::Var) || self.check_keyword() {
21043 let first = self.advance().text.clone();
21045 if self.match_token(TokenType::Dot) {
21046 let second = self.expect_identifier_or_keyword()?;
21047 if self.match_token(TokenType::Dot) {
21048 let third = self.expect_identifier_or_keyword()?;
21049 return Ok(Expression::boxed_column(Column {
21050 name: Identifier::new(format!("{}.{}.{}", first, second, third)),
21051 table: None,
21052 join_mark: false,
21053 trailing_comments: Vec::new(),
21054 span: None,
21055 inferred_type: None,
21056 }));
21057 }
21058 return Ok(Expression::boxed_column(Column {
21059 name: Identifier::new(format!("{}.{}", first, second)),
21060 table: None,
21061 join_mark: false,
21062 trailing_comments: Vec::new(),
21063 span: None,
21064 inferred_type: None,
21065 }));
21066 }
21067 return Ok(Expression::boxed_column(Column {
21068 name: Identifier::new(first),
21069 table: None,
21070 join_mark: false,
21071 trailing_comments: Vec::new(),
21072 span: None,
21073 inferred_type: None,
21074 }));
21075 }
21076
21077 Err(self.parse_error("Expected value for COPY parameter"))
21078 }
21079
21080 fn parse_stage_reference_from_string(&mut self) -> Result<Expression> {
21083 use crate::expressions::StageReference;
21084
21085 let string_token = self.advance();
21087 let full_path = string_token.text.clone();
21088
21089 let parts: Vec<&str> = full_path.splitn(2, '/').collect();
21091 let name = parts[0].to_string();
21092 let path = if parts.len() > 1 {
21093 Some(format!("/{}", parts[1]))
21094 } else {
21095 None
21096 };
21097
21098 let (file_format, pattern) = if self.match_token(TokenType::LParen) {
21100 let mut ff = None;
21101 let mut pat = None;
21102
21103 loop {
21104 if self.match_identifier("FILE_FORMAT") {
21105 self.expect(TokenType::FArrow)?; ff = Some(self.parse_primary()?);
21107 } else if self.match_identifier("PATTERN") || self.match_token(TokenType::Pattern) {
21108 self.expect(TokenType::FArrow)?; if let Expression::Literal(lit) = self.parse_primary()? {
21111 if let Literal::String(s) = lit.as_ref() {
21112 pat = Some(s.clone());
21113 }
21114 }
21115 } else {
21116 break;
21117 }
21118
21119 if !self.match_token(TokenType::Comma) {
21120 break;
21121 }
21122 }
21123
21124 self.expect(TokenType::RParen)?;
21125 (ff, pat)
21126 } else {
21127 (None, None)
21128 };
21129
21130 Ok(Expression::StageReference(Box::new(StageReference {
21131 name,
21132 path,
21133 file_format,
21134 pattern,
21135 quoted: true, })))
21137 }
21138
21139 fn parse_stage_reference_from_var(&mut self) -> Result<Expression> {
21142 use crate::expressions::StageReference;
21143
21144 let var_token = self.advance();
21146 let mut name = var_token.text.clone();
21147
21148 while self.match_token(TokenType::Dot) {
21150 name.push('.');
21151 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
21152 name.push_str(&self.advance().text);
21153 } else if self.check(TokenType::Percent) {
21154 self.skip();
21156 name.push('%');
21157 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
21158 name.push_str(&self.advance().text);
21159 }
21160 } else {
21161 break;
21162 }
21163 }
21164
21165 let path = if self.match_token(TokenType::Slash) {
21167 let mut path_str = String::from("/");
21168 while !self.is_at_end() {
21170 if self.check(TokenType::Identifier)
21171 || self.check(TokenType::Var)
21172 || self.check(TokenType::Number)
21173 || self.check(TokenType::Dot)
21174 || self.check(TokenType::Dash)
21175 || self.check(TokenType::Star)
21176 || self.check(TokenType::To)
21177 || self.is_safe_keyword_as_identifier()
21178 {
21179 path_str.push_str(&self.advance().text);
21180 } else if self.match_token(TokenType::Slash) {
21181 path_str.push('/');
21182 } else {
21183 break;
21184 }
21185 }
21186 Some(path_str)
21187 } else {
21188 None
21189 };
21190
21191 let (file_format, pattern) = if self.match_token(TokenType::LParen) {
21193 let mut ff = None;
21194 let mut pat = None;
21195
21196 loop {
21197 if self.match_identifier("FILE_FORMAT") {
21198 self.expect(TokenType::FArrow)?; ff = Some(self.parse_primary()?);
21200 } else if self.match_identifier("PATTERN") || self.match_token(TokenType::Pattern) {
21201 self.expect(TokenType::FArrow)?; if let Expression::Literal(lit) = self.parse_primary()? {
21204 if let Literal::String(s) = lit.as_ref() {
21205 pat = Some(s.clone());
21206 }
21207 }
21208 } else {
21209 break;
21210 }
21211
21212 if !self.match_token(TokenType::Comma) {
21213 break;
21214 }
21215 }
21216
21217 self.expect(TokenType::RParen)?;
21218 (ff, pat)
21219 } else {
21220 (None, None)
21221 };
21222
21223 Ok(Expression::StageReference(Box::new(StageReference {
21224 name,
21225 path,
21226 file_format,
21227 pattern,
21228 quoted: false,
21229 })))
21230 }
21231
21232 fn parse_stage_reference(&mut self) -> Result<Expression> {
21235 use crate::expressions::StageReference;
21236
21237 self.expect(TokenType::DAt)?; let mut name = String::from("@");
21241
21242 if self.check(TokenType::Tilde) {
21246 self.skip();
21247 name.push('~');
21248 } else if self.check(TokenType::Percent) {
21249 self.skip();
21250 name.push('%');
21251 loop {
21253 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
21254 name.push_str(&self.advance().text);
21255 } else {
21256 break;
21257 }
21258 if self.match_token(TokenType::Dot) {
21260 name.push('.');
21261 } else {
21262 break;
21263 }
21264 }
21265 } else {
21266 loop {
21268 if self.check(TokenType::QuotedIdentifier) {
21269 let text = self.advance().text;
21271 name.push('"');
21272 name.push_str(&text);
21273 name.push('"');
21274 } else if self.check(TokenType::Percent) {
21275 self.skip();
21277 name.push('%');
21278 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
21279 name.push_str(&self.advance().text);
21280 }
21281 } else if self.check(TokenType::Identifier)
21282 || self.check(TokenType::Var)
21283 || self.is_safe_keyword_as_identifier()
21284 {
21285 name.push_str(&self.advance().text);
21286 } else {
21287 break;
21288 }
21289
21290 if self.match_token(TokenType::Dot) {
21292 name.push('.');
21293 } else {
21294 break;
21295 }
21296 }
21297 }
21298
21299 let path = if self.match_token(TokenType::Slash) {
21301 let mut path_str = String::from("/");
21302 while !self.is_at_end() {
21305 if self.check(TokenType::Identifier)
21306 || self.check(TokenType::Var)
21307 || self.check(TokenType::Number)
21308 || self.check(TokenType::Dot)
21309 || self.check(TokenType::Dash)
21310 || self.check(TokenType::Star)
21311 || self.check(TokenType::To)
21312 || self.is_safe_keyword_as_identifier()
21313 {
21314 path_str.push_str(&self.advance().text);
21315 } else if self.match_token(TokenType::Slash) {
21316 path_str.push('/');
21317 } else {
21318 break;
21319 }
21320 }
21321 Some(path_str)
21322 } else {
21323 None
21324 };
21325
21326 let (file_format, pattern) = if self.match_token(TokenType::LParen) {
21328 let mut ff = None;
21329 let mut pat = None;
21330
21331 loop {
21332 if self.match_identifier("FILE_FORMAT") {
21333 self.expect(TokenType::FArrow)?; ff = Some(self.parse_primary()?);
21335 } else if self.match_identifier("PATTERN") || self.match_token(TokenType::Pattern) {
21336 self.expect(TokenType::FArrow)?; if let Expression::Literal(lit) = self.parse_primary()? {
21339 if let Literal::String(s) = lit.as_ref() {
21340 pat = Some(s.clone());
21341 }
21342 }
21343 } else {
21344 break;
21345 }
21346
21347 if !self.match_token(TokenType::Comma) {
21348 break;
21349 }
21350 }
21351
21352 self.expect(TokenType::RParen)?;
21353 (ff, pat)
21354 } else {
21355 (None, None)
21356 };
21357
21358 Ok(Expression::StageReference(Box::new(StageReference {
21359 name,
21360 path,
21361 file_format,
21362 pattern,
21363 quoted: false,
21364 })))
21365 }
21366
21367 fn parse_file_location(&mut self) -> Result<Expression> {
21370 if self.check(TokenType::DAt) {
21372 self.skip(); let mut stage_path = String::from("@");
21374
21375 if self.check(TokenType::Percent) || self.check(TokenType::Mod) {
21377 stage_path.push('%');
21378 self.skip(); }
21380 else if self.check(TokenType::Tilde) {
21382 stage_path.push('~');
21383 self.skip(); }
21385
21386 if self.check(TokenType::Var) || self.check_keyword() || self.is_identifier_token() {
21388 stage_path.push_str(&self.advance().text);
21389 }
21390 while self.check(TokenType::Dot) {
21392 self.skip(); stage_path.push('.');
21394 if self.check(TokenType::Var) || self.check_keyword() || self.is_identifier_token()
21395 {
21396 stage_path.push_str(&self.advance().text);
21397 }
21398 }
21399 if self.match_token(TokenType::Slash) {
21403 stage_path.push('/');
21404 while !self.is_at_end() {
21405 if (self.check(TokenType::Var)
21406 || self.check(TokenType::Identifier)
21407 || self.check(TokenType::Number)
21408 || self.check(TokenType::Dot)
21409 || self.check(TokenType::Dash)
21410 || self.check(TokenType::Star)
21411 || self.check(TokenType::To)
21412 || self.is_safe_keyword_as_identifier())
21413 && !self.check_next(TokenType::Eq)
21414 {
21415 stage_path.push_str(&self.advance().text);
21416 } else if self.match_token(TokenType::Slash) {
21417 stage_path.push('/');
21418 } else {
21419 break;
21420 }
21421 }
21422 }
21423 return Ok(Expression::Literal(Box::new(Literal::String(stage_path))));
21424 }
21425
21426 if self.check(TokenType::Var) && self.peek().text.starts_with('@') {
21429 let mut stage_path = self.advance().text.clone();
21430 while self.check(TokenType::Dot) {
21432 self.skip(); stage_path.push('.');
21434 if self.check(TokenType::Var) || self.check_keyword() || self.is_identifier_token()
21435 {
21436 stage_path.push_str(&self.advance().text);
21437 }
21438 }
21439 if self.match_token(TokenType::Slash) {
21441 stage_path.push('/');
21442 while !self.is_at_end() {
21443 if (self.check(TokenType::Var)
21444 || self.check(TokenType::Identifier)
21445 || self.check(TokenType::Number)
21446 || self.check(TokenType::Dot)
21447 || self.check(TokenType::Dash)
21448 || self.check(TokenType::Star)
21449 || self.check(TokenType::To)
21450 || self.is_safe_keyword_as_identifier())
21451 && !self.check_next(TokenType::Eq)
21452 {
21453 stage_path.push_str(&self.advance().text);
21454 } else if self.match_token(TokenType::Slash) {
21455 stage_path.push('/');
21456 } else {
21457 break;
21458 }
21459 }
21460 }
21461 return Ok(Expression::Literal(Box::new(Literal::String(stage_path))));
21462 }
21463
21464 if self.check(TokenType::String) {
21466 let token = self.advance();
21467 return Ok(Expression::Literal(Box::new(Literal::String(
21468 token.text.clone(),
21469 ))));
21470 }
21471
21472 if self.check(TokenType::QuotedIdentifier) {
21474 let token = self.advance();
21475 return Ok(Expression::Identifier(Identifier::quoted(
21476 token.text.clone(),
21477 )));
21478 }
21479
21480 if self.check(TokenType::Var) || self.check_keyword() {
21482 let ident = self.advance().text.clone();
21483 return Ok(Expression::boxed_column(Column {
21484 name: Identifier::new(ident),
21485 table: None,
21486 join_mark: false,
21487 trailing_comments: Vec::new(),
21488 span: None,
21489 inferred_type: None,
21490 }));
21491 }
21492
21493 Err(self.parse_error("Expected file location"))
21494 }
21495
21496 fn parse_stage_reference_as_string(&mut self) -> Result<Expression> {
21500 if self.check(TokenType::DAt) {
21502 self.skip(); let mut stage_path = String::from("@");
21504
21505 if self.check(TokenType::Percent) || self.check(TokenType::Mod) {
21507 stage_path.push('%');
21508 self.skip(); }
21510 else if self.check(TokenType::Tilde) {
21512 stage_path.push('~');
21513 self.skip(); while self.check(TokenType::Slash) {
21516 self.skip(); stage_path.push('/');
21518 if (self.check(TokenType::Var)
21519 || self.check_keyword()
21520 || self.is_identifier_token())
21521 && !self.check_next(TokenType::Eq)
21522 {
21523 stage_path.push_str(&self.advance().text);
21524 }
21525 }
21526 return Ok(Expression::Literal(Box::new(Literal::String(stage_path))));
21527 }
21528
21529 if self.check(TokenType::QuotedIdentifier) {
21531 let text = &self.peek().text;
21533 stage_path.push('"');
21534 stage_path.push_str(text);
21535 stage_path.push('"');
21536 self.skip();
21537 } else if self.check(TokenType::Var)
21538 || self.check_keyword()
21539 || self.check(TokenType::Identifier)
21540 {
21541 stage_path.push_str(&self.advance().text);
21542 }
21543
21544 while self.check(TokenType::Dot) {
21546 self.skip(); stage_path.push('.');
21548 if self.check(TokenType::QuotedIdentifier) {
21549 let text = &self.peek().text;
21551 stage_path.push('"');
21552 stage_path.push_str(text);
21553 stage_path.push('"');
21554 self.skip();
21555 } else if self.check(TokenType::Var)
21556 || self.check_keyword()
21557 || self.check(TokenType::Identifier)
21558 {
21559 stage_path.push_str(&self.advance().text);
21560 }
21561 }
21562
21563 while self.check(TokenType::Slash) {
21565 self.skip(); stage_path.push('/');
21567 if (self.check(TokenType::Var)
21569 || self.check_keyword()
21570 || self.is_identifier_token())
21571 && !self.check_next(TokenType::Eq)
21572 {
21573 stage_path.push_str(&self.advance().text);
21574 }
21575 }
21576 return Ok(Expression::Literal(Box::new(Literal::String(stage_path))));
21577 }
21578
21579 if self.check(TokenType::Var) && self.peek().text.starts_with('@') {
21581 let mut stage_path = self.advance().text.clone();
21582
21583 while self.check(TokenType::Dot) {
21585 self.skip(); stage_path.push('.');
21587 if self.check(TokenType::QuotedIdentifier) {
21588 let text = &self.peek().text;
21589 stage_path.push('"');
21590 stage_path.push_str(text);
21591 stage_path.push('"');
21592 self.skip();
21593 } else if self.check(TokenType::Var)
21594 || self.check_keyword()
21595 || self.check(TokenType::Identifier)
21596 {
21597 stage_path.push_str(&self.advance().text);
21598 }
21599 }
21600
21601 while self.check(TokenType::Slash) {
21603 self.skip(); stage_path.push('/');
21605 if (self.check(TokenType::Var)
21606 || self.check_keyword()
21607 || self.is_identifier_token())
21608 && !self.check_next(TokenType::Eq)
21609 {
21610 stage_path.push_str(&self.advance().text);
21611 }
21612 }
21613 return Ok(Expression::Literal(Box::new(Literal::String(stage_path))));
21614 }
21615
21616 Err(self.parse_error("Expected stage reference starting with @"))
21617 }
21618
21619 fn parse_put(&mut self) -> Result<Expression> {
21622 self.expect(TokenType::Put)?;
21623
21624 let (source, source_quoted) = if self.check(TokenType::String) {
21626 (self.advance().text.clone(), true)
21627 } else {
21628 let mut source_parts = Vec::new();
21631 while !self.is_at_end() {
21632 if self.check(TokenType::DAt) {
21634 break;
21635 }
21636 if self.check(TokenType::Var) && self.peek().text.starts_with('@') {
21637 break;
21638 }
21639 let token = self.advance();
21640 source_parts.push(token.text.clone());
21641 }
21642 (source_parts.join(""), false)
21643 };
21644
21645 let target = self.parse_stage_reference_as_string()?;
21647
21648 let mut params = Vec::new();
21652 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
21653 let is_param_name = self.check(TokenType::Var)
21654 || self.check_keyword()
21655 || self.check(TokenType::Overwrite);
21656 if is_param_name {
21657 let name = self.advance().text.clone();
21658 let value = if self.match_token(TokenType::Eq) {
21659 Some(self.parse_primary()?)
21660 } else {
21661 None
21662 };
21663 params.push(CopyParameter {
21664 name,
21665 value,
21666 values: Vec::new(),
21667 eq: true,
21668 });
21669 } else {
21670 break;
21671 }
21672 }
21673
21674 Ok(Expression::Put(Box::new(PutStmt {
21675 source,
21676 source_quoted,
21677 target,
21678 params,
21679 })))
21680 }
21681
21682 fn join_command_tokens(&self, tokens: Vec<(String, TokenType)>) -> String {
21685 let mut result = String::new();
21686 let mut prev_token_type: Option<TokenType> = None;
21687 let mut prev_prev_token_type: Option<TokenType> = None;
21688
21689 for (i, (text, token_type)) in tokens.iter().enumerate() {
21690 let needs_space = if result.is_empty() {
21691 false
21692 } else {
21693 match (prev_token_type, *token_type) {
21694 (Some(TokenType::DAt), _) => false,
21696 (Some(TokenType::Dot), _) => false,
21698 (_, TokenType::Dot) => false,
21699 (Some(TokenType::LParen), _) => false,
21701 (_, TokenType::LParen) => false,
21702 (_, TokenType::RParen) => false,
21703 (Some(TokenType::LBracket), _) => false,
21705 (_, TokenType::LBracket) => false,
21706 (_, TokenType::RBracket) => false,
21707 (_, TokenType::Comma) => false,
21709 (Some(TokenType::Slash), _) => false,
21711 (_, TokenType::Slash) => false,
21712 (Some(TokenType::Colon), _) => false,
21714 (_, TokenType::Colon) => false,
21715 (Some(TokenType::Mod), _) => false,
21717 (_, TokenType::Mod) => false,
21718 (Some(TokenType::Percent), _) => false,
21719 (_, TokenType::Percent) => false,
21720 (Some(TokenType::Var), TokenType::Eq) => {
21725 if i >= 1 && tokens[i - 1].0.starts_with('@') {
21727 true
21728 } else if i + 1 < tokens.len() {
21729 let next_type = tokens[i + 1].1;
21731 let is_terminal_value =
21733 i + 2 >= tokens.len() || tokens[i + 2].1 == TokenType::Var;
21734 match next_type {
21735 TokenType::Number | TokenType::True | TokenType::False => {
21738 !is_terminal_value
21739 }
21740 TokenType::String => !is_terminal_value,
21742 _ => true,
21744 }
21745 } else {
21746 true
21747 }
21748 }
21749 (Some(TokenType::Eq), TokenType::Number)
21751 | (Some(TokenType::Eq), TokenType::True)
21752 | (Some(TokenType::Eq), TokenType::False)
21753 | (Some(TokenType::Eq), TokenType::String) => {
21754 let is_terminal =
21756 i + 1 >= tokens.len() || tokens[i + 1].1 == TokenType::Var;
21757 match prev_prev_token_type {
21758 Some(TokenType::Var) => {
21761 if i >= 2 && tokens[i - 2].0.starts_with('@') {
21763 true
21764 } else {
21765 !is_terminal
21766 }
21767 }
21768 _ => true, }
21770 }
21771 (Some(TokenType::Eq), TokenType::Var) => true,
21773 (Some(TokenType::DColon), _) => false,
21775 (_, TokenType::DColon) => false,
21776 _ => true,
21778 }
21779 };
21780
21781 if needs_space {
21782 result.push(' ');
21783 }
21784 result.push_str(text);
21785 prev_prev_token_type = prev_token_type;
21786 prev_token_type = Some(*token_type);
21787 }
21788 result
21789 }
21790
21791 fn join_teradata_option_tokens(&self, tokens: Vec<(String, TokenType)>) -> String {
21796 let mut result = String::new();
21797 let mut prev_token_type: Option<TokenType> = None;
21798
21799 for (text, token_type) in tokens {
21800 let needs_space = if result.is_empty() {
21801 false
21802 } else {
21803 match (prev_token_type, token_type) {
21804 (Some(TokenType::Dot), _) => false,
21805 (_, TokenType::Dot) => false,
21806 (Some(TokenType::LParen), _) => false,
21807 (_, TokenType::LParen) => false,
21808 (_, TokenType::RParen) => false,
21809 (_, TokenType::Comma) => false,
21810 (Some(TokenType::Eq), _) => false,
21811 (_, TokenType::Eq) => false,
21812 _ => true,
21813 }
21814 };
21815
21816 if needs_space {
21817 result.push(' ');
21818 }
21819 result.push_str(&text);
21820 prev_token_type = Some(token_type);
21821 }
21822
21823 result
21824 }
21825
21826 fn parse_rm_command(&mut self) -> Result<Expression> {
21829 let command_token = self.advance(); let command_name = command_token.text.to_ascii_uppercase();
21831
21832 let mut tokens = vec![(command_name, command_token.token_type)];
21834 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
21835 let token = self.advance();
21836 tokens.push((token.text.clone(), token.token_type));
21837 }
21838
21839 Ok(Expression::Command(Box::new(Command {
21840 this: self.join_command_tokens(tokens),
21841 })))
21842 }
21843
21844 fn parse_get_command(&mut self) -> Result<Expression> {
21847 let get_token = self.advance(); let mut tokens = vec![("GET".to_string(), get_token.token_type)];
21851 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
21852 let token = self.advance();
21853 let text = match token.token_type {
21855 TokenType::String => format!("'{}'", token.text),
21856 TokenType::QuotedIdentifier => format!("\"{}\"", token.text),
21857 _ => token.text.clone(),
21858 };
21859 tokens.push((text, token.token_type));
21860 }
21861
21862 Ok(Expression::Command(Box::new(Command {
21863 this: self.join_command_tokens(tokens),
21864 })))
21865 }
21866
21867 fn parse_call(&mut self) -> Result<Expression> {
21870 let call_token = self.advance(); let mut tokens = vec![("CALL".to_string(), call_token.token_type)];
21874 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
21875 let token = self.advance();
21876 tokens.push((token.text.clone(), token.token_type));
21877 }
21878
21879 Ok(Expression::Command(Box::new(Command {
21880 this: self.join_command_tokens(tokens),
21881 })))
21882 }
21883
21884 fn parse_kill(&mut self) -> Result<Expression> {
21887 self.expect(TokenType::Kill)?;
21888
21889 let kind = if self.match_identifier("CONNECTION") {
21891 Some("CONNECTION".to_string())
21892 } else if self.match_identifier("QUERY") {
21893 Some("QUERY".to_string())
21894 } else {
21895 None
21896 };
21897
21898 let this = self.parse_primary()?;
21900
21901 Ok(Expression::Kill(Box::new(Kill { this, kind })))
21902 }
21903
21904 fn parse_execute(&mut self) -> Result<Expression> {
21907 self.expect(TokenType::Execute)?;
21908
21909 let this = if self.check(TokenType::LParen) {
21911 self.skip(); let expr = self
21913 .parse_disjunction()?
21914 .unwrap_or(Expression::Null(crate::expressions::Null));
21915 self.expect(TokenType::RParen)?;
21916 Expression::Paren(Box::new(crate::expressions::Paren {
21917 this: expr,
21918 trailing_comments: Vec::new(),
21919 }))
21920 } else {
21921 let proc_name = self.parse_table_ref()?;
21923 Expression::Table(Box::new(proc_name))
21924 };
21925
21926 let mut parameters = Vec::new();
21928
21929 while self.check(TokenType::Var) || self.check(TokenType::Parameter) {
21931 let token = self.advance();
21933 let param_name = if token.text.starts_with('@') {
21934 token.text.clone()
21935 } else {
21936 format!("@{}", token.text)
21937 };
21938
21939 if self.match_token(TokenType::Eq) {
21941 let value = self.parse_primary()?;
21943 let output = self.match_token(TokenType::Output);
21944 parameters.push(ExecuteParameter {
21945 name: param_name,
21946 value,
21947 positional: false,
21948 output,
21949 });
21950 } else {
21951 let output = self.match_token(TokenType::Output);
21953 parameters.push(ExecuteParameter {
21954 name: param_name.clone(),
21955 value: Expression::boxed_column(Column {
21956 name: Identifier::new(¶m_name),
21957 table: None,
21958 join_mark: false,
21959 trailing_comments: Vec::new(),
21960 span: None,
21961 inferred_type: None,
21962 }),
21963 positional: true,
21964 output,
21965 });
21966 }
21967
21968 if !self.match_token(TokenType::Comma) {
21970 break;
21971 }
21972 }
21973
21974 let suffix = if self.check(TokenType::With) {
21976 let start = self.current;
21977 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
21979 self.skip();
21980 }
21981 Some(self.tokens_to_sql(start, self.current))
21982 } else {
21983 None
21984 };
21985
21986 Ok(Expression::Execute(Box::new(ExecuteStatement {
21987 this,
21988 parameters,
21989 suffix,
21990 })))
21991 }
21992
21993 fn parse_grant(&mut self) -> Result<Expression> {
21996 self.expect(TokenType::Grant)?;
21997
21998 if matches!(
22003 self.config.dialect,
22004 Some(crate::dialects::DialectType::ClickHouse)
22005 ) {
22006 let saved_pos = self.current;
22008 let mut depth = 0i32;
22010 let mut on_count = 0;
22011 let mut found_to = false;
22012 let mut has_star_in_name = false;
22013 let mut has_replace_option = false;
22014 let mut i = self.current;
22015 while i < self.tokens.len() && self.tokens[i].token_type != TokenType::Semicolon {
22016 match self.tokens[i].token_type {
22017 TokenType::LParen => depth += 1,
22018 TokenType::RParen => depth -= 1,
22019 TokenType::On if depth == 0 => on_count += 1,
22020 TokenType::To if depth == 0 => {
22021 found_to = true;
22022 }
22023 TokenType::Star if depth == 0 && on_count > 0 && !found_to => {
22024 if i > 0
22026 && self.tokens[i - 1].token_type != TokenType::Dot
22027 && self.tokens[i - 1].token_type != TokenType::On
22028 {
22029 has_star_in_name = true;
22030 }
22031 }
22032 TokenType::Replace if depth == 0 && found_to => {
22033 has_replace_option = true;
22034 }
22035 _ => {}
22036 }
22037 i += 1;
22038 }
22039 if (found_to && on_count == 0) || on_count > 1 || has_star_in_name || has_replace_option
22040 {
22041 self.current = saved_pos;
22043 return self
22044 .parse_command()?
22045 .ok_or_else(|| self.parse_error("Failed to parse GRANT statement"));
22046 }
22047 self.current = saved_pos;
22048 }
22049
22050 let privileges = self.parse_privileges()?;
22052
22053 self.expect(TokenType::On)?;
22055
22056 let kind = self.parse_object_kind()?;
22058
22059 let securable = self.parse_securable_name()?;
22061
22062 let function_params = if self.check(TokenType::LParen) {
22064 self.parse_function_param_types()?
22065 } else {
22066 Vec::new()
22067 };
22068
22069 self.expect(TokenType::To)?;
22071
22072 let principals = self.parse_principals()?;
22074
22075 let grant_option = self.match_token(TokenType::With)
22077 && self.check(TokenType::Grant)
22078 && {
22079 self.skip();
22080 self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("OPTION")
22081 }
22082 && {
22083 self.skip();
22084 true
22085 };
22086
22087 let as_principal = if self.match_token(TokenType::As) {
22089 let name = self.expect_identifier_or_keyword()?;
22090 Some(Identifier::new(name))
22091 } else {
22092 None
22093 };
22094
22095 Ok(Expression::Grant(Box::new(Grant {
22096 privileges,
22097 kind,
22098 securable,
22099 function_params,
22100 principals,
22101 grant_option,
22102 as_principal,
22103 })))
22104 }
22105
22106 fn parse_revoke(&mut self) -> Result<Expression> {
22109 self.expect(TokenType::Revoke)?;
22110
22111 if matches!(
22113 self.config.dialect,
22114 Some(crate::dialects::DialectType::ClickHouse)
22115 ) {
22116 let saved_pos = self.current;
22117 let mut depth = 0i32;
22118 let mut on_count = 0;
22119 let mut found_from = false;
22120 let mut has_star_in_name = false;
22121 let mut i = self.current;
22122 while i < self.tokens.len() && self.tokens[i].token_type != TokenType::Semicolon {
22123 match self.tokens[i].token_type {
22124 TokenType::LParen => depth += 1,
22125 TokenType::RParen => depth -= 1,
22126 TokenType::On if depth == 0 => on_count += 1,
22127 TokenType::From if depth == 0 => {
22128 found_from = true;
22129 }
22130 TokenType::Star if depth == 0 && on_count > 0 && !found_from => {
22131 if i > 0
22132 && self.tokens[i - 1].token_type != TokenType::Dot
22133 && self.tokens[i - 1].token_type != TokenType::On
22134 {
22135 has_star_in_name = true;
22136 }
22137 }
22138 _ => {}
22139 }
22140 i += 1;
22141 }
22142 if (found_from && on_count == 0) || on_count > 1 || has_star_in_name {
22143 self.current = saved_pos;
22144 return self
22145 .parse_command()?
22146 .ok_or_else(|| self.parse_error("Failed to parse REVOKE statement"));
22147 }
22148 self.current = saved_pos;
22149 }
22150
22151 let grant_option = if self.check(TokenType::Grant) {
22153 self.skip();
22154 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("OPTION") {
22155 self.skip();
22156 self.expect(TokenType::For)?;
22157 true
22158 } else {
22159 return Err(self.parse_error("Expected OPTION after GRANT in REVOKE"));
22160 }
22161 } else {
22162 false
22163 };
22164
22165 let privileges = self.parse_privileges()?;
22167
22168 self.expect(TokenType::On)?;
22170
22171 let kind = self.parse_object_kind()?;
22173
22174 let securable = self.parse_securable_name()?;
22176
22177 let function_params = if self.check(TokenType::LParen) {
22179 self.parse_function_param_types()?
22180 } else {
22181 Vec::new()
22182 };
22183
22184 self.expect(TokenType::From)?;
22186
22187 let principals = self.parse_principals()?;
22189
22190 let cascade = self.match_token(TokenType::Cascade);
22192 let restrict = if !cascade {
22193 self.match_token(TokenType::Restrict)
22194 } else {
22195 false
22196 };
22197
22198 Ok(Expression::Revoke(Box::new(Revoke {
22199 privileges,
22200 kind,
22201 securable,
22202 function_params,
22203 principals,
22204 grant_option,
22205 cascade,
22206 restrict,
22207 })))
22208 }
22209
22210 fn parse_privileges(&mut self) -> Result<Vec<Privilege>> {
22213 let mut privileges = Vec::new();
22214 loop {
22215 let mut priv_parts = Vec::new();
22216 while !self.is_at_end() {
22218 if self.check(TokenType::On)
22219 || self.check(TokenType::Comma)
22220 || self.check(TokenType::LParen)
22221 {
22222 break;
22223 }
22224 if self.is_identifier_or_keyword_token() {
22225 priv_parts.push(self.advance().text.to_ascii_uppercase());
22226 } else {
22227 break;
22228 }
22229 }
22230 if priv_parts.is_empty() {
22231 break;
22232 }
22233 let priv_name = priv_parts.join(" ");
22234
22235 let columns = if self.match_token(TokenType::LParen) {
22237 let mut cols = Vec::new();
22238 loop {
22239 if self.is_identifier_or_keyword_token() {
22241 cols.push(self.advance().text.to_string());
22242 } else if self.check(TokenType::RParen) {
22243 break;
22244 } else {
22245 break;
22246 }
22247 if !self.match_token(TokenType::Comma) {
22248 break;
22249 }
22250 }
22251 self.expect(TokenType::RParen)?;
22252 cols
22253 } else {
22254 Vec::new()
22255 };
22256
22257 privileges.push(Privilege {
22258 name: priv_name,
22259 columns,
22260 });
22261 if !self.match_token(TokenType::Comma) {
22262 break;
22263 }
22264 }
22265 Ok(privileges)
22266 }
22267
22268 fn parse_object_kind(&mut self) -> Result<Option<String>> {
22270 if self.check(TokenType::Table) {
22271 self.skip();
22272 Ok(Some("TABLE".to_string()))
22273 } else if self.check(TokenType::Schema) {
22274 self.skip();
22275 Ok(Some("SCHEMA".to_string()))
22276 } else if self.check(TokenType::Database) {
22277 self.skip();
22278 Ok(Some("DATABASE".to_string()))
22279 } else if self.check(TokenType::Function) {
22280 self.skip();
22281 Ok(Some("FUNCTION".to_string()))
22282 } else if self.check(TokenType::View) {
22283 self.skip();
22284 Ok(Some("VIEW".to_string()))
22285 } else if self.check(TokenType::Procedure) {
22286 self.skip();
22287 Ok(Some("PROCEDURE".to_string()))
22288 } else if self.check(TokenType::Sequence) {
22289 self.skip();
22290 Ok(Some("SEQUENCE".to_string()))
22291 } else if self.check(TokenType::Warehouse) {
22292 self.skip();
22293 Ok(Some("WAREHOUSE".to_string()))
22294 } else if self.check_identifier("STAGE")
22295 || self.check_identifier("INTEGRATION")
22296 || self.check_identifier("TASK")
22297 || self.check_identifier("STREAM")
22298 || self.check_identifier("PIPE")
22299 || self.check_identifier("TAG")
22300 || self.check_identifier("SHARE")
22301 {
22302 let kind = self.advance().text.to_ascii_uppercase();
22303 Ok(Some(kind))
22304 } else if self.check_identifier("FILE")
22305 && self.current + 1 < self.tokens.len()
22306 && self.tokens[self.current + 1]
22307 .text
22308 .eq_ignore_ascii_case("FORMAT")
22309 {
22310 self.skip(); self.skip(); Ok(Some("FILE FORMAT".to_string()))
22313 } else if self.check_identifier("NETWORK")
22314 && self.current + 1 < self.tokens.len()
22315 && self.tokens[self.current + 1]
22316 .text
22317 .eq_ignore_ascii_case("POLICY")
22318 {
22319 self.skip(); self.skip(); Ok(Some("NETWORK POLICY".to_string()))
22322 } else {
22323 Ok(None)
22324 }
22325 }
22326
22327 fn parse_principals(&mut self) -> Result<Vec<GrantPrincipal>> {
22329 let mut principals = Vec::new();
22330 loop {
22331 let is_role =
22333 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("ROLE") {
22334 self.skip();
22335 true
22336 } else {
22337 false
22338 };
22339 let is_group = if !is_role && self.check(TokenType::Group) {
22341 self.skip();
22342 true
22343 } else {
22344 false
22345 };
22346 let is_share = if !is_role && !is_group && self.check_identifier("SHARE") {
22348 self.skip();
22349 true
22350 } else {
22351 false
22352 };
22353 let name = self.expect_identifier_or_keyword_with_quoted()?;
22355 principals.push(GrantPrincipal {
22356 name,
22357 is_role,
22358 is_group,
22359 is_share,
22360 });
22361 if !self.match_token(TokenType::Comma) {
22362 break;
22363 }
22364 }
22365 Ok(principals)
22366 }
22367
22368 fn parse_securable_name(&mut self) -> Result<Identifier> {
22371 let first = if self.match_token(TokenType::Star) {
22373 "*".to_string()
22374 } else {
22375 self.expect_identifier_or_keyword()?
22376 };
22377 let mut parts = vec![first];
22378
22379 while self.match_token(TokenType::Dot) {
22380 let next = if self.match_token(TokenType::Star) {
22381 "*".to_string()
22382 } else {
22383 self.expect_identifier_or_keyword()?
22384 };
22385 parts.push(next);
22386 }
22387
22388 Ok(Identifier::new(parts.join(".")))
22389 }
22390
22391 fn parse_function_param_types(&mut self) -> Result<Vec<String>> {
22394 self.expect(TokenType::LParen)?;
22395
22396 let mut params = Vec::new();
22397 if !self.check(TokenType::RParen) {
22398 loop {
22399 let param_type = self.expect_identifier_or_keyword()?;
22401 params.push(param_type);
22402 if !self.match_token(TokenType::Comma) {
22403 break;
22404 }
22405 }
22406 }
22407
22408 self.expect(TokenType::RParen)?;
22409 Ok(params)
22410 }
22411
22412 fn parse_comment(&mut self) -> Result<Expression> {
22414 self.expect(TokenType::Comment)?;
22415
22416 let exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
22418
22419 self.expect(TokenType::On)?;
22421
22422 let materialized = if self.match_token(TokenType::Materialized) {
22424 true
22425 } else if self.check(TokenType::Var)
22426 && self.peek().text.eq_ignore_ascii_case("MATERIALIZED")
22427 {
22428 self.skip();
22429 true
22430 } else {
22431 false
22432 };
22433
22434 let kind = self.expect_identifier_or_keyword()?.to_ascii_uppercase();
22436
22437 let this = if kind == "PROCEDURE" || kind == "FUNCTION" {
22440 let name_token = self.advance();
22442 let mut name_str = name_token.text.clone();
22443
22444 while self.match_token(TokenType::Dot) {
22446 let next = self.advance();
22447 name_str.push('.');
22448 name_str.push_str(&next.text);
22449 }
22450
22451 if self.match_token(TokenType::LParen) {
22453 name_str.push('(');
22454 let mut first = true;
22455 while !self.check(TokenType::RParen) && !self.is_at_end() {
22456 if !first {
22457 name_str.push_str(", ");
22458 }
22459 first = false;
22460 let param_token = self.advance();
22461 name_str.push_str(¶m_token.text);
22462 self.match_token(TokenType::Comma);
22463 }
22464 self.expect(TokenType::RParen)?;
22465 name_str.push(')');
22466 }
22467
22468 Expression::Identifier(Identifier::new(name_str))
22469 } else {
22470 self.parse_qualified_name()?
22471 };
22472
22473 if self.check(TokenType::Is) {
22475 self.skip();
22476 } else {
22477 return Err(self.parse_error("Expected IS in COMMENT ON statement"));
22478 }
22479
22480 let expression = self.parse_primary()?;
22482
22483 Ok(Expression::Comment(Box::new(Comment {
22484 this,
22485 kind,
22486 expression,
22487 exists,
22488 materialized,
22489 })))
22490 }
22491
22492 fn parse_set(&mut self) -> Result<Expression> {
22494 self.expect(TokenType::Set)?;
22495
22496 let mut items = Vec::new();
22497
22498 if matches!(
22500 self.config.dialect,
22501 Some(crate::dialects::DialectType::ClickHouse)
22502 ) && self.check(TokenType::Default)
22503 {
22504 let mut parts = vec!["SET".to_string()];
22505 while !self.is_at_end() && self.peek().token_type != TokenType::Semicolon {
22506 parts.push(self.advance().text.clone());
22507 }
22508 return Ok(Expression::Command(Box::new(crate::expressions::Command {
22509 this: parts.join(" "),
22510 })));
22511 }
22512
22513 if matches!(
22515 self.config.dialect,
22516 Some(crate::dialects::DialectType::Teradata)
22517 ) && self.match_identifier("QUERY_BAND")
22518 {
22519 return self.parse_query_band();
22520 }
22521
22522 if self.match_identifier("CHARACTER") {
22524 self.expect(TokenType::Set)?;
22526 let value = if self.match_token(TokenType::Default) {
22527 Expression::Identifier(Identifier::new("DEFAULT".to_string()))
22528 } else {
22529 self.parse_primary()?
22530 };
22531 items.push(SetItem {
22532 name: Expression::Identifier(Identifier::new("CHARACTER SET".to_string())),
22533 value,
22534 kind: None,
22535 no_equals: false,
22536 });
22537 return Ok(Expression::SetStatement(Box::new(SetStatement { items })));
22538 }
22539
22540 if self.match_identifier("NAMES") {
22541 let value = if self.match_token(TokenType::Default) {
22543 Expression::Identifier(Identifier::new("DEFAULT".to_string()))
22544 } else {
22545 self.parse_primary()?
22546 };
22547 let collation = if self.match_identifier("COLLATE") {
22549 Some(self.parse_primary()?)
22550 } else {
22551 None
22552 };
22553 items.push(SetItem {
22554 name: Expression::Identifier(Identifier::new("NAMES".to_string())),
22555 value,
22556 kind: None,
22557 no_equals: false,
22558 });
22559 if let Some(coll) = collation {
22560 items.push(SetItem {
22561 name: Expression::Identifier(Identifier::new("COLLATE".to_string())),
22562 value: coll,
22563 kind: None,
22564 no_equals: false,
22565 });
22566 }
22567 return Ok(Expression::SetStatement(Box::new(SetStatement { items })));
22568 }
22569
22570 let mut set_is_variable = if self.check(TokenType::Var) {
22572 let text = self.peek().text.to_uppercase();
22573 if text == "VARIABLE" || text == "VAR" {
22574 if let Some(next) = self.tokens.get(self.current + 1) {
22576 if next.token_type != TokenType::Eq
22577 && next.token_type != TokenType::To
22578 && next.token_type != TokenType::ColonEq
22579 {
22580 self.skip(); true
22582 } else {
22583 false
22584 }
22585 } else {
22586 false
22587 }
22588 } else {
22589 false
22590 }
22591 } else {
22592 false
22593 };
22594
22595 loop {
22596 let kind = if self.match_identifier("GLOBAL") {
22599 Some("GLOBAL".to_string())
22600 } else if self.match_token(TokenType::Local) {
22601 Some("LOCAL".to_string())
22602 } else if self.match_identifier("SESSION") {
22603 Some("SESSION".to_string())
22604 } else if self.match_identifier("PERSIST") {
22605 Some("PERSIST".to_string())
22606 } else if self.match_identifier("PERSIST_ONLY") {
22607 Some("PERSIST_ONLY".to_string())
22608 } else if set_is_variable {
22609 set_is_variable = false; Some("VARIABLE".to_string())
22611 } else {
22612 None
22613 };
22614
22615 if self.match_token(TokenType::Transaction) {
22617 let mut characteristics = Vec::new();
22619 loop {
22620 let mut char_tokens = Vec::new();
22621 while !self.is_at_end()
22624 && !self.check(TokenType::Comma)
22625 && !self.check(TokenType::Semicolon)
22626 {
22627 if self.is_identifier_token()
22629 || self.is_safe_keyword_as_identifier()
22630 || self.check(TokenType::Only)
22631 || self.check(TokenType::Repeatable)
22632 {
22633 char_tokens.push(self.advance().text);
22634 } else {
22635 break;
22636 }
22637 }
22638 if !char_tokens.is_empty() {
22639 characteristics.push(char_tokens.join(" "));
22640 }
22641 if !self.match_token(TokenType::Comma) {
22642 break;
22643 }
22644 }
22645
22646 let name = Expression::Identifier(Identifier::new("TRANSACTION".to_string()));
22647 let value = if characteristics.is_empty() {
22648 Expression::Identifier(Identifier::new("".to_string()))
22649 } else {
22650 Expression::Identifier(Identifier::new(characteristics.join(", ")))
22651 };
22652
22653 items.push(SetItem {
22654 name,
22655 value,
22656 kind,
22657 no_equals: false,
22658 });
22659 break;
22660 }
22661
22662 let name = {
22665 if self.check(TokenType::AtAt) {
22666 self.skip(); let mut name_str = "@@".to_string();
22669 let first = self.advance().text.clone();
22670 name_str.push_str(&first);
22671 while self.match_token(TokenType::Dot) {
22673 let next = self.advance().text.clone();
22674 name_str.push('.');
22675 name_str.push_str(&next);
22676 }
22677 Expression::Identifier(Identifier::new(name_str))
22678 } else if self.check(TokenType::DAt) {
22679 self.skip(); let mut name_str = "@".to_string();
22682 let first = self.advance().text.clone();
22683 name_str.push_str(&first);
22684 Expression::Identifier(Identifier::new(name_str))
22685 } else if self.check(TokenType::LParen) {
22686 self.skip(); let mut vars = Vec::new();
22689 loop {
22690 let var_name = self.advance().text.clone();
22691 vars.push(Expression::Column(Box::new(Column {
22692 name: Identifier::new(var_name),
22693 table: None,
22694 join_mark: false,
22695 trailing_comments: Vec::new(),
22696 span: None,
22697 inferred_type: None,
22698 })));
22699 if !self.match_token(TokenType::Comma) {
22700 break;
22701 }
22702 }
22703 self.expect(TokenType::RParen)?;
22704 Expression::Tuple(Box::new(crate::expressions::Tuple { expressions: vars }))
22705 } else {
22706 let first = self.advance().text.clone();
22707 let mut name_str = first;
22708 while self.match_token(TokenType::Dot) {
22710 let next = self.advance().text.clone();
22711 name_str.push('.');
22712 name_str.push_str(&next);
22713 }
22714 while self.check(TokenType::Colon) && !self.check_next(TokenType::Eq) {
22717 self.skip(); let next = self.advance().text.clone();
22719 name_str.push(':');
22720 name_str.push_str(&next);
22721 }
22722 Expression::Identifier(Identifier::new(name_str))
22723 }
22724 };
22725
22726 if self.match_token(TokenType::Eq) || self.match_token(TokenType::ColonEq) {
22728 } else if self.match_token(TokenType::To) {
22730 } else if self.is_at_end()
22732 || self.check(TokenType::Semicolon)
22733 || self.check(TokenType::Comma)
22734 {
22735 items.push(SetItem {
22739 name,
22740 value: Expression::Identifier(Identifier::new("".to_string())),
22741 kind,
22742 no_equals: false,
22743 });
22744 if !self.match_token(TokenType::Comma) {
22745 break;
22746 }
22747 continue;
22748 } else {
22749 if self.check(TokenType::On) || self.check_keyword_text("OFF") {
22752 let val = self.advance().text;
22753 let name_with_val = match &name {
22755 Expression::Column(col) => format!("{} {}", col.name.name, val),
22756 Expression::Identifier(id) => format!("{} {}", id.name, val),
22757 _ => val.clone(),
22758 };
22759 items.push(SetItem {
22760 name: Expression::Identifier(Identifier::new(name_with_val)),
22761 value: Expression::Identifier(Identifier::new("".to_string())),
22762 kind,
22763 no_equals: false,
22764 });
22765 if !self.match_token(TokenType::Comma) {
22766 break;
22767 }
22768 continue;
22769 }
22770 if !self.is_at_end() && !self.check(TokenType::Semicolon) {
22773 let value = self.parse_expression()?;
22774 items.push(SetItem {
22775 name,
22776 value,
22777 kind,
22778 no_equals: true,
22779 });
22780 if !self.match_token(TokenType::Comma) {
22781 break;
22782 }
22783 continue;
22784 }
22785 return Err(self.parse_error("Expected '=' or 'TO' in SET statement"));
22786 }
22787
22788 let value = if self.check(TokenType::On) || self.check_keyword_text("OFF") {
22790 Expression::Identifier(Identifier::new(self.advance().text.clone()))
22791 } else if self.match_token(TokenType::Default) {
22792 Expression::Identifier(Identifier::new("DEFAULT".to_string()))
22793 } else {
22794 self.parse_expression()?
22795 };
22796
22797 items.push(SetItem {
22798 name,
22799 value,
22800 kind,
22801 no_equals: false,
22802 });
22803
22804 if !self.match_token(TokenType::Comma) {
22805 break;
22806 }
22807 }
22808
22809 Ok(Expression::SetStatement(Box::new(SetStatement { items })))
22810 }
22811
22812 fn parse_query_band(&mut self) -> Result<Expression> {
22814 self.expect(TokenType::Eq)?;
22815
22816 let value = if self.match_identifier("NONE") {
22817 Expression::Var(Box::new(Var {
22818 this: "NONE".to_string(),
22819 }))
22820 } else if self.check(TokenType::String) {
22821 Expression::Literal(Box::new(Literal::String(self.expect_string()?)))
22822 } else {
22823 self.parse_primary()?
22824 };
22825
22826 let update = if self.match_token(TokenType::Update) || self.match_identifier("UPDATE") {
22827 Some(Box::new(Expression::Boolean(BooleanLiteral {
22828 value: true,
22829 })))
22830 } else {
22831 None
22832 };
22833
22834 let _ = self.match_token(TokenType::For);
22835
22836 let scope = if self.match_token(TokenType::Session) || self.match_identifier("SESSION") {
22837 if self.match_identifier("VOLATILE") {
22838 Some("SESSION VOLATILE".to_string())
22839 } else {
22840 Some("SESSION".to_string())
22841 }
22842 } else if self.match_token(TokenType::Transaction) || self.match_identifier("TRANSACTION") {
22843 Some("TRANSACTION".to_string())
22844 } else if self.match_identifier("VOLATILE") {
22845 Some("VOLATILE".to_string())
22846 } else {
22847 None
22848 };
22849
22850 Ok(Expression::QueryBand(Box::new(QueryBand {
22851 this: Box::new(value),
22852 scope: scope.map(|s| Box::new(Expression::Var(Box::new(Var { this: s })))),
22853 update,
22854 })))
22855 }
22856
22857 fn parse_fetch(&mut self) -> Result<Fetch> {
22859 let direction = if self.match_token(TokenType::First) {
22863 "FIRST".to_string()
22864 } else if self.match_token(TokenType::Next) {
22865 "NEXT".to_string()
22866 } else {
22867 "FIRST".to_string() };
22869
22870 let count = if !self.check(TokenType::Row)
22872 && !self.check(TokenType::Rows)
22873 && !self.check(TokenType::Percent)
22874 && !self.check(TokenType::Only)
22875 {
22876 if self.check(TokenType::Number)
22878 || self.check(TokenType::LParen)
22879 || self.check(TokenType::DAt)
22880 || self.check(TokenType::Var)
22881 {
22882 Some(self.parse_primary()?)
22883 } else {
22884 None
22885 }
22886 } else {
22887 None
22888 };
22889
22890 let percent = self.match_token(TokenType::Percent);
22892
22893 let rows = self.match_token(TokenType::Row) || self.match_token(TokenType::Rows);
22895
22896 self.match_token(TokenType::Only);
22898 let with_ties = self.match_keywords(&[TokenType::With, TokenType::Ties]);
22899
22900 Ok(Fetch {
22901 direction,
22902 count,
22903 percent,
22904 rows,
22905 with_ties,
22906 })
22907 }
22908
22909 fn parse_qualified_name(&mut self) -> Result<Expression> {
22911 let first = self.expect_identifier_or_keyword()?;
22912 let mut parts = vec![first];
22913
22914 while self.match_token(TokenType::Dot) {
22915 let next = self.expect_identifier_or_keyword()?;
22916 parts.push(next);
22917 }
22918
22919 if parts.len() == 1 {
22920 Ok(Expression::Identifier(Identifier::new(parts.remove(0))))
22921 } else if parts.len() == 2 {
22922 Ok(Expression::boxed_column(Column {
22923 table: Some(Identifier::new(parts[0].clone())),
22924 name: Identifier::new(parts[1].clone()),
22925 join_mark: false,
22926 trailing_comments: Vec::new(),
22927 span: None,
22928 inferred_type: None,
22929 }))
22930 } else {
22931 let column_name = parts.pop().unwrap();
22933 let table_name = parts.join(".");
22934 Ok(Expression::boxed_column(Column {
22935 table: Some(Identifier::new(table_name)),
22936 name: Identifier::new(column_name),
22937 join_mark: false,
22938 trailing_comments: Vec::new(),
22939 span: None,
22940 inferred_type: None,
22941 }))
22942 }
22943 }
22944
22945 fn parse_create_schema(&mut self, leading_comments: Vec<String>) -> Result<Expression> {
22949 self.expect(TokenType::Schema)?;
22950
22951 let if_not_exists =
22952 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
22953 let name = self.parse_identifier_parts()?;
22954
22955 let clone_from = if self.match_identifier("CLONE") {
22957 Some(self.parse_identifier_parts()?)
22958 } else {
22959 None
22960 };
22961
22962 let at_clause = if self.match_identifier("AT") || self.match_token(TokenType::Before) {
22965 let keyword = self.previous().text.to_ascii_uppercase();
22966 self.expect(TokenType::LParen)?;
22967 let mut result = format!("{} (", keyword);
22969 let mut prev_token_type: Option<TokenType> = None;
22970 let mut paren_depth = 1; while !self.is_at_end() && paren_depth > 0 {
22972 let token = self.advance();
22973 if token.token_type == TokenType::LParen {
22974 paren_depth += 1;
22975 } else if token.token_type == TokenType::RParen {
22976 paren_depth -= 1;
22977 if paren_depth == 0 {
22978 break; }
22980 }
22981 let needs_space = !result.ends_with('(')
22983 && prev_token_type != Some(TokenType::Arrow)
22984 && prev_token_type != Some(TokenType::Dash)
22985 && prev_token_type != Some(TokenType::LParen)
22986 && token.token_type != TokenType::LParen; if needs_space
22988 && token.token_type != TokenType::RParen
22989 && token.token_type != TokenType::Comma
22990 {
22991 result.push(' ');
22992 }
22993 if token.token_type == TokenType::String {
22995 result.push('\'');
22996 result.push_str(&token.text.replace('\'', "''"));
22997 result.push('\'');
22998 } else {
22999 result.push_str(&token.text);
23000 }
23001 if token.token_type == TokenType::Arrow || token.token_type == TokenType::Comma {
23002 result.push(' ');
23003 }
23004 prev_token_type = Some(token.token_type);
23005 }
23006 result.push(')');
23007 Some(Expression::Raw(Raw { sql: result }))
23008 } else {
23009 None
23010 };
23011
23012 let authorization = if self.match_token(TokenType::Authorization) {
23013 Some(Identifier::new(self.expect_identifier()?))
23014 } else {
23015 None
23016 };
23017
23018 let mut properties = Vec::new();
23020
23021 if self.match_token(TokenType::With) {
23023 self.expect(TokenType::LParen)?;
23024 loop {
23025 let prop_name = if self.check(TokenType::String) {
23027 Expression::Literal(Box::new(Literal::String(self.expect_string()?)))
23028 } else {
23029 Expression::Identifier(Identifier::new(self.expect_identifier_or_keyword()?))
23030 };
23031 self.expect(TokenType::Eq)?;
23032 let prop_value = self.parse_expression()?;
23034 properties.push(Expression::Property(Box::new(Property {
23036 this: Box::new(prop_name),
23037 value: Some(Box::new(prop_value)),
23038 })));
23039 if !self.match_token(TokenType::Comma) {
23040 break;
23041 }
23042 }
23043 self.expect(TokenType::RParen)?;
23044 }
23045
23046 if self.match_token(TokenType::Default) && self.match_token(TokenType::Collate) {
23048 let collation = self.parse_primary()?;
23050 properties.push(Expression::CollateProperty(Box::new(CollateProperty {
23051 this: Box::new(collation),
23052 default: Some(Box::new(Expression::Boolean(BooleanLiteral {
23053 value: true,
23054 }))),
23055 })));
23056 }
23057
23058 Ok(Expression::CreateSchema(Box::new(CreateSchema {
23059 name,
23060 if_not_exists,
23061 authorization,
23062 clone_from,
23063 at_clause,
23064 properties,
23065 leading_comments,
23066 })))
23067 }
23068
23069 fn parse_drop_schema(&mut self) -> Result<Expression> {
23071 self.expect(TokenType::Schema)?;
23072
23073 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
23074 let name = Identifier::new(self.expect_identifier()?);
23075
23076 let cascade = self.match_token(TokenType::Cascade);
23077 if !cascade {
23078 self.match_token(TokenType::Restrict);
23079 }
23080
23081 Ok(Expression::DropSchema(Box::new(DropSchema {
23082 name,
23083 if_exists,
23084 cascade,
23085 })))
23086 }
23087
23088 fn parse_create_database(&mut self) -> Result<Expression> {
23090 self.expect(TokenType::Database)?;
23091
23092 let if_not_exists =
23093 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
23094 let name = Identifier::new(self.expect_identifier()?);
23095
23096 let clone_from = if self.match_identifier("CLONE") {
23098 Some(Identifier::new(self.expect_identifier()?))
23099 } else {
23100 None
23101 };
23102
23103 let at_clause = if self.match_identifier("AT") || self.match_token(TokenType::Before) {
23106 let keyword = self.previous().text.to_ascii_uppercase();
23107 self.expect(TokenType::LParen)?;
23108 let mut result = format!("{} (", keyword);
23110 let mut prev_token_type: Option<TokenType> = None;
23111 let mut paren_depth = 1; while !self.is_at_end() && paren_depth > 0 {
23113 let token = self.advance();
23114 if token.token_type == TokenType::LParen {
23115 paren_depth += 1;
23116 } else if token.token_type == TokenType::RParen {
23117 paren_depth -= 1;
23118 if paren_depth == 0 {
23119 break; }
23121 }
23122 let needs_space = !result.ends_with('(')
23124 && prev_token_type != Some(TokenType::Arrow)
23125 && prev_token_type != Some(TokenType::Dash)
23126 && prev_token_type != Some(TokenType::LParen)
23127 && token.token_type != TokenType::LParen; if needs_space
23129 && token.token_type != TokenType::RParen
23130 && token.token_type != TokenType::Comma
23131 {
23132 result.push(' ');
23133 }
23134 if token.token_type == TokenType::String {
23136 result.push('\'');
23137 result.push_str(&token.text.replace('\'', "''"));
23138 result.push('\'');
23139 } else {
23140 result.push_str(&token.text);
23141 }
23142 if token.token_type == TokenType::Arrow || token.token_type == TokenType::Comma {
23143 result.push(' ');
23144 }
23145 prev_token_type = Some(token.token_type);
23146 }
23147 result.push(')');
23148 Some(Expression::Raw(Raw { sql: result }))
23149 } else {
23150 None
23151 };
23152
23153 let _on_cluster = self.parse_on_cluster_clause()?;
23155
23156 let mut options = Vec::new();
23157
23158 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
23160 if self.match_identifier("OWNER") || self.match_token(TokenType::Eq) {
23161 self.match_token(TokenType::Eq);
23162 options.push(DatabaseOption::Owner(Identifier::new(
23163 self.expect_identifier()?,
23164 )));
23165 } else if self.match_identifier("TEMPLATE") {
23166 self.match_token(TokenType::Eq);
23167 options.push(DatabaseOption::Template(Identifier::new(
23168 self.expect_identifier()?,
23169 )));
23170 } else if self.match_identifier("ENCODING") {
23171 self.match_token(TokenType::Eq);
23172 let encoding = if self.check(TokenType::String) {
23173 let tok = self.advance();
23174 tok.text.trim_matches('\'').to_string()
23175 } else {
23176 self.expect_identifier()?
23177 };
23178 options.push(DatabaseOption::Encoding(encoding));
23179 } else if self.match_identifier("CHARACTER") {
23180 self.match_token(TokenType::Set);
23181 self.match_token(TokenType::Eq);
23182 let charset = if self.check(TokenType::String) {
23183 let tok = self.advance();
23184 tok.text.trim_matches('\'').to_string()
23185 } else {
23186 self.expect_identifier()?
23187 };
23188 options.push(DatabaseOption::CharacterSet(charset));
23189 } else if self.match_identifier("COLLATE") {
23190 self.match_token(TokenType::Eq);
23191 let collate = if self.check(TokenType::String) {
23192 let tok = self.advance();
23193 tok.text.trim_matches('\'').to_string()
23194 } else {
23195 self.expect_identifier()?
23196 };
23197 options.push(DatabaseOption::Collate(collate));
23198 } else if self.match_identifier("LOCATION") {
23199 self.match_token(TokenType::Eq);
23200 let loc = if self.check(TokenType::String) {
23201 let tok = self.advance();
23202 tok.text.trim_matches('\'').to_string()
23203 } else {
23204 self.expect_identifier()?
23205 };
23206 options.push(DatabaseOption::Location(loc));
23207 } else {
23208 break;
23209 }
23210 }
23211
23212 Ok(Expression::CreateDatabase(Box::new(CreateDatabase {
23213 name,
23214 if_not_exists,
23215 options,
23216 clone_from,
23217 at_clause,
23218 })))
23219 }
23220
23221 fn parse_drop_database(&mut self) -> Result<Expression> {
23223 self.expect(TokenType::Database)?;
23224
23225 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
23226
23227 if !if_exists
23229 && matches!(
23230 self.config.dialect,
23231 Some(crate::dialects::DialectType::ClickHouse)
23232 )
23233 {
23234 if self.check(TokenType::If)
23235 && self.current + 1 < self.tokens.len()
23236 && self.tokens[self.current + 1]
23237 .text
23238 .eq_ignore_ascii_case("EMPTY")
23239 {
23240 self.skip(); self.skip(); }
23243 }
23244 let name = Identifier::new(self.expect_identifier()?);
23245
23246 let sync = if matches!(
23248 self.config.dialect,
23249 Some(crate::dialects::DialectType::ClickHouse)
23250 ) {
23251 let _ = self.parse_on_cluster_clause()?;
23252 self.match_identifier("SYNC")
23253 } else {
23254 false
23255 };
23256
23257 Ok(Expression::DropDatabase(Box::new(DropDatabase {
23258 name,
23259 if_exists,
23260 sync,
23261 })))
23262 }
23263
23264 fn parse_create_function(
23266 &mut self,
23267 or_replace: bool,
23268 or_alter: bool,
23269 temporary: bool,
23270 is_table_function: bool,
23271 ) -> Result<Expression> {
23272 self.expect(TokenType::Function)?;
23273
23274 let if_not_exists =
23275 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
23276 let name = self.parse_table_ref()?;
23277
23278 let (parameters, has_parens) = if self.match_token(TokenType::LParen) {
23280 let params = self.parse_function_parameters()?;
23281 self.expect(TokenType::RParen)?;
23282 (params, true)
23283 } else {
23284 (Vec::new(), false)
23285 };
23286
23287 let mut language_first = false;
23289 let mut return_type = None;
23290 let mut language = None;
23291 let mut sql_data_access = None;
23292
23293 if self.match_token(TokenType::Language) {
23295 language = Some(self.expect_identifier_or_keyword()?);
23296 language_first = true;
23297 }
23298
23299 let mut returns_table_body: Option<String> = None;
23301 if self.match_token(TokenType::Returns) {
23302 if self.check(TokenType::Var) && self.peek().text.starts_with('@') {
23303 let var_name = self.advance().text.clone();
23305 if self.check(TokenType::Table) {
23306 self.skip(); return_type = Some(DataType::Custom {
23308 name: "TABLE".to_string(),
23309 });
23310 if self.match_token(TokenType::LParen) {
23312 let start = self.current;
23313 let mut depth = 1;
23314 while depth > 0 && !self.is_at_end() {
23315 if self.check(TokenType::LParen) {
23316 depth += 1;
23317 }
23318 if self.check(TokenType::RParen) {
23319 depth -= 1;
23320 if depth == 0 {
23321 break;
23322 }
23323 }
23324 self.skip();
23325 }
23326 let mut col_defs_str = String::new();
23328 for (i, tok) in self.tokens[start..self.current].iter().enumerate() {
23329 let prev_tok = if i > 0 {
23332 Some(&self.tokens[start + i - 1])
23333 } else {
23334 None
23335 };
23336 let needs_space = i > 0
23337 && tok.token_type != TokenType::Comma
23338 && tok.token_type != TokenType::RParen
23339 && tok.token_type != TokenType::LParen
23340 && prev_tok
23341 .map(|p| p.token_type != TokenType::LParen)
23342 .unwrap_or(true);
23343 if needs_space {
23344 col_defs_str.push(' ');
23345 }
23346 col_defs_str.push_str(&tok.text);
23347 }
23348 returns_table_body = Some(format!("{} TABLE ({})", var_name, col_defs_str));
23349 self.expect(TokenType::RParen)?;
23350 } else {
23351 returns_table_body = Some(format!("{} TABLE", var_name));
23352 }
23353 } else {
23354 return_type = Some(self.parse_data_type()?);
23356 }
23357 } else if self.check(TokenType::Table) {
23358 self.skip(); if self.check(TokenType::Lt) {
23364 self.skip(); let mut cols = Vec::new();
23367 loop {
23368 let col_name = self.expect_identifier()?;
23369 let col_type = self.parse_data_type()?;
23370 cols.push(format!(
23371 "{} {}",
23372 col_name,
23373 self.data_type_to_string(&col_type)
23374 ));
23375 if !self.match_token(TokenType::Comma) {
23376 break;
23377 }
23378 }
23379 if !self.match_token(TokenType::Gt) {
23380 return Err(self.parse_error("Expected > after TABLE column definitions"));
23381 }
23382 returns_table_body = Some(format!("TABLE <{}>", cols.join(", ")));
23383 } else if self.check(TokenType::LParen) {
23384 self.skip(); let mut cols = Vec::new();
23387 loop {
23388 let col_name = self.expect_identifier()?;
23389 let col_type = self.parse_data_type()?;
23390 cols.push(format!(
23391 "{} {}",
23392 col_name,
23393 self.data_type_to_string(&col_type)
23394 ));
23395 if !self.match_token(TokenType::Comma) {
23396 break;
23397 }
23398 }
23399 self.expect(TokenType::RParen)?;
23400 returns_table_body = Some(format!("TABLE ({})", cols.join(", ")));
23401 } else {
23402 return_type = Some(DataType::Custom {
23404 name: "TABLE".to_string(),
23405 });
23406 }
23407 } else {
23408 return_type = Some(self.parse_function_return_type()?);
23410 }
23411 }
23412
23413 let mut deterministic = None;
23414 let mut returns_null_on_null_input = None;
23415 let mut strict = false;
23416 let mut security = None;
23417 let mut body = None;
23418 let mut set_options: Vec<FunctionSetOption> = Vec::new();
23419 let mut property_order: Vec<FunctionPropertyKind> = Vec::new();
23420 let mut options: Vec<Expression> = Vec::new();
23421 let mut environment: Vec<Expression> = Vec::new();
23422 let mut handler: Option<String> = None;
23423 let mut parameter_style: Option<String> = None;
23424
23425 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
23427 if self.check(TokenType::Returns)
23428 && self.current + 1 < self.tokens.len()
23429 && self.tokens[self.current + 1].token_type == TokenType::Null
23430 {
23431 self.skip(); self.skip(); self.match_token(TokenType::On);
23435 self.match_token(TokenType::Null);
23436 self.match_token(TokenType::Input);
23437 returns_null_on_null_input = Some(true);
23438 if !property_order.contains(&FunctionPropertyKind::NullInput) {
23439 property_order.push(FunctionPropertyKind::NullInput);
23440 }
23441 } else if self.match_token(TokenType::Returns) {
23442 return_type = Some(self.parse_data_type()?);
23444 } else if self.match_token(TokenType::Language) {
23445 language = Some(self.expect_identifier_or_keyword()?);
23447 if !property_order.contains(&FunctionPropertyKind::Language) {
23448 property_order.push(FunctionPropertyKind::Language);
23449 }
23450 } else if self.match_token(TokenType::Not) && self.match_identifier("DETERMINISTIC") {
23451 deterministic = Some(false);
23452 if !property_order.contains(&FunctionPropertyKind::Determinism) {
23453 property_order.push(FunctionPropertyKind::Determinism);
23454 }
23455 } else if self.match_identifier("DETERMINISTIC") {
23456 deterministic = Some(true);
23457 if !property_order.contains(&FunctionPropertyKind::Determinism) {
23458 property_order.push(FunctionPropertyKind::Determinism);
23459 }
23460 } else if self.match_identifier("IMMUTABLE") {
23461 deterministic = Some(true);
23462 if !property_order.contains(&FunctionPropertyKind::Determinism) {
23463 property_order.push(FunctionPropertyKind::Determinism);
23464 }
23465 } else if self.match_identifier("STABLE") || self.match_identifier("VOLATILE") {
23466 deterministic = Some(false);
23467 if !property_order.contains(&FunctionPropertyKind::Determinism) {
23468 property_order.push(FunctionPropertyKind::Determinism);
23469 }
23470 } else if self.match_identifier("STRICT") {
23471 returns_null_on_null_input = Some(true);
23472 strict = true;
23473 if !property_order.contains(&FunctionPropertyKind::NullInput) {
23474 property_order.push(FunctionPropertyKind::NullInput);
23475 }
23476 } else if self.match_identifier("CALLED") {
23477 self.match_token(TokenType::On);
23478 self.match_token(TokenType::Null);
23479 self.match_token(TokenType::Input);
23480 returns_null_on_null_input = Some(false);
23481 if !property_order.contains(&FunctionPropertyKind::NullInput) {
23482 property_order.push(FunctionPropertyKind::NullInput);
23483 }
23484 } else if self.match_identifier("SECURITY") {
23485 if self.match_identifier("DEFINER") {
23486 security = Some(FunctionSecurity::Definer);
23487 } else if self.match_identifier("INVOKER") {
23488 security = Some(FunctionSecurity::Invoker);
23489 }
23490 if !property_order.contains(&FunctionPropertyKind::Security) {
23491 property_order.push(FunctionPropertyKind::Security);
23492 }
23493 } else if self.match_identifier("CONTAINS") {
23494 self.match_identifier("SQL");
23496 sql_data_access = Some(SqlDataAccess::ContainsSql);
23497 if !property_order.contains(&FunctionPropertyKind::SqlDataAccess) {
23498 property_order.push(FunctionPropertyKind::SqlDataAccess);
23499 }
23500 } else if self.match_identifier("READS") {
23501 self.match_identifier("SQL");
23503 self.match_identifier("DATA");
23504 sql_data_access = Some(SqlDataAccess::ReadsSqlData);
23505 if !property_order.contains(&FunctionPropertyKind::SqlDataAccess) {
23506 property_order.push(FunctionPropertyKind::SqlDataAccess);
23507 }
23508 } else if self.match_identifier("MODIFIES") {
23509 self.match_identifier("SQL");
23511 self.match_identifier("DATA");
23512 sql_data_access = Some(SqlDataAccess::ModifiesSqlData);
23513 if !property_order.contains(&FunctionPropertyKind::SqlDataAccess) {
23514 property_order.push(FunctionPropertyKind::SqlDataAccess);
23515 }
23516 } else if self.match_token(TokenType::No) && self.match_identifier("SQL") {
23517 sql_data_access = Some(SqlDataAccess::NoSql);
23519 if !property_order.contains(&FunctionPropertyKind::SqlDataAccess) {
23520 property_order.push(FunctionPropertyKind::SqlDataAccess);
23521 }
23522 } else if self.match_token(TokenType::Set) {
23523 let opt_name = self.expect_identifier_or_keyword()?;
23525 let value = if self.match_token(TokenType::From) {
23526 if !self.match_token(TokenType::Current) {
23528 return Err(self.parse_error("Expected CURRENT after FROM in SET option"));
23529 }
23530 FunctionSetValue::FromCurrent
23531 } else {
23532 let use_to = self.match_token(TokenType::To);
23534 if !use_to && !self.match_token(TokenType::Eq) {
23535 return Err(self.parse_error("Expected = or TO after SET key"));
23536 }
23537 let val = if self.check(TokenType::String) {
23539 let tok = self.advance();
23540 format!("'{}'", tok.text)
23541 } else {
23542 self.expect_identifier_or_keyword()?
23543 };
23544 FunctionSetValue::Value { value: val, use_to }
23545 };
23546 set_options.push(FunctionSetOption {
23547 name: opt_name,
23548 value,
23549 });
23550 if !property_order.contains(&FunctionPropertyKind::Set) {
23551 property_order.push(FunctionPropertyKind::Set);
23552 }
23553 } else if self.match_token(TokenType::As) {
23554 if !property_order.contains(&FunctionPropertyKind::As) {
23556 property_order.push(FunctionPropertyKind::As);
23557 }
23558 if self.match_identifier("RETURN") {
23559 let expr = if self.check(TokenType::Select) || self.check(TokenType::With) {
23561 self.parse_statement()?
23563 } else {
23564 self.parse_expression()?
23565 };
23566 body = Some(FunctionBody::Return(expr));
23567 } else if self.check(TokenType::Select) || self.check(TokenType::With) {
23568 let stmt = self.parse_statement()?;
23570 body = Some(FunctionBody::Expression(stmt));
23571 } else if self.check(TokenType::DollarString) {
23572 let tok = self.advance();
23573 let (tag, content) = crate::tokens::parse_dollar_string_token(&tok.text);
23575 body = Some(FunctionBody::DollarQuoted { content, tag });
23576 } else if self.check(TokenType::String) {
23577 let tok = self.advance();
23578 body = Some(FunctionBody::StringLiteral(tok.text.clone()));
23579 } else if self.match_token(TokenType::Begin) {
23580 let mut block_content = String::new();
23582 let mut depth = 1;
23583 while depth > 0 && !self.is_at_end() {
23584 let tok = self.advance();
23585 if tok.token_type == TokenType::Begin {
23586 depth += 1;
23587 } else if tok.token_type == TokenType::End {
23588 depth -= 1;
23589 if depth == 0 {
23590 break;
23591 }
23592 }
23593 block_content.push_str(&tok.text);
23594 block_content.push(' ');
23595 }
23596 body = Some(FunctionBody::Block(block_content.trim().to_string()));
23597 } else {
23598 let expr = self.parse_expression()?;
23600 body = Some(FunctionBody::Expression(expr));
23601 }
23602 } else if self.match_identifier("RETURN") {
23603 let expr = if self.check(TokenType::Select) || self.check(TokenType::With) {
23605 self.parse_statement()?
23606 } else {
23607 self.parse_expression()?
23608 };
23609 body = Some(FunctionBody::Return(expr));
23610 } else if self.match_identifier("EXTERNAL") {
23611 self.match_identifier("NAME");
23612 let ext_name = if self.check(TokenType::String) {
23613 let tok = self.advance();
23614 tok.text.trim_matches('\'').to_string()
23615 } else {
23616 self.expect_identifier()?
23617 };
23618 body = Some(FunctionBody::External(ext_name));
23619 } else if self.match_identifier("OPTIONS") {
23620 let parsed_options = self.parse_options_list()?;
23622 options.extend(parsed_options);
23623 if !property_order.contains(&FunctionPropertyKind::Options) {
23624 property_order.push(FunctionPropertyKind::Options);
23625 }
23626 } else if self.match_identifier("ENVIRONMENT") {
23627 let parsed_env = self.parse_environment_list()?;
23629 environment.extend(parsed_env);
23630 if !property_order.contains(&FunctionPropertyKind::Environment) {
23631 property_order.push(FunctionPropertyKind::Environment);
23632 }
23633 } else if self.match_identifier("HANDLER") {
23634 if self.check(TokenType::String) {
23636 let tok = self.advance();
23637 handler = Some(tok.text.clone());
23638 }
23639 if !property_order.contains(&FunctionPropertyKind::Handler) {
23640 property_order.push(FunctionPropertyKind::Handler);
23641 }
23642 } else if self.match_text_seq(&["PARAMETER", "STYLE"]) {
23643 let style = self.expect_identifier_or_keyword()?;
23645 parameter_style = Some(style.to_ascii_uppercase());
23646 if !property_order.contains(&FunctionPropertyKind::ParameterStyle) {
23647 property_order.push(FunctionPropertyKind::ParameterStyle);
23648 }
23649 } else if self.check_identifier("SQL")
23650 && self.current + 1 < self.tokens.len()
23651 && self.tokens[self.current + 1]
23652 .text
23653 .eq_ignore_ascii_case("SECURITY")
23654 {
23655 self.skip(); self.skip(); if self.match_identifier("DEFINER") {
23659 security = Some(FunctionSecurity::Definer);
23660 } else if self.match_identifier("INVOKER") {
23661 security = Some(FunctionSecurity::Invoker);
23662 }
23663 if !property_order.contains(&FunctionPropertyKind::Security) {
23664 property_order.push(FunctionPropertyKind::Security);
23665 }
23666 } else if self.check(TokenType::Select) || self.check(TokenType::With) {
23667 let stmt = self.parse_statement()?;
23669 body = Some(FunctionBody::Expression(stmt));
23670 if !property_order.contains(&FunctionPropertyKind::As) {
23671 property_order.push(FunctionPropertyKind::As);
23672 }
23673 } else {
23674 break;
23675 }
23676 }
23677
23678 if options.is_empty() && self.match_identifier("OPTIONS") {
23680 let parsed_options = self.parse_options_list()?;
23681 options.extend(parsed_options);
23682 if !property_order.contains(&FunctionPropertyKind::Options) {
23683 property_order.push(FunctionPropertyKind::Options);
23684 }
23685 }
23686
23687 Ok(Expression::CreateFunction(Box::new(CreateFunction {
23688 name,
23689 parameters,
23690 return_type,
23691 body,
23692 or_replace,
23693 or_alter,
23694 if_not_exists,
23695 temporary,
23696 language,
23697 deterministic,
23698 returns_null_on_null_input,
23699 security,
23700 has_parens,
23701 sql_data_access,
23702 returns_table_body,
23703 language_first,
23704 set_options,
23705 strict,
23706 options,
23707 is_table_function,
23708 property_order,
23709 environment,
23710 handler,
23711 parameter_style,
23712 })))
23713 }
23714
23715 fn parse_function_parameters(&mut self) -> Result<Vec<FunctionParameter>> {
23717 let mut params = Vec::new();
23718
23719 if self.check(TokenType::RParen) {
23720 return Ok(params);
23721 }
23722
23723 loop {
23724 let mut mode = None;
23725 let mut mode_text: Option<String> = None;
23726
23727 if self.match_token(TokenType::In) {
23730 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("OUT") {
23732 let out_text = self.advance().text.clone(); mode_text = Some(format!("IN {}", out_text));
23734 mode = Some(ParameterMode::InOut);
23735 } else {
23736 mode_text = Some("IN".to_string());
23737 mode = Some(ParameterMode::In);
23738 }
23739 } else if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("OUT") {
23740 let text = self.advance().text.clone();
23741 mode_text = Some(text);
23742 mode = Some(ParameterMode::Out);
23743 } else if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("INOUT") {
23744 let text = self.advance().text.clone();
23745 mode_text = Some(text);
23746 mode = Some(ParameterMode::InOut);
23747 } else if self.check(TokenType::Var)
23748 && self.peek().text.eq_ignore_ascii_case("VARIADIC")
23749 {
23750 let text = self.advance().text.clone();
23751 mode_text = Some(text);
23752 mode = Some(ParameterMode::Variadic);
23753 }
23754
23755 let (name, data_type) = if mode.is_some() {
23764 let saved = self.current;
23765 let type_result = self.parse_data_type();
23767 if let Ok(dt) = type_result {
23768 if self.check(TokenType::Comma)
23769 || self.check(TokenType::RParen)
23770 || self.check(TokenType::Default)
23771 || self.check(TokenType::Eq)
23772 {
23773 (None, dt)
23775 } else {
23776 self.current = saved;
23778 let first_ident =
23779 if self.check(TokenType::Input) || self.check(TokenType::Output) {
23780 let token = self.advance();
23781 Identifier {
23782 name: token.text,
23783 quoted: false,
23784 trailing_comments: Vec::new(),
23785 span: None,
23786 }
23787 } else {
23788 self.expect_identifier_with_quoted()?
23789 };
23790 self.match_token(TokenType::As);
23791 let dt = self.parse_data_type()?;
23792 (Some(first_ident), dt)
23793 }
23794 } else {
23795 self.current = saved;
23797 let first_ident =
23798 if self.check(TokenType::Input) || self.check(TokenType::Output) {
23799 let token = self.advance();
23800 Identifier {
23801 name: token.text,
23802 quoted: false,
23803 trailing_comments: Vec::new(),
23804 span: None,
23805 }
23806 } else {
23807 self.expect_identifier_with_quoted()?
23808 };
23809 if self.check(TokenType::Comma)
23810 || self.check(TokenType::RParen)
23811 || self.check(TokenType::Default)
23812 {
23813 (None, self.identifier_to_datatype(&first_ident.name)?)
23814 } else {
23815 self.match_token(TokenType::As);
23816 let dt = self.parse_data_type()?;
23817 (Some(first_ident), dt)
23818 }
23819 }
23820 } else {
23821 let first_ident = if self.check(TokenType::Input) || self.check(TokenType::Output) {
23824 let token = self.advance();
23825 Identifier {
23826 name: token.text,
23827 quoted: false,
23828 trailing_comments: Vec::new(),
23829 span: None,
23830 }
23831 } else {
23832 self.expect_identifier_with_quoted()?
23833 };
23834
23835 if self.check(TokenType::Comma)
23837 || self.check(TokenType::RParen)
23838 || self.check(TokenType::Default)
23839 {
23840 (None, self.identifier_to_datatype(&first_ident.name)?)
23842 } else {
23843 self.match_token(TokenType::As);
23846 let dt = self.parse_data_type()?;
23847 (Some(first_ident), dt)
23848 }
23849 };
23850
23851 let default = if self.match_token(TokenType::Default) || self.match_token(TokenType::Eq)
23852 {
23853 Some(self.parse_expression()?)
23854 } else {
23855 None
23856 };
23857
23858 params.push(FunctionParameter {
23859 name,
23860 data_type,
23861 mode,
23862 default,
23863 mode_text: mode_text.clone(),
23864 });
23865
23866 if !self.match_token(TokenType::Comma) {
23867 break;
23868 }
23869 }
23870
23871 Ok(params)
23872 }
23873
23874 fn parse_tsql_procedure_params(&mut self) -> Result<Vec<FunctionParameter>> {
23877 let mut params = Vec::new();
23878 loop {
23879 if !self.check(TokenType::Var) {
23880 break;
23881 }
23882 let name = self.advance().text.clone();
23883 self.match_token(TokenType::As);
23885 let data_type = self.parse_data_type()?;
23886 let default = if self.match_token(TokenType::Default) || self.match_token(TokenType::Eq)
23887 {
23888 Some(self.parse_expression()?)
23889 } else {
23890 None
23891 };
23892 params.push(FunctionParameter {
23893 name: Some(Identifier::new(name)),
23894 data_type,
23895 mode: None,
23896 default,
23897 mode_text: None,
23898 });
23899 if !self.match_token(TokenType::Comma) {
23900 break;
23901 }
23902 }
23903 Ok(params)
23904 }
23905
23906 fn identifier_to_datatype(&self, ident: &str) -> Result<DataType> {
23911 Ok(DataType::Custom {
23914 name: ident.to_string(),
23915 })
23916 }
23917
23918 fn parse_function_return_type(&mut self) -> Result<DataType> {
23923 if matches!(
23925 self.config.dialect,
23926 Some(crate::dialects::DialectType::MySQL)
23927 ) {
23928 return self.parse_data_type();
23929 }
23930
23931 if (self.check(TokenType::Identifier) || self.check(TokenType::Var))
23933 && !self.check_next(TokenType::LParen) && !self.check_next(TokenType::LBracket)
23935 {
23937 let type_name = self.advance().text.clone();
23938 return Ok(DataType::Custom { name: type_name });
23941 }
23942
23943 self.parse_data_type()
23945 }
23946
23947 fn parse_drop_function(&mut self) -> Result<Expression> {
23949 self.expect(TokenType::Function)?;
23950
23951 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
23952 let name = self.parse_table_ref()?;
23953
23954 let parameters = if self.match_token(TokenType::LParen) {
23956 let mut types = Vec::new();
23957 if !self.check(TokenType::RParen) {
23958 loop {
23959 types.push(self.parse_data_type()?);
23960 if !self.match_token(TokenType::Comma) {
23961 break;
23962 }
23963 }
23964 }
23965 self.expect(TokenType::RParen)?;
23966 Some(types)
23967 } else {
23968 None
23969 };
23970
23971 let cascade = self.match_token(TokenType::Cascade);
23972 if !cascade {
23973 self.match_token(TokenType::Restrict);
23974 }
23975
23976 Ok(Expression::DropFunction(Box::new(DropFunction {
23977 name,
23978 parameters,
23979 if_exists,
23980 cascade,
23981 })))
23982 }
23983
23984 fn parse_create_procedure(&mut self, or_replace: bool, or_alter: bool) -> Result<Expression> {
23986 let use_proc_keyword = self.peek().text.eq_ignore_ascii_case("PROC");
23988 self.expect(TokenType::Procedure)?;
23989
23990 let if_not_exists =
23991 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
23992 let name = self.parse_table_ref()?;
23993
23994 let (parameters, has_parens) = if self.match_token(TokenType::LParen) {
23996 let params = self.parse_function_parameters()?;
23997 self.expect(TokenType::RParen)?;
23998 (params, true)
23999 } else if self.check(TokenType::Var) && !self.check(TokenType::As) {
24000 let params = self.parse_tsql_procedure_params()?;
24003 (params, false)
24004 } else {
24005 (Vec::new(), false)
24006 };
24007
24008 let mut language = None;
24009 let mut security = None;
24010 let mut body = None;
24011 let mut return_type = None;
24012 let mut execute_as = None;
24013 let mut with_options: Vec<String> = Vec::new();
24014
24015 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
24017 if self.match_token(TokenType::Returns) {
24018 return_type = Some(self.parse_data_type()?);
24020 } else if self.match_identifier("EXECUTE") || self.match_token(TokenType::Execute) {
24021 if self.match_token(TokenType::As) {
24023 if self.match_identifier("CALLER") {
24024 execute_as = Some("CALLER".to_string());
24025 } else if self.match_identifier("OWNER") {
24026 execute_as = Some("OWNER".to_string());
24027 } else if self.match_identifier("SELF") {
24028 execute_as = Some("SELF".to_string());
24029 }
24030 }
24031 } else if self.match_token(TokenType::Language) {
24032 language = Some(self.expect_identifier_or_keyword()?);
24034 } else if self.match_identifier("SECURITY") {
24035 if self.match_identifier("DEFINER") {
24036 security = Some(FunctionSecurity::Definer);
24037 } else if self.match_identifier("INVOKER") {
24038 security = Some(FunctionSecurity::Invoker);
24039 }
24040 } else if self.match_token(TokenType::With) {
24041 loop {
24045 if self.match_identifier("EXECUTE") || self.match_token(TokenType::Execute) {
24046 self.expect(TokenType::As)?;
24048 if self.check(TokenType::String) {
24049 let tok = self.advance();
24050 with_options.push(format!("EXECUTE AS '{}'", tok.text));
24051 } else {
24052 let ident = self.expect_identifier_or_keyword()?;
24053 with_options.push(format!("EXECUTE AS {}", ident.to_ascii_uppercase()));
24054 }
24055 } else {
24056 let opt = self.expect_identifier_or_keyword()?;
24057 with_options.push(opt.to_ascii_uppercase());
24058 }
24059 if !self.match_token(TokenType::Comma) {
24060 break;
24061 }
24062 }
24063 } else if self.match_token(TokenType::As) {
24064 if self.check(TokenType::String) {
24066 let tok = self.advance();
24068 body = Some(FunctionBody::StringLiteral(tok.text.clone()));
24069 } else if self.match_token(TokenType::Begin) {
24070 let mut statements = Vec::new();
24072 while !self.check(TokenType::End) && !self.is_at_end() {
24073 while self.match_token(TokenType::Semicolon) {}
24075 if self.check(TokenType::End) {
24076 break;
24077 }
24078 statements.push(self.parse_statement()?);
24079 self.match_token(TokenType::Semicolon);
24081 }
24082 self.expect(TokenType::End)?;
24083 body = Some(FunctionBody::Statements(statements));
24084 } else {
24085 let stmt = self.parse_statement()?;
24087 body = Some(FunctionBody::Expression(stmt));
24088 }
24089 } else {
24090 break;
24091 }
24092 }
24093
24094 Ok(Expression::CreateProcedure(Box::new(CreateProcedure {
24095 name,
24096 parameters,
24097 body,
24098 or_replace,
24099 or_alter,
24100 if_not_exists,
24101 language,
24102 security,
24103 return_type,
24104 execute_as,
24105 with_options,
24106 has_parens,
24107 use_proc_keyword,
24108 })))
24109 }
24110
24111 fn parse_drop_procedure(&mut self) -> Result<Expression> {
24113 self.expect(TokenType::Procedure)?;
24114
24115 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
24116 let name = self.parse_table_ref()?;
24117
24118 let parameters = if self.match_token(TokenType::LParen) {
24119 let mut types = Vec::new();
24120 if !self.check(TokenType::RParen) {
24121 loop {
24122 types.push(self.parse_data_type()?);
24123 if !self.match_token(TokenType::Comma) {
24124 break;
24125 }
24126 }
24127 }
24128 self.expect(TokenType::RParen)?;
24129 Some(types)
24130 } else {
24131 None
24132 };
24133
24134 let cascade = self.match_token(TokenType::Cascade);
24135 if !cascade {
24136 self.match_token(TokenType::Restrict);
24137 }
24138
24139 Ok(Expression::DropProcedure(Box::new(DropProcedure {
24140 name,
24141 parameters,
24142 if_exists,
24143 cascade,
24144 })))
24145 }
24146
24147 fn parse_create_sequence(&mut self, temporary: bool, or_replace: bool) -> Result<Expression> {
24149 self.expect(TokenType::Sequence)?;
24150
24151 let if_not_exists =
24152 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
24153 let name = self.parse_table_ref()?;
24154
24155 let mut seq = CreateSequence {
24156 name,
24157 if_not_exists,
24158 temporary,
24159 or_replace,
24160 as_type: None,
24161 increment: None,
24162 minvalue: None,
24163 maxvalue: None,
24164 start: None,
24165 cache: None,
24166 cycle: false,
24167 owned_by: None,
24168 owned_by_none: false,
24169 order: None,
24170 comment: None,
24171 sharing: None,
24172 scale_modifier: None,
24173 shard_modifier: None,
24174 property_order: Vec::new(),
24175 };
24176
24177 if self.match_token(TokenType::As) {
24179 seq.as_type = Some(self.parse_data_type()?);
24180 }
24181
24182 self.match_token(TokenType::With);
24185
24186 loop {
24187 self.match_token(TokenType::Comma);
24189
24190 if self.is_at_end() || self.check(TokenType::Semicolon) {
24191 break;
24192 }
24193
24194 if self.match_token(TokenType::Increment) || self.match_identifier("INCREMENT") {
24195 self.match_token(TokenType::By);
24196 self.match_token(TokenType::Eq); seq.increment = Some(self.parse_signed_integer()?);
24198 seq.property_order.push(SeqPropKind::Increment);
24199 } else if self.match_token(TokenType::Minvalue) {
24200 seq.minvalue = Some(SequenceBound::Value(self.parse_signed_integer()?));
24201 seq.property_order.push(SeqPropKind::Minvalue);
24202 } else if self.match_keywords(&[TokenType::No, TokenType::Minvalue]) {
24203 seq.minvalue = Some(SequenceBound::None);
24204 seq.property_order.push(SeqPropKind::Minvalue);
24205 } else if self.match_identifier("NOMINVALUE") {
24206 seq.minvalue = Some(SequenceBound::None);
24207 seq.property_order.push(SeqPropKind::NoMinvalueWord);
24208 } else if self.match_token(TokenType::Maxvalue) {
24209 seq.maxvalue = Some(SequenceBound::Value(self.parse_signed_integer()?));
24210 seq.property_order.push(SeqPropKind::Maxvalue);
24211 } else if self.match_keywords(&[TokenType::No, TokenType::Maxvalue]) {
24212 seq.maxvalue = Some(SequenceBound::None);
24213 seq.property_order.push(SeqPropKind::Maxvalue);
24214 } else if self.match_identifier("NOMAXVALUE") {
24215 seq.maxvalue = Some(SequenceBound::None);
24216 seq.property_order.push(SeqPropKind::NoMaxvalueWord);
24217 } else if self.match_token(TokenType::Start) {
24218 self.match_token(TokenType::With);
24219 self.match_token(TokenType::Eq); seq.start = Some(self.parse_signed_integer()?);
24221 seq.property_order.push(SeqPropKind::Start);
24222 } else if self.match_token(TokenType::Cache) {
24223 seq.cache = Some(self.parse_signed_integer()?);
24224 seq.property_order.push(SeqPropKind::Cache);
24225 } else if self.match_identifier("NOCACHE") {
24226 seq.property_order.push(SeqPropKind::NoCacheWord);
24228 } else if self.match_token(TokenType::Cycle) {
24229 seq.cycle = true;
24230 seq.property_order.push(SeqPropKind::Cycle);
24231 } else if self.match_token(TokenType::NoCycle) {
24232 seq.cycle = false;
24234 seq.property_order.push(SeqPropKind::NoCycleWord);
24235 } else if self.match_token(TokenType::No) {
24236 if self.match_token(TokenType::Cycle) {
24238 seq.cycle = false;
24239 seq.property_order.push(SeqPropKind::NoCycle);
24240 } else if self.match_token(TokenType::Cache) || self.match_identifier("CACHE") {
24241 seq.property_order.push(SeqPropKind::NoCache);
24242 } else if self.match_token(TokenType::Minvalue) {
24243 seq.minvalue = Some(SequenceBound::None);
24244 seq.property_order.push(SeqPropKind::Minvalue);
24245 } else if self.match_token(TokenType::Maxvalue) {
24246 seq.maxvalue = Some(SequenceBound::None);
24247 seq.property_order.push(SeqPropKind::Maxvalue);
24248 } else {
24249 break;
24251 }
24252 } else if self.match_token(TokenType::Owned) {
24253 self.expect(TokenType::By)?;
24254 if self.match_identifier("NONE") {
24255 seq.owned_by = None;
24256 seq.owned_by_none = true;
24257 } else {
24258 seq.owned_by = Some(self.parse_table_ref()?);
24259 }
24260 seq.property_order.push(SeqPropKind::OwnedBy);
24261 } else if self.match_token(TokenType::Order) {
24262 seq.order = Some(true);
24264 seq.property_order.push(SeqPropKind::Order);
24265 } else if self.match_identifier("NOORDER") {
24266 seq.order = Some(false);
24268 seq.property_order.push(SeqPropKind::NoOrder);
24269 } else if self.match_token(TokenType::Comment) || self.match_identifier("COMMENT") {
24270 self.expect(TokenType::Eq)?;
24272 let comment_val = self.expect(TokenType::String)?;
24273 seq.comment = Some(comment_val.text.clone());
24274 seq.property_order.push(SeqPropKind::Comment);
24275 } else if self.match_identifier("SHARING") {
24276 self.expect(TokenType::Eq)?;
24278 let val = self.expect_identifier_or_keyword()?;
24279 seq.sharing = Some(val);
24280 seq.property_order.push(SeqPropKind::Sharing);
24281 } else if self.match_identifier("NOKEEP") {
24282 seq.property_order.push(SeqPropKind::NoKeep);
24283 } else if self.match_token(TokenType::Keep) || self.match_identifier("KEEP") {
24284 seq.property_order.push(SeqPropKind::Keep);
24285 } else if self.match_identifier("SCALE") {
24286 let modifier = if self.match_identifier("EXTEND") {
24287 "EXTEND".to_string()
24288 } else if self.match_identifier("NOEXTEND") {
24289 "NOEXTEND".to_string()
24290 } else {
24291 String::new()
24292 };
24293 seq.scale_modifier = Some(modifier);
24294 seq.property_order.push(SeqPropKind::Scale);
24295 } else if self.match_identifier("NOSCALE") {
24296 seq.property_order.push(SeqPropKind::NoScale);
24297 } else if self.match_identifier("SHARD") {
24298 let modifier = if self.match_identifier("EXTEND") {
24299 "EXTEND".to_string()
24300 } else if self.match_identifier("NOEXTEND") {
24301 "NOEXTEND".to_string()
24302 } else {
24303 String::new()
24304 };
24305 seq.shard_modifier = Some(modifier);
24306 seq.property_order.push(SeqPropKind::Shard);
24307 } else if self.match_identifier("NOSHARD") {
24308 seq.property_order.push(SeqPropKind::NoShard);
24309 } else if self.match_identifier("SESSION") {
24310 seq.property_order.push(SeqPropKind::Session);
24311 } else if self.match_identifier("GLOBAL") {
24312 seq.property_order.push(SeqPropKind::Global);
24313 } else {
24314 break;
24315 }
24316 }
24317
24318 Ok(Expression::CreateSequence(Box::new(seq)))
24319 }
24320
24321 fn parse_signed_integer(&mut self) -> Result<i64> {
24323 let negative = self.match_token(TokenType::Dash);
24324 let tok = self.expect(TokenType::Number)?;
24325 let value: i64 = tok
24326 .text
24327 .parse()
24328 .map_err(|_| self.parse_error(format!("Invalid integer: {}", tok.text)))?;
24329 Ok(if negative { -value } else { value })
24330 }
24331
24332 fn parse_drop_sequence(&mut self) -> Result<Expression> {
24334 self.expect(TokenType::Sequence)?;
24335
24336 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
24337 let name = self.parse_table_ref()?;
24338
24339 let cascade = self.match_token(TokenType::Cascade);
24340 if !cascade {
24341 self.match_token(TokenType::Restrict);
24342 }
24343
24344 Ok(Expression::DropSequence(Box::new(DropSequence {
24345 name,
24346 if_exists,
24347 cascade,
24348 })))
24349 }
24350
24351 fn parse_alter_sequence(&mut self) -> Result<Expression> {
24353 self.expect(TokenType::Sequence)?;
24354
24355 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
24356 let name = self.parse_table_ref()?;
24357
24358 let mut seq = AlterSequence {
24359 name,
24360 if_exists,
24361 increment: None,
24362 minvalue: None,
24363 maxvalue: None,
24364 start: None,
24365 restart: None,
24366 cache: None,
24367 cycle: None,
24368 owned_by: None,
24369 };
24370
24371 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
24373 if self.match_token(TokenType::Increment) || self.match_identifier("INCREMENT") {
24374 self.match_token(TokenType::By);
24375 seq.increment = Some(self.parse_signed_integer()?);
24376 } else if self.match_token(TokenType::Minvalue) {
24377 seq.minvalue = Some(SequenceBound::Value(self.parse_signed_integer()?));
24378 } else if self.match_keywords(&[TokenType::No, TokenType::Minvalue]) {
24379 seq.minvalue = Some(SequenceBound::None);
24380 } else if self.match_token(TokenType::Maxvalue) {
24381 seq.maxvalue = Some(SequenceBound::Value(self.parse_signed_integer()?));
24382 } else if self.match_keywords(&[TokenType::No, TokenType::Maxvalue]) {
24383 seq.maxvalue = Some(SequenceBound::None);
24384 } else if self.match_token(TokenType::Start) {
24385 self.match_token(TokenType::With);
24386 seq.start = Some(self.parse_signed_integer()?);
24387 } else if self.match_token(TokenType::Restart) {
24388 if self.match_token(TokenType::With)
24389 || self.check(TokenType::Number)
24390 || self.check(TokenType::Dash)
24391 {
24392 seq.restart = Some(Some(self.parse_signed_integer()?));
24393 } else {
24394 seq.restart = Some(None);
24395 }
24396 } else if self.match_token(TokenType::Cache) {
24397 seq.cache = Some(self.parse_signed_integer()?);
24398 } else if self.match_token(TokenType::Cycle) {
24399 seq.cycle = Some(true);
24400 } else if self.match_token(TokenType::NoCycle) {
24401 seq.cycle = Some(false);
24402 } else if self.match_token(TokenType::Owned) {
24403 self.expect(TokenType::By)?;
24404 if self.match_identifier("NONE") {
24405 seq.owned_by = Some(None);
24406 } else {
24407 seq.owned_by = Some(Some(self.parse_table_ref()?));
24408 }
24409 } else {
24410 break;
24411 }
24412 }
24413
24414 Ok(Expression::AlterSequence(Box::new(seq)))
24415 }
24416
24417 fn parse_create_trigger(
24419 &mut self,
24420 or_replace: bool,
24421 or_alter: bool,
24422 constraint: bool,
24423 create_pos: usize,
24424 ) -> Result<Expression> {
24425 self.expect(TokenType::Trigger)?;
24426
24427 let name = self.expect_identifier_with_quoted()?;
24428
24429 if self.check(TokenType::On) && !constraint {
24433 self.current = create_pos;
24434 return self.fallback_to_command(create_pos);
24435 }
24436
24437 let timing = if self.match_token(TokenType::Before) {
24439 TriggerTiming::Before
24440 } else if self.match_token(TokenType::After) {
24441 TriggerTiming::After
24442 } else if self.match_token(TokenType::Instead) {
24443 self.expect(TokenType::Of)?;
24444 TriggerTiming::InsteadOf
24445 } else {
24446 self.current = create_pos;
24448 return self.fallback_to_command(create_pos);
24449 };
24450
24451 let mut events = Vec::new();
24453 loop {
24454 if self.match_token(TokenType::Insert) {
24455 events.push(TriggerEvent::Insert);
24456 } else if self.match_token(TokenType::Update) {
24457 if self.match_token(TokenType::Of) {
24458 let mut cols = Vec::new();
24459 loop {
24460 cols.push(Identifier::new(self.expect_identifier()?));
24461 if !self.match_token(TokenType::Comma) {
24462 break;
24463 }
24464 }
24465 events.push(TriggerEvent::Update(Some(cols)));
24466 } else {
24467 events.push(TriggerEvent::Update(None));
24468 }
24469 } else if self.match_token(TokenType::Delete) {
24470 events.push(TriggerEvent::Delete);
24471 } else if self.match_token(TokenType::Truncate) {
24472 events.push(TriggerEvent::Truncate);
24473 } else {
24474 break;
24475 }
24476
24477 if !self.match_token(TokenType::Or) {
24478 break;
24479 }
24480 }
24481
24482 self.expect(TokenType::On)?;
24483 let table = self.parse_table_ref()?;
24484
24485 let referencing = if !constraint && self.match_token(TokenType::Referencing) {
24487 let mut ref_clause = TriggerReferencing {
24488 old_table: None,
24489 new_table: None,
24490 old_row: None,
24491 new_row: None,
24492 };
24493 while self.match_token(TokenType::Old) || self.match_token(TokenType::New) {
24494 let is_old = self.previous().token_type == TokenType::Old;
24495 let is_table = self.match_token(TokenType::Table);
24496 let _is_row = !is_table && self.match_token(TokenType::Row);
24497 self.match_token(TokenType::As);
24498 let alias = Identifier::new(self.expect_identifier()?);
24499
24500 if is_old {
24501 if is_table {
24502 ref_clause.old_table = Some(alias);
24503 } else {
24504 ref_clause.old_row = Some(alias);
24505 }
24506 } else {
24507 if is_table {
24508 ref_clause.new_table = Some(alias);
24509 } else {
24510 ref_clause.new_row = Some(alias);
24511 }
24512 }
24513 }
24514 Some(ref_clause)
24515 } else {
24516 None
24517 };
24518
24519 let mut deferrable = None;
24521 let mut initially_deferred = None;
24522 if constraint {
24523 if self.match_identifier("DEFERRABLE") {
24524 deferrable = Some(true);
24525 } else if self.match_keywords(&[TokenType::Not, TokenType::Identifier]) {
24526 deferrable = Some(false);
24528 }
24529 if self.match_identifier("INITIALLY") {
24530 if self.match_identifier("DEFERRED") {
24531 initially_deferred = Some(true);
24532 } else if self.match_identifier("IMMEDIATE") {
24533 initially_deferred = Some(false);
24534 }
24535 }
24536 }
24537
24538 let for_each = if self.match_token(TokenType::For) {
24540 self.match_token(TokenType::Each);
24541 if self.match_token(TokenType::Row) {
24542 Some(TriggerForEach::Row)
24543 } else if self.match_token(TokenType::Statement) {
24544 Some(TriggerForEach::Statement)
24545 } else {
24546 Some(TriggerForEach::Row)
24547 }
24548 } else {
24549 None
24550 };
24551
24552 let (when, when_paren) = if self.match_token(TokenType::When) {
24554 let has_paren = self.match_token(TokenType::LParen);
24555 let expr = self.parse_expression()?;
24556 if has_paren {
24557 self.expect(TokenType::RParen)?;
24558 }
24559 (Some(expr), has_paren)
24560 } else {
24561 (None, false)
24562 };
24563
24564 let body = if self.match_token(TokenType::Execute) {
24566 self.match_token(TokenType::Function);
24567 self.match_token(TokenType::Procedure);
24568 let func_name = self.parse_table_ref()?;
24569 self.expect(TokenType::LParen)?;
24570 let mut args = Vec::new();
24571 if !self.check(TokenType::RParen) {
24572 loop {
24573 args.push(self.parse_expression()?);
24574 if !self.match_token(TokenType::Comma) {
24575 break;
24576 }
24577 }
24578 }
24579 self.expect(TokenType::RParen)?;
24580 TriggerBody::Execute {
24581 function: func_name,
24582 args,
24583 }
24584 } else if self.match_token(TokenType::Begin) {
24585 let body_start = if !self.is_at_end() {
24587 self.tokens[self.current].span.start
24588 } else {
24589 0
24590 };
24591 let mut depth = 1;
24592 while depth > 0 && !self.is_at_end() {
24593 let tok = self.advance();
24594 if tok.token_type == TokenType::Begin {
24595 depth += 1;
24596 } else if tok.token_type == TokenType::End {
24597 depth -= 1;
24598 if depth == 0 {
24599 break;
24600 }
24601 }
24602 }
24603 let block_content = if let Some(ref source) = self.source {
24605 let body_end = if self.current > 0 {
24607 self.tokens[self.current - 1].span.start
24608 } else {
24609 body_start
24610 };
24611 source[body_start..body_end].trim().to_string()
24612 } else {
24613 String::new()
24615 };
24616 TriggerBody::Block(block_content)
24617 } else {
24618 return Err(self.parse_error("Expected EXECUTE or BEGIN in trigger body"));
24619 };
24620
24621 Ok(Expression::CreateTrigger(Box::new(CreateTrigger {
24622 name,
24623 table,
24624 timing,
24625 events,
24626 for_each,
24627 when,
24628 when_paren,
24629 body,
24630 or_replace,
24631 or_alter,
24632 constraint,
24633 deferrable,
24634 initially_deferred,
24635 referencing,
24636 })))
24637 }
24638
24639 fn parse_drop_trigger(&mut self) -> Result<Expression> {
24641 self.expect(TokenType::Trigger)?;
24642
24643 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
24644 let name = Identifier::new(self.expect_identifier()?);
24645
24646 let table = if self.match_token(TokenType::On) {
24647 Some(self.parse_table_ref()?)
24648 } else {
24649 None
24650 };
24651
24652 let cascade = self.match_token(TokenType::Cascade);
24653 if !cascade {
24654 self.match_token(TokenType::Restrict);
24655 }
24656
24657 Ok(Expression::DropTrigger(Box::new(DropTrigger {
24658 name,
24659 table,
24660 if_exists,
24661 cascade,
24662 })))
24663 }
24664
24665 fn parse_create_type(&mut self) -> Result<Expression> {
24667 self.expect(TokenType::Type)?;
24668
24669 let if_not_exists =
24670 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
24671 let name = self.parse_table_ref()?;
24672
24673 self.expect(TokenType::As)?;
24674
24675 let definition = if self.match_token(TokenType::Enum) {
24676 self.expect(TokenType::LParen)?;
24678 let mut values = Vec::new();
24679 loop {
24680 let tok = self.expect(TokenType::String)?;
24681 values.push(tok.text.trim_matches('\'').to_string());
24682 if !self.match_token(TokenType::Comma) {
24683 break;
24684 }
24685 }
24686 self.expect(TokenType::RParen)?;
24687 TypeDefinition::Enum(values)
24688 } else if self.match_token(TokenType::LParen) {
24689 let mut attrs = Vec::new();
24691 loop {
24692 let attr_name = Identifier::new(self.expect_identifier()?);
24693 let data_type = self.parse_data_type()?;
24694 let collate = if self.match_identifier("COLLATE") {
24695 Some(Identifier::new(self.expect_identifier()?))
24696 } else {
24697 None
24698 };
24699 attrs.push(TypeAttribute {
24700 name: attr_name,
24701 data_type,
24702 collate,
24703 });
24704 if !self.match_token(TokenType::Comma) {
24705 break;
24706 }
24707 }
24708 self.expect(TokenType::RParen)?;
24709 TypeDefinition::Composite(attrs)
24710 } else if self.match_token(TokenType::Range) {
24711 self.expect(TokenType::LParen)?;
24713 self.match_identifier("SUBTYPE");
24714 self.match_token(TokenType::Eq);
24715 let subtype = self.parse_data_type()?;
24716
24717 let mut subtype_diff = None;
24718 let mut canonical = None;
24719
24720 while self.match_token(TokenType::Comma) {
24721 if self.match_identifier("SUBTYPE_DIFF") {
24722 self.match_token(TokenType::Eq);
24723 subtype_diff = Some(self.expect_identifier()?);
24724 } else if self.match_identifier("CANONICAL") {
24725 self.match_token(TokenType::Eq);
24726 canonical = Some(self.expect_identifier()?);
24727 }
24728 }
24729 self.expect(TokenType::RParen)?;
24730
24731 TypeDefinition::Range {
24732 subtype,
24733 subtype_diff,
24734 canonical,
24735 }
24736 } else {
24737 return Err(
24738 self.parse_error("Expected ENUM, composite type definition, or RANGE after AS")
24739 );
24740 };
24741
24742 Ok(Expression::CreateType(Box::new(CreateType {
24743 name,
24744 definition,
24745 if_not_exists,
24746 })))
24747 }
24748
24749 fn parse_create_domain(&mut self) -> Result<Expression> {
24751 self.expect(TokenType::Domain)?;
24752
24753 let if_not_exists =
24754 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
24755 let name = self.parse_table_ref()?;
24756
24757 self.expect(TokenType::As)?;
24758 let base_type = self.parse_data_type()?;
24759
24760 let mut default = None;
24761 let mut constraints = Vec::new();
24762
24763 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
24765 if self.match_token(TokenType::Default) {
24766 default = Some(self.parse_expression()?);
24767 } else if self.match_token(TokenType::Constraint) {
24768 let constr_name = Some(Identifier::new(self.expect_identifier()?));
24769 self.expect(TokenType::Check)?;
24770 self.expect(TokenType::LParen)?;
24771 let check_expr = self.parse_expression()?;
24772 self.expect(TokenType::RParen)?;
24773 constraints.push(DomainConstraint {
24774 name: constr_name,
24775 check: check_expr,
24776 });
24777 } else if self.match_token(TokenType::Check) {
24778 self.expect(TokenType::LParen)?;
24779 let check_expr = self.parse_expression()?;
24780 self.expect(TokenType::RParen)?;
24781 constraints.push(DomainConstraint {
24782 name: None,
24783 check: check_expr,
24784 });
24785 } else if self.match_keywords(&[TokenType::Not, TokenType::Null]) {
24786 constraints.push(DomainConstraint {
24788 name: None,
24789 check: Expression::IsNull(Box::new(IsNull {
24790 this: Expression::Identifier(Identifier::new("VALUE")),
24791 not: true,
24792 postfix_form: false,
24793 })),
24794 });
24795 } else {
24796 break;
24797 }
24798 }
24799
24800 Ok(Expression::CreateType(Box::new(CreateType {
24801 name,
24802 definition: TypeDefinition::Domain {
24803 base_type,
24804 default,
24805 constraints,
24806 },
24807 if_not_exists,
24808 })))
24809 }
24810
24811 fn parse_create_stage(&mut self, or_replace: bool, temporary: bool) -> Result<Expression> {
24813 self.skip(); let start = self.current;
24816 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
24817 self.skip();
24818 }
24819 let sql = self.tokens_to_sql_stage_format(start, self.current);
24820
24821 let mut prefix = String::from("CREATE");
24823 if or_replace {
24824 prefix.push_str(" OR REPLACE");
24825 }
24826 if temporary {
24827 prefix.push_str(" TEMPORARY");
24828 }
24829 prefix.push_str(" STAGE");
24830
24831 Ok(Expression::Raw(Raw {
24832 sql: format!("{} {}", prefix, sql),
24833 }))
24834 }
24835
24836 fn parse_create_tag(&mut self, or_replace: bool) -> Result<Expression> {
24838 self.skip(); let start = self.current;
24841 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
24842 self.skip();
24843 }
24844 let sql = self.tokens_to_sql(start, self.current);
24845 let prefix = if or_replace {
24846 "CREATE OR REPLACE TAG"
24847 } else {
24848 "CREATE TAG"
24849 };
24850 Ok(Expression::Raw(Raw {
24851 sql: format!("{} {}", prefix, sql),
24852 }))
24853 }
24854
24855 fn parse_create_stream(&mut self, _or_replace: bool) -> Result<Expression> {
24857 self.skip(); let start = self.current;
24860 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
24861 self.skip();
24862 }
24863 let sql = self.tokens_to_sql(start, self.current);
24864 Ok(Expression::Raw(Raw {
24865 sql: format!("CREATE STREAM {}", sql),
24866 }))
24867 }
24868
24869 fn parse_create_task(&mut self, or_replace: bool) -> Result<Expression> {
24874 self.skip(); let if_not_exists =
24877 self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
24878
24879 let mut name = String::new();
24881 if self.check(TokenType::Var) || self.check_keyword() || self.is_identifier_token() {
24882 name.push_str(&self.advance().text);
24883 }
24884 while self.check(TokenType::Dot) {
24885 self.skip();
24886 name.push('.');
24887 if self.check(TokenType::Var) || self.check_keyword() || self.is_identifier_token() {
24888 name.push_str(&self.advance().text);
24889 }
24890 }
24891
24892 let props_start = self.current;
24894 while !self.is_at_end() && !self.check(TokenType::Semicolon) && !self.check(TokenType::As) {
24895 self.skip();
24896 }
24897 let properties = self.tokens_to_sql(props_start, self.current);
24898
24899 if !self.match_token(TokenType::As) {
24901 return Err(self.parse_error("Expected AS keyword in CREATE TASK"));
24902 }
24903
24904 let body = self.parse_statement()?;
24905
24906 Ok(Expression::CreateTask(Box::new(
24907 crate::expressions::CreateTask {
24908 or_replace,
24909 if_not_exists,
24910 name,
24911 properties,
24912 body,
24913 },
24914 )))
24915 }
24916
24917 fn parse_create_file_format(
24919 &mut self,
24920 or_replace: bool,
24921 temporary: bool,
24922 ) -> Result<Expression> {
24923 self.skip(); self.skip(); let start = self.current;
24927 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
24928 self.skip();
24929 }
24930 let sql = self.tokens_to_sql(start, self.current);
24931 let mut prefix = String::from("CREATE");
24932 if or_replace {
24933 prefix.push_str(" OR REPLACE");
24934 }
24935 if temporary {
24936 prefix.push_str(" TEMPORARY");
24937 }
24938 prefix.push_str(" FILE FORMAT ");
24939 prefix.push_str(&sql);
24940 Ok(Expression::Raw(Raw { sql: prefix }))
24941 }
24942
24943 fn parse_drop_type(&mut self) -> Result<Expression> {
24945 self.expect(TokenType::Type)?;
24946
24947 let if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
24948 let name = self.parse_table_ref()?;
24949
24950 let cascade = self.match_token(TokenType::Cascade);
24951 if !cascade {
24952 self.match_token(TokenType::Restrict);
24953 }
24954
24955 Ok(Expression::DropType(Box::new(DropType {
24956 name,
24957 if_exists,
24958 cascade,
24959 })))
24960 }
24961
24962 fn parse_alter_view_with_modifiers(
24963 &mut self,
24964 algorithm: Option<String>,
24965 definer: Option<String>,
24966 sql_security: Option<String>,
24967 ) -> Result<Expression> {
24968 self.expect(TokenType::View)?;
24969
24970 let name = self.parse_table_ref()?;
24971 let mut actions = Vec::new();
24972
24973 let columns = if self.check(TokenType::LParen) {
24976 let saved = self.current;
24978 self.skip(); let is_column_aliases = self.check(TokenType::Identifier)
24982 || self.check(TokenType::Var)
24983 || self.check(TokenType::QuotedIdentifier);
24984
24985 if is_column_aliases {
24986 let mut cols = Vec::new();
24988 loop {
24989 let col_name = self.expect_identifier()?;
24990 let comment = if self.match_token(TokenType::Comment) {
24992 Some(self.expect_string()?)
24993 } else {
24994 None
24995 };
24996 cols.push(ViewColumn {
24997 name: Identifier::new(col_name),
24998 comment,
24999 options: Vec::new(),
25000 });
25001 if !self.match_token(TokenType::Comma) {
25002 break;
25003 }
25004 }
25005 self.expect(TokenType::RParen)?;
25006 cols
25007 } else {
25008 self.current = saved; Vec::new()
25010 }
25011 } else {
25012 Vec::new()
25013 };
25014
25015 let with_option = if self.match_token(TokenType::With) {
25017 let opt = self.expect_identifier_or_keyword()?;
25018 Some(opt.to_ascii_uppercase())
25019 } else {
25020 None
25021 };
25022
25023 if self.match_token(TokenType::Rename) {
25025 self.expect(TokenType::To)?;
25026 actions.push(AlterViewAction::Rename(self.parse_table_ref()?));
25027 } else if self.match_identifier("OWNER") {
25028 self.expect(TokenType::To)?;
25029 actions.push(AlterViewAction::OwnerTo(Identifier::new(
25030 self.expect_identifier()?,
25031 )));
25032 } else if self.match_token(TokenType::Set) {
25033 if self.match_identifier("TBLPROPERTIES") {
25036 let props = self.parse_tblproperties_key_value_list()?;
25037 actions.push(AlterViewAction::SetTblproperties(props));
25038 } else if self.match_token(TokenType::Authorization) {
25039 let mut auth_text = String::new();
25040 if self.match_texts(&["ROLE"]) {
25041 auth_text.push_str("ROLE ");
25042 }
25043 let user = self.expect_identifier()?;
25044 auth_text.push_str(&user);
25045 actions.push(AlterViewAction::SetAuthorization(auth_text));
25046 } else {
25047 self.expect(TokenType::Schema)?;
25048 actions.push(AlterViewAction::SetSchema(Identifier::new(
25049 self.expect_identifier()?,
25050 )));
25051 }
25052 } else if self.match_identifier("UNSET") {
25053 if !self.match_identifier("TBLPROPERTIES") {
25055 return Err(self.parse_error("Expected TBLPROPERTIES after UNSET"));
25056 }
25057 let keys = self.parse_tblproperties_key_list()?;
25058 actions.push(AlterViewAction::UnsetTblproperties(keys));
25059 } else if self.match_token(TokenType::Alter) {
25060 self.match_token(TokenType::Column);
25061 let col_name = Identifier::new(self.expect_identifier()?);
25062 let action = self.parse_alter_column_action()?;
25063 actions.push(AlterViewAction::AlterColumn {
25064 name: col_name,
25065 action,
25066 });
25067 } else if self.match_token(TokenType::As) {
25068 let query = self.parse_statement()?;
25070 actions.push(AlterViewAction::AsSelect(Box::new(query)));
25071 }
25072
25073 Ok(Expression::AlterView(Box::new(AlterView {
25074 name,
25075 actions,
25076 algorithm,
25077 definer,
25078 sql_security,
25079 with_option,
25080 columns,
25081 })))
25082 }
25083
25084 fn parse_tblproperties_key_value_list(&mut self) -> Result<Vec<(String, String)>> {
25086 self.expect(TokenType::LParen)?;
25087 let mut props = Vec::new();
25088 loop {
25089 let key = self.expect_string()?;
25090 self.expect(TokenType::Eq)?;
25091 let value = self.expect_string()?;
25092 props.push((key, value));
25093 if !self.match_token(TokenType::Comma) {
25094 break;
25095 }
25096 }
25097 self.expect(TokenType::RParen)?;
25098 Ok(props)
25099 }
25100
25101 fn parse_tblproperties_key_list(&mut self) -> Result<Vec<String>> {
25103 self.expect(TokenType::LParen)?;
25104 let mut keys = Vec::new();
25105 loop {
25106 let key = self.expect_string()?;
25107 keys.push(key);
25108 if !self.match_token(TokenType::Comma) {
25109 break;
25110 }
25111 }
25112 self.expect(TokenType::RParen)?;
25113 Ok(keys)
25114 }
25115
25116 fn parse_alter_index(&mut self) -> Result<Expression> {
25118 self.expect(TokenType::Index)?;
25119
25120 let name = self.expect_identifier_or_keyword_with_quoted()?;
25122
25123 let table = if self.match_token(TokenType::On) {
25124 Some(self.parse_table_ref()?)
25125 } else {
25126 None
25127 };
25128
25129 let mut actions = Vec::new();
25130
25131 if self.match_token(TokenType::Rename) {
25133 self.expect(TokenType::To)?;
25134 actions.push(AlterIndexAction::Rename(
25136 self.expect_identifier_or_keyword_with_quoted()?,
25137 ));
25138 } else if self.match_token(TokenType::Set) {
25139 self.match_identifier("TABLESPACE");
25140 actions.push(AlterIndexAction::SetTablespace(
25141 self.expect_identifier_or_keyword_with_quoted()?,
25142 ));
25143 } else if self.match_identifier("VISIBLE") {
25144 actions.push(AlterIndexAction::Visible(true));
25145 } else if self.match_identifier("INVISIBLE") {
25146 actions.push(AlterIndexAction::Visible(false));
25147 }
25148
25149 Ok(Expression::AlterIndex(Box::new(AlterIndex {
25150 name,
25151 table,
25152 actions,
25153 })))
25154 }
25155
25156 fn parse_expression(&mut self) -> Result<Expression> {
25162 let mut left = self.parse_or()?;
25163
25164 while self.match_token(TokenType::ColonEq) {
25167 let right = self.parse_or()?;
25168 left = Expression::PropertyEQ(Box::new(BinaryOp::new(left, right)));
25169 }
25170
25171 if matches!(
25174 self.config.dialect,
25175 Some(crate::dialects::DialectType::ClickHouse)
25176 ) && self.match_token(TokenType::Parameter)
25177 {
25178 if self.check(TokenType::Colon) {
25179 return Err(
25180 self.parse_error("Expected true expression after ? in ClickHouse ternary")
25181 );
25182 }
25183 let true_value = self.parse_or()?;
25184 let false_value = if self.match_token(TokenType::Colon) {
25185 self.parse_or()?
25186 } else {
25187 Expression::Null(Null)
25188 };
25189 left = Expression::IfFunc(Box::new(IfFunc {
25190 original_name: None,
25191 condition: left,
25192 true_value,
25193 false_value: Some(false_value),
25194 inferred_type: None,
25195 }));
25196 }
25197
25198 if matches!(
25204 self.config.dialect,
25205 Some(crate::dialects::DialectType::ClickHouse)
25206 ) {
25207 while self.check(TokenType::Apply) && self.check_next(TokenType::LParen) {
25208 self.skip(); self.skip(); let expr = self.parse_expression()?;
25211 self.expect(TokenType::RParen)?;
25212 left = Expression::Apply(Box::new(crate::expressions::Apply {
25213 this: Box::new(left),
25214 expression: Box::new(expr),
25215 }));
25216 }
25217 }
25218
25219 Ok(left)
25220 }
25221
25222 fn parse_or(&mut self) -> Result<Expression> {
25224 let mut left = self.parse_xor()?;
25225
25226 while self.check(TokenType::Or)
25227 || (self.dpipe_is_logical_or() && self.check(TokenType::DPipe))
25228 {
25229 let mut all_comments = self.previous_trailing_comments().to_vec();
25230 all_comments.extend_from_slice(self.current_leading_comments());
25232 self.skip(); all_comments.extend_from_slice(self.previous_trailing_comments());
25234 if !all_comments.is_empty() {
25236 Self::clear_rightmost_trailing_comments(&mut left);
25237 }
25238 all_comments.retain(|c| !c.trim().is_empty());
25240 let mut left_comments = Vec::new();
25242 let mut operator_comments = Vec::new();
25243 for comment in all_comments {
25244 if comment.starts_with("/*") {
25245 left_comments.push(comment);
25246 } else {
25247 operator_comments.push(comment);
25248 }
25249 }
25250 let mut right = self.parse_xor()?;
25251 if !self.pending_leading_comments.is_empty() {
25253 let pending = std::mem::take(&mut self.pending_leading_comments);
25254 right = Expression::Annotated(Box::new(Annotated {
25255 this: right,
25256 trailing_comments: pending,
25257 }));
25258 }
25259 left = Expression::Or(Box::new(BinaryOp {
25260 left,
25261 right,
25262 left_comments,
25263 operator_comments,
25264 trailing_comments: Vec::new(),
25265 inferred_type: None,
25266 }));
25267 }
25268
25269 Ok(Self::maybe_rebalance_boolean_chain(left, false))
25270 }
25271
25272 fn dpipe_is_logical_or(&self) -> bool {
25274 matches!(
25275 self.config.dialect,
25276 Some(crate::dialects::DialectType::MySQL | crate::dialects::DialectType::Solr)
25277 )
25278 }
25279
25280 fn parse_xor(&mut self) -> Result<Expression> {
25282 let mut left = self.parse_and()?;
25283
25284 while self.match_token(TokenType::Xor) {
25285 let right = self.parse_and()?;
25286 left = Expression::Xor(Box::new(Xor {
25287 this: Some(Box::new(left)),
25288 expression: Some(Box::new(right)),
25289 expressions: Vec::new(),
25290 }));
25291 }
25292
25293 Ok(left)
25294 }
25295
25296 fn parse_and(&mut self) -> Result<Expression> {
25298 let mut left = self.parse_not()?;
25299
25300 while self.check(TokenType::And) {
25301 let mut all_comments = self.previous_trailing_comments().to_vec();
25303 all_comments.extend_from_slice(self.current_leading_comments());
25305 self.skip(); all_comments.extend_from_slice(self.previous_trailing_comments());
25308 if !all_comments.is_empty() {
25310 Self::clear_rightmost_trailing_comments(&mut left);
25311 }
25312 all_comments.retain(|c| !c.trim().is_empty());
25314 let mut left_comments = Vec::new();
25319 let mut operator_comments = Vec::new();
25320 for comment in all_comments {
25321 if comment.starts_with("/*") {
25322 left_comments.push(comment);
25323 } else {
25324 operator_comments.push(comment);
25325 }
25326 }
25327 let mut right = self.parse_not()?;
25328 if !self.pending_leading_comments.is_empty() {
25332 let pending = std::mem::take(&mut self.pending_leading_comments);
25333 right = Expression::Annotated(Box::new(Annotated {
25334 this: right,
25335 trailing_comments: pending,
25336 }));
25337 }
25338 left = Expression::And(Box::new(BinaryOp {
25339 left,
25340 right,
25341 left_comments,
25342 operator_comments,
25343 trailing_comments: Vec::new(),
25344 inferred_type: None,
25345 }));
25346 }
25347
25348 Ok(Self::maybe_rebalance_boolean_chain(left, true))
25349 }
25350
25351 fn maybe_rebalance_boolean_chain(expr: Expression, is_and: bool) -> Expression {
25354 if !Self::should_rebalance_boolean_chain(&expr, is_and) {
25355 return expr;
25356 }
25357
25358 let terms = Self::flatten_boolean_terms_owned(expr, is_and);
25359 if terms.len() <= 2 {
25360 return Self::build_balanced_boolean_tree(terms, is_and);
25361 }
25362
25363 Self::build_balanced_boolean_tree(terms, is_and)
25364 }
25365
25366 fn should_rebalance_boolean_chain(expr: &Expression, is_and: bool) -> bool {
25367 let mut leaf_count = 0usize;
25368 let mut stack = vec![expr];
25369
25370 while let Some(node) = stack.pop() {
25371 match (is_and, node) {
25372 (true, Expression::And(op)) => {
25373 if !op.left_comments.is_empty()
25374 || !op.operator_comments.is_empty()
25375 || !op.trailing_comments.is_empty()
25376 {
25377 return false;
25378 }
25379 stack.push(&op.right);
25380 stack.push(&op.left);
25381 }
25382 (false, Expression::Or(op)) => {
25383 if !op.left_comments.is_empty()
25384 || !op.operator_comments.is_empty()
25385 || !op.trailing_comments.is_empty()
25386 {
25387 return false;
25388 }
25389 stack.push(&op.right);
25390 stack.push(&op.left);
25391 }
25392 _ => leaf_count += 1,
25393 }
25394 }
25395
25396 leaf_count > 2
25397 }
25398
25399 fn flatten_boolean_terms_owned(expr: Expression, is_and: bool) -> Vec<Expression> {
25400 let mut terms = Vec::new();
25401 let mut stack = vec![expr];
25402
25403 while let Some(node) = stack.pop() {
25404 match (is_and, node) {
25405 (true, Expression::And(op)) => {
25406 stack.push(op.right);
25407 stack.push(op.left);
25408 }
25409 (false, Expression::Or(op)) => {
25410 stack.push(op.right);
25411 stack.push(op.left);
25412 }
25413 (_, other) => terms.push(other),
25414 }
25415 }
25416
25417 terms
25418 }
25419
25420 fn build_balanced_boolean_tree(mut terms: Vec<Expression>, is_and: bool) -> Expression {
25421 if terms.is_empty() {
25422 return Expression::Null(Null);
25423 }
25424
25425 while terms.len() > 1 {
25426 let mut next = Vec::with_capacity((terms.len() + 1) / 2);
25427 let mut iter = terms.into_iter();
25428
25429 while let Some(left) = iter.next() {
25430 if let Some(right) = iter.next() {
25431 let combined = if is_and {
25432 Expression::And(Box::new(BinaryOp::new(left, right)))
25433 } else {
25434 Expression::Or(Box::new(BinaryOp::new(left, right)))
25435 };
25436 next.push(combined);
25437 } else {
25438 next.push(left);
25439 }
25440 }
25441
25442 terms = next;
25443 }
25444
25445 terms.pop().unwrap_or(Expression::Null(Null))
25446 }
25447
25448 fn parse_not(&mut self) -> Result<Expression> {
25450 if self.match_token(TokenType::Not) {
25451 let expr = self.parse_not()?;
25452 Ok(Expression::Not(Box::new(UnaryOp::new(expr))))
25453 } else {
25454 self.parse_comparison()
25455 }
25456 }
25457
25458 fn parse_comparison(&mut self) -> Result<Expression> {
25460 let pre_left_comments = self.current_leading_comments().to_vec();
25463 let mut left = self.parse_bitwise_or()?;
25464
25465 let has_comparison_op = !self.is_at_end()
25471 && matches!(
25472 self.peek().token_type,
25473 TokenType::Eq
25474 | TokenType::Neq
25475 | TokenType::Lt
25476 | TokenType::Gt
25477 | TokenType::Lte
25478 | TokenType::Gte
25479 | TokenType::Is
25480 | TokenType::In
25481 | TokenType::Not
25482 | TokenType::Between
25483 | TokenType::Like
25484 | TokenType::ILike
25485 | TokenType::RLike
25486 | TokenType::SimilarTo
25487 );
25488
25489 if !pre_left_comments.is_empty() {
25490 if has_comparison_op {
25491 match &mut left {
25493 Expression::Column(col) => {
25494 col.trailing_comments.extend(pre_left_comments);
25495 }
25496 Expression::Identifier(id) => {
25497 id.trailing_comments.extend(pre_left_comments);
25498 }
25499 _ => {
25500 left = Expression::Annotated(Box::new(Annotated {
25501 this: left,
25502 trailing_comments: pre_left_comments,
25503 }));
25504 }
25505 }
25506 } else {
25507 self.pending_leading_comments = pre_left_comments;
25510 }
25511 }
25512
25513 loop {
25514 let mut global_in = false;
25515 if matches!(
25516 self.config.dialect,
25517 Some(crate::dialects::DialectType::ClickHouse)
25518 ) && self.check_identifier("GLOBAL")
25519 && (self.check_next(TokenType::Not) || self.check_next(TokenType::In))
25520 {
25521 self.skip();
25522 global_in = true;
25523 }
25524
25525 let expr = if self.match_token(TokenType::Eq) {
25526 if self.match_token(TokenType::Any) || self.match_token(TokenType::Some) {
25528 let was_any = self.previous_token_type() == Some(TokenType::Any);
25529 self.expect(TokenType::LParen)?;
25530 let inner = self.parse_statement()?;
25531 self.expect(TokenType::RParen)?;
25532 let subquery = if was_any {
25533 self.maybe_wrap_in_subquery(inner)
25534 } else {
25535 inner
25536 };
25537 Expression::Any(Box::new(QuantifiedExpr {
25538 this: left,
25539 subquery,
25540 op: Some(QuantifiedOp::Eq),
25541 }))
25542 } else if self.match_token(TokenType::All) {
25543 self.expect(TokenType::LParen)?;
25544 let inner = self.parse_statement()?;
25545 self.expect(TokenType::RParen)?;
25546 let subquery = self.maybe_wrap_in_subquery(inner);
25547 Expression::All(Box::new(QuantifiedExpr {
25548 this: left,
25549 subquery,
25550 op: Some(QuantifiedOp::Eq),
25551 }))
25552 } else {
25553 let right = self.parse_bitwise_or()?;
25554 let trailing_comments = self.previous_trailing_comments().to_vec();
25555 Expression::Eq(Box::new(BinaryOp {
25556 left,
25557 right,
25558 left_comments: Vec::new(),
25559 operator_comments: Vec::new(),
25560 trailing_comments,
25561 inferred_type: None,
25562 }))
25563 }
25564 } else if self.match_token(TokenType::Neq) {
25565 if self.match_token(TokenType::Any) || self.match_token(TokenType::Some) {
25567 let was_any = self.previous_token_type() == Some(TokenType::Any);
25568 self.expect(TokenType::LParen)?;
25569 let inner = self.parse_statement()?;
25570 self.expect(TokenType::RParen)?;
25571 let subquery = if was_any {
25572 self.maybe_wrap_in_subquery(inner)
25573 } else {
25574 inner
25575 };
25576 Expression::Any(Box::new(QuantifiedExpr {
25577 this: left,
25578 subquery,
25579 op: Some(QuantifiedOp::Neq),
25580 }))
25581 } else if self.match_token(TokenType::All) {
25582 self.expect(TokenType::LParen)?;
25583 let inner = self.parse_statement()?;
25584 self.expect(TokenType::RParen)?;
25585 let subquery = self.maybe_wrap_in_subquery(inner);
25586 Expression::All(Box::new(QuantifiedExpr {
25587 this: left,
25588 subquery,
25589 op: Some(QuantifiedOp::Neq),
25590 }))
25591 } else {
25592 let right = self.parse_bitwise_or()?;
25593 let trailing_comments = self.previous_trailing_comments().to_vec();
25594 Expression::Neq(Box::new(BinaryOp {
25595 left,
25596 right,
25597 left_comments: Vec::new(),
25598 operator_comments: Vec::new(),
25599 trailing_comments,
25600 inferred_type: None,
25601 }))
25602 }
25603 } else if self.match_token(TokenType::Lt) {
25604 if self.match_token(TokenType::Any) || self.match_token(TokenType::Some) {
25606 let was_any = self.previous_token_type() == Some(TokenType::Any);
25607 self.expect(TokenType::LParen)?;
25608 let inner = self.parse_statement()?;
25609 self.expect(TokenType::RParen)?;
25610 let subquery = if was_any {
25611 self.maybe_wrap_in_subquery(inner)
25612 } else {
25613 inner
25614 };
25615 Expression::Any(Box::new(QuantifiedExpr {
25616 this: left,
25617 subquery,
25618 op: Some(QuantifiedOp::Lt),
25619 }))
25620 } else if self.match_token(TokenType::All) {
25621 self.expect(TokenType::LParen)?;
25622 let inner = self.parse_statement()?;
25623 self.expect(TokenType::RParen)?;
25624 let subquery = self.maybe_wrap_in_subquery(inner);
25625 Expression::All(Box::new(QuantifiedExpr {
25626 this: left,
25627 subquery,
25628 op: Some(QuantifiedOp::Lt),
25629 }))
25630 } else {
25631 let right = self.parse_bitwise_or()?;
25632 let trailing_comments = self.previous_trailing_comments().to_vec();
25633 Expression::Lt(Box::new(BinaryOp {
25634 left,
25635 right,
25636 left_comments: Vec::new(),
25637 operator_comments: Vec::new(),
25638 trailing_comments,
25639 inferred_type: None,
25640 }))
25641 }
25642 } else if self.match_token(TokenType::Lte) {
25643 if self.match_token(TokenType::Any) || self.match_token(TokenType::Some) {
25645 let was_any = self.previous_token_type() == Some(TokenType::Any);
25646 self.expect(TokenType::LParen)?;
25647 let inner = self.parse_statement()?;
25648 self.expect(TokenType::RParen)?;
25649 let subquery = if was_any {
25650 self.maybe_wrap_in_subquery(inner)
25651 } else {
25652 inner
25653 };
25654 Expression::Any(Box::new(QuantifiedExpr {
25655 this: left,
25656 subquery,
25657 op: Some(QuantifiedOp::Lte),
25658 }))
25659 } else if self.match_token(TokenType::All) {
25660 self.expect(TokenType::LParen)?;
25661 let inner = self.parse_statement()?;
25662 self.expect(TokenType::RParen)?;
25663 let subquery = self.maybe_wrap_in_subquery(inner);
25664 Expression::All(Box::new(QuantifiedExpr {
25665 this: left,
25666 subquery,
25667 op: Some(QuantifiedOp::Lte),
25668 }))
25669 } else {
25670 let right = self.parse_bitwise_or()?;
25671 let trailing_comments = self.previous_trailing_comments().to_vec();
25672 Expression::Lte(Box::new(BinaryOp {
25673 left,
25674 right,
25675 left_comments: Vec::new(),
25676 operator_comments: Vec::new(),
25677 trailing_comments,
25678 inferred_type: None,
25679 }))
25680 }
25681 } else if self.match_token(TokenType::Gt) {
25682 if self.match_token(TokenType::Any) || self.match_token(TokenType::Some) {
25684 let was_any = self.previous_token_type() == Some(TokenType::Any);
25685 self.expect(TokenType::LParen)?;
25686 let inner = self.parse_statement()?;
25687 self.expect(TokenType::RParen)?;
25688 let subquery = if was_any {
25689 self.maybe_wrap_in_subquery(inner)
25690 } else {
25691 inner
25692 };
25693 Expression::Any(Box::new(QuantifiedExpr {
25694 this: left,
25695 subquery,
25696 op: Some(QuantifiedOp::Gt),
25697 }))
25698 } else if self.match_token(TokenType::All) {
25699 self.expect(TokenType::LParen)?;
25700 let inner = self.parse_statement()?;
25701 self.expect(TokenType::RParen)?;
25702 let subquery = self.maybe_wrap_in_subquery(inner);
25703 Expression::All(Box::new(QuantifiedExpr {
25704 this: left,
25705 subquery,
25706 op: Some(QuantifiedOp::Gt),
25707 }))
25708 } else {
25709 let right = self.parse_bitwise_or()?;
25710 let trailing_comments = self.previous_trailing_comments().to_vec();
25711 Expression::Gt(Box::new(BinaryOp {
25712 left,
25713 right,
25714 left_comments: Vec::new(),
25715 operator_comments: Vec::new(),
25716 trailing_comments,
25717 inferred_type: None,
25718 }))
25719 }
25720 } else if self.match_token(TokenType::Gte) {
25721 if self.match_token(TokenType::Any) || self.match_token(TokenType::Some) {
25723 let was_any = self.previous_token_type() == Some(TokenType::Any);
25724 self.expect(TokenType::LParen)?;
25725 let inner = self.parse_statement()?;
25726 self.expect(TokenType::RParen)?;
25727 let subquery = if was_any {
25728 self.maybe_wrap_in_subquery(inner)
25729 } else {
25730 inner
25731 };
25732 Expression::Any(Box::new(QuantifiedExpr {
25733 this: left,
25734 subquery,
25735 op: Some(QuantifiedOp::Gte),
25736 }))
25737 } else if self.match_token(TokenType::All) {
25738 self.expect(TokenType::LParen)?;
25739 let inner = self.parse_statement()?;
25740 self.expect(TokenType::RParen)?;
25741 let subquery = self.maybe_wrap_in_subquery(inner);
25742 Expression::All(Box::new(QuantifiedExpr {
25743 this: left,
25744 subquery,
25745 op: Some(QuantifiedOp::Gte),
25746 }))
25747 } else {
25748 let right = self.parse_bitwise_or()?;
25749 let trailing_comments = self.previous_trailing_comments().to_vec();
25750 Expression::Gte(Box::new(BinaryOp {
25751 left,
25752 right,
25753 left_comments: Vec::new(),
25754 operator_comments: Vec::new(),
25755 trailing_comments,
25756 inferred_type: None,
25757 }))
25758 }
25759 } else if self.match_token(TokenType::NullsafeEq) {
25760 let right = self.parse_bitwise_or()?;
25762 let trailing_comments = self.previous_trailing_comments().to_vec();
25763 Expression::NullSafeEq(Box::new(BinaryOp {
25764 left,
25765 right,
25766 left_comments: Vec::new(),
25767 operator_comments: Vec::new(),
25768 trailing_comments,
25769 inferred_type: None,
25770 }))
25771 } else if self.check_identifier("SOUNDS") && self.check_next(TokenType::Like) {
25772 self.skip(); self.skip(); let right = self.parse_bitwise_or()?;
25776 let soundex_left = Expression::Function(Box::new(Function::new(
25778 "SOUNDEX".to_string(),
25779 vec![left],
25780 )));
25781 let soundex_right = Expression::Function(Box::new(Function::new(
25782 "SOUNDEX".to_string(),
25783 vec![right],
25784 )));
25785 Expression::Eq(Box::new(BinaryOp::new(soundex_left, soundex_right)))
25786 } else if self.match_token(TokenType::Like) {
25787 let quantifier = if self.match_token(TokenType::Any) {
25789 Some("ANY".to_string())
25790 } else if self.match_token(TokenType::All) {
25791 Some("ALL".to_string())
25792 } else if self.match_token(TokenType::Some) {
25793 Some("SOME".to_string())
25794 } else {
25795 None
25796 };
25797 let right = self.parse_bitwise_or()?;
25798 let escape = if self.match_token(TokenType::Escape) {
25799 Some(self.parse_primary()?)
25800 } else {
25801 None
25802 };
25803 Expression::Like(Box::new(LikeOp {
25804 left,
25805 right,
25806 escape,
25807 quantifier,
25808 inferred_type: None,
25809 }))
25810 } else if self.match_token(TokenType::ILike) {
25811 let quantifier = if self.match_token(TokenType::Any) {
25813 Some("ANY".to_string())
25814 } else if self.match_token(TokenType::All) {
25815 Some("ALL".to_string())
25816 } else if self.match_token(TokenType::Some) {
25817 Some("SOME".to_string())
25818 } else {
25819 None
25820 };
25821 let right = self.parse_bitwise_or()?;
25822 let escape = if self.match_token(TokenType::Escape) {
25823 Some(self.parse_primary()?)
25824 } else {
25825 None
25826 };
25827 Expression::ILike(Box::new(LikeOp {
25828 left,
25829 right,
25830 escape,
25831 quantifier,
25832 inferred_type: None,
25833 }))
25834 } else if self.check_identifier("SIMILAR") && self.check_next(TokenType::To) {
25835 self.skip(); self.skip(); let pattern = self.parse_bitwise_or()?;
25839 let escape = if self.match_token(TokenType::Escape) {
25840 Some(self.parse_primary()?)
25841 } else {
25842 None
25843 };
25844 Expression::SimilarTo(Box::new(SimilarToExpr {
25845 this: left,
25846 pattern,
25847 escape,
25848 not: false,
25849 }))
25850 } else if self.match_token(TokenType::Glob) {
25851 let right = self.parse_bitwise_or()?;
25852 Expression::Glob(Box::new(BinaryOp::new(left, right)))
25853 } else if self.match_token(TokenType::Match) {
25854 let right = self.parse_bitwise_or()?;
25856 Expression::Match(Box::new(BinaryOp::new(left, right)))
25857 } else if self.match_token(TokenType::RLike) || self.match_token(TokenType::Tilde) {
25858 let right = self.parse_bitwise_or()?;
25860 Expression::RegexpLike(Box::new(RegexpFunc {
25861 this: left,
25862 pattern: right,
25863 flags: None,
25864 }))
25865 } else if matches!(
25866 self.config.dialect,
25867 Some(crate::dialects::DialectType::Exasol)
25868 ) && self.check_identifier("REGEXP_LIKE")
25869 {
25870 self.skip(); let right = self.parse_bitwise_or()?;
25873 Expression::RegexpLike(Box::new(RegexpFunc {
25874 this: left,
25875 pattern: right,
25876 flags: None,
25877 }))
25878 } else if self.match_token(TokenType::IRLike) {
25879 let right = self.parse_bitwise_or()?;
25881 Expression::RegexpILike(Box::new(RegexpILike {
25882 this: Box::new(left),
25883 expression: Box::new(right),
25884 flag: None,
25885 }))
25886 } else if self.match_token(TokenType::NotLike) {
25887 let right = self.parse_bitwise_or()?;
25889 let escape = if self.match_token(TokenType::Escape) {
25890 Some(self.parse_primary()?)
25891 } else {
25892 None
25893 };
25894 let like_expr = Expression::Like(Box::new(LikeOp {
25895 left,
25896 right,
25897 escape,
25898 quantifier: None,
25899 inferred_type: None,
25900 }));
25901 Expression::Not(Box::new(UnaryOp::new(like_expr)))
25902 } else if self.match_token(TokenType::NotILike) {
25903 let right = self.parse_bitwise_or()?;
25905 let escape = if self.match_token(TokenType::Escape) {
25906 Some(self.parse_primary()?)
25907 } else {
25908 None
25909 };
25910 let ilike_expr = Expression::ILike(Box::new(LikeOp {
25911 left,
25912 right,
25913 escape,
25914 quantifier: None,
25915 inferred_type: None,
25916 }));
25917 Expression::Not(Box::new(UnaryOp::new(ilike_expr)))
25918 } else if self.match_token(TokenType::NotRLike) {
25919 let right = self.parse_bitwise_or()?;
25921 let regexp_expr = Expression::RegexpLike(Box::new(RegexpFunc {
25922 this: left,
25923 pattern: right,
25924 flags: None,
25925 }));
25926 Expression::Not(Box::new(UnaryOp::new(regexp_expr)))
25927 } else if self.match_token(TokenType::NotIRLike) {
25928 let right = self.parse_bitwise_or()?;
25930 let regexp_expr = Expression::RegexpILike(Box::new(RegexpILike {
25931 this: Box::new(left),
25932 expression: Box::new(right),
25933 flag: None,
25934 }));
25935 Expression::Not(Box::new(UnaryOp::new(regexp_expr)))
25936 } else if self.check(TokenType::Is)
25937 && !self.is_last_expression_token(TokenType::Is)
25938 && self.match_token(TokenType::Is)
25939 {
25940 let not = self.match_token(TokenType::Not);
25941 if self.match_token(TokenType::Null) {
25942 let expr = Expression::IsNull(Box::new(IsNull {
25943 this: left,
25944 not,
25945 postfix_form: false,
25946 }));
25947 if matches!(
25949 self.config.dialect,
25950 Some(crate::dialects::DialectType::ClickHouse)
25951 ) && self.check(TokenType::DColon)
25952 {
25953 self.skip(); let data_type = self.parse_data_type_for_cast()?;
25955 Expression::Cast(Box::new(Cast {
25956 this: expr,
25957 to: data_type,
25958 trailing_comments: Vec::new(),
25959 double_colon_syntax: true,
25960 format: None,
25961 default: None,
25962 inferred_type: None,
25963 }))
25964 } else {
25965 expr
25966 }
25967 } else if self.match_token(TokenType::True) {
25968 Expression::IsTrue(Box::new(IsTrueFalse { this: left, not }))
25970 } else if self.match_token(TokenType::False) {
25971 Expression::IsFalse(Box::new(IsTrueFalse { this: left, not }))
25973 } else if self.match_token(TokenType::Distinct) {
25974 self.expect(TokenType::From)?;
25976 let right = self.parse_bitwise_or()?;
25977 if not {
25978 Expression::NullSafeEq(Box::new(BinaryOp::new(left, right)))
25980 } else {
25981 Expression::NullSafeNeq(Box::new(BinaryOp::new(left, right)))
25983 }
25984 } else if self.match_identifier("UNKNOWN") {
25985 Expression::IsNull(Box::new(IsNull {
25987 this: left,
25988 not,
25989 postfix_form: false,
25990 }))
25991 } else if self.match_texts(&["JSON"]) {
25992 let json_type = if self.match_texts(&["VALUE"]) {
25994 Some("VALUE".to_string())
25995 } else if self.match_texts(&["SCALAR"]) {
25996 Some("SCALAR".to_string())
25997 } else if self.match_texts(&["OBJECT"]) {
25998 Some("OBJECT".to_string())
25999 } else if self.match_texts(&["ARRAY"]) {
26000 Some("ARRAY".to_string())
26001 } else {
26002 None
26003 };
26004
26005 let unique_keys = if self.match_text_seq(&["WITH", "UNIQUE", "KEYS"]) {
26007 Some(JsonUniqueKeys::With)
26008 } else if self.match_text_seq(&["WITHOUT", "UNIQUE", "KEYS"]) {
26009 Some(JsonUniqueKeys::Without)
26010 } else if self.match_text_seq(&["UNIQUE", "KEYS"]) {
26011 Some(JsonUniqueKeys::Shorthand)
26013 } else {
26014 None
26015 };
26016
26017 Expression::IsJson(Box::new(IsJson {
26018 this: left,
26019 json_type,
26020 unique_keys,
26021 negated: not,
26022 }))
26023 } else {
26024 let right = self.parse_primary()?;
26027 let is_expr = Expression::Is(Box::new(BinaryOp::new(left, right)));
26028 if not {
26029 Expression::Not(Box::new(UnaryOp::new(is_expr)))
26030 } else {
26031 is_expr
26032 }
26033 }
26034 } else if self.match_token(TokenType::Not) {
26035 if self.match_token(TokenType::In) {
26037 if self.check_identifier("UNNEST") {
26039 self.skip(); self.expect(TokenType::LParen)?;
26041 let unnest_expr = self.parse_expression()?;
26042 self.expect(TokenType::RParen)?;
26043 Expression::In(Box::new(In {
26044 this: left,
26045 expressions: Vec::new(),
26046 query: None,
26047 not: true,
26048 global: global_in,
26049 unnest: Some(Box::new(unnest_expr)),
26050 is_field: false,
26051 }))
26052 } else if self.match_token(TokenType::LParen) {
26053 if self.check(TokenType::Select) || self.check(TokenType::With) {
26054 let subquery = self.parse_statement()?;
26055 self.expect(TokenType::RParen)?;
26056 Expression::In(Box::new(In {
26057 this: left,
26058 expressions: Vec::new(),
26059 query: Some(subquery),
26060 not: true,
26061 global: global_in,
26062 unnest: None,
26063 is_field: false,
26064 }))
26065 } else if self.check(TokenType::RParen) {
26066 self.skip();
26068 Expression::In(Box::new(In {
26069 this: left,
26070 expressions: Vec::new(),
26071 query: None,
26072 not: true,
26073 global: global_in,
26074 unnest: None,
26075 is_field: false,
26076 }))
26077 } else {
26078 let expressions = self.parse_expression_list()?;
26079 self.expect(TokenType::RParen)?;
26080 Expression::In(Box::new(In {
26081 this: left,
26082 expressions,
26083 query: None,
26084 not: true,
26085 global: global_in,
26086 unnest: None,
26087 is_field: false,
26088 }))
26089 }
26090 } else {
26091 let table_expr = self.parse_primary()?;
26093 Expression::In(Box::new(In {
26094 this: left,
26095 expressions: vec![table_expr],
26096 query: None,
26097 not: true,
26098 global: global_in,
26099 unnest: None,
26100 is_field: true,
26101 }))
26102 }
26103 } else if self.match_token(TokenType::Between) {
26104 let symmetric = if self.match_texts(&["SYMMETRIC"]) {
26106 Some(true)
26107 } else if self.match_texts(&["ASYMMETRIC"]) {
26108 Some(false)
26109 } else {
26110 None
26111 };
26112 let low = self.parse_bitwise_or()?;
26113 self.expect(TokenType::And)?;
26114 let high = self.parse_bitwise_or()?;
26115 Expression::Between(Box::new(Between {
26116 this: left,
26117 low,
26118 high,
26119 not: true,
26120 symmetric,
26121 }))
26122 } else if self.check_identifier("SOUNDS") && self.check_next(TokenType::Like) {
26123 self.skip(); self.skip(); let right = self.parse_bitwise_or()?;
26127 let soundex_left = Expression::Function(Box::new(Function::new(
26128 "SOUNDEX".to_string(),
26129 vec![left],
26130 )));
26131 let soundex_right = Expression::Function(Box::new(Function::new(
26132 "SOUNDEX".to_string(),
26133 vec![right],
26134 )));
26135 let eq_expr =
26136 Expression::Eq(Box::new(BinaryOp::new(soundex_left, soundex_right)));
26137 Expression::Not(Box::new(UnaryOp::new(eq_expr)))
26138 } else if self.match_token(TokenType::Like) {
26139 let right = self.parse_bitwise_or()?;
26140 let escape = if self.match_token(TokenType::Escape) {
26141 Some(self.parse_primary()?)
26142 } else {
26143 None
26144 };
26145 let like_expr = Expression::Like(Box::new(LikeOp {
26146 left,
26147 right,
26148 escape,
26149 quantifier: None,
26150 inferred_type: None,
26151 }));
26152 Expression::Not(Box::new(UnaryOp::new(like_expr)))
26153 } else if self.match_token(TokenType::ILike) {
26154 let right = self.parse_bitwise_or()?;
26155 let escape = if self.match_token(TokenType::Escape) {
26156 Some(self.parse_primary()?)
26157 } else {
26158 None
26159 };
26160 let ilike_expr = Expression::ILike(Box::new(LikeOp {
26161 left,
26162 right,
26163 escape,
26164 quantifier: None,
26165 inferred_type: None,
26166 }));
26167 Expression::Not(Box::new(UnaryOp::new(ilike_expr)))
26168 } else if self.check_identifier("SIMILAR") && self.check_next(TokenType::To) {
26169 self.skip(); self.skip(); let pattern = self.parse_bitwise_or()?;
26173 let escape = if self.match_token(TokenType::Escape) {
26174 Some(self.parse_primary()?)
26175 } else {
26176 None
26177 };
26178 Expression::SimilarTo(Box::new(SimilarToExpr {
26179 this: left,
26180 pattern,
26181 escape,
26182 not: true,
26183 }))
26184 } else if self.match_token(TokenType::RLike) {
26185 let right = self.parse_bitwise_or()?;
26186 let regexp_expr = Expression::RegexpLike(Box::new(RegexpFunc {
26187 this: left,
26188 pattern: right,
26189 flags: None,
26190 }));
26191 Expression::Not(Box::new(UnaryOp::new(regexp_expr)))
26192 } else if self.match_token(TokenType::Null) {
26193 let is_null =
26196 Expression::Is(Box::new(BinaryOp::new(left, Expression::Null(Null))));
26197 Expression::Not(Box::new(UnaryOp::new(is_null)))
26198 } else {
26199 return Ok(left);
26201 }
26202 } else if self.match_token(TokenType::In) {
26203 if self.check_identifier("UNNEST") {
26205 self.skip(); self.expect(TokenType::LParen)?;
26207 let unnest_expr = self.parse_expression()?;
26208 self.expect(TokenType::RParen)?;
26209 Expression::In(Box::new(In {
26210 this: left,
26211 expressions: Vec::new(),
26212 query: None,
26213 not: false,
26214 global: global_in,
26215 unnest: Some(Box::new(unnest_expr)),
26216 is_field: false,
26217 }))
26218 } else if self.match_token(TokenType::LParen) {
26219 if self.check(TokenType::Select) || self.check(TokenType::With) {
26222 let subquery = self.parse_statement()?;
26224 self.expect(TokenType::RParen)?;
26225 Expression::In(Box::new(In {
26226 this: left,
26227 expressions: Vec::new(),
26228 query: Some(subquery),
26229 not: false,
26230 global: global_in,
26231 unnest: None,
26232 is_field: false,
26233 }))
26234 } else if self.check(TokenType::RParen) {
26235 self.skip();
26237 Expression::In(Box::new(In {
26238 this: left,
26239 expressions: Vec::new(),
26240 query: None,
26241 not: false,
26242 global: global_in,
26243 unnest: None,
26244 is_field: false,
26245 }))
26246 } else {
26247 let expressions = self.parse_expression_list()?;
26248 self.expect(TokenType::RParen)?;
26249 Expression::In(Box::new(In {
26250 this: left,
26251 expressions,
26252 query: None,
26253 not: false,
26254 global: global_in,
26255 unnest: None,
26256 is_field: false,
26257 }))
26258 }
26259 } else {
26260 let expr = self.parse_bitwise_or()?;
26262 Expression::In(Box::new(In {
26263 this: left,
26264 expressions: vec![expr],
26265 query: None,
26266 not: false,
26267 global: global_in,
26268 unnest: None,
26269 is_field: true,
26270 }))
26271 }
26272 } else if self.match_token(TokenType::Between) {
26273 let symmetric = if self.match_texts(&["SYMMETRIC"]) {
26275 Some(true)
26276 } else if self.match_texts(&["ASYMMETRIC"]) {
26277 Some(false)
26278 } else {
26279 None
26280 };
26281 let low = self.parse_bitwise_or()?;
26282 self.expect(TokenType::And)?;
26283 let high = self.parse_bitwise_or()?;
26284 Expression::Between(Box::new(Between {
26285 this: left,
26286 low,
26287 high,
26288 not: false,
26289 symmetric,
26290 }))
26291 } else if self.match_token(TokenType::Adjacent) {
26292 let right = self.parse_bitwise_or()?;
26293 Expression::Adjacent(Box::new(BinaryOp::new(left, right)))
26294 } else if self.check(TokenType::Overlaps)
26295 && self.current + 1 < self.tokens.len()
26296 && !matches!(
26297 self.tokens[self.current + 1].token_type,
26298 TokenType::Semicolon
26299 | TokenType::Comma
26300 | TokenType::From
26301 | TokenType::Where
26302 | TokenType::RParen
26303 | TokenType::As
26304 | TokenType::Join
26305 | TokenType::On
26306 | TokenType::OrderBy
26307 | TokenType::GroupBy
26308 | TokenType::Having
26309 | TokenType::Limit
26310 | TokenType::Union
26311 | TokenType::Except
26312 | TokenType::Intersect
26313 | TokenType::Eof
26314 )
26315 {
26316 self.skip(); let right = self.parse_bitwise_or()?;
26318 Expression::Overlaps(Box::new(OverlapsExpr {
26319 this: Some(left),
26320 expression: Some(right),
26321 left_start: None,
26322 left_end: None,
26323 right_start: None,
26324 right_end: None,
26325 }))
26326 } else if self.match_token(TokenType::IsNull) {
26327 Expression::IsNull(Box::new(IsNull {
26329 this: left,
26330 not: false,
26331 postfix_form: true,
26332 }))
26333 } else if self.match_token(TokenType::NotNull) {
26334 Expression::IsNull(Box::new(IsNull {
26336 this: left,
26337 not: true,
26338 postfix_form: true,
26339 }))
26340 } else if self.match_token(TokenType::AtAt) {
26341 let right = self.parse_bitwise_or()?;
26343 Expression::TsMatch(Box::new(BinaryOp::new(left, right)))
26344 } else if self.match_token(TokenType::AtGt) {
26345 let right = self.parse_bitwise_or()?;
26347 Expression::ArrayContainsAll(Box::new(BinaryOp::new(left, right)))
26348 } else if self.match_token(TokenType::LtAt) {
26349 let right = self.parse_bitwise_or()?;
26351 Expression::ArrayContainedBy(Box::new(BinaryOp::new(left, right)))
26352 } else if self.match_token(TokenType::DAmp) {
26353 let right = self.parse_bitwise_or()?;
26355 Expression::ArrayOverlaps(Box::new(BinaryOp::new(left, right)))
26356 } else if self.match_token(TokenType::QMarkAmp) {
26357 let right = self.parse_bitwise_or()?;
26359 Expression::JSONBContainsAllTopKeys(Box::new(BinaryOp::new(left, right)))
26360 } else if self.match_token(TokenType::QMarkPipe) {
26361 let right = self.parse_bitwise_or()?;
26363 Expression::JSONBContainsAnyTopKeys(Box::new(BinaryOp::new(left, right)))
26364 } else if !matches!(
26365 self.config.dialect,
26366 Some(crate::dialects::DialectType::ClickHouse)
26367 ) && self.match_token(TokenType::Parameter)
26368 {
26369 let right = self.parse_bitwise_or()?;
26374 Expression::JSONBContains(Box::new(BinaryFunc {
26375 original_name: Some("?".to_string()),
26376 this: left,
26377 expression: right,
26378 inferred_type: None,
26379 }))
26380 } else if self.match_token(TokenType::HashDash) {
26381 let right = self.parse_bitwise_or()?;
26383 Expression::JSONBDeleteAtPath(Box::new(BinaryOp::new(left, right)))
26384 } else if self.match_token(TokenType::AmpLt) {
26385 let right = self.parse_bitwise_or()?;
26387 Expression::ExtendsLeft(Box::new(BinaryOp::new(left, right)))
26388 } else if self.match_token(TokenType::AmpGt) {
26389 let right = self.parse_bitwise_or()?;
26391 Expression::ExtendsRight(Box::new(BinaryOp::new(left, right)))
26392 } else if self.match_identifier("MEMBER") {
26393 self.expect(TokenType::Of)?;
26395 self.expect(TokenType::LParen)?;
26396 let right = self.parse_expression()?;
26397 self.expect(TokenType::RParen)?;
26398 Expression::MemberOf(Box::new(BinaryOp::new(left, right)))
26399 } else if self.match_token(TokenType::CaretAt) {
26400 let right = self.parse_bitwise_or()?;
26402 Expression::StartsWith(Box::new(BinaryFunc {
26403 original_name: Some("^@".to_string()),
26404 this: left,
26405 expression: right,
26406 inferred_type: None,
26407 }))
26408 } else if self.match_token(TokenType::LrArrow) {
26409 let right = self.parse_bitwise_or()?;
26411 Expression::EuclideanDistance(Box::new(EuclideanDistance {
26412 this: Box::new(left),
26413 expression: Box::new(right),
26414 }))
26415 } else if self.match_token(TokenType::Operator) {
26416 self.expect(TokenType::LParen)?;
26419
26420 let mut op_text = String::new();
26423 while !self.check(TokenType::RParen) && !self.is_at_end() {
26424 op_text.push_str(&self.peek().text);
26425 self.skip();
26426 }
26427 self.expect(TokenType::RParen)?;
26428
26429 let mut comments = if self.current > 0 {
26433 std::mem::take(&mut self.tokens[self.current - 1].trailing_comments)
26434 } else {
26435 Vec::new()
26436 };
26437 if comments.is_empty() && !self.is_at_end() {
26438 comments = std::mem::take(&mut self.tokens[self.current].comments);
26439 }
26440
26441 let right = self.parse_bitwise_or()?;
26443
26444 Expression::Operator(Box::new(Operator {
26445 this: Box::new(left),
26446 operator: Some(Box::new(Expression::Identifier(Identifier::new(op_text)))),
26447 expression: Box::new(right),
26448 comments,
26449 }))
26450 } else {
26451 return Ok(left);
26452 };
26453
26454 left = expr;
26455 }
26456 }
26457
26458 fn parse_bitwise_or(&mut self) -> Result<Expression> {
26460 let mut left = self.parse_bitwise_xor()?;
26461
26462 loop {
26463 if self.match_token(TokenType::Pipe) {
26464 let right = self.parse_bitwise_xor()?;
26465 left = Expression::BitwiseOr(Box::new(BinaryOp::new(left, right)));
26466 } else {
26467 return Ok(left);
26468 }
26469 }
26470 }
26471
26472 fn parse_bitwise_continuation(&mut self, left: Expression) -> Result<Expression> {
26477 let mult_result = self.parse_multiplication_continuation(left)?;
26480 let add_result = self.parse_addition_continuation(mult_result)?;
26481 self.parse_bitwise_or_continuation(add_result)
26482 }
26483
26484 fn parse_bitwise_or_continuation(&mut self, mut left: Expression) -> Result<Expression> {
26486 loop {
26487 if self.match_token(TokenType::Pipe) {
26488 let right = self.parse_bitwise_xor()?;
26489 left = Expression::BitwiseOr(Box::new(BinaryOp::new(left, right)));
26490 } else {
26491 return Ok(left);
26492 }
26493 }
26494 }
26495
26496 fn parse_multiplication_continuation(&mut self, mut left: Expression) -> Result<Expression> {
26498 loop {
26499 let expr = if self.match_token(TokenType::Star) {
26500 let right = self.parse_power()?;
26501 Expression::Mul(Box::new(BinaryOp::new(left, right)))
26502 } else if self.match_token(TokenType::Slash) {
26503 let right = self.parse_power()?;
26504 Expression::Div(Box::new(BinaryOp::new(left, right)))
26505 } else if self.match_token(TokenType::Percent) {
26506 let right = self.parse_power()?;
26507 Expression::Mod(Box::new(BinaryOp::new(left, right)))
26508 } else if !self.check(TokenType::QuotedIdentifier)
26509 && (self.match_identifier("DIV") || self.match_token(TokenType::Div))
26510 {
26511 let matched_as_var = self.previous().token_type == TokenType::Var;
26516 if matched_as_var
26517 && (self.is_at_end()
26518 || self.check(TokenType::Semicolon)
26519 || self.check(TokenType::From)
26520 || self.check(TokenType::Where)
26521 || self.check(TokenType::Comma)
26522 || self.check(TokenType::RParen))
26523 {
26524 self.current -= 1;
26526 return Ok(left);
26527 }
26528 let right = self.parse_power()?;
26529 Expression::IntDiv(Box::new(crate::expressions::BinaryFunc {
26530 this: left,
26531 expression: right,
26532 original_name: None,
26533 inferred_type: None,
26534 }))
26535 } else {
26536 return Ok(left);
26537 };
26538 left = expr;
26539 }
26540 }
26541
26542 fn parse_addition_continuation(&mut self, mut left: Expression) -> Result<Expression> {
26544 loop {
26545 let left_comments = self.previous_trailing_comments().to_vec();
26546
26547 let expr = if self.match_token(TokenType::Plus) {
26548 let operator_comments = self.previous_trailing_comments().to_vec();
26549 let right = self.parse_at_time_zone()?;
26550 let trailing_comments = self.previous_trailing_comments().to_vec();
26551 Expression::Add(Box::new(BinaryOp {
26552 left,
26553 right,
26554 left_comments,
26555 operator_comments,
26556 trailing_comments,
26557 inferred_type: None,
26558 }))
26559 } else if self.match_token(TokenType::Dash) {
26560 let operator_comments = self.previous_trailing_comments().to_vec();
26561 let right = self.parse_at_time_zone()?;
26562 let trailing_comments = self.previous_trailing_comments().to_vec();
26563 Expression::Sub(Box::new(BinaryOp {
26564 left,
26565 right,
26566 left_comments,
26567 operator_comments,
26568 trailing_comments,
26569 inferred_type: None,
26570 }))
26571 } else if !self.dpipe_is_logical_or() && self.match_token(TokenType::DPipe) {
26572 let operator_comments = self.previous_trailing_comments().to_vec();
26573 let right = self.parse_at_time_zone()?;
26574 let trailing_comments = self.previous_trailing_comments().to_vec();
26575 Expression::Concat(Box::new(BinaryOp {
26576 left,
26577 right,
26578 left_comments,
26579 operator_comments,
26580 trailing_comments,
26581 inferred_type: None,
26582 }))
26583 } else if self.match_token(TokenType::DQMark) {
26584 let right = self.parse_at_time_zone()?;
26585 Expression::Coalesce(Box::new(crate::expressions::VarArgFunc {
26586 expressions: vec![left, right],
26587 original_name: None,
26588 inferred_type: None,
26589 }))
26590 } else {
26591 return Ok(left);
26592 };
26593
26594 left = expr;
26595 }
26596 }
26597
26598 fn parse_bitwise_xor(&mut self) -> Result<Expression> {
26600 let mut left = self.parse_bitwise_and()?;
26601
26602 loop {
26603 if matches!(
26605 self.config.dialect,
26606 Some(crate::dialects::DialectType::PostgreSQL)
26607 | Some(crate::dialects::DialectType::Redshift)
26608 ) {
26609 if self.match_token(TokenType::Hash) {
26610 let right = self.parse_bitwise_and()?;
26611 left = Expression::BitwiseXor(Box::new(BinaryOp::new(left, right)));
26612 } else {
26613 return Ok(left);
26614 }
26615 } else if self.match_token(TokenType::Caret) {
26616 let right = self.parse_bitwise_and()?;
26617 left = Expression::BitwiseXor(Box::new(BinaryOp::new(left, right)));
26618 } else {
26619 return Ok(left);
26620 }
26621 }
26622 }
26623
26624 fn parse_bitwise_and(&mut self) -> Result<Expression> {
26626 let mut left = self.parse_shift()?;
26627
26628 loop {
26629 if self.match_token(TokenType::Amp) {
26630 let right = self.parse_shift()?;
26631 left = Expression::BitwiseAnd(Box::new(BinaryOp::new(left, right)));
26632 } else {
26633 return Ok(left);
26634 }
26635 }
26636 }
26637
26638 fn parse_shift(&mut self) -> Result<Expression> {
26640 let mut left = self.parse_addition()?;
26641
26642 loop {
26643 if self.match_token(TokenType::LtLt) {
26644 let right = self.parse_addition()?;
26645 left = Expression::BitwiseLeftShift(Box::new(BinaryOp::new(left, right)));
26646 } else if self.match_token(TokenType::GtGt) {
26647 let right = self.parse_addition()?;
26648 left = Expression::BitwiseRightShift(Box::new(BinaryOp::new(left, right)));
26649 } else {
26650 return Ok(left);
26651 }
26652 }
26653 }
26654
26655 fn parse_addition(&mut self) -> Result<Expression> {
26657 let mut left = self.parse_at_time_zone()?;
26658
26659 loop {
26660 let left_comments = self.previous_trailing_comments().to_vec();
26662
26663 let expr = if self.match_token(TokenType::Plus) {
26664 let operator_comments = self.previous_trailing_comments().to_vec();
26666 let right = self.parse_at_time_zone()?;
26667 let trailing_comments = self.previous_trailing_comments().to_vec();
26668 Expression::Add(Box::new(BinaryOp {
26669 left,
26670 right,
26671 left_comments,
26672 operator_comments,
26673 trailing_comments,
26674 inferred_type: None,
26675 }))
26676 } else if self.match_token(TokenType::Dash) {
26677 let operator_comments = self.previous_trailing_comments().to_vec();
26678 let right = self.parse_at_time_zone()?;
26679 let trailing_comments = self.previous_trailing_comments().to_vec();
26680 Expression::Sub(Box::new(BinaryOp {
26681 left,
26682 right,
26683 left_comments,
26684 operator_comments,
26685 trailing_comments,
26686 inferred_type: None,
26687 }))
26688 } else if !self.dpipe_is_logical_or() && self.match_token(TokenType::DPipe) {
26689 let operator_comments = self.previous_trailing_comments().to_vec();
26690 let right = self.parse_at_time_zone()?;
26691 let trailing_comments = self.previous_trailing_comments().to_vec();
26692 Expression::Concat(Box::new(BinaryOp {
26693 left,
26694 right,
26695 left_comments,
26696 operator_comments,
26697 trailing_comments,
26698 inferred_type: None,
26699 }))
26700 } else if self.match_token(TokenType::DQMark) {
26701 let right = self.parse_at_time_zone()?;
26702 Expression::Coalesce(Box::new(crate::expressions::VarArgFunc {
26703 expressions: vec![left, right],
26704 original_name: None,
26705 inferred_type: None,
26706 }))
26707 } else {
26708 return Ok(left);
26709 };
26710
26711 left = expr;
26712 }
26713 }
26714
26715 fn parse_at_time_zone(&mut self) -> Result<Expression> {
26717 let mut expr = self.parse_multiplication()?;
26718
26719 while self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("AT") {
26721 self.skip(); if self.check(TokenType::Time) {
26724 self.skip(); if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("ZONE") {
26726 self.skip(); let zone = self.parse_unary()?;
26728 expr = Expression::AtTimeZone(Box::new(AtTimeZone { this: expr, zone }));
26729 } else {
26730 return Err(self.parse_error("Expected ZONE after AT TIME"));
26731 }
26732 } else {
26733 return Err(self.parse_error("Expected TIME after AT"));
26734 }
26735 }
26736
26737 Ok(expr)
26738 }
26739
26740 fn parse_multiplication(&mut self) -> Result<Expression> {
26742 let mut left = self.parse_power()?;
26743
26744 loop {
26745 let expr = if self.match_token(TokenType::Star) {
26746 let right = self.parse_power()?;
26747 Expression::Mul(Box::new(BinaryOp::new(left, right)))
26748 } else if self.match_token(TokenType::Slash) {
26749 let right = self.parse_power()?;
26750 Expression::Div(Box::new(BinaryOp::new(left, right)))
26751 } else if self.match_token(TokenType::Percent) {
26752 let right = self.parse_power()?;
26753 Expression::Mod(Box::new(BinaryOp::new(left, right)))
26754 } else if !self.check(TokenType::QuotedIdentifier)
26755 && (self.match_identifier("MOD") || self.match_token(TokenType::Mod))
26756 {
26757 let right = self.parse_power()?;
26760 Expression::Mod(Box::new(BinaryOp::new(left, right)))
26761 } else if !self.check(TokenType::QuotedIdentifier)
26762 && (self.match_identifier("DIV") || self.match_token(TokenType::Div))
26763 {
26764 let matched_as_var = self.previous().token_type == TokenType::Var;
26769 if matched_as_var
26770 && (self.is_at_end()
26771 || self.check(TokenType::Semicolon)
26772 || self.check(TokenType::From)
26773 || self.check(TokenType::Where)
26774 || self.check(TokenType::Comma)
26775 || self.check(TokenType::RParen))
26776 {
26777 self.current -= 1;
26779 return Ok(left);
26780 }
26781 let right = self.parse_power()?;
26782 Expression::IntDiv(Box::new(crate::expressions::BinaryFunc {
26783 this: left,
26784 expression: right,
26785 original_name: None,
26786 inferred_type: None,
26787 }))
26788 } else {
26789 return Ok(left);
26790 };
26791
26792 left = expr;
26793 }
26794 }
26795
26796 fn parse_power(&mut self) -> Result<Expression> {
26799 let mut left = self.parse_unary()?;
26800
26801 loop {
26802 if self.match_token(TokenType::DStar) {
26803 let right = self.parse_unary()?;
26804 left = Expression::Power(Box::new(BinaryFunc {
26805 original_name: Some("**".to_string()),
26806 this: left,
26807 expression: right,
26808 inferred_type: None,
26809 }));
26810 } else if matches!(
26811 self.config.dialect,
26812 Some(crate::dialects::DialectType::PostgreSQL)
26813 | Some(crate::dialects::DialectType::Redshift)
26814 | Some(crate::dialects::DialectType::DuckDB)
26815 ) && self.match_token(TokenType::Caret)
26816 {
26817 let right = self.parse_unary()?;
26818 left = Expression::Power(Box::new(BinaryFunc {
26819 original_name: None,
26820 this: left,
26821 expression: right,
26822 inferred_type: None,
26823 }));
26824 } else {
26825 return Ok(left);
26826 }
26827 }
26828 }
26829
26830 fn try_parse_type_literal(&mut self) -> Result<Option<Expression>> {
26834 let start_pos = self.current;
26836
26837 if !self.check(TokenType::Identifier) && !self.check(TokenType::Var) {
26839 return Ok(None);
26840 }
26841
26842 let type_name = self.peek().text.to_ascii_uppercase();
26844
26845 let is_type_literal_type = matches!(
26850 type_name.as_str(),
26851 "POINT" | "LINE" | "LSEG" | "BOX" | "PATH" | "POLYGON" | "CIRCLE" |
26853 "INET" | "CIDR" | "MACADDR" | "MACADDR8" |
26855 "UUID" | "JSON" | "JSONB" | "XML" | "BIT" | "VARBIT" |
26857 "INT4RANGE" | "INT8RANGE" | "NUMRANGE" | "TSRANGE" | "TSTZRANGE" | "DATERANGE"
26859 );
26860
26861 if !is_type_literal_type {
26862 return Ok(None);
26863 }
26864
26865 if self.current + 1 >= self.tokens.len() {
26867 return Ok(None);
26868 }
26869
26870 if self.tokens[self.current + 1].token_type != TokenType::String {
26871 return Ok(None);
26872 }
26873
26874 self.skip();
26877
26878 let data_type = match self.parse_data_type_from_name(&type_name) {
26880 Ok(dt) => dt,
26881 Err(_) => {
26882 self.current = start_pos;
26884 return Ok(None);
26885 }
26886 };
26887
26888 if !self.check(TokenType::String) {
26890 self.current = start_pos;
26892 return Ok(None);
26893 }
26894
26895 let string_token = self.advance();
26896 let value = Expression::Literal(Box::new(Literal::String(string_token.text.clone())));
26897
26898 if matches!(data_type, DataType::Json | DataType::JsonB)
26900 || matches!(type_name.as_str(), "JSON" | "JSONB")
26901 {
26902 return Ok(Some(Expression::ParseJson(Box::new(UnaryFunc {
26903 this: value,
26904 original_name: None,
26905 inferred_type: None,
26906 }))));
26907 }
26908
26909 Ok(Some(Expression::Cast(Box::new(Cast {
26911 this: value,
26912 to: data_type,
26913 trailing_comments: Vec::new(),
26914 double_colon_syntax: false,
26915 format: None,
26916 default: None,
26917 inferred_type: None,
26918 }))))
26919 }
26920
26921 fn try_parse_type_shorthand_cast(&mut self) -> Result<Option<Expression>> {
26925 let is_generic = self.config.dialect.is_none()
26927 || matches!(
26928 self.config.dialect,
26929 Some(crate::dialects::DialectType::Generic)
26930 );
26931 if !is_generic {
26932 return Ok(None);
26933 }
26934
26935 let start_pos = self.current;
26936
26937 if !self.is_type_keyword() {
26939 return Ok(None);
26940 }
26941
26942 if self.current + 1 >= self.tokens.len() {
26945 return Ok(None);
26946 }
26947
26948 let next_type = self.tokens[self.current + 1].token_type;
26949 if !matches!(next_type, TokenType::Number | TokenType::String) {
26951 return Ok(None);
26952 }
26953
26954 let type_token = self.advance();
26956 let type_name = type_token.text.to_ascii_uppercase();
26957
26958 let data_type = match type_name.as_str() {
26960 "INT" | "INTEGER" => DataType::Int {
26961 length: None,
26962 integer_spelling: type_name == "INTEGER",
26963 },
26964 "BIGINT" => DataType::BigInt { length: None },
26965 "SMALLINT" => DataType::SmallInt { length: None },
26966 "TINYINT" => DataType::TinyInt { length: None },
26967 "FLOAT" => DataType::Float {
26968 precision: None,
26969 scale: None,
26970 real_spelling: false,
26971 },
26972 "DOUBLE" => DataType::Double {
26973 precision: None,
26974 scale: None,
26975 },
26976 "DECIMAL" | "NUMERIC" => DataType::Decimal {
26977 precision: None,
26978 scale: None,
26979 },
26980 "REAL" => DataType::Float {
26981 precision: None,
26982 scale: None,
26983 real_spelling: true,
26984 },
26985 "VARCHAR" => DataType::VarChar {
26986 length: None,
26987 parenthesized_length: false,
26988 },
26989 "CHAR" => DataType::Char { length: None },
26990 "TEXT" | "STRING" => DataType::Text,
26991 "BOOLEAN" | "BOOL" => DataType::Boolean,
26992 "BINARY" => DataType::Binary { length: None },
26993 "VARBINARY" => DataType::VarBinary { length: None },
26994 _ => {
26995 self.current = start_pos;
26997 return Ok(None);
26998 }
26999 };
27000
27001 let value = if self.check(TokenType::String) {
27003 let tok = self.advance();
27004 Expression::Literal(Box::new(Literal::String(tok.text.clone())))
27005 } else if self.check(TokenType::Number) {
27006 let tok = self.advance();
27007 Expression::Literal(Box::new(Literal::Number(tok.text.clone())))
27008 } else {
27009 self.current = start_pos;
27010 return Ok(None);
27011 };
27012
27013 Ok(Some(Expression::Cast(Box::new(Cast {
27015 this: value,
27016 to: data_type,
27017 trailing_comments: Vec::new(),
27018 double_colon_syntax: false,
27019 format: None,
27020 default: None,
27021 inferred_type: None,
27022 }))))
27023 }
27024
27025 fn parse_unary(&mut self) -> Result<Expression> {
27027 if self.match_token(TokenType::Plus) {
27028 self.parse_unary()
27031 } else if self.match_token(TokenType::Dash) {
27032 let expr = self.parse_unary()?;
27033 Ok(Expression::Neg(Box::new(UnaryOp::new(expr))))
27034 } else if self.match_token(TokenType::Plus) {
27035 self.parse_unary()
27037 } else if self.match_token(TokenType::Tilde) {
27038 let expr = self.parse_unary()?;
27039 Ok(Expression::BitwiseNot(Box::new(UnaryOp::new(expr))))
27040 } else if self.match_token(TokenType::DPipeSlash) {
27041 let expr = self.parse_unary()?;
27043 Ok(Expression::Cbrt(Box::new(UnaryFunc::with_name(
27044 expr,
27045 "||/".to_string(),
27046 ))))
27047 } else if self.match_token(TokenType::PipeSlash) {
27048 let expr = self.parse_unary()?;
27050 Ok(Expression::Sqrt(Box::new(UnaryFunc::with_name(
27051 expr,
27052 "|/".to_string(),
27053 ))))
27054 } else if self.check(TokenType::DAt)
27055 && matches!(
27056 self.config.dialect,
27057 Some(crate::dialects::DialectType::DuckDB)
27058 )
27059 {
27060 self.skip(); let expr = self.parse_bitwise_or()?;
27067 Ok(Expression::Abs(Box::new(UnaryFunc::new(expr))))
27068 } else if self.check(TokenType::Var)
27069 && self.peek().text.starts_with('@')
27070 && matches!(
27071 self.config.dialect,
27072 Some(crate::dialects::DialectType::DuckDB)
27073 )
27074 {
27075 let token = self.advance(); let col_name = &token.text[1..]; let col_expr = Expression::boxed_column(Column {
27083 name: Identifier::new(col_name),
27084 table: None,
27085 join_mark: false,
27086 trailing_comments: Vec::new(),
27087 span: None,
27088 inferred_type: None,
27089 });
27090
27091 if self.check(TokenType::Plus)
27095 || self.check(TokenType::Dash)
27096 || self.check(TokenType::Star)
27097 || self.check(TokenType::Slash)
27098 || self.check(TokenType::Percent)
27099 || self.check(TokenType::Amp)
27100 || self.check(TokenType::Pipe)
27101 || self.check(TokenType::Caret)
27102 || self.check(TokenType::LtLt)
27103 || self.check(TokenType::GtGt)
27104 {
27105 let full_expr = self.parse_bitwise_continuation(col_expr)?;
27109 Ok(Expression::Abs(Box::new(UnaryFunc::new(full_expr))))
27110 } else {
27111 Ok(Expression::Abs(Box::new(UnaryFunc::new(col_expr))))
27113 }
27114 } else if self.check(TokenType::DAt)
27115 && (self.check_next(TokenType::LParen) || self.check_next(TokenType::Dash))
27116 {
27117 self.skip(); let expr = self.parse_bitwise_or()?;
27120 Ok(Expression::Abs(Box::new(UnaryFunc::new(expr))))
27121 } else if self.check(TokenType::Prior)
27122 && !self.check_next(TokenType::As)
27123 && !self.check_next(TokenType::Comma)
27124 && !self.check_next(TokenType::RParen)
27125 && !self.check_next(TokenType::Semicolon)
27126 && self.current + 1 < self.tokens.len()
27127 {
27128 self.skip(); let expr = self.parse_bitwise_or()?;
27134 Ok(Expression::Prior(Box::new(Prior { this: expr })))
27135 } else {
27136 if let Some(type_literal) = self.try_parse_type_literal()? {
27139 return self.parse_postfix_operators(type_literal);
27140 }
27141 if let Some(type_cast) = self.try_parse_type_shorthand_cast()? {
27144 return self.parse_postfix_operators(type_cast);
27145 }
27146 let expr = self.parse_primary()?;
27147 self.parse_postfix_operators(expr)
27149 }
27150 }
27151
27152 fn parse_postfix_operators(&mut self, mut expr: Expression) -> Result<Expression> {
27154 if self.check(TokenType::LParen) && self.check_next(TokenType::Plus) {
27157 let saved_pos = self.current;
27159 if self.match_token(TokenType::LParen)
27160 && self.match_token(TokenType::Plus)
27161 && self.match_token(TokenType::RParen)
27162 {
27163 if let Expression::Column(ref mut col) = expr {
27165 col.join_mark = true;
27166 }
27167 } else {
27168 self.current = saved_pos;
27169 }
27170 }
27171
27172 while self.match_token(TokenType::Exclamation) {
27174 let attr = self.parse_primary()?;
27177 expr = Expression::ModelAttribute(Box::new(ModelAttribute {
27178 this: Box::new(expr),
27179 expression: Box::new(attr),
27180 }));
27181 }
27182
27183 expr = self.parse_colon_json_path(expr)?;
27186
27187 if matches!(
27194 self.config.dialect,
27195 Some(crate::dialects::DialectType::SingleStore)
27196 ) {
27197 expr = self.parse_singlestore_json_path(expr)?;
27198 } else {
27199 while self.match_token(TokenType::DColon) {
27203 let data_type = self.parse_data_type_for_cast()?;
27204 expr = Expression::Cast(Box::new(Cast {
27205 this: expr,
27206 to: data_type,
27207 trailing_comments: Vec::new(),
27208 double_colon_syntax: true,
27209 format: None,
27210 default: None,
27211 inferred_type: None,
27212 }));
27213 }
27214 }
27215
27216 if matches!(
27218 self.config.dialect,
27219 Some(crate::dialects::DialectType::Teradata)
27220 ) && self.check(TokenType::LParen)
27221 && self.check_next(TokenType::Format)
27222 {
27223 self.skip(); self.skip(); let format = self.expect_string()?;
27226 self.expect(TokenType::RParen)?;
27227 expr = Expression::FormatPhrase(Box::new(FormatPhrase {
27228 this: Box::new(expr),
27229 format,
27230 }));
27231 }
27232
27233 Ok(expr)
27234 }
27235
27236 fn parse_singlestore_json_path(&mut self, mut expr: Expression) -> Result<Expression> {
27243 loop {
27244 if self.match_token(TokenType::DColon) {
27245 let path_key = if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
27248 self.advance().text
27249 } else if self.check(TokenType::Number) {
27250 self.advance().text
27252 } else {
27253 return Err(self.parse_error("Expected identifier after ::"));
27254 };
27255
27256 expr = Expression::Function(Box::new(Function::new(
27257 "JSON_EXTRACT_JSON".to_string(),
27258 vec![expr, Expression::string(&path_key)],
27259 )));
27260 } else if self.match_token(TokenType::DColonDollar) {
27261 let path_key = if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
27263 self.advance().text
27264 } else {
27265 return Err(self.parse_error("Expected identifier after ::$"));
27266 };
27267
27268 expr = Expression::Function(Box::new(Function::new(
27269 "JSON_EXTRACT_STRING".to_string(),
27270 vec![expr, Expression::string(&path_key)],
27271 )));
27272 } else if self.match_token(TokenType::DColonPercent) {
27273 let path_key = if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
27275 self.advance().text
27276 } else {
27277 return Err(self.parse_error("Expected identifier after ::%"));
27278 };
27279
27280 expr = Expression::Function(Box::new(Function::new(
27281 "JSON_EXTRACT_DOUBLE".to_string(),
27282 vec![expr, Expression::string(&path_key)],
27283 )));
27284 } else if self.match_token(TokenType::DColonQMark) {
27285 let path_key = if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
27287 self.advance().text
27288 } else {
27289 return Err(self.parse_error("Expected identifier after ::?"));
27290 };
27291
27292 expr = Expression::Function(Box::new(Function::new(
27294 "JSON_EXTRACT_JSON".to_string(), vec![expr, Expression::string(&format!("?{}", path_key))],
27296 )));
27297 } else {
27298 break;
27299 }
27300 }
27301 Ok(expr)
27302 }
27303
27304 fn parse_colon_json_path(&mut self, mut this: Expression) -> Result<Expression> {
27311 if matches!(
27314 self.config.dialect,
27315 Some(crate::dialects::DialectType::DuckDB)
27316 ) {
27317 return Ok(this);
27318 }
27319
27320 if matches!(
27323 self.config.dialect,
27324 Some(crate::dialects::DialectType::ClickHouse)
27325 ) {
27326 return Ok(this);
27327 }
27328
27329 let is_valid_json_path_base = matches!(
27332 &this,
27333 Expression::Column(_) |
27334 Expression::Identifier(_) |
27335 Expression::Dot(_) |
27336 Expression::JSONExtract(_) | Expression::Function(_) | Expression::ParseJson(_) | Expression::Parameter(_) );
27341
27342 if !is_valid_json_path_base {
27343 return Ok(this);
27344 }
27345
27346 if !self.check(TokenType::Colon) {
27348 return Ok(this);
27349 }
27350
27351 if self.check_next(TokenType::Colon) {
27353 return Ok(this);
27355 }
27356
27357 let mut path_string = String::new();
27361
27362 while self.check(TokenType::Colon) && !self.check_next(TokenType::Colon) {
27364 let saved_pos = self.current;
27367 let saved_path_len = path_string.len();
27368
27369 self.skip();
27371
27372 let mut had_initial_component = false;
27377 if self.check(TokenType::QuotedIdentifier) {
27378 let quoted_name = self.advance().text.clone();
27382 let is_snowflake = matches!(
27383 self.config.dialect,
27384 Some(crate::dialects::DialectType::Snowflake)
27385 );
27386 let needs_bracket = quoted_name.contains(' ') || quoted_name.contains('\'');
27387 if is_snowflake && !needs_bracket {
27388 if !path_string.is_empty() {
27391 path_string.push('.');
27392 }
27393 path_string.push_str("ed_name);
27394 } else if is_snowflake && needs_bracket {
27395 path_string.push_str("[\"");
27398 path_string.push_str("ed_name);
27401 path_string.push_str("\"]");
27402 } else {
27403 path_string.push_str("[\"");
27406 for c in quoted_name.chars() {
27407 if c == '"' {
27408 path_string.push_str("\\\"");
27409 } else {
27410 path_string.push(c);
27411 }
27412 }
27413 path_string.push_str("\"]");
27414 }
27415 had_initial_component = true;
27416 } else if self.is_identifier_token()
27417 || self.is_safe_keyword_as_identifier()
27418 || self.is_reserved_keyword_as_identifier()
27419 {
27420 if !path_string.is_empty() {
27422 path_string.push('.');
27423 }
27424 let first_part = self.advance().text;
27425 path_string.push_str(&first_part);
27426 had_initial_component = true;
27427 } else if self.check(TokenType::LBracket) {
27428 had_initial_component = true;
27431 }
27432
27433 if !had_initial_component {
27434 self.current = saved_pos;
27438 path_string.truncate(saved_path_len);
27439 break;
27440 }
27441
27442 loop {
27444 if self.match_token(TokenType::LBracket) {
27446 if self.check(TokenType::Number) {
27448 path_string.push('[');
27449 let idx = self.advance().text;
27450 path_string.push_str(&idx);
27451 self.expect(TokenType::RBracket)?;
27452 path_string.push(']');
27453 } else if self.check(TokenType::Star) {
27454 path_string.push('[');
27456 self.skip();
27457 path_string.push('*');
27458 self.expect(TokenType::RBracket)?;
27459 path_string.push(']');
27460 } else if self.check(TokenType::String) {
27461 let key = self.advance().text;
27464 self.expect(TokenType::RBracket)?;
27465 let needs_brackets =
27467 key.contains(' ') || key.contains('"') || key.contains('\'');
27468 if needs_brackets {
27469 path_string.push_str("[\"");
27471 for c in key.chars() {
27472 if c == '"' {
27473 path_string.push_str("\\\"");
27474 } else {
27475 path_string.push(c);
27476 }
27477 }
27478 path_string.push_str("\"]");
27479 } else {
27480 if !path_string.is_empty() {
27483 path_string.push('.');
27484 }
27485 path_string.push_str(&key);
27486 }
27487 } else if self.check(TokenType::QuotedIdentifier) {
27488 let key = self.advance().text;
27492 self.expect(TokenType::RBracket)?;
27493 path_string.push_str("[\"");
27495 for c in key.chars() {
27496 if c == '"' {
27497 path_string.push_str("\\\"");
27498 } else {
27499 path_string.push(c);
27500 }
27501 }
27502 path_string.push_str("\"]");
27503 } else if self.is_identifier_token() {
27504 let saved_bracket_pos = self.current;
27508 let ident_text = self.advance().text.clone();
27509 if self.check(TokenType::Dot) {
27510 self.current = saved_bracket_pos;
27513 let index_expr = self.parse_expression()?;
27515 self.expect(TokenType::RBracket)?;
27516
27517 let path_expr =
27519 Expression::Literal(Box::new(Literal::String(path_string)));
27520 let json_extract = Expression::JSONExtract(Box::new(JSONExtract {
27521 this: Box::new(this),
27522 expression: Box::new(path_expr),
27523 only_json_types: None,
27524 expressions: Vec::new(),
27525 variant_extract: Some(Box::new(Expression::Boolean(
27526 BooleanLiteral { value: true },
27527 ))),
27528 json_query: None,
27529 option: None,
27530 quote: None,
27531 on_condition: None,
27532 requires_json: None,
27533 }));
27534
27535 let subscript = Expression::Subscript(Box::new(Subscript {
27537 this: json_extract,
27538 index: index_expr,
27539 }));
27540
27541 let mut suffix_path = String::new();
27546 loop {
27547 if self.match_token(TokenType::Dot) {
27548 if !suffix_path.is_empty() {
27550 suffix_path.push('.');
27551 }
27552 if self.is_identifier_token()
27553 || self.is_safe_keyword_as_identifier()
27554 || self.is_reserved_keyword_as_identifier()
27555 {
27556 let part = self.advance().text;
27557 suffix_path.push_str(&part);
27558 } else {
27559 return Err(self.parse_error(
27560 "Expected identifier after . in JSON path",
27561 ));
27562 }
27563 } else if self.check(TokenType::LBracket) {
27564 break;
27567 } else {
27568 break;
27569 }
27570 }
27571
27572 let result_base = if suffix_path.is_empty() {
27574 subscript
27575 } else {
27576 Expression::JSONExtract(Box::new(JSONExtract {
27578 this: Box::new(subscript),
27579 expression: Box::new(Expression::Literal(Box::new(
27580 Literal::String(suffix_path),
27581 ))),
27582 only_json_types: None,
27583 expressions: Vec::new(),
27584 variant_extract: Some(Box::new(Expression::Boolean(
27585 BooleanLiteral { value: true },
27586 ))),
27587 json_query: None,
27588 option: None,
27589 quote: None,
27590 on_condition: None,
27591 requires_json: None,
27592 }))
27593 };
27594
27595 if self.match_token(TokenType::LBracket) {
27597 let index_expr2 = self.parse_expression()?;
27599 self.expect(TokenType::RBracket)?;
27600 let subscript2 = Expression::Subscript(Box::new(Subscript {
27601 this: result_base,
27602 index: index_expr2,
27603 }));
27604 this = subscript2;
27606 path_string = String::new();
27607 } else {
27608 this = result_base;
27609 path_string = String::new();
27610 }
27611
27612 break;
27616 } else {
27617 path_string.push('[');
27619 path_string.push_str(&ident_text);
27620 self.expect(TokenType::RBracket)?;
27621 path_string.push(']');
27622 }
27623 } else {
27624 path_string.push('[');
27626 self.expect(TokenType::RBracket)?;
27627 path_string.push(']');
27628 }
27629 } else if self.match_token(TokenType::Dot) {
27630 path_string.push('.');
27632 if self.is_identifier_token()
27633 || self.is_safe_keyword_as_identifier()
27634 || self.is_reserved_keyword_as_identifier()
27635 {
27636 let part = self.advance().text;
27637 path_string.push_str(&part);
27638 } else {
27639 return Err(self.parse_error("Expected identifier after . in JSON path"));
27640 }
27641 } else {
27642 break;
27643 }
27644 }
27645 }
27646
27647 if path_string.is_empty() {
27649 return Ok(this);
27650 }
27651
27652 let path_expr = Expression::Literal(Box::new(Literal::String(path_string)));
27654 let json_extract = Expression::JSONExtract(Box::new(JSONExtract {
27655 this: Box::new(this),
27656 expression: Box::new(path_expr),
27657 only_json_types: None,
27658 expressions: Vec::new(),
27659 variant_extract: Some(Box::new(Expression::Boolean(BooleanLiteral {
27660 value: true,
27661 }))),
27662 json_query: None,
27663 option: None,
27664 quote: None,
27665 on_condition: None,
27666 requires_json: None,
27667 }));
27668
27669 Ok(json_extract)
27670 }
27671
27672 fn is_reserved_keyword_as_identifier(&self) -> bool {
27674 if self.is_at_end() {
27675 return false;
27676 }
27677 let token = self.peek();
27678 matches!(
27680 token.token_type,
27681 TokenType::From
27682 | TokenType::Select
27683 | TokenType::Where
27684 | TokenType::And
27685 | TokenType::Or
27686 | TokenType::Not
27687 | TokenType::In
27688 | TokenType::As
27689 | TokenType::On
27690 | TokenType::Join
27691 | TokenType::Left
27692 | TokenType::Right
27693 | TokenType::Inner
27694 | TokenType::Outer
27695 | TokenType::Cross
27696 | TokenType::Full
27697 | TokenType::Group
27698 | TokenType::Order
27699 | TokenType::By
27700 | TokenType::Having
27701 | TokenType::Limit
27702 | TokenType::Offset
27703 | TokenType::Union
27704 | TokenType::Except
27705 | TokenType::Intersect
27706 | TokenType::All
27707 | TokenType::Distinct
27708 | TokenType::Case
27709 | TokenType::When
27710 | TokenType::Then
27711 | TokenType::Else
27712 | TokenType::End
27713 | TokenType::Null
27714 | TokenType::True
27715 | TokenType::False
27716 | TokenType::Between
27717 | TokenType::Like
27718 | TokenType::Is
27719 | TokenType::Exists
27720 | TokenType::Insert
27721 | TokenType::Update
27722 | TokenType::Delete
27723 | TokenType::Create
27724 | TokenType::Alter
27725 | TokenType::Drop
27726 | TokenType::Table
27727 | TokenType::View
27728 | TokenType::Index
27729 | TokenType::Set
27730 | TokenType::Values
27731 | TokenType::Into
27732 | TokenType::Default
27733 | TokenType::Key
27734 | TokenType::Unique
27735 | TokenType::Check
27736 | TokenType::Constraint
27737 | TokenType::References
27738 )
27739 }
27740
27741 fn parse_primary(&mut self) -> Result<Expression> {
27743 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("APPROXIMATE") {
27746 let saved_pos = self.current;
27747 self.skip(); let func = self.parse_primary()?;
27750 if let Expression::Count(ref count_expr) = func {
27752 if count_expr.distinct {
27753 let this_expr = count_expr.this.clone().unwrap_or_else(|| {
27754 Expression::Star(crate::expressions::Star {
27755 table: None,
27756 except: None,
27757 replace: None,
27758 rename: None,
27759 trailing_comments: Vec::new(),
27760 span: None,
27761 })
27762 });
27763 return Ok(Expression::ApproxDistinct(Box::new(
27764 crate::expressions::AggFunc {
27765 this: this_expr,
27766 distinct: false,
27767 filter: None,
27768 order_by: Vec::new(),
27769 name: Some("APPROX_DISTINCT".to_string()),
27770 ignore_nulls: None,
27771 having_max: None,
27772 limit: None,
27773 inferred_type: None,
27774 },
27775 )));
27776 }
27777 }
27778 self.current = saved_pos;
27780 }
27781
27782 if let Some(connect_by_root) = self.try_parse_connect_by_root_expression()? {
27783 return Ok(connect_by_root);
27784 }
27785
27786 if matches!(
27789 self.config.dialect,
27790 Some(crate::dialects::DialectType::PostgreSQL)
27791 | Some(crate::dialects::DialectType::Redshift)
27792 ) {
27793 if self.check(TokenType::Var) && self.peek().text.eq_ignore_ascii_case("VARIADIC") {
27794 self.skip(); let expr = self.parse_bitwise_or()?;
27796 return Ok(Expression::Variadic(Box::new(
27797 crate::expressions::Variadic {
27798 this: Box::new(expr),
27799 },
27800 )));
27801 }
27802 }
27803
27804 if matches!(
27806 self.config.dialect,
27807 Some(crate::dialects::DialectType::MySQL)
27808 | Some(crate::dialects::DialectType::SingleStore)
27809 | Some(crate::dialects::DialectType::Doris)
27810 | Some(crate::dialects::DialectType::StarRocks)
27811 ) {
27812 if self.check(TokenType::Var) || self.check(TokenType::Identifier) {
27813 if self.peek().text.starts_with('_')
27814 && Self::is_mysql_charset_introducer(&self.peek().text.to_ascii_uppercase())
27815 {
27816 if self.current + 1 < self.tokens.len() {
27818 let next_tt = self.tokens[self.current + 1].token_type;
27819 if matches!(
27820 next_tt,
27821 TokenType::String | TokenType::HexString | TokenType::BitString
27822 ) {
27823 let charset_token = self.advance(); let charset_name = charset_token.text.clone();
27825 let literal = self.parse_primary()?; return Ok(Expression::Introducer(Box::new(
27827 crate::expressions::Introducer {
27828 this: Box::new(Expression::Column(Box::new(
27829 crate::expressions::Column {
27830 name: crate::expressions::Identifier {
27831 name: charset_name,
27832 quoted: false,
27833 trailing_comments: Vec::new(),
27834 span: None,
27835 },
27836 table: None,
27837 join_mark: false,
27838 trailing_comments: Vec::new(),
27839 span: None,
27840 inferred_type: None,
27841 },
27842 ))),
27843 expression: Box::new(literal),
27844 },
27845 )));
27846 }
27847 }
27848 }
27849 }
27850 }
27851
27852 if self.match_token(TokenType::LBracket) {
27854 if self.match_token(TokenType::RBracket) {
27856 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
27857 expressions: Vec::new(),
27858 bracket_notation: true,
27859 use_list_keyword: false,
27860 })));
27861 }
27862
27863 let first_expr = self.parse_expression()?;
27865
27866 if self.match_token(TokenType::For) {
27868 let loop_var = self.parse_primary()?;
27870
27871 let position = if self.match_token(TokenType::Comma) {
27873 Some(self.parse_primary()?)
27874 } else {
27875 None
27876 };
27877
27878 if !self.match_token(TokenType::In) {
27880 return Err(self.parse_error("Expected IN in comprehension"));
27881 }
27882
27883 let iterator = self.parse_expression()?;
27885
27886 let condition = if self.match_token(TokenType::If) {
27888 Some(self.parse_expression()?)
27889 } else {
27890 None
27891 };
27892
27893 self.expect(TokenType::RBracket)?;
27895
27896 return Ok(Expression::Comprehension(Box::new(Comprehension {
27898 this: Box::new(first_expr),
27899 expression: Box::new(loop_var),
27900 position: position.map(Box::new),
27901 iterator: Some(Box::new(iterator)),
27902 condition: condition.map(Box::new),
27903 })));
27904 }
27905
27906 let first_expr = if matches!(
27909 self.config.dialect,
27910 Some(crate::dialects::DialectType::ClickHouse)
27911 ) && self.check(TokenType::As)
27912 && !self.check_next(TokenType::RBracket)
27913 {
27914 self.skip(); let alias = self.expect_identifier()?;
27916 Expression::Alias(Box::new(Alias::new(first_expr, Identifier::new(alias))))
27917 } else {
27918 first_expr
27919 };
27920 let mut expressions = vec![first_expr];
27921 while self.match_token(TokenType::Comma) {
27922 if self.check(TokenType::RBracket) {
27924 break;
27925 }
27926 let expr = self.parse_expression()?;
27927 let expr = if matches!(
27929 self.config.dialect,
27930 Some(crate::dialects::DialectType::ClickHouse)
27931 ) && self.check(TokenType::As)
27932 && !self.check_next(TokenType::RBracket)
27933 {
27934 self.skip(); let alias = self.expect_identifier()?;
27936 Expression::Alias(Box::new(Alias::new(expr, Identifier::new(alias))))
27937 } else {
27938 expr
27939 };
27940 expressions.push(expr);
27941 }
27942 self.expect(TokenType::RBracket)?;
27943 return self.maybe_parse_subscript(Expression::ArrayFunc(Box::new(ArrayConstructor {
27944 expressions,
27945 bracket_notation: true,
27946 use_list_keyword: false,
27947 })));
27948 }
27949
27950 if self.match_token(TokenType::LBrace) {
27953 if matches!(
27956 self.config.dialect,
27957 Some(crate::dialects::DialectType::ClickHouse)
27958 ) {
27959 self.current -= 1;
27960 if let Some(param) = self.parse_clickhouse_braced_parameter()? {
27961 return self.maybe_parse_subscript(param);
27962 }
27963 self.current += 1;
27965 }
27966
27967 if self.match_token(TokenType::RBrace) {
27969 return self.maybe_parse_subscript(Expression::MapFunc(Box::new(MapConstructor {
27970 keys: Vec::new(),
27971 values: Vec::new(),
27972 curly_brace_syntax: true,
27973 with_map_keyword: false,
27974 })));
27975 }
27976
27977 if self.check_identifier("fn") {
27980 self.skip(); let func_name = self.expect_identifier_or_keyword_with_quoted()?;
27983 self.expect(TokenType::LParen)?;
27984
27985 let mut args = Vec::new();
27987 if !self.check(TokenType::RParen) {
27988 loop {
27989 args.push(self.parse_expression()?);
27990 if !self.match_token(TokenType::Comma) {
27991 break;
27992 }
27993 }
27994 }
27995 self.expect(TokenType::RParen)?;
27996 self.expect(TokenType::RBrace)?;
27997
27998 return Ok(Expression::Function(Box::new(Function::new(
28000 func_name.name,
28001 args,
28002 ))));
28003 }
28004
28005 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
28007 let type_text = self.peek().text.to_lowercase();
28008 if (type_text == "d" || type_text == "t" || type_text == "ts")
28009 && self.check_next(TokenType::String)
28010 {
28011 self.skip(); let value = self.expect_string()?;
28013 self.expect(TokenType::RBrace)?;
28014
28015 return match type_text.as_str() {
28017 "d" => Ok(Expression::Date(Box::new(
28018 crate::expressions::UnaryFunc::new(Expression::Literal(Box::new(
28019 crate::expressions::Literal::String(value),
28020 ))),
28021 ))),
28022 "t" => Ok(Expression::Time(Box::new(
28023 crate::expressions::UnaryFunc::new(Expression::Literal(Box::new(
28024 crate::expressions::Literal::String(value),
28025 ))),
28026 ))),
28027 "ts" => Ok(Expression::Timestamp(Box::new(
28028 crate::expressions::TimestampFunc {
28029 this: Some(Box::new(Expression::Literal(Box::new(
28030 crate::expressions::Literal::String(value),
28031 )))),
28032 zone: None,
28033 with_tz: None,
28034 safe: None,
28035 },
28036 ))),
28037 _ => {
28038 Err(self
28039 .parse_error(format!("Unknown ODBC datetime type: {}", type_text)))
28040 }
28041 };
28042 }
28043 }
28044
28045 let is_table_star = (self.check(TokenType::Identifier) || self.check(TokenType::Var))
28049 && self.check_next(TokenType::Dot)
28050 && self
28051 .tokens
28052 .get(self.current + 2)
28053 .map(|t| t.token_type == TokenType::Star)
28054 .unwrap_or(false);
28055 let is_wildcard = self.check(TokenType::Star) || is_table_star;
28056
28057 if is_wildcard {
28058 let wildcard_expr = if self.match_token(TokenType::Star) {
28060 if self.check_keyword_text("ILIKE") {
28063 self.skip();
28064 let pattern = self.parse_expression()?;
28065 Expression::ILike(Box::new(LikeOp {
28067 left: Expression::Star(Star {
28068 table: None,
28069 except: None,
28070 replace: None,
28071 rename: None,
28072 trailing_comments: Vec::new(),
28073 span: None,
28074 }),
28075 right: pattern,
28076 escape: None,
28077 quantifier: None,
28078 inferred_type: None,
28079 }))
28080 } else {
28081 let star = self.parse_star_modifiers(None)?;
28083 Expression::Star(star)
28084 }
28085 } else {
28086 let table_name = self.expect_identifier_or_keyword_with_quoted()?;
28088 self.expect(TokenType::Dot)?;
28089 self.expect(TokenType::Star)?;
28090 let star = self.parse_star_modifiers(Some(table_name))?;
28091 Expression::Star(star)
28092 };
28093
28094 self.expect(TokenType::RBrace)?;
28095
28096 return Ok(Expression::BracedWildcard(Box::new(wildcard_expr)));
28098 }
28099
28100 let mut keys = Vec::new();
28102 let mut values = Vec::new();
28103 loop {
28104 let key = self.parse_expression()?;
28105 self.expect(TokenType::Colon)?;
28106 let value = self.parse_expression()?;
28107 keys.push(key);
28108 values.push(value);
28109 if !self.match_token(TokenType::Comma) {
28110 break;
28111 }
28112 if self.check(TokenType::RBrace) {
28114 break;
28115 }
28116 }
28117 self.expect(TokenType::RBrace)?;
28118 return self.maybe_parse_subscript(Expression::MapFunc(Box::new(MapConstructor {
28119 keys,
28120 values,
28121 curly_brace_syntax: true,
28122 with_map_keyword: false,
28123 })));
28124 }
28125
28126 if self.match_token(TokenType::LParen) {
28128 let lparen_comments = self.previous_trailing_comments().to_vec();
28130
28131 if self.check(TokenType::RParen) {
28133 self.skip(); if self.match_token(TokenType::Arrow) || self.match_token(TokenType::FArrow) {
28136 let body = self.parse_expression()?;
28137 return Ok(Expression::Lambda(Box::new(LambdaExpr {
28138 parameters: Vec::new(),
28139 body,
28140 colon: false,
28141 parameter_types: Vec::new(),
28142 })));
28143 }
28144 return self.maybe_parse_subscript(Expression::Tuple(Box::new(Tuple {
28146 expressions: Vec::new(),
28147 })));
28148 }
28149
28150 if self.check(TokenType::Values) {
28152 let values = self.parse_values()?;
28153 self.expect(TokenType::RParen)?;
28154 return Ok(Expression::Subquery(Box::new(Subquery {
28155 this: values,
28156 alias: None,
28157 column_aliases: Vec::new(),
28158 order_by: None,
28159 limit: None,
28160 offset: None,
28161 distribute_by: None,
28162 sort_by: None,
28163 cluster_by: None,
28164 lateral: false,
28165 modifiers_inside: false,
28166 trailing_comments: self.previous_trailing_comments().to_vec(),
28167 inferred_type: None,
28168 })));
28169 }
28170
28171 let is_explain_subquery = self.check(TokenType::Var)
28173 && self.peek().text.eq_ignore_ascii_case("EXPLAIN")
28174 && self.peek_nth(1).map_or(false, |t| {
28175 matches!(
28177 t.token_type,
28178 TokenType::Select
28179 | TokenType::Insert
28180 | TokenType::Create
28181 | TokenType::Alter
28182 | TokenType::Drop
28183 | TokenType::Set
28184 | TokenType::System
28185 | TokenType::Table
28186 ) || matches!(
28187 t.text.to_ascii_uppercase().as_str(),
28188 "SYNTAX" | "AST" | "PLAN" | "PIPELINE" | "ESTIMATE" | "CURRENT" | "QUERY"
28189 ) || (t.token_type == TokenType::Var
28190 && self
28191 .peek_nth(2)
28192 .map_or(false, |t2| t2.token_type == TokenType::Eq))
28193 });
28194 if matches!(
28197 self.config.dialect,
28198 Some(crate::dialects::DialectType::ClickHouse)
28199 ) {
28200 let mut look = self.current;
28201 let mut is_tuple_lambda = true;
28202 let mut param_count = 0;
28203 loop {
28204 if look >= self.tokens.len() {
28205 is_tuple_lambda = false;
28206 break;
28207 }
28208 let tt = self.tokens[look].token_type;
28209 if tt == TokenType::Identifier
28210 || tt == TokenType::Var
28211 || tt == TokenType::QuotedIdentifier
28212 || tt.is_keyword()
28213 {
28214 param_count += 1;
28215 look += 1;
28216 } else {
28217 is_tuple_lambda = false;
28218 break;
28219 }
28220 if look >= self.tokens.len() {
28221 is_tuple_lambda = false;
28222 break;
28223 }
28224 if self.tokens[look].token_type == TokenType::Comma {
28225 look += 1;
28226 } else if self.tokens[look].token_type == TokenType::RParen {
28227 look += 1;
28228 break;
28229 } else {
28230 is_tuple_lambda = false;
28231 break;
28232 }
28233 }
28234 if is_tuple_lambda
28235 && param_count >= 1
28236 && look < self.tokens.len()
28237 && self.tokens[look].token_type == TokenType::Arrow
28238 {
28239 let mut params = Vec::new();
28241 loop {
28242 let tok = self.advance();
28243 params.push(Identifier::new(tok.text));
28244 if self.match_token(TokenType::Comma) {
28245 continue;
28246 }
28247 break;
28248 }
28249 self.expect(TokenType::RParen)?;
28250 self.expect(TokenType::Arrow)?;
28251 let body = self.parse_expression()?;
28252 return Ok(Expression::Lambda(Box::new(LambdaExpr {
28253 parameters: params,
28254 body,
28255 colon: false,
28256 parameter_types: Vec::new(),
28257 })));
28258 }
28259 }
28260 if self.check(TokenType::Select)
28261 || self.check(TokenType::With)
28262 || self.check(TokenType::From)
28263 || is_explain_subquery
28264 {
28265 let query = self.parse_statement()?;
28266
28267 let limit = if self.match_token(TokenType::Limit) {
28270 Some(Limit {
28271 this: self.parse_expression()?,
28272 percent: false,
28273 comments: Vec::new(),
28274 })
28275 } else {
28276 None
28277 };
28278 let offset = if self.match_token(TokenType::Offset) {
28279 Some(Offset {
28280 this: self.parse_expression()?,
28281 rows: None,
28282 })
28283 } else {
28284 None
28285 };
28286
28287 self.expect(TokenType::RParen)?;
28288
28289 let subquery = if limit.is_some() || offset.is_some() {
28291 Expression::Subquery(Box::new(Subquery {
28293 this: query,
28294 alias: None,
28295 column_aliases: Vec::new(),
28296 order_by: None,
28297 limit,
28298 offset,
28299 distribute_by: None,
28300 sort_by: None,
28301 cluster_by: None,
28302 lateral: false,
28303 modifiers_inside: true,
28304 trailing_comments: self.previous_trailing_comments().to_vec(),
28305 inferred_type: None,
28306 }))
28307 } else {
28308 Expression::Subquery(Box::new(Subquery {
28309 this: query,
28310 alias: None,
28311 column_aliases: Vec::new(),
28312 order_by: None,
28313 limit: None,
28314 offset: None,
28315 distribute_by: None,
28316 sort_by: None,
28317 cluster_by: None,
28318 lateral: false,
28319 modifiers_inside: false,
28320 trailing_comments: self.previous_trailing_comments().to_vec(),
28321 inferred_type: None,
28322 }))
28323 };
28324
28325 let set_result = self.parse_set_operation(subquery)?;
28327
28328 let had_set_operation = matches!(
28332 &set_result,
28333 Expression::Union(_) | Expression::Intersect(_) | Expression::Except(_)
28334 );
28335
28336 let result = if had_set_operation {
28337 let order_by = if self.check(TokenType::Order) {
28338 self.expect(TokenType::Order)?;
28339 self.expect(TokenType::By)?;
28340 Some(self.parse_order_by()?)
28341 } else {
28342 None
28343 };
28344 let limit_after = if self.match_token(TokenType::Limit) {
28345 Some(Limit {
28346 this: self.parse_expression()?,
28347 percent: false,
28348 comments: Vec::new(),
28349 })
28350 } else {
28351 None
28352 };
28353 let offset_after = if self.match_token(TokenType::Offset) {
28354 Some(Offset {
28355 this: self.parse_expression()?,
28356 rows: None,
28357 })
28358 } else {
28359 None
28360 };
28361
28362 if order_by.is_some() || limit_after.is_some() || offset_after.is_some() {
28364 Expression::Subquery(Box::new(Subquery {
28365 this: set_result,
28366 alias: None,
28367 column_aliases: Vec::new(),
28368 order_by,
28369 limit: limit_after,
28370 offset: offset_after,
28371 lateral: false,
28372 modifiers_inside: false,
28373 trailing_comments: Vec::new(),
28374 distribute_by: None,
28375 sort_by: None,
28376 cluster_by: None,
28377 inferred_type: None,
28378 }))
28379 } else {
28380 set_result
28381 }
28382 } else {
28383 set_result
28384 };
28385 return self.maybe_parse_subscript(result);
28387 }
28388
28389 if self.check(TokenType::LParen) {
28392 let expr = self.parse_expression()?;
28393
28394 let first_expr = if self.match_token(TokenType::As) {
28396 let alias = self.expect_identifier_or_alias_keyword_with_quoted()?;
28397 Expression::Alias(Box::new(Alias::new(expr, alias)))
28398 } else {
28399 expr
28400 };
28401
28402 if self.match_token(TokenType::Comma) {
28405 let mut expressions = vec![first_expr];
28406 loop {
28407 if self.check(TokenType::RParen) {
28408 break;
28409 } let elem = self.parse_expression()?;
28411 let elem = if self.match_token(TokenType::As) {
28413 let alias = self.expect_identifier_or_keyword()?;
28414 Expression::Alias(Box::new(Alias::new(elem, Identifier::new(alias))))
28415 } else {
28416 elem
28417 };
28418 expressions.push(elem);
28419 if !self.match_token(TokenType::Comma) {
28420 break;
28421 }
28422 }
28423 self.expect(TokenType::RParen)?;
28424 let tuple_expr = Expression::Tuple(Box::new(Tuple { expressions }));
28425 return self.maybe_parse_subscript(tuple_expr);
28426 }
28427
28428 let result = first_expr;
28429
28430 self.expect(TokenType::RParen)?;
28431 let mut nested_paren_comments = lparen_comments.clone();
28432 nested_paren_comments.extend_from_slice(self.previous_trailing_comments());
28433 if self.check(TokenType::Union)
28435 || self.check(TokenType::Intersect)
28436 || self.check(TokenType::Except)
28437 {
28438 if let Expression::Subquery(subq) = &result {
28440 let set_result = self.parse_set_operation(subq.this.clone())?;
28441
28442 let order_by = if self.check(TokenType::Order) {
28444 self.expect(TokenType::Order)?;
28445 self.expect(TokenType::By)?;
28446 Some(self.parse_order_by()?)
28447 } else {
28448 None
28449 };
28450 let limit = if self.match_token(TokenType::Limit) {
28451 Some(Limit {
28452 this: self.parse_expression()?,
28453 percent: false,
28454 comments: Vec::new(),
28455 })
28456 } else {
28457 None
28458 };
28459 let offset = if self.match_token(TokenType::Offset) {
28460 Some(Offset {
28461 this: self.parse_expression()?,
28462 rows: None,
28463 })
28464 } else {
28465 None
28466 };
28467
28468 return Ok(Expression::Subquery(Box::new(Subquery {
28469 this: set_result,
28470 alias: None,
28471 column_aliases: Vec::new(),
28472 order_by,
28473 limit,
28474 offset,
28475 lateral: false,
28476 modifiers_inside: false,
28477 trailing_comments: Vec::new(),
28478 distribute_by: None,
28479 sort_by: None,
28480 cluster_by: None,
28481 inferred_type: None,
28482 })));
28483 }
28484 }
28485 return self.maybe_parse_over(Expression::Paren(Box::new(Paren {
28486 this: result,
28487 trailing_comments: nested_paren_comments,
28488 })));
28489 }
28490
28491 let expr = self.parse_expression()?;
28492
28493 let first_expr = if self.match_token(TokenType::As) {
28495 let alias = self.expect_identifier_or_keyword_with_quoted()?;
28496 Expression::Alias(Box::new(Alias::new(expr, alias)))
28497 } else {
28498 expr
28499 };
28500
28501 if self.match_token(TokenType::Comma) {
28503 let mut expressions = vec![first_expr];
28504 if self.check(TokenType::RParen) {
28506 self.skip(); let tuple_expr = Expression::Tuple(Box::new(Tuple { expressions }));
28508 return self.maybe_parse_subscript(tuple_expr);
28509 }
28510 loop {
28512 let elem = self.parse_expression()?;
28513 let elem_with_alias = if self.match_token(TokenType::As) {
28514 let alias = self.expect_identifier_or_keyword_with_quoted()?;
28515 Expression::Alias(Box::new(Alias::new(elem, alias)))
28516 } else {
28517 elem
28518 };
28519 expressions.push(elem_with_alias);
28520 if !self.match_token(TokenType::Comma) {
28521 break;
28522 }
28523 if self.check(TokenType::RParen) {
28525 break;
28526 }
28527 }
28528
28529 self.expect(TokenType::RParen)?;
28530
28531 if self.match_token(TokenType::Arrow) {
28533 let parameters = expressions
28534 .into_iter()
28535 .filter_map(|e| {
28536 if let Expression::Column(c) = e {
28537 Some(c.name)
28538 } else if let Expression::Identifier(id) = e {
28539 Some(id)
28540 } else {
28541 None
28542 }
28543 })
28544 .collect();
28545 let body = self.parse_expression()?;
28546 return Ok(Expression::Lambda(Box::new(LambdaExpr {
28547 parameters,
28548 body,
28549 colon: false,
28550 parameter_types: Vec::new(),
28551 })));
28552 }
28553
28554 let tuple_expr = Expression::Tuple(Box::new(Tuple { expressions }));
28559 let result = if self.check(TokenType::As) {
28560 let after_as = self.current + 1;
28562 let after_ident = self.current + 2;
28563 let is_type_constructor = after_ident < self.tokens.len()
28564 && (self.tokens[after_as].token_type == TokenType::Identifier
28565 || self.tokens[after_as].token_type == TokenType::Var
28566 || self.tokens[after_as].token_type == TokenType::Nullable
28567 || self.tokens[after_as].token_type == TokenType::Struct
28568 || self.tokens[after_as].token_type == TokenType::Array)
28569 && (self.tokens[after_ident].token_type == TokenType::LParen
28570 || self.tokens[after_ident].token_type == TokenType::Lt);
28571 let is_cast_type = after_ident < self.tokens.len()
28573 && (self.tokens[after_as].token_type == TokenType::Identifier
28574 || self.tokens[after_as].token_type == TokenType::Var
28575 || self.tokens[after_as].token_type.is_keyword())
28576 && self.tokens[after_ident].token_type == TokenType::RParen;
28577 if is_type_constructor || is_cast_type {
28578 tuple_expr
28579 } else {
28580 self.skip(); let alias = self.expect_identifier()?;
28582 Expression::Alias(Box::new(Alias::new(tuple_expr, Identifier::new(alias))))
28583 }
28584 } else {
28585 tuple_expr
28586 };
28587
28588 return self.maybe_parse_subscript(result);
28590 }
28591
28592 if matches!(
28594 self.config.dialect,
28595 Some(crate::dialects::DialectType::ClickHouse)
28596 ) && self.match_token(TokenType::Arrow)
28597 {
28598 let parameters = if let Expression::Column(c) = first_expr {
28599 vec![c.name]
28600 } else if let Expression::Identifier(id) = first_expr {
28601 vec![id]
28602 } else {
28603 return Err(self.parse_error("Expected identifier as lambda parameter"));
28604 };
28605 let body = self.parse_expression()?;
28606 self.expect(TokenType::RParen)?;
28607 return Ok(Expression::Paren(Box::new(Paren {
28608 this: Expression::Lambda(Box::new(LambdaExpr {
28609 parameters,
28610 body,
28611 colon: false,
28612 parameter_types: Vec::new(),
28613 })),
28614 trailing_comments: Vec::new(),
28615 })));
28616 }
28617
28618 self.expect(TokenType::RParen)?;
28619 let mut paren_comments = lparen_comments.clone();
28621 paren_comments.extend_from_slice(self.previous_trailing_comments());
28622
28623 if self.match_token(TokenType::Arrow) {
28625 let parameters = if let Expression::Column(c) = first_expr {
28627 vec![c.name]
28628 } else if let Expression::Identifier(id) = first_expr {
28629 vec![id]
28630 } else {
28631 return Err(self.parse_error("Expected identifier as lambda parameter"));
28632 };
28633 let body = self.parse_expression()?;
28634 return Ok(Expression::Lambda(Box::new(LambdaExpr {
28635 parameters,
28636 body,
28637 colon: false,
28638 parameter_types: Vec::new(),
28639 })));
28640 }
28641
28642 return self.maybe_parse_over(Expression::Paren(Box::new(Paren {
28643 this: first_expr,
28644 trailing_comments: paren_comments,
28645 })));
28646 }
28647
28648 if self.match_token(TokenType::Null) {
28650 return Ok(Expression::Null(Null));
28651 }
28652
28653 if self.match_token(TokenType::True) {
28655 return Ok(Expression::Boolean(BooleanLiteral { value: true }));
28656 }
28657
28658 if self.match_token(TokenType::False) {
28660 return Ok(Expression::Boolean(BooleanLiteral { value: false }));
28661 }
28662
28663 if self.check(TokenType::Lambda) {
28665 if let Some(lambda) = self.parse_lambda()? {
28666 return Ok(lambda);
28667 }
28668 }
28669
28670 if self.check(TokenType::Case) && !self.check_next(TokenType::Dot) {
28672 let case_expr = self.parse_case()?;
28673 return self.maybe_parse_over(case_expr);
28674 }
28675
28676 if self.check(TokenType::Cast) {
28678 let cast_expr = self.parse_cast()?;
28679 return self.maybe_parse_subscript(cast_expr);
28680 }
28681
28682 if self.check(TokenType::TryCast) {
28684 let cast_expr = self.parse_try_cast()?;
28685 return self.maybe_parse_subscript(cast_expr);
28686 }
28687
28688 if self.check(TokenType::SafeCast) {
28690 let cast_expr = self.parse_safe_cast()?;
28691 return self.maybe_parse_subscript(cast_expr);
28692 }
28693
28694 if self.check(TokenType::Exists)
28697 && matches!(
28698 self.config.dialect,
28699 Some(crate::dialects::DialectType::ClickHouse)
28700 )
28701 && !self.check_next(TokenType::LParen)
28702 {
28703 let tok = self.advance();
28704 return Ok(Expression::Identifier(Identifier::new(tok.text)));
28705 }
28706 if self.match_token(TokenType::Exists) {
28707 self.expect(TokenType::LParen)?;
28708
28709 if self.check(TokenType::Select)
28712 || self.check(TokenType::With)
28713 || self.check(TokenType::From)
28714 || (self.check(TokenType::LParen)
28715 && self
28716 .peek_nth(1)
28717 .map(|t| {
28718 matches!(
28719 t.token_type,
28720 TokenType::Select | TokenType::With | TokenType::From
28721 )
28722 })
28723 .unwrap_or(false))
28724 {
28725 let query = self.parse_statement()?;
28726 self.expect(TokenType::RParen)?;
28727 return Ok(Expression::Exists(Box::new(Exists {
28728 this: query,
28729 not: false,
28730 })));
28731 }
28732
28733 let array_expr = self.parse_expression()?;
28736 self.expect(TokenType::Comma)?;
28737 let predicate = self.parse_expression()?;
28738 self.expect(TokenType::RParen)?;
28739 return Ok(Expression::Function(Box::new(Function {
28740 name: "EXISTS".to_string(),
28741 args: vec![array_expr, predicate],
28742 distinct: false,
28743 trailing_comments: Vec::new(),
28744 use_bracket_syntax: false,
28745 no_parens: false,
28746 quoted: false,
28747 span: None,
28748 inferred_type: None,
28749 })));
28750 }
28751
28752 if self.check(TokenType::Interval) {
28754 if let Some(interval_expr) = self.try_parse_interval()? {
28755 return Ok(interval_expr);
28756 }
28757 let token = self.advance();
28759 return Ok(Expression::Identifier(Identifier::new(token.text)));
28760 }
28761
28762 if self.check(TokenType::Date) {
28764 let token = self.advance();
28765 let original_text = token.text.clone();
28766 if self.check(TokenType::String) {
28767 let str_token = self.advance();
28768 if self.config.dialect.is_none() {
28769 return Ok(Expression::Cast(Box::new(Cast {
28771 this: Expression::Literal(Box::new(Literal::String(str_token.text))),
28772 to: DataType::Date,
28773 trailing_comments: Vec::new(),
28774 double_colon_syntax: false,
28775 format: None,
28776 default: None,
28777 inferred_type: None,
28778 })));
28779 }
28780 return Ok(Expression::Literal(Box::new(Literal::Date(str_token.text))));
28781 }
28782 if self.match_token(TokenType::LParen) {
28784 let func_expr = self.parse_typed_function(&original_text, "DATE", false)?;
28785 return self.maybe_parse_over(func_expr);
28786 }
28787 return Ok(Expression::boxed_column(Column {
28789 name: Identifier::new(original_text),
28790 table: None,
28791 join_mark: false,
28792 trailing_comments: Vec::new(),
28793 span: None,
28794 inferred_type: None,
28795 }));
28796 }
28797
28798 if self.check(TokenType::Time) {
28800 let token = self.advance();
28801 let original_text = token.text.clone();
28802 if self.check(TokenType::String) {
28803 let str_token = self.advance();
28804 return Ok(Expression::Literal(Box::new(Literal::Time(str_token.text))));
28805 }
28806 if self.match_token(TokenType::LParen) {
28808 let func_expr = self.parse_typed_function(&original_text, "TIME", false)?;
28809 return self.maybe_parse_over(func_expr);
28810 }
28811 return self.maybe_parse_subscript(Expression::boxed_column(Column {
28813 name: Identifier::new(original_text),
28814 table: None,
28815 join_mark: false,
28816 trailing_comments: Vec::new(),
28817 span: None,
28818 inferred_type: None,
28819 }));
28820 }
28821
28822 if self.check(TokenType::Timestamp) {
28825 let token = self.advance();
28826 let original_text = token.text.clone();
28827 if self.check(TokenType::String) {
28828 let str_token = self.advance();
28829 if self.config.dialect.is_none() {
28830 return Ok(Expression::Cast(Box::new(Cast {
28832 this: Expression::Literal(Box::new(Literal::String(str_token.text))),
28833 to: DataType::Timestamp {
28834 precision: None,
28835 timezone: false,
28836 },
28837 trailing_comments: Vec::new(),
28838 double_colon_syntax: false,
28839 format: None,
28840 default: None,
28841 inferred_type: None,
28842 })));
28843 }
28844 return Ok(Expression::Literal(Box::new(Literal::Timestamp(
28846 str_token.text,
28847 ))));
28848 }
28849 if self.check(TokenType::LParen) {
28852 let is_data_type = self.check_next(TokenType::Number) && {
28855 let mut lookahead = self.current + 2;
28857 while lookahead < self.tokens.len()
28859 && self.tokens[lookahead].token_type == TokenType::RParen
28860 {
28861 lookahead += 1;
28862 break;
28863 }
28864 lookahead < self.tokens.len()
28866 && (self.tokens[lookahead].token_type == TokenType::With
28867 || self.tokens[lookahead].text.eq_ignore_ascii_case("WITHOUT")
28868 || self.tokens[lookahead].token_type == TokenType::String)
28869 };
28870
28871 if is_data_type {
28872 self.skip(); let precision = Some(self.expect_number()? as u32);
28875 self.expect(TokenType::RParen)?;
28876
28877 let data_type = if self.match_token(TokenType::With) {
28878 if self.match_token(TokenType::Local) {
28879 self.match_keyword("TIME");
28881 self.match_keyword("ZONE");
28882 DataType::Custom {
28883 name: format!("TIMESTAMPLTZ({})", precision.unwrap()),
28884 }
28885 } else {
28886 self.match_keyword("TIME");
28887 self.match_keyword("ZONE");
28888 DataType::Timestamp {
28889 precision,
28890 timezone: true,
28891 }
28892 }
28893 } else if self.match_keyword("WITHOUT") {
28894 self.match_keyword("TIME");
28895 self.match_keyword("ZONE");
28896 DataType::Timestamp {
28897 precision,
28898 timezone: false,
28899 }
28900 } else {
28901 DataType::Timestamp {
28902 precision,
28903 timezone: false,
28904 }
28905 };
28906
28907 if self.check(TokenType::String) {
28909 let str_token = self.advance();
28910 return Ok(Expression::Cast(Box::new(Cast {
28911 this: Expression::Literal(Box::new(Literal::String(str_token.text))),
28912 to: data_type,
28913 trailing_comments: Vec::new(),
28914 double_colon_syntax: false,
28915 format: None,
28916 default: None,
28917 inferred_type: None,
28918 })));
28919 }
28920
28921 return Ok(Expression::DataType(data_type));
28922 }
28923
28924 self.skip(); let func_expr = self.parse_typed_function(&original_text, "TIMESTAMP", false)?;
28927 return self.maybe_parse_over(func_expr);
28928 }
28929 if (self.check(TokenType::With)
28932 && self.peek_nth(1).map_or(false, |t| {
28933 t.text.eq_ignore_ascii_case("TIME") || t.text.eq_ignore_ascii_case("LOCAL")
28934 }))
28935 || self.check_keyword_text("WITHOUT")
28936 {
28937 let data_type = if self.match_token(TokenType::With) {
28938 if self.match_token(TokenType::Local) {
28939 self.match_keyword("TIME");
28941 self.match_keyword("ZONE");
28942 DataType::Custom {
28943 name: "TIMESTAMPLTZ".to_string(),
28944 }
28945 } else {
28946 self.match_keyword("TIME");
28947 self.match_keyword("ZONE");
28948 DataType::Timestamp {
28949 precision: None,
28950 timezone: true,
28951 }
28952 }
28953 } else if self.match_keyword("WITHOUT") {
28954 self.match_keyword("TIME");
28955 self.match_keyword("ZONE");
28956 DataType::Timestamp {
28957 precision: None,
28958 timezone: false,
28959 }
28960 } else {
28961 DataType::Timestamp {
28962 precision: None,
28963 timezone: false,
28964 }
28965 };
28966
28967 if self.check(TokenType::String) {
28969 let str_token = self.advance();
28970 return Ok(Expression::Cast(Box::new(Cast {
28971 this: Expression::Literal(Box::new(Literal::String(str_token.text))),
28972 to: data_type,
28973 trailing_comments: Vec::new(),
28974 double_colon_syntax: false,
28975 format: None,
28976 default: None,
28977 inferred_type: None,
28978 })));
28979 }
28980
28981 return Ok(Expression::DataType(data_type));
28982 }
28983 return Ok(Expression::boxed_column(Column {
28985 name: Identifier::new(original_text),
28986 table: None,
28987 join_mark: false,
28988 trailing_comments: Vec::new(),
28989 span: None,
28990 inferred_type: None,
28991 }));
28992 }
28993
28994 if self.check(TokenType::DateTime) {
28996 let token = self.advance();
28997 let original_text = token.text.clone();
28998 if self.check(TokenType::String) {
28999 let str_token = self.advance();
29000 return Ok(Expression::Literal(Box::new(Literal::Datetime(
29001 str_token.text,
29002 ))));
29003 }
29004 if self.match_token(TokenType::LParen) {
29006 let func_expr = self.parse_typed_function(&original_text, "DATETIME", false)?;
29007 return self.maybe_parse_over(func_expr);
29008 }
29009 return Ok(Expression::boxed_column(Column {
29011 name: Identifier::new(original_text),
29012 table: None,
29013 join_mark: false,
29014 trailing_comments: Vec::new(),
29015 span: None,
29016 inferred_type: None,
29017 }));
29018 }
29019
29020 if self.check(TokenType::Row) && self.check_next(TokenType::LParen) {
29022 self.skip(); self.expect(TokenType::LParen)?;
29024 let args = if !self.check(TokenType::RParen) {
29026 self.parse_expression_list()?
29027 } else {
29028 Vec::new()
29029 };
29030 self.expect(TokenType::RParen)?;
29031 let func_expr = Expression::Function(Box::new(Function {
29032 name: "ROW".to_string(),
29033 args,
29034 distinct: false,
29035 trailing_comments: Vec::new(),
29036 use_bracket_syntax: false,
29037 no_parens: false,
29038 quoted: false,
29039 span: None,
29040 inferred_type: None,
29041 }));
29042 return self.maybe_parse_over(func_expr);
29043 }
29044
29045 if self.check(TokenType::Number) {
29047 let token = self.advance();
29048 if matches!(
29049 self.config.dialect,
29050 Some(crate::dialects::DialectType::MySQL)
29051 ) {
29052 let text = token.text.as_str();
29053 if text.len() > 2
29054 && (text.starts_with("0x") || text.starts_with("0X"))
29055 && !text[2..].chars().all(|c| c.is_ascii_hexdigit())
29056 {
29057 let ident = Expression::Identifier(Identifier {
29058 name: token.text,
29059 quoted: true,
29060 trailing_comments: Vec::new(),
29061 span: None,
29062 });
29063 return self.maybe_parse_subscript(ident);
29064 }
29065 }
29066 if matches!(
29067 self.config.dialect,
29068 Some(crate::dialects::DialectType::Teradata)
29069 ) && token.text == "0"
29070 {
29071 if let Some(next) = self.tokens.get(self.current) {
29072 let is_adjacent = token.span.end == next.span.start;
29073 let next_text = next.text.as_str();
29074 let is_hex_prefix = next_text.starts_with('x') || next_text.starts_with('X');
29075 if is_adjacent
29076 && matches!(next.token_type, TokenType::Identifier | TokenType::Var)
29077 && is_hex_prefix
29078 && next_text.len() > 1
29079 && next_text[1..].chars().all(|c| c.is_ascii_hexdigit())
29080 {
29081 let hex_token = self.advance();
29083 let hex = hex_token.text[1..].to_string();
29084 let literal = Expression::Literal(Box::new(Literal::HexString(hex)));
29085 return self.maybe_parse_subscript(literal);
29086 }
29087 }
29088 }
29089 if matches!(
29090 self.config.dialect,
29091 Some(crate::dialects::DialectType::ClickHouse)
29092 ) {
29093 if let Some(next) = self.tokens.get(self.current) {
29094 let is_adjacent = token.span.end == next.span.start;
29095 if is_adjacent
29096 && matches!(next.token_type, TokenType::Identifier | TokenType::Var)
29097 && next.text.starts_with('_')
29098 {
29099 let suffix = next.text.clone();
29100 self.skip(); let combined = format!("{}{}", token.text, suffix);
29102 let literal = Expression::Literal(Box::new(Literal::Number(combined)));
29103 return self.maybe_parse_subscript(literal);
29104 }
29105 }
29106 }
29107 let literal = if let Some(sep_pos) = token.text.find("::") {
29109 let num_part = &token.text[..sep_pos];
29110 let type_name = &token.text[sep_pos + 2..];
29111 let num_expr = Expression::Literal(Box::new(Literal::Number(num_part.to_string())));
29112 let data_type = match type_name {
29113 "BIGINT" => crate::expressions::DataType::BigInt { length: None },
29114 "SMALLINT" => crate::expressions::DataType::SmallInt { length: None },
29115 "TINYINT" => crate::expressions::DataType::TinyInt { length: None },
29116 "DOUBLE" => crate::expressions::DataType::Double {
29117 precision: None,
29118 scale: None,
29119 },
29120 "FLOAT" => crate::expressions::DataType::Float {
29121 precision: None,
29122 scale: None,
29123 real_spelling: false,
29124 },
29125 "DECIMAL" => crate::expressions::DataType::Decimal {
29126 precision: None,
29127 scale: None,
29128 },
29129 _ => crate::expressions::DataType::Custom {
29130 name: type_name.to_string(),
29131 },
29132 };
29133 Expression::Cast(Box::new(crate::expressions::Cast {
29134 this: num_expr,
29135 to: data_type,
29136 trailing_comments: Vec::new(),
29137 double_colon_syntax: false,
29138 format: None,
29139 default: None,
29140 inferred_type: None,
29141 }))
29142 } else {
29143 Expression::Literal(Box::new(Literal::Number(token.text)))
29144 };
29145 return self.maybe_parse_subscript(literal);
29146 }
29147
29148 if self.check(TokenType::String) {
29151 let token = self.advance();
29152 let first_literal = Expression::Literal(Box::new(Literal::String(token.text)));
29153
29154 if self.check(TokenType::String) {
29157 let mut expressions = vec![first_literal];
29158 while self.check(TokenType::String) {
29159 let next_token = self.advance();
29160 expressions.push(Expression::Literal(Box::new(Literal::String(
29161 next_token.text,
29162 ))));
29163 }
29164 let concat_func =
29166 Expression::Function(Box::new(Function::new("CONCAT", expressions)));
29167 return self.maybe_parse_subscript(concat_func);
29168 }
29169
29170 return self.maybe_parse_subscript(first_literal);
29171 }
29172
29173 if self.check(TokenType::DollarString) {
29176 let token = self.advance();
29177 let literal = Expression::Literal(Box::new(Literal::DollarString(token.text)));
29178 return self.maybe_parse_subscript(literal);
29179 }
29180
29181 if self.check(TokenType::TripleDoubleQuotedString) {
29183 let token = self.advance();
29184 let literal =
29185 Expression::Literal(Box::new(Literal::TripleQuotedString(token.text, '"')));
29186 return self.maybe_parse_subscript(literal);
29187 }
29188
29189 if self.check(TokenType::TripleSingleQuotedString) {
29191 let token = self.advance();
29192 let literal =
29193 Expression::Literal(Box::new(Literal::TripleQuotedString(token.text, '\'')));
29194 return self.maybe_parse_subscript(literal);
29195 }
29196
29197 if self.check(TokenType::NationalString) {
29199 let token = self.advance();
29200 let literal = Expression::Literal(Box::new(Literal::NationalString(token.text)));
29201 return self.maybe_parse_subscript(literal);
29202 }
29203
29204 if self.check(TokenType::HexString) {
29206 let token = self.advance();
29207 let literal = Expression::Literal(Box::new(Literal::HexString(token.text)));
29208 return self.maybe_parse_subscript(literal);
29209 }
29210
29211 if self.check(TokenType::HexNumber) {
29213 let token = self.advance();
29214 if matches!(
29215 self.config.dialect,
29216 Some(crate::dialects::DialectType::MySQL)
29217 ) {
29218 let text = token.text.as_str();
29219 if text.len() > 2
29220 && (text.starts_with("0x") || text.starts_with("0X"))
29221 && !text[2..].chars().all(|c| c.is_ascii_hexdigit())
29222 {
29223 let ident = Expression::Identifier(Identifier {
29224 name: token.text,
29225 quoted: true,
29226 trailing_comments: Vec::new(),
29227 span: None,
29228 });
29229 return self.maybe_parse_subscript(ident);
29230 }
29231 }
29232 let literal = Expression::Literal(Box::new(Literal::HexNumber(token.text)));
29233 return self.maybe_parse_subscript(literal);
29234 }
29235
29236 if self.check(TokenType::BitString) {
29238 let token = self.advance();
29239 let literal = Expression::Literal(Box::new(Literal::BitString(token.text)));
29240 return self.maybe_parse_subscript(literal);
29241 }
29242
29243 if self.check(TokenType::ByteString) {
29245 let token = self.advance();
29246 let literal = Expression::Literal(Box::new(Literal::ByteString(token.text)));
29247 return self.maybe_parse_subscript(literal);
29248 }
29249
29250 if self.check(TokenType::RawString) {
29252 let token = self.advance();
29253 let literal = Expression::Literal(Box::new(Literal::RawString(token.text)));
29256 return self.maybe_parse_subscript(literal);
29257 }
29258
29259 if self.check(TokenType::EscapeString) {
29261 let token = self.advance();
29262 let literal = Expression::Literal(Box::new(Literal::EscapeString(token.text)));
29264 return self.maybe_parse_subscript(literal);
29265 }
29266
29267 if self.check(TokenType::Star) {
29269 if self.check_next_identifier("COLUMNS") {
29272 if self
29274 .tokens
29275 .get(self.current + 2)
29276 .map(|t| t.token_type == TokenType::LParen)
29277 .unwrap_or(false)
29278 {
29279 self.skip(); self.skip(); self.skip(); let arg = if self.check(TokenType::Star) {
29285 self.skip(); Expression::Star(Star {
29287 table: None,
29288 except: None,
29289 replace: None,
29290 rename: None,
29291 trailing_comments: Vec::new(),
29292 span: None,
29293 })
29294 } else {
29295 self.parse_expression()?
29296 };
29297
29298 self.expect(TokenType::RParen)?;
29299
29300 return Ok(Expression::Columns(Box::new(Columns {
29302 this: Box::new(arg),
29303 unpack: Some(Box::new(Expression::Boolean(BooleanLiteral {
29304 value: true,
29305 }))),
29306 })));
29307 }
29308 }
29309
29310 self.skip(); let star = self.parse_star_modifiers(None)?;
29313 return Ok(Expression::Star(star));
29314 }
29315
29316 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
29320 let name_upper = self.peek().text.to_ascii_uppercase();
29321 if (name_upper == "ARRAY" || name_upper == "MAP" || name_upper == "STRUCT")
29322 && self.check_next(TokenType::Lt)
29323 {
29324 self.skip(); let data_type = self.parse_data_type_from_name(&name_upper)?;
29326
29327 if self.match_token(TokenType::LParen) {
29330 if name_upper == "STRUCT" {
29331 let args = if self.check(TokenType::RParen) {
29333 Vec::new()
29334 } else {
29335 self.parse_struct_args()?
29336 };
29337 self.expect(TokenType::RParen)?;
29338
29339 let fields: Vec<(Option<String>, Expression)> =
29341 args.into_iter().map(|e| (None, e)).collect();
29342
29343 let struct_expr = Expression::Struct(Box::new(Struct { fields }));
29345 let cast_expr = Expression::Cast(Box::new(Cast {
29346 this: struct_expr,
29347 to: data_type,
29348 trailing_comments: Vec::new(),
29349 double_colon_syntax: false,
29350 format: None,
29351 default: None,
29352 inferred_type: None,
29353 }));
29354 return self.maybe_parse_subscript(cast_expr);
29355 } else if name_upper == "ARRAY" {
29356 let mut expressions = Vec::new();
29358 if !self.check(TokenType::RParen) {
29359 loop {
29360 expressions.push(self.parse_expression()?);
29361 if !self.match_token(TokenType::Comma) {
29362 break;
29363 }
29364 }
29365 }
29366 self.expect(TokenType::RParen)?;
29367
29368 let array_expr = Expression::Array(Box::new(Array { expressions }));
29370 let cast_expr = Expression::Cast(Box::new(Cast {
29371 this: array_expr,
29372 to: data_type,
29373 trailing_comments: Vec::new(),
29374 double_colon_syntax: false,
29375 format: None,
29376 default: None,
29377 inferred_type: None,
29378 }));
29379 return self.maybe_parse_subscript(cast_expr);
29380 }
29381 } else if self.match_token(TokenType::LBracket) {
29382 let expressions = if self.check(TokenType::RBracket) {
29384 Vec::new()
29385 } else {
29386 self.parse_expression_list()?
29387 };
29388 self.expect(TokenType::RBracket)?;
29389 let array_expr = Expression::Array(Box::new(Array { expressions }));
29391 let cast_expr = Expression::Cast(Box::new(Cast {
29392 this: array_expr,
29393 to: data_type,
29394 trailing_comments: Vec::new(),
29395 double_colon_syntax: false,
29396 format: None,
29397 default: None,
29398 inferred_type: None,
29399 }));
29400 return self.maybe_parse_subscript(cast_expr);
29401 }
29402
29403 return Ok(Expression::DataType(data_type));
29404 }
29405 if name_upper == "MAP" && self.check_next(TokenType::LBrace) {
29407 self.skip(); self.expect(TokenType::LBrace)?;
29409
29410 if self.match_token(TokenType::RBrace) {
29412 return self.maybe_parse_subscript(Expression::MapFunc(Box::new(
29413 MapConstructor {
29414 keys: Vec::new(),
29415 values: Vec::new(),
29416 curly_brace_syntax: true,
29417 with_map_keyword: true,
29418 },
29419 )));
29420 }
29421
29422 let mut keys = Vec::new();
29424 let mut values = Vec::new();
29425 loop {
29426 let key = self.parse_primary()?;
29427 self.expect(TokenType::Colon)?;
29428 let value = self.parse_expression()?;
29429 keys.push(key);
29430 values.push(value);
29431 if !self.match_token(TokenType::Comma) {
29432 break;
29433 }
29434 if self.check(TokenType::RBrace) {
29436 break;
29437 }
29438 }
29439 self.expect(TokenType::RBrace)?;
29440
29441 return self.maybe_parse_subscript(Expression::MapFunc(Box::new(MapConstructor {
29442 keys,
29443 values,
29444 curly_brace_syntax: true,
29445 with_map_keyword: true,
29446 })));
29447 }
29448 }
29449
29450 if (self.check(TokenType::Case) || self.check(TokenType::Top))
29453 && self.check_next(TokenType::Dot)
29454 {
29455 let token = self.advance();
29456 let ident = Identifier::new(token.text);
29457 self.expect(TokenType::Dot)?;
29458 if self.match_token(TokenType::Star) {
29459 let star = self.parse_star_modifiers(Some(ident))?;
29461 return Ok(Expression::Star(star));
29462 }
29463 let col_ident = self.expect_identifier_or_keyword_with_quoted()?;
29465 let trailing_comments = self.previous_trailing_comments().to_vec();
29467 let mut col = Expression::boxed_column(Column {
29468 name: col_ident,
29469 table: Some(ident),
29470 join_mark: false,
29471 trailing_comments,
29472 span: None,
29473 inferred_type: None,
29474 });
29475 if self.check(TokenType::LParen) && self.check_next(TokenType::Plus) {
29477 let saved_pos = self.current;
29478 if self.match_token(TokenType::LParen)
29479 && self.match_token(TokenType::Plus)
29480 && self.match_token(TokenType::RParen)
29481 {
29482 if let Expression::Column(ref mut c) = col {
29483 c.join_mark = true;
29484 }
29485 } else {
29486 self.current = saved_pos;
29487 }
29488 }
29489 return self.maybe_parse_subscript(col);
29490 }
29491
29492 if self.check(TokenType::Var)
29496 && self.peek().text.eq_ignore_ascii_case("BINARY")
29497 && !self.check_next(TokenType::LParen)
29498 && !self.check_next(TokenType::Dot)
29499 && !self.check_next(TokenType::RParen)
29500 && !self.check_next(TokenType::Comma)
29501 && !self.is_at_end()
29502 {
29503 let next_idx = self.current + 1;
29505 let has_expr = next_idx < self.tokens.len()
29506 && !matches!(
29507 self.tokens[next_idx].token_type,
29508 TokenType::Semicolon | TokenType::Eof | TokenType::RParen | TokenType::Comma
29509 );
29510 if has_expr {
29511 self.skip(); let expr = self.parse_unary()?;
29513 return Ok(Expression::Cast(Box::new(Cast {
29514 this: expr,
29515 to: DataType::Binary { length: None },
29516 trailing_comments: Vec::new(),
29517 double_colon_syntax: false,
29518 format: None,
29519 default: None,
29520 inferred_type: None,
29521 })));
29522 }
29523 }
29524
29525 if self.check(TokenType::RLike) && self.check_next(TokenType::LParen) {
29528 let token = self.advance(); self.skip(); let args = if self.check(TokenType::RParen) {
29531 Vec::new()
29532 } else {
29533 self.parse_function_arguments()?
29534 };
29535 self.expect(TokenType::RParen)?;
29536 let func = Expression::Function(Box::new(Function {
29537 name: token.text.clone(), args,
29539 distinct: false,
29540 trailing_comments: Vec::new(),
29541 use_bracket_syntax: false,
29542 no_parens: false,
29543 quoted: false,
29544 span: None,
29545 inferred_type: None,
29546 }));
29547 return self.maybe_parse_over(func);
29548 }
29549
29550 if self.check(TokenType::Insert) && self.check_next(TokenType::LParen) {
29554 let token = self.advance(); self.skip(); let args = if self.check(TokenType::RParen) {
29557 Vec::new()
29558 } else {
29559 self.parse_function_arguments()?
29560 };
29561 self.expect(TokenType::RParen)?;
29562 let func = Expression::Function(Box::new(Function {
29563 name: token.text.clone(),
29564 args,
29565 distinct: false,
29566 trailing_comments: Vec::new(),
29567 use_bracket_syntax: false,
29568 no_parens: false,
29569 quoted: false,
29570 span: None,
29571 inferred_type: None,
29572 }));
29573 return self.maybe_parse_over(func);
29574 }
29575
29576 if matches!(
29579 self.config.dialect,
29580 Some(crate::dialects::DialectType::ClickHouse)
29581 ) && (self.check(TokenType::Except)
29582 || self.check(TokenType::Intersect)
29583 || self.check(TokenType::RLike))
29584 && self.check_next(TokenType::LParen)
29585 {
29586 let token = self.advance(); self.skip(); let args = if self.check(TokenType::RParen) {
29589 Vec::new()
29590 } else {
29591 self.parse_function_arguments()?
29592 };
29593 self.expect(TokenType::RParen)?;
29594 let func = Expression::Function(Box::new(Function {
29595 name: token.text.clone(),
29596 args,
29597 distinct: false,
29598 trailing_comments: Vec::new(),
29599 use_bracket_syntax: false,
29600 no_parens: false,
29601 quoted: false,
29602 span: None,
29603 inferred_type: None,
29604 }));
29605 return self.maybe_parse_over(func);
29606 }
29607
29608 if matches!(
29611 self.peek().token_type,
29612 TokenType::CurrentDate
29613 | TokenType::CurrentTimestamp
29614 | TokenType::CurrentTime
29615 | TokenType::CurrentDateTime
29616 ) {
29617 if matches!(
29619 self.config.dialect,
29620 Some(crate::dialects::DialectType::Snowflake)
29621 ) && self.peek().token_type == TokenType::CurrentTime
29622 {
29623 self.skip(); if self.match_token(TokenType::LParen) {
29625 if !self.check(TokenType::RParen) {
29627 let _ = self.parse_function_arguments()?;
29628 }
29629 self.expect(TokenType::RParen)?;
29630 }
29631 return self.maybe_parse_subscript(Expression::Localtime(Box::new(
29632 crate::expressions::Localtime { this: None },
29633 )));
29634 }
29635 if self.check_next(TokenType::LParen) {
29636 let token = self.advance(); self.skip(); let args = if self.check(TokenType::RParen) {
29640 Vec::new()
29641 } else {
29642 self.parse_function_arguments()?
29643 };
29644 self.expect(TokenType::RParen)?;
29645 let func = Expression::Function(Box::new(Function {
29646 name: token.text.clone(),
29647 args,
29648 distinct: false,
29649 trailing_comments: Vec::new(),
29650 use_bracket_syntax: false,
29651 no_parens: false,
29652 quoted: false,
29653 span: None,
29654 inferred_type: None,
29655 }));
29656 return self.maybe_parse_subscript(func);
29657 } else {
29658 let token = self.advance();
29660 let func = Expression::Function(Box::new(Function {
29661 name: token.text.clone(),
29662 args: Vec::new(),
29663 distinct: false,
29664 trailing_comments: Vec::new(),
29665 use_bracket_syntax: false,
29666 no_parens: true,
29667 quoted: false,
29668 span: None,
29669 inferred_type: None,
29670 }));
29671 return self.maybe_parse_subscript(func);
29672 }
29673 }
29674
29675 if self.is_identifier_token() && self.check_next(TokenType::String) {
29678 let upper_name = self.peek().text.to_ascii_uppercase();
29679 if matches!(
29680 upper_name.as_str(),
29681 "NUMERIC" | "DECIMAL" | "BIGNUMERIC" | "BIGDECIMAL"
29682 ) {
29683 self.skip(); let str_token = self.advance(); let data_type = match upper_name.as_str() {
29686 "NUMERIC" | "DECIMAL" | "BIGNUMERIC" | "BIGDECIMAL" => {
29687 crate::expressions::DataType::Decimal {
29688 precision: None,
29689 scale: None,
29690 }
29691 }
29692 _ => unreachable!("type keyword already matched in outer if-condition"),
29693 };
29694 return Ok(Expression::Cast(Box::new(crate::expressions::Cast {
29695 this: Expression::Literal(Box::new(Literal::String(str_token.text))),
29696 to: data_type,
29697 trailing_comments: Vec::new(),
29698 double_colon_syntax: false,
29699 format: None,
29700 default: None,
29701 inferred_type: None,
29702 })));
29703 }
29704 }
29705
29706 if self.is_identifier_token() {
29708 let upper_name = self.peek().text.to_ascii_uppercase();
29711 if !self.check_next(TokenType::LParen)
29712 && !self.check_next(TokenType::Dot)
29713 && crate::function_registry::is_no_paren_function_name_upper(upper_name.as_str())
29714 && !(matches!(
29715 self.config.dialect,
29716 Some(crate::dialects::DialectType::ClickHouse)
29717 ) && upper_name.as_str() == "CURRENT_TIMESTAMP")
29718 {
29719 let token = self.advance();
29720 let func = Expression::Function(Box::new(Function {
29721 name: token.text.clone(), args: Vec::new(),
29723 distinct: false,
29724 trailing_comments: Vec::new(),
29725 use_bracket_syntax: false,
29726 no_parens: true, quoted: false,
29728 span: None,
29729 inferred_type: None,
29730 }));
29731 return self.maybe_parse_subscript(func);
29732 }
29733
29734 let ident = self.expect_identifier_with_quoted()?;
29735 let name = ident.name.clone();
29736 let quoted = ident.quoted;
29737
29738 let is_teradata_format_phrase = matches!(
29740 self.config.dialect,
29741 Some(crate::dialects::DialectType::Teradata)
29742 ) && self.check(TokenType::LParen)
29743 && self.check_next(TokenType::Format);
29744 if !is_teradata_format_phrase && self.match_token(TokenType::LParen) {
29745 let upper_name = name.to_ascii_uppercase();
29746 let func_expr = self.parse_typed_function(&name, &upper_name, quoted)?;
29747 let func_expr = self.maybe_parse_clickhouse_parameterized_agg(func_expr)?;
29748 return self.maybe_parse_over(func_expr);
29750 }
29751
29752 if self.match_token(TokenType::Dot) {
29754 if self.match_token(TokenType::Star) {
29755 let star = self.parse_star_modifiers(Some(ident))?;
29757 let mut star_expr = Expression::Star(star);
29758 if matches!(
29760 self.config.dialect,
29761 Some(crate::dialects::DialectType::ClickHouse)
29762 ) {
29763 loop {
29764 if self.check(TokenType::Apply) {
29765 self.skip();
29766 let apply_expr = if self.match_token(TokenType::LParen) {
29767 let e = self.parse_expression()?;
29768 self.expect(TokenType::RParen)?;
29769 e
29770 } else {
29771 self.parse_expression()?
29772 };
29773 star_expr =
29774 Expression::Apply(Box::new(crate::expressions::Apply {
29775 this: Box::new(star_expr),
29776 expression: Box::new(apply_expr),
29777 }));
29778 } else if self.check(TokenType::Except)
29779 || self.check(TokenType::Exclude)
29780 {
29781 self.skip();
29782 self.match_identifier("STRICT");
29783 if self.match_token(TokenType::LParen) {
29784 loop {
29785 if self.check(TokenType::RParen) {
29786 break;
29787 }
29788 let _ = self.parse_expression()?;
29789 if !self.match_token(TokenType::Comma) {
29790 break;
29791 }
29792 }
29793 self.expect(TokenType::RParen)?;
29794 } else if self.is_identifier_token()
29795 || self.is_safe_keyword_as_identifier()
29796 {
29797 let _ = self.parse_expression()?;
29798 }
29799 } else if self.check(TokenType::Replace) {
29800 self.skip();
29801 self.match_identifier("STRICT");
29802 if self.match_token(TokenType::LParen) {
29803 loop {
29804 if self.check(TokenType::RParen) {
29805 break;
29806 }
29807 let _ = self.parse_expression()?;
29808 if self.match_token(TokenType::As) {
29809 if self.is_identifier_token()
29810 || self.is_safe_keyword_as_identifier()
29811 {
29812 self.skip();
29813 }
29814 }
29815 if !self.match_token(TokenType::Comma) {
29816 break;
29817 }
29818 }
29819 self.expect(TokenType::RParen)?;
29820 } else {
29821 let _ = self.parse_expression()?;
29822 if self.match_token(TokenType::As) {
29823 if self.is_identifier_token()
29824 || self.is_safe_keyword_as_identifier()
29825 {
29826 self.skip();
29827 }
29828 }
29829 }
29830 } else {
29831 break;
29832 }
29833 }
29834 }
29835 return Ok(star_expr);
29836 }
29837 if self.check(TokenType::Number) {
29840 let field_name = self.advance().text;
29841 let col_expr = Expression::Dot(Box::new(DotAccess {
29842 this: Expression::boxed_column(Column {
29843 name: ident,
29844 table: None,
29845 join_mark: false,
29846 trailing_comments: Vec::new(),
29847 span: None,
29848 inferred_type: None,
29849 }),
29850 field: Identifier::new(field_name),
29851 }));
29852 return self.maybe_parse_subscript(col_expr);
29853 }
29854 if matches!(
29855 self.config.dialect,
29856 Some(crate::dialects::DialectType::ClickHouse)
29857 ) && self.check(TokenType::Dash)
29858 && self.current + 1 < self.tokens.len()
29859 && self.tokens[self.current + 1].token_type == TokenType::Number
29860 {
29861 self.skip(); let num = self.advance().text;
29863 let field_name = format!("-{}", num);
29864 let col_expr = Expression::Dot(Box::new(DotAccess {
29865 this: Expression::boxed_column(Column {
29866 name: ident,
29867 table: None,
29868 join_mark: false,
29869 trailing_comments: Vec::new(),
29870 span: None,
29871 inferred_type: None,
29872 }),
29873 field: Identifier::new(field_name),
29874 }));
29875 return self.maybe_parse_subscript(col_expr);
29876 }
29877 if matches!(
29879 self.config.dialect,
29880 Some(crate::dialects::DialectType::ClickHouse)
29881 ) && self.check(TokenType::Caret)
29882 {
29883 self.skip(); let mut field_name = "^".to_string();
29885 if self.check(TokenType::Identifier)
29886 || self.check(TokenType::Var)
29887 || self.check_keyword()
29888 {
29889 field_name.push_str(&self.advance().text);
29890 }
29891 let col_expr = Expression::Dot(Box::new(DotAccess {
29892 this: Expression::boxed_column(Column {
29893 name: ident,
29894 table: None,
29895 join_mark: false,
29896 trailing_comments: Vec::new(),
29897 span: None,
29898 inferred_type: None,
29899 }),
29900 field: Identifier::new(field_name),
29901 }));
29902 return self.maybe_parse_subscript(col_expr);
29903 }
29904 let col_ident = self.expect_identifier_or_keyword_with_quoted()?;
29906
29907 if self.check(TokenType::LParen) && self.check_next(TokenType::Plus) {
29910 let saved_pos = self.current;
29911 if self.match_token(TokenType::LParen)
29912 && self.match_token(TokenType::Plus)
29913 && self.match_token(TokenType::RParen)
29914 {
29915 let trailing_comments = self.previous_trailing_comments().to_vec();
29916 let col = Expression::boxed_column(Column {
29917 name: col_ident,
29918 table: Some(ident),
29919 join_mark: true,
29920 trailing_comments,
29921 span: None,
29922 inferred_type: None,
29923 });
29924 return self.maybe_parse_subscript(col);
29925 } else {
29926 self.current = saved_pos;
29927 }
29928 }
29929
29930 if self.check(TokenType::LParen) {
29932 self.skip(); let args = if self.check(TokenType::RParen) {
29935 Vec::new()
29936 } else {
29937 self.parse_expression_list()?
29938 };
29939 self.expect(TokenType::RParen)?;
29940 let method_call = Expression::MethodCall(Box::new(MethodCall {
29941 this: Expression::boxed_column(Column {
29942 name: ident.clone(),
29943 table: None,
29944 join_mark: false,
29945 trailing_comments: Vec::new(),
29946 span: None,
29947 inferred_type: None,
29948 }),
29949 method: col_ident,
29950 args,
29951 }));
29952 return self.maybe_parse_subscript(method_call);
29953 }
29954
29955 let trailing_comments = self.previous_trailing_comments().to_vec();
29957 let col = Expression::boxed_column(Column {
29958 name: col_ident,
29959 table: Some(ident),
29960 join_mark: false,
29961 trailing_comments,
29962 span: None,
29963 inferred_type: None,
29964 });
29965 return self.maybe_parse_subscript(col);
29966 }
29967
29968 if !quoted
29972 && matches!(
29973 self.config.dialect,
29974 Some(crate::dialects::DialectType::Oracle) | None
29975 )
29976 {
29977 if let Some(pseudocolumn_type) = PseudocolumnType::from_str(&name) {
29978 return Ok(Expression::Pseudocolumn(Pseudocolumn {
29979 kind: pseudocolumn_type,
29980 }));
29981 }
29982 }
29983
29984 if self.check(TokenType::Arrow)
29987 && !self
29988 .peek_nth(1)
29989 .map_or(false, |t| t.token_type == TokenType::String)
29990 {
29991 self.skip(); let body = self.parse_expression()?;
29993 return Ok(Expression::Lambda(Box::new(LambdaExpr {
29994 parameters: vec![ident],
29995 body,
29996 colon: false,
29997 parameter_types: Vec::new(),
29998 })));
29999 }
30000
30001 let trailing_comments = self.previous_trailing_comments().to_vec();
30003 let col = Expression::boxed_column(Column {
30004 name: ident,
30005 table: None,
30006 join_mark: false,
30007 trailing_comments,
30008 span: None,
30009 inferred_type: None,
30010 });
30011 return self.maybe_parse_subscript(col);
30012 }
30013
30014 if self.check(TokenType::If)
30021 && !self.check_next(TokenType::Dot)
30022 && (!self.check_next(TokenType::LParen)
30023 || matches!(
30024 self.config.dialect,
30025 Some(crate::dialects::DialectType::TSQL)
30026 | Some(crate::dialects::DialectType::Fabric)
30027 ))
30028 {
30029 let saved_pos = self.current;
30030 self.skip(); if let Some(if_expr) = self.parse_if()? {
30032 return Ok(if_expr);
30033 }
30034 self.current = saved_pos;
30037 }
30038
30039 if self.check(TokenType::Next)
30042 && self.current + 2 < self.tokens.len()
30043 && self.tokens[self.current + 1]
30044 .text
30045 .eq_ignore_ascii_case("VALUE")
30046 && self.tokens[self.current + 2]
30047 .text
30048 .eq_ignore_ascii_case("FOR")
30049 {
30050 self.skip(); if let Some(expr) = self.parse_next_value_for()? {
30052 return Ok(expr);
30053 }
30054 }
30055
30056 if matches!(
30058 self.config.dialect,
30059 Some(crate::dialects::DialectType::ClickHouse)
30060 ) && self.check(TokenType::From)
30061 && (self.check_next(TokenType::Comma) || self.check_next(TokenType::Dot))
30062 {
30063 let token = self.advance();
30064 let name = token.text.clone();
30065 if self.match_token(TokenType::Dot) {
30066 let col_name = self.expect_identifier_or_keyword()?;
30068 return Ok(Expression::Column(Box::new(crate::expressions::Column {
30069 name: Identifier::new(col_name),
30070 table: Some(Identifier::new(name)),
30071 join_mark: false,
30072 trailing_comments: Vec::new(),
30073 span: None,
30074 inferred_type: None,
30075 })));
30076 }
30077 return Ok(Expression::Column(Box::new(crate::expressions::Column {
30078 name: Identifier::new(name),
30079 table: None,
30080 join_mark: false,
30081 trailing_comments: Vec::new(),
30082 span: None,
30083 inferred_type: None,
30084 })));
30085 }
30086
30087 if matches!(
30090 self.config.dialect,
30091 Some(crate::dialects::DialectType::ClickHouse)
30092 ) && self.check(TokenType::Except)
30093 && !self.check_next(TokenType::LParen)
30094 {
30095 let token = self.advance();
30096 let name = token.text.clone();
30097 if self.match_token(TokenType::Dot) {
30098 let col_name = self.expect_identifier_or_keyword()?;
30099 return Ok(Expression::Column(Box::new(crate::expressions::Column {
30100 name: Identifier::new(col_name),
30101 table: Some(Identifier::new(name)),
30102 join_mark: false,
30103 trailing_comments: Vec::new(),
30104 span: None,
30105 inferred_type: None,
30106 })));
30107 }
30108 return Ok(Expression::Column(Box::new(crate::expressions::Column {
30109 name: Identifier::new(name),
30110 table: None,
30111 join_mark: false,
30112 trailing_comments: Vec::new(),
30113 span: None,
30114 inferred_type: None,
30115 })));
30116 }
30117
30118 if matches!(
30121 self.config.dialect,
30122 Some(crate::dialects::DialectType::ClickHouse)
30123 ) && self.peek().token_type.is_keyword()
30124 && !self.is_safe_keyword_as_identifier()
30125 {
30126 let next_tt = self
30127 .peek_nth(1)
30128 .map(|t| t.token_type)
30129 .unwrap_or(TokenType::Semicolon);
30130 let is_expr_context = !matches!(
30137 next_tt,
30138 TokenType::Identifier
30139 | TokenType::Var
30140 | TokenType::QuotedIdentifier
30141 | TokenType::LParen
30142 | TokenType::Number
30143 | TokenType::String
30144 );
30145 if is_expr_context {
30146 let token = self.advance();
30147 return Ok(Expression::boxed_column(Column {
30148 name: Identifier::new(token.text),
30149 table: None,
30150 join_mark: false,
30151 trailing_comments: Vec::new(),
30152 span: None,
30153 inferred_type: None,
30154 }));
30155 }
30156 }
30157 if self.check(TokenType::Percent)
30161 && (
30162 self.check_next(TokenType::Var) || self.check_next(TokenType::LParen)
30164 )
30166 {
30167 self.skip(); if self.match_token(TokenType::LParen) {
30170 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
30172 let name = self.advance().text;
30173 self.expect(TokenType::RParen)?;
30174 if self.check(TokenType::Var) && self.peek().text == "s" {
30176 self.skip(); }
30178 return Ok(Expression::Parameter(Box::new(Parameter {
30179 name: Some(name),
30180 index: None,
30181 style: ParameterStyle::Percent,
30182 quoted: false,
30183 string_quoted: false,
30184 expression: None,
30185 })));
30186 } else {
30187 return Err(self.parse_error("Expected parameter name after %("));
30188 }
30189 }
30190 if self.check(TokenType::Var) && self.peek().text == "s" {
30192 self.skip(); return Ok(Expression::Parameter(Box::new(Parameter {
30194 name: None,
30195 index: None,
30196 style: ParameterStyle::Percent,
30197 quoted: false,
30198 string_quoted: false,
30199 expression: None,
30200 })));
30201 }
30202 self.current -= 1;
30204 }
30205
30206 if self.is_safe_keyword_as_identifier() {
30210 let token = self.advance();
30211 let name = token.text.clone();
30212
30213 let is_teradata_format_phrase = matches!(
30215 self.config.dialect,
30216 Some(crate::dialects::DialectType::Teradata)
30217 ) && self.check(TokenType::LParen)
30218 && self.check_next(TokenType::Format);
30219 if !is_teradata_format_phrase && self.match_token(TokenType::LParen) {
30220 let upper_name = name.to_ascii_uppercase();
30221 let func_expr = self.parse_typed_function(&name, &upper_name, false)?;
30222 let func_expr = self.maybe_parse_clickhouse_parameterized_agg(func_expr)?;
30223 return self.maybe_parse_over(func_expr);
30224 }
30225
30226 if self.match_token(TokenType::Dot) {
30228 if self.match_token(TokenType::Star) {
30229 let ident = Identifier::new(name);
30231 let star = self.parse_star_modifiers(Some(ident))?;
30232 return Ok(Expression::Star(star));
30233 }
30234 if matches!(
30236 self.config.dialect,
30237 Some(crate::dialects::DialectType::ClickHouse)
30238 ) && self.check(TokenType::Caret)
30239 {
30240 self.skip(); let mut field_name = "^".to_string();
30242 if self.check(TokenType::Identifier)
30243 || self.check(TokenType::Var)
30244 || self.check_keyword()
30245 {
30246 field_name.push_str(&self.advance().text);
30247 }
30248 let col = Expression::Dot(Box::new(DotAccess {
30249 this: Expression::boxed_column(Column {
30250 name: Identifier::new(name),
30251 table: None,
30252 join_mark: false,
30253 trailing_comments: Vec::new(),
30254 span: None,
30255 inferred_type: None,
30256 }),
30257 field: Identifier::new(field_name),
30258 }));
30259 return self.maybe_parse_subscript(col);
30260 }
30261
30262 if self.check(TokenType::Number) {
30264 let field_name = self.advance().text;
30265 let col_expr = Expression::Dot(Box::new(DotAccess {
30266 this: Expression::boxed_column(Column {
30267 name: Identifier::new(name),
30268 table: None,
30269 join_mark: false,
30270 trailing_comments: Vec::new(),
30271 span: None,
30272 inferred_type: None,
30273 }),
30274 field: Identifier::new(field_name),
30275 }));
30276 return self.maybe_parse_subscript(col_expr);
30277 }
30278
30279 let col_ident = self.expect_identifier_or_keyword_with_quoted()?;
30281
30282 if self.check(TokenType::LParen) {
30284 self.skip(); let args = if self.check(TokenType::RParen) {
30286 Vec::new()
30287 } else {
30288 self.parse_expression_list()?
30289 };
30290 self.expect(TokenType::RParen)?;
30291 let method_call = Expression::MethodCall(Box::new(MethodCall {
30292 this: Expression::Identifier(Identifier::new(name)),
30293 method: col_ident,
30294 args,
30295 }));
30296 return self.maybe_parse_subscript(method_call);
30297 }
30298
30299 let trailing_comments = self.previous_trailing_comments().to_vec();
30301 let mut col = Expression::boxed_column(Column {
30302 name: col_ident,
30303 table: Some(Identifier::new(name)),
30304 join_mark: false,
30305 trailing_comments,
30306 span: None,
30307 inferred_type: None,
30308 });
30309 if self.check(TokenType::LParen) && self.check_next(TokenType::Plus) {
30311 let saved_pos = self.current;
30312 if self.match_token(TokenType::LParen)
30313 && self.match_token(TokenType::Plus)
30314 && self.match_token(TokenType::RParen)
30315 {
30316 if let Expression::Column(ref mut c) = col {
30317 c.join_mark = true;
30318 }
30319 } else {
30320 self.current = saved_pos;
30321 }
30322 }
30323 return self.maybe_parse_subscript(col);
30324 }
30325
30326 let trailing_comments = self.previous_trailing_comments().to_vec();
30329 let ident = Identifier::new(name);
30330 let col = Expression::boxed_column(Column {
30331 name: ident,
30332 table: None,
30333 join_mark: false,
30334 trailing_comments,
30335 span: None,
30336 inferred_type: None,
30337 });
30338 return self.maybe_parse_subscript(col);
30339 }
30340
30341 if self.match_token(TokenType::AtAt) {
30343 let name = if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
30345 let mut n = self.advance().text;
30346 if self.match_token(TokenType::Dot) {
30348 if self.check(TokenType::Identifier)
30349 || self.check(TokenType::Var)
30350 || self.is_safe_keyword_as_identifier()
30351 {
30352 n.push('.');
30353 n.push_str(&self.advance().text);
30354 }
30355 }
30356 n
30357 } else if self.check_keyword() {
30358 self.advance().text
30360 } else {
30361 return Err(self.parse_error("Expected variable name after @@"));
30362 };
30363 return Ok(Expression::Parameter(Box::new(Parameter {
30364 name: Some(name),
30365 index: None,
30366 style: ParameterStyle::DoubleAt,
30367 quoted: false,
30368 string_quoted: false,
30369 expression: None,
30370 })));
30371 }
30372
30373 if self.match_token(TokenType::DAt) {
30375 let (name, quoted, string_quoted) =
30377 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
30378 (self.advance().text, false, false)
30379 } else if self.check(TokenType::QuotedIdentifier) {
30380 let token = self.advance();
30382 (token.text, true, false)
30383 } else if self.check(TokenType::String) {
30384 let token = self.advance();
30386 (token.text, false, true)
30387 } else if self.check(TokenType::Number) {
30388 let token = self.advance();
30390 (token.text, false, false)
30391 } else if self.peek().token_type.is_keyword() {
30392 let token = self.advance();
30394 (token.text, false, false)
30395 } else {
30396 return Err(self.parse_error("Expected variable name after @"));
30397 };
30398 return Ok(Expression::Parameter(Box::new(Parameter {
30399 name: Some(name),
30400 index: None,
30401 style: ParameterStyle::At,
30402 quoted,
30403 string_quoted,
30404 expression: None,
30405 })));
30406 }
30407
30408 if self.check(TokenType::Parameter) {
30410 let token = self.advance();
30411 if let Ok(index) = token.text.parse::<u32>() {
30413 let param = Expression::Parameter(Box::new(Parameter {
30415 name: None,
30416 index: Some(index),
30417 style: ParameterStyle::Dollar,
30418 quoted: false,
30419 string_quoted: false,
30420 expression: None,
30421 }));
30422 let result = self.parse_colon_json_path(param)?;
30424 return self.maybe_parse_subscript(result);
30425 } else {
30426 return Ok(Expression::Placeholder(Placeholder { index: None }));
30428 }
30429 }
30430
30431 if self.match_token(TokenType::Colon) {
30433 if self.check(TokenType::Number) {
30435 let num_token = self.advance();
30436 if let Ok(index) = num_token.text.parse::<u32>() {
30437 return Ok(Expression::Parameter(Box::new(Parameter {
30438 name: None,
30439 index: Some(index),
30440 style: ParameterStyle::Colon,
30441 quoted: false,
30442 string_quoted: false,
30443 expression: None,
30444 })));
30445 }
30446 return Err(
30447 self.parse_error(format!("Invalid colon parameter: :{}", num_token.text))
30448 );
30449 }
30450 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
30452 let name = self.advance().text;
30453 return Ok(Expression::Parameter(Box::new(Parameter {
30454 name: Some(name),
30455 index: None,
30456 style: ParameterStyle::Colon,
30457 quoted: false,
30458 string_quoted: false,
30459 expression: None,
30460 })));
30461 } else {
30462 return Err(self.parse_error("Expected parameter name after :"));
30463 }
30464 }
30465
30466 if self.match_token(TokenType::Dollar) {
30468 if self.match_token(TokenType::LBrace) {
30471 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
30473 let name_token = self.advance();
30474 let expression = if self.match_token(TokenType::Colon) {
30476 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
30477 let expr_token = self.advance();
30478 Some(expr_token.text.clone())
30479 } else {
30480 return Err(self.parse_error("Expected identifier after : in ${...}"));
30481 }
30482 } else {
30483 None
30484 };
30485 self.expect(TokenType::RBrace)?;
30486 return Ok(Expression::Parameter(Box::new(Parameter {
30487 name: Some(name_token.text.clone()),
30488 index: None,
30489 style: ParameterStyle::DollarBrace,
30490 quoted: false,
30491 string_quoted: false,
30492 expression,
30493 })));
30494 } else {
30495 return Err(self.parse_error("Expected identifier after ${"));
30496 }
30497 }
30498 if self.check(TokenType::Number) {
30500 let num_token = self.advance();
30501 if let Ok(index) = num_token.text.parse::<u32>() {
30503 let param_expr = Expression::Parameter(Box::new(Parameter {
30504 name: None,
30505 index: Some(index),
30506 style: ParameterStyle::Dollar,
30507 quoted: false,
30508 string_quoted: false,
30509 expression: None,
30510 }));
30511 let result = self.parse_colon_json_path(param_expr)?;
30513 return self.maybe_parse_subscript(result);
30515 }
30516 return Err(
30518 self.parse_error(format!("Invalid dollar parameter: ${}", num_token.text))
30519 );
30520 }
30521 if self.check(TokenType::Identifier)
30523 || self.check(TokenType::Var)
30524 || self.is_safe_keyword_as_identifier()
30525 {
30526 let name_token = self.advance();
30527 return Ok(Expression::Parameter(Box::new(Parameter {
30528 name: Some(name_token.text.clone()),
30529 index: None,
30530 style: ParameterStyle::Dollar,
30531 quoted: false,
30532 string_quoted: false,
30533 expression: None,
30534 })));
30535 }
30536 return Err(self.parse_error("Expected number or identifier after $"));
30538 }
30539
30540 if self.match_token(TokenType::Percent) {
30542 if self.match_token(TokenType::LParen) {
30544 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
30546 let name = self.advance().text;
30547 self.expect(TokenType::RParen)?;
30548 if self.check(TokenType::Var) && self.peek().text == "s" {
30550 self.skip(); }
30552 return Ok(Expression::Parameter(Box::new(Parameter {
30553 name: Some(name),
30554 index: None,
30555 style: ParameterStyle::Percent,
30556 quoted: false,
30557 string_quoted: false,
30558 expression: None,
30559 })));
30560 } else {
30561 return Err(self.parse_error("Expected parameter name after %("));
30562 }
30563 }
30564 if self.check(TokenType::Var) && self.peek().text == "s" {
30566 self.skip(); return Ok(Expression::Parameter(Box::new(Parameter {
30568 name: None,
30569 index: None,
30570 style: ParameterStyle::Percent,
30571 quoted: false,
30572 string_quoted: false,
30573 expression: None,
30574 })));
30575 }
30576 return Err(self.parse_error("Expected 's' or '(' after % for parameter"));
30578 }
30579
30580 if (self.check(TokenType::Left)
30583 || self.check(TokenType::Right)
30584 || self.check(TokenType::Outer)
30585 || self.check(TokenType::Full)
30586 || self.check(TokenType::All)
30587 || self.check(TokenType::Only)
30588 || self.check(TokenType::Next)
30589 || self.check(TokenType::If))
30590 && self.check_next(TokenType::Dot)
30591 {
30592 let token = self.advance();
30593 let ident = Identifier::new(token.text);
30594 self.expect(TokenType::Dot)?;
30595 if self.match_token(TokenType::Star) {
30596 let star = self.parse_star_modifiers(Some(ident))?;
30597 return Ok(Expression::Star(star));
30598 }
30599 let col_ident = self.expect_identifier_or_keyword_with_quoted()?;
30600 let trailing_comments = self.previous_trailing_comments().to_vec();
30601 let mut col = Expression::boxed_column(Column {
30602 name: col_ident,
30603 table: Some(ident),
30604 join_mark: false,
30605 trailing_comments,
30606 span: None,
30607 inferred_type: None,
30608 });
30609 if self.check(TokenType::LParen) && self.check_next(TokenType::Plus) {
30611 let saved_pos = self.current;
30612 if self.match_token(TokenType::LParen)
30613 && self.match_token(TokenType::Plus)
30614 && self.match_token(TokenType::RParen)
30615 {
30616 if let Expression::Column(ref mut c) = col {
30617 c.join_mark = true;
30618 }
30619 } else {
30620 self.current = saved_pos;
30621 }
30622 }
30623 return self.maybe_parse_subscript(col);
30624 }
30625
30626 if self.check(TokenType::Next) {
30629 if self.check_next(TokenType::LParen) {
30631 let token = self.advance();
30632 self.skip(); let args = self.parse_function_args_list()?;
30634 self.expect(TokenType::RParen)?;
30635 return Ok(Expression::Function(Box::new(Function {
30636 name: token.text,
30637 args,
30638 distinct: false,
30639 trailing_comments: Vec::new(),
30640 use_bracket_syntax: false,
30641 no_parens: false,
30642 quoted: false,
30643 span: None,
30644 inferred_type: None,
30645 })));
30646 }
30647 }
30648
30649 if self.can_be_alias_keyword()
30653 && !self.check_next(TokenType::Join)
30654 && !self.check_next(TokenType::LParen)
30655 {
30656 let token = self.advance();
30657 let trailing_comments = self.previous_trailing_comments().to_vec();
30658 let col = Expression::boxed_column(Column {
30659 name: Identifier::new(token.text),
30660 table: None,
30661 join_mark: false,
30662 trailing_comments,
30663 span: None,
30664 inferred_type: None,
30665 });
30666 return self.maybe_parse_subscript(col);
30667 }
30668
30669 Err(self.parse_error(format!("Unexpected token: {:?}", self.peek().token_type)))
30670 }
30671
30672 fn is_aggregate_function(name: &str) -> bool {
30674 crate::function_registry::is_aggregate_function_name(name)
30675 }
30676
30677 fn log_base_first(&self) -> bool {
30680 !matches!(
30681 self.config.dialect,
30682 Some(crate::dialects::DialectType::BigQuery)
30683 | Some(crate::dialects::DialectType::TSQL)
30684 | Some(crate::dialects::DialectType::Tableau)
30685 | Some(crate::dialects::DialectType::Fabric)
30686 )
30687 }
30688
30689 fn log_defaults_to_ln(&self) -> bool {
30692 matches!(
30693 self.config.dialect,
30694 Some(crate::dialects::DialectType::MySQL)
30695 | Some(crate::dialects::DialectType::BigQuery)
30696 | Some(crate::dialects::DialectType::TSQL)
30697 | Some(crate::dialects::DialectType::ClickHouse)
30698 | Some(crate::dialects::DialectType::Hive)
30699 | Some(crate::dialects::DialectType::Spark)
30700 | Some(crate::dialects::DialectType::Databricks)
30701 | Some(crate::dialects::DialectType::Drill)
30702 | Some(crate::dialects::DialectType::Dremio)
30703 )
30704 }
30705
30706 fn try_parse_registry_typed_function(
30708 &mut self,
30709 name: &str,
30710 upper_name: &str,
30711 canonical_upper_name: &str,
30712 quoted: bool,
30713 ) -> Result<Option<Expression>> {
30714 let Some(spec) =
30715 crate::function_registry::typed_function_spec_by_canonical_upper(canonical_upper_name)
30716 else {
30717 return Ok(None);
30718 };
30719
30720 match (spec.parse_kind, spec.canonical_name) {
30721 (crate::function_registry::TypedParseKind::AggregateLike, "COUNT_IF") => {
30722 let distinct = self.match_token(TokenType::Distinct);
30723 let this = self.parse_expression()?;
30724 let this = if matches!(
30726 self.config.dialect,
30727 Some(crate::dialects::DialectType::ClickHouse)
30728 ) && self.check(TokenType::As)
30729 {
30730 let next_idx = self.current + 1;
30731 let after_alias_idx = self.current + 2;
30732 let is_alias = next_idx < self.tokens.len()
30733 && (matches!(
30734 self.tokens[next_idx].token_type,
30735 TokenType::Identifier | TokenType::Var | TokenType::QuotedIdentifier
30736 ) || self.tokens[next_idx].token_type.is_keyword())
30737 && after_alias_idx < self.tokens.len()
30738 && matches!(
30739 self.tokens[after_alias_idx].token_type,
30740 TokenType::RParen | TokenType::Comma
30741 );
30742 if is_alias {
30743 self.skip(); let alias_token = self.advance();
30745 Expression::Alias(Box::new(crate::expressions::Alias {
30746 this,
30747 alias: Identifier::new(alias_token.text.clone()),
30748 column_aliases: Vec::new(),
30749 pre_alias_comments: Vec::new(),
30750 trailing_comments: Vec::new(),
30751 inferred_type: None,
30752 }))
30753 } else {
30754 this
30755 }
30756 } else {
30757 this
30758 };
30759 if matches!(
30760 self.config.dialect,
30761 Some(crate::dialects::DialectType::ClickHouse)
30762 ) && self.match_token(TokenType::Comma)
30763 {
30764 let mut args = vec![this];
30765 let arg = self.parse_expression()?;
30766 let arg = if self.check(TokenType::As) {
30768 let next_idx = self.current + 1;
30769 let after_alias_idx = self.current + 2;
30770 let is_alias = next_idx < self.tokens.len()
30771 && (matches!(
30772 self.tokens[next_idx].token_type,
30773 TokenType::Identifier
30774 | TokenType::Var
30775 | TokenType::QuotedIdentifier
30776 ) || self.tokens[next_idx].token_type.is_keyword())
30777 && after_alias_idx < self.tokens.len()
30778 && matches!(
30779 self.tokens[after_alias_idx].token_type,
30780 TokenType::RParen | TokenType::Comma
30781 );
30782 if is_alias {
30783 self.skip(); let alias_token = self.advance();
30785 Expression::Alias(Box::new(crate::expressions::Alias {
30786 this: arg,
30787 alias: Identifier::new(alias_token.text.clone()),
30788 column_aliases: Vec::new(),
30789 pre_alias_comments: Vec::new(),
30790 trailing_comments: Vec::new(),
30791 inferred_type: None,
30792 }))
30793 } else {
30794 arg
30795 }
30796 } else {
30797 arg
30798 };
30799 args.push(arg);
30800 while self.match_token(TokenType::Comma) {
30801 args.push(self.parse_expression()?);
30802 }
30803 self.expect(TokenType::RParen)?;
30804 return Ok(Some(Expression::CombinedAggFunc(Box::new(
30805 CombinedAggFunc {
30806 this: Box::new(Expression::Identifier(Identifier::new("countIf"))),
30807 expressions: args,
30808 },
30809 ))));
30810 }
30811 self.expect(TokenType::RParen)?;
30812 let filter = self.parse_filter_clause()?;
30813 Ok(Some(Expression::CountIf(Box::new(AggFunc {
30814 ignore_nulls: None,
30815 this,
30816 distinct,
30817 filter,
30818 order_by: Vec::new(),
30819 having_max: None,
30820 name: Some(name.to_string()),
30821 limit: None,
30822 inferred_type: None,
30823 }))))
30824 }
30825 (crate::function_registry::TypedParseKind::Binary, "STARTS_WITH")
30826 | (crate::function_registry::TypedParseKind::Binary, "ENDS_WITH") => {
30827 let this = self.parse_expression()?;
30828 self.expect(TokenType::Comma)?;
30829 let expression = self.parse_expression()?;
30830 self.expect(TokenType::RParen)?;
30831 let func = BinaryFunc {
30832 original_name: None,
30833 this,
30834 expression,
30835 inferred_type: None,
30836 };
30837 let expr = match spec.canonical_name {
30838 "STARTS_WITH" => Expression::StartsWith(Box::new(func)),
30839 "ENDS_WITH" => Expression::EndsWith(Box::new(func)),
30840 _ => unreachable!("binary typed parse kind already matched in caller"),
30841 };
30842 Ok(Some(expr))
30843 }
30844 (crate::function_registry::TypedParseKind::Binary, "ATAN2") => {
30845 let this = self.parse_expression()?;
30846 self.expect(TokenType::Comma)?;
30847 let expression = self.parse_expression()?;
30848 self.expect(TokenType::RParen)?;
30849 Ok(Some(Expression::Atan2(Box::new(BinaryFunc {
30850 original_name: None,
30851 this,
30852 expression,
30853 inferred_type: None,
30854 }))))
30855 }
30856 (crate::function_registry::TypedParseKind::Binary, "MAP_FROM_ARRAYS")
30857 | (crate::function_registry::TypedParseKind::Binary, "MAP_CONTAINS_KEY")
30858 | (crate::function_registry::TypedParseKind::Binary, "ELEMENT_AT") => {
30859 let this = self.parse_expression()?;
30860 self.expect(TokenType::Comma)?;
30861 let expression = self.parse_expression()?;
30862 self.expect(TokenType::RParen)?;
30863 let func = BinaryFunc {
30864 original_name: None,
30865 this,
30866 expression,
30867 inferred_type: None,
30868 };
30869 let expr = match spec.canonical_name {
30870 "MAP_FROM_ARRAYS" => Expression::MapFromArrays(Box::new(func)),
30871 "MAP_CONTAINS_KEY" => Expression::MapContainsKey(Box::new(func)),
30872 "ELEMENT_AT" => Expression::ElementAt(Box::new(func)),
30873 _ => unreachable!("binary map parse kind already matched in caller"),
30874 };
30875 Ok(Some(expr))
30876 }
30877 (crate::function_registry::TypedParseKind::Binary, "CONTAINS")
30878 | (crate::function_registry::TypedParseKind::Binary, "MOD")
30879 | (crate::function_registry::TypedParseKind::Binary, "POW") => {
30880 let this = self.parse_expression()?;
30881 self.expect(TokenType::Comma)?;
30882 let expression = self.parse_expression()?;
30883 self.expect(TokenType::RParen)?;
30884 let expr = match spec.canonical_name {
30885 "CONTAINS" => Expression::Contains(Box::new(BinaryFunc {
30886 original_name: None,
30887 this,
30888 expression,
30889 inferred_type: None,
30890 })),
30891 "MOD" => Expression::ModFunc(Box::new(BinaryFunc {
30892 original_name: None,
30893 this,
30894 expression,
30895 inferred_type: None,
30896 })),
30897 "POW" => Expression::Power(Box::new(BinaryFunc {
30898 original_name: None,
30899 this,
30900 expression,
30901 inferred_type: None,
30902 })),
30903 _ => unreachable!("binary scalar parse kind already matched in caller"),
30904 };
30905 Ok(Some(expr))
30906 }
30907 (crate::function_registry::TypedParseKind::Binary, "ADD_MONTHS")
30908 | (crate::function_registry::TypedParseKind::Binary, "MONTHS_BETWEEN")
30909 | (crate::function_registry::TypedParseKind::Binary, "NEXT_DAY") => {
30910 let this = self.parse_expression()?;
30911 self.expect(TokenType::Comma)?;
30912 let expression = self.parse_expression()?;
30913 if spec.canonical_name == "MONTHS_BETWEEN" && self.match_token(TokenType::Comma) {
30914 let round_off = self.parse_expression()?;
30915 self.expect(TokenType::RParen)?;
30916 return Ok(Some(Expression::Function(Box::new(
30917 crate::expressions::Function::new(
30918 "MONTHS_BETWEEN".to_string(),
30919 vec![this, expression, round_off],
30920 ),
30921 ))));
30922 }
30923 self.expect(TokenType::RParen)?;
30924 let func = BinaryFunc {
30925 original_name: None,
30926 this,
30927 expression,
30928 inferred_type: None,
30929 };
30930 let expr = match spec.canonical_name {
30931 "ADD_MONTHS" => Expression::AddMonths(Box::new(func)),
30932 "MONTHS_BETWEEN" => Expression::MonthsBetween(Box::new(func)),
30933 "NEXT_DAY" => Expression::NextDay(Box::new(func)),
30934 _ => unreachable!("date binary parse kind already matched in caller"),
30935 };
30936 Ok(Some(expr))
30937 }
30938 (crate::function_registry::TypedParseKind::Binary, "ARRAY_CONTAINS")
30939 | (crate::function_registry::TypedParseKind::Binary, "ARRAY_POSITION")
30940 | (crate::function_registry::TypedParseKind::Binary, "ARRAY_APPEND")
30941 | (crate::function_registry::TypedParseKind::Binary, "ARRAY_PREPEND")
30942 | (crate::function_registry::TypedParseKind::Binary, "ARRAY_UNION")
30943 | (crate::function_registry::TypedParseKind::Binary, "ARRAY_EXCEPT")
30944 | (crate::function_registry::TypedParseKind::Binary, "ARRAY_REMOVE") => {
30945 let this = self.parse_expression()?;
30946 self.expect(TokenType::Comma)?;
30947 let expression = self.parse_expression()?;
30948 self.expect(TokenType::RParen)?;
30949 let func = BinaryFunc {
30950 original_name: None,
30951 this,
30952 expression,
30953 inferred_type: None,
30954 };
30955 let expr = match spec.canonical_name {
30956 "ARRAY_CONTAINS" => Expression::ArrayContains(Box::new(func)),
30957 "ARRAY_POSITION" => Expression::ArrayPosition(Box::new(func)),
30958 "ARRAY_APPEND" => Expression::ArrayAppend(Box::new(func)),
30959 "ARRAY_PREPEND" => Expression::ArrayPrepend(Box::new(func)),
30960 "ARRAY_UNION" => Expression::ArrayUnion(Box::new(func)),
30961 "ARRAY_EXCEPT" => Expression::ArrayExcept(Box::new(func)),
30962 "ARRAY_REMOVE" => Expression::ArrayRemove(Box::new(func)),
30963 _ => unreachable!("array binary parse kind already matched in caller"),
30964 };
30965 Ok(Some(expr))
30966 }
30967 (crate::function_registry::TypedParseKind::Unary, "LENGTH") => {
30968 let this = self.parse_expression()?;
30969 if self.match_token(TokenType::Comma) {
30971 let encoding = self.parse_expression()?;
30972 self.expect(TokenType::RParen)?;
30973 Ok(Some(Expression::Function(Box::new(Function::new(
30975 upper_name,
30976 vec![this, encoding],
30977 )))))
30978 } else {
30979 self.expect(TokenType::RParen)?;
30980 Ok(Some(Expression::Length(Box::new(UnaryFunc::new(this)))))
30981 }
30982 }
30983 (crate::function_registry::TypedParseKind::Unary, "LOWER") => {
30984 let this = self.parse_expression_with_clickhouse_alias()?;
30985 self.expect(TokenType::RParen)?;
30986 Ok(Some(Expression::Lower(Box::new(UnaryFunc::new(this)))))
30987 }
30988 (crate::function_registry::TypedParseKind::Unary, "UPPER") => {
30989 let this = self.parse_expression_with_clickhouse_alias()?;
30990 self.expect(TokenType::RParen)?;
30991 Ok(Some(Expression::Upper(Box::new(UnaryFunc::new(this)))))
30992 }
30993 (crate::function_registry::TypedParseKind::Unary, "TYPEOF") => {
30994 let this = self.parse_expression()?;
30995 let this = self.maybe_clickhouse_alias(this);
30997 if self.match_token(TokenType::Comma) {
30998 let mut all_args = vec![this];
31000 let remaining = self.parse_function_arguments()?;
31001 all_args.extend(remaining);
31002 self.expect(TokenType::RParen)?;
31003 Ok(Some(Expression::Function(Box::new(Function {
31004 name: name.to_string(),
31005 args: all_args,
31006 distinct: false,
31007 trailing_comments: Vec::new(),
31008 use_bracket_syntax: false,
31009 no_parens: false,
31010 quoted: false,
31011 span: None,
31012 inferred_type: None,
31013 }))))
31014 } else {
31015 self.expect(TokenType::RParen)?;
31016 Ok(Some(Expression::Typeof(Box::new(UnaryFunc::new(this)))))
31017 }
31018 }
31019 (crate::function_registry::TypedParseKind::Unary, "DAYOFWEEK")
31020 | (crate::function_registry::TypedParseKind::Unary, "DAYOFYEAR")
31021 | (crate::function_registry::TypedParseKind::Unary, "DAYOFMONTH")
31022 | (crate::function_registry::TypedParseKind::Unary, "WEEKOFYEAR") => {
31023 let this = self.parse_expression()?;
31024 self.expect(TokenType::RParen)?;
31025 let func = UnaryFunc::new(this);
31026 let expr = match spec.canonical_name {
31027 "DAYOFWEEK" => Expression::DayOfWeek(Box::new(func)),
31028 "DAYOFYEAR" => Expression::DayOfYear(Box::new(func)),
31029 "DAYOFMONTH" => Expression::DayOfMonth(Box::new(func)),
31030 "WEEKOFYEAR" => Expression::WeekOfYear(Box::new(func)),
31031 _ => unreachable!("date-part unary parse kind already matched in caller"),
31032 };
31033 Ok(Some(expr))
31034 }
31035 (crate::function_registry::TypedParseKind::Unary, "SIN")
31036 | (crate::function_registry::TypedParseKind::Unary, "COS")
31037 | (crate::function_registry::TypedParseKind::Unary, "TAN")
31038 | (crate::function_registry::TypedParseKind::Unary, "ASIN")
31039 | (crate::function_registry::TypedParseKind::Unary, "ACOS")
31040 | (crate::function_registry::TypedParseKind::Unary, "ATAN")
31041 | (crate::function_registry::TypedParseKind::Unary, "RADIANS")
31042 | (crate::function_registry::TypedParseKind::Unary, "DEGREES") => {
31043 let this = self.parse_expression()?;
31044 if spec.canonical_name == "ATAN" && self.match_token(TokenType::Comma) {
31046 let expression = self.parse_expression()?;
31047 self.expect(TokenType::RParen)?;
31048 return Ok(Some(Expression::Atan2(Box::new(BinaryFunc {
31049 original_name: Some("ATAN".to_string()),
31050 this,
31051 expression,
31052 inferred_type: None,
31053 }))));
31054 }
31055 self.expect(TokenType::RParen)?;
31056 let func = UnaryFunc::new(this);
31057 let expr = match spec.canonical_name {
31058 "SIN" => Expression::Sin(Box::new(func)),
31059 "COS" => Expression::Cos(Box::new(func)),
31060 "TAN" => Expression::Tan(Box::new(func)),
31061 "ASIN" => Expression::Asin(Box::new(func)),
31062 "ACOS" => Expression::Acos(Box::new(func)),
31063 "ATAN" => Expression::Atan(Box::new(func)),
31064 "RADIANS" => Expression::Radians(Box::new(func)),
31065 "DEGREES" => Expression::Degrees(Box::new(func)),
31066 _ => unreachable!("trig unary parse kind already matched in caller"),
31067 };
31068 Ok(Some(expr))
31069 }
31070 (crate::function_registry::TypedParseKind::Unary, "YEAR")
31071 | (crate::function_registry::TypedParseKind::Unary, "MONTH")
31072 | (crate::function_registry::TypedParseKind::Unary, "DAY")
31073 | (crate::function_registry::TypedParseKind::Unary, "HOUR")
31074 | (crate::function_registry::TypedParseKind::Unary, "MINUTE")
31075 | (crate::function_registry::TypedParseKind::Unary, "SECOND")
31076 | (crate::function_registry::TypedParseKind::Unary, "DAYOFWEEK_ISO")
31077 | (crate::function_registry::TypedParseKind::Unary, "QUARTER")
31078 | (crate::function_registry::TypedParseKind::Unary, "EPOCH")
31079 | (crate::function_registry::TypedParseKind::Unary, "EPOCH_MS") => {
31080 let this = self.parse_expression()?;
31081 self.expect(TokenType::RParen)?;
31082 let func = UnaryFunc::new(this);
31083 let expr = match spec.canonical_name {
31084 "YEAR" => Expression::Year(Box::new(func)),
31085 "MONTH" => Expression::Month(Box::new(func)),
31086 "DAY" => Expression::Day(Box::new(func)),
31087 "HOUR" => Expression::Hour(Box::new(func)),
31088 "MINUTE" => Expression::Minute(Box::new(func)),
31089 "SECOND" => Expression::Second(Box::new(func)),
31090 "DAYOFWEEK_ISO" => Expression::DayOfWeekIso(Box::new(func)),
31091 "QUARTER" => Expression::Quarter(Box::new(func)),
31092 "EPOCH" => Expression::Epoch(Box::new(func)),
31093 "EPOCH_MS" => Expression::EpochMs(Box::new(func)),
31094 _ => unreachable!("date unary parse kind already matched in caller"),
31095 };
31096 Ok(Some(expr))
31097 }
31098 (crate::function_registry::TypedParseKind::Unary, "ARRAY_LENGTH")
31099 | (crate::function_registry::TypedParseKind::Unary, "ARRAY_SIZE")
31100 | (crate::function_registry::TypedParseKind::Unary, "CARDINALITY")
31101 | (crate::function_registry::TypedParseKind::Unary, "ARRAY_REVERSE")
31102 | (crate::function_registry::TypedParseKind::Unary, "ARRAY_DISTINCT")
31103 | (crate::function_registry::TypedParseKind::Unary, "ARRAY_COMPACT")
31104 | (crate::function_registry::TypedParseKind::Unary, "EXPLODE")
31105 | (crate::function_registry::TypedParseKind::Unary, "EXPLODE_OUTER") => {
31106 let this = self.parse_expression()?;
31107 if (spec.canonical_name == "ARRAY_LENGTH" || spec.canonical_name == "ARRAY_SIZE")
31110 && self.match_token(TokenType::Comma)
31111 {
31112 let dimension = self.parse_expression()?;
31113 self.expect(TokenType::RParen)?;
31114 return Ok(Some(Expression::Function(Box::new(Function {
31115 name: name.to_string(),
31116 args: vec![this, dimension],
31117 distinct: false,
31118 trailing_comments: Vec::new(),
31119 use_bracket_syntax: false,
31120 no_parens: false,
31121 quoted: false,
31122 span: None,
31123 inferred_type: None,
31124 }))));
31125 }
31126 self.expect(TokenType::RParen)?;
31127 let func = UnaryFunc::new(this);
31128 let expr = match spec.canonical_name {
31129 "ARRAY_LENGTH" => Expression::ArrayLength(Box::new(func)),
31130 "ARRAY_SIZE" => Expression::ArraySize(Box::new(func)),
31131 "CARDINALITY" => Expression::Cardinality(Box::new(func)),
31132 "ARRAY_REVERSE" => Expression::ArrayReverse(Box::new(func)),
31133 "ARRAY_DISTINCT" => Expression::ArrayDistinct(Box::new(func)),
31134 "ARRAY_COMPACT" => Expression::ArrayCompact(Box::new(func)),
31135 "EXPLODE" => Expression::Explode(Box::new(func)),
31136 "EXPLODE_OUTER" => Expression::ExplodeOuter(Box::new(func)),
31137 _ => unreachable!("array unary parse kind already matched in caller"),
31138 };
31139 Ok(Some(expr))
31140 }
31141 (crate::function_registry::TypedParseKind::Unary, "MAP_FROM_ENTRIES")
31142 | (crate::function_registry::TypedParseKind::Unary, "MAP_KEYS")
31143 | (crate::function_registry::TypedParseKind::Unary, "MAP_VALUES") => {
31144 let this = self.parse_expression()?;
31145 self.expect(TokenType::RParen)?;
31146 let func = UnaryFunc::new(this);
31147 let expr = match spec.canonical_name {
31148 "MAP_FROM_ENTRIES" => Expression::MapFromEntries(Box::new(func)),
31149 "MAP_KEYS" => Expression::MapKeys(Box::new(func)),
31150 "MAP_VALUES" => Expression::MapValues(Box::new(func)),
31151 _ => unreachable!("map unary parse kind already matched in caller"),
31152 };
31153 Ok(Some(expr))
31154 }
31155 (crate::function_registry::TypedParseKind::Unary, "ABS") => {
31156 let this = self.parse_expression_with_clickhouse_alias()?;
31157 self.expect(TokenType::RParen)?;
31158 Ok(Some(Expression::Abs(Box::new(UnaryFunc::new(this)))))
31159 }
31160 (crate::function_registry::TypedParseKind::Unary, "SQRT")
31161 | (crate::function_registry::TypedParseKind::Unary, "EXP")
31162 | (crate::function_registry::TypedParseKind::Unary, "LN") => {
31163 let this = self.parse_expression()?;
31164 self.expect(TokenType::RParen)?;
31165 let expr = match spec.canonical_name {
31166 "SQRT" => Expression::Sqrt(Box::new(UnaryFunc::new(this))),
31167 "EXP" => Expression::Exp(Box::new(UnaryFunc::new(this))),
31168 "LN" => Expression::Ln(Box::new(UnaryFunc::new(this))),
31169 _ => unreachable!("math unary parse kind already matched in caller"),
31170 };
31171 Ok(Some(expr))
31172 }
31173 (crate::function_registry::TypedParseKind::Variadic, "TO_NUMBER")
31174 | (crate::function_registry::TypedParseKind::Variadic, "TRY_TO_NUMBER") => {
31175 let args = self.parse_expression_list()?;
31176 self.expect(TokenType::RParen)?;
31177 let this = args.get(0).cloned().unwrap_or(Expression::Null(Null {}));
31178 let format = args.get(1).cloned().map(Box::new);
31179 let precision = args.get(2).cloned().map(Box::new);
31180 let scale = args.get(3).cloned().map(Box::new);
31181 let safe = if spec.canonical_name == "TRY_TO_NUMBER" {
31182 Some(Box::new(Expression::Boolean(BooleanLiteral {
31183 value: true,
31184 })))
31185 } else {
31186 None
31187 };
31188 Ok(Some(Expression::ToNumber(Box::new(ToNumber {
31189 this: Box::new(this),
31190 format,
31191 nlsparam: None,
31192 precision,
31193 scale,
31194 safe,
31195 safe_name: None,
31196 }))))
31197 }
31198 (crate::function_registry::TypedParseKind::Variadic, "SUBSTRING") => {
31199 let this = self.parse_expression()?;
31200 let this = self.try_clickhouse_func_arg_alias(this);
31202
31203 if self.match_token(TokenType::From) {
31205 let start = self.parse_expression()?;
31206 let start = self.try_clickhouse_func_arg_alias(start);
31207 let length = if self.match_token(TokenType::For) {
31208 let len = self.parse_expression()?;
31209 Some(self.try_clickhouse_func_arg_alias(len))
31210 } else {
31211 None
31212 };
31213 self.expect(TokenType::RParen)?;
31214 Ok(Some(Expression::Substring(Box::new(SubstringFunc {
31215 this,
31216 start,
31217 length,
31218 from_for_syntax: true,
31219 }))))
31220 } else if self.match_token(TokenType::For) {
31221 let length_expr = self.parse_expression()?;
31223 let length_expr = self.try_clickhouse_func_arg_alias(length_expr);
31224 let start = if self.match_token(TokenType::From) {
31225 let s = self.parse_expression()?;
31226 self.try_clickhouse_func_arg_alias(s)
31227 } else {
31228 Expression::Literal(Box::new(Literal::Number("1".to_string())))
31230 };
31231 self.expect(TokenType::RParen)?;
31232 Ok(Some(Expression::Substring(Box::new(SubstringFunc {
31233 this,
31234 start,
31235 length: Some(length_expr),
31236 from_for_syntax: true,
31237 }))))
31238 } else if self.match_token(TokenType::Comma) {
31239 let start = self.parse_expression()?;
31241 let start = self.try_clickhouse_func_arg_alias(start);
31242 let length = if self.match_token(TokenType::Comma) {
31243 let len = self.parse_expression()?;
31244 Some(self.try_clickhouse_func_arg_alias(len))
31245 } else {
31246 None
31247 };
31248 self.expect(TokenType::RParen)?;
31249 Ok(Some(Expression::Substring(Box::new(SubstringFunc {
31250 this,
31251 start,
31252 length,
31253 from_for_syntax: false,
31254 }))))
31255 } else {
31256 self.expect(TokenType::RParen)?;
31258 Ok(Some(Expression::Function(Box::new(Function {
31260 name: name.to_string(),
31261 args: vec![this],
31262 distinct: false,
31263 trailing_comments: Vec::new(),
31264 use_bracket_syntax: false,
31265 no_parens: false,
31266 quoted: false,
31267 span: None,
31268 inferred_type: None,
31269 }))))
31270 }
31271 }
31272 (crate::function_registry::TypedParseKind::Variadic, "DATE_PART") => {
31273 let part = self.parse_expression()?;
31274 let mut part = if matches!(
31276 self.config.dialect,
31277 Some(crate::dialects::DialectType::TSQL)
31278 | Some(crate::dialects::DialectType::Fabric)
31279 ) {
31280 self.normalize_tsql_date_part(part)
31281 } else {
31282 part
31283 };
31284 if !self.match_token(TokenType::From) && !self.match_token(TokenType::Comma) {
31286 return Err(self.parse_error("Expected FROM or comma in DATE_PART"));
31287 }
31288 let from_expr = self.parse_expression()?;
31289 self.expect(TokenType::RParen)?;
31290 if matches!(
31291 self.config.dialect,
31292 Some(crate::dialects::DialectType::Snowflake)
31293 ) {
31294 if self
31295 .try_parse_date_part_field_identifier_expr(&part)
31296 .is_some()
31297 {
31298 part = self.convert_date_part_identifier_expr_to_var(part);
31299 }
31300 }
31301 Ok(Some(Expression::Function(Box::new(Function {
31302 name: "DATE_PART".to_string(),
31303 args: vec![part, from_expr],
31304 distinct: false,
31305 trailing_comments: Vec::new(),
31306 use_bracket_syntax: false,
31307 no_parens: false,
31308 quoted: false,
31309 span: None,
31310 inferred_type: None,
31311 }))))
31312 }
31313 (crate::function_registry::TypedParseKind::Variadic, "DATEADD") => {
31314 let mut first_arg = self.parse_expression()?;
31315 first_arg = self.try_clickhouse_func_arg_alias(first_arg);
31316 self.expect(TokenType::Comma)?;
31317 let second_arg = self.parse_expression()?;
31318 let second_arg = self.try_clickhouse_func_arg_alias(second_arg);
31319
31320 if self.match_token(TokenType::Comma) {
31322 let third_arg = self.parse_expression()?;
31323 let third_arg = self.try_clickhouse_func_arg_alias(third_arg);
31324 self.expect(TokenType::RParen)?;
31325 if matches!(
31326 self.config.dialect,
31327 Some(crate::dialects::DialectType::Snowflake)
31328 ) {
31329 if self
31330 .try_parse_date_part_unit_identifier_expr(&first_arg)
31331 .is_some()
31332 {
31333 first_arg = self.convert_date_part_identifier_expr_to_var(first_arg);
31334 }
31335 }
31336 Ok(Some(Expression::Function(Box::new(Function {
31337 name: name.to_string(),
31338 args: vec![first_arg, second_arg, third_arg],
31339 distinct: false,
31340 trailing_comments: Vec::new(),
31341 use_bracket_syntax: false,
31342 no_parens: false,
31343 quoted: false,
31344 span: None,
31345 inferred_type: None,
31346 }))))
31347 } else {
31348 self.expect(TokenType::RParen)?;
31350 Ok(Some(Expression::Function(Box::new(Function {
31351 name: name.to_string(),
31352 args: vec![first_arg, second_arg],
31353 distinct: false,
31354 trailing_comments: Vec::new(),
31355 use_bracket_syntax: false,
31356 no_parens: false,
31357 quoted: false,
31358 span: None,
31359 inferred_type: None,
31360 }))))
31361 }
31362 }
31363 (crate::function_registry::TypedParseKind::Variadic, "DATEDIFF") => {
31364 let first_arg = self.parse_expression()?;
31366 let first_arg = self.try_clickhouse_func_arg_alias(first_arg);
31367 self.expect(TokenType::Comma)?;
31368 let second_arg = self.parse_expression()?;
31369 let second_arg = self.try_clickhouse_func_arg_alias(second_arg);
31370 let mut args = if self.match_token(TokenType::Comma) {
31372 let third_arg = self.parse_expression()?;
31373 let third_arg = self.try_clickhouse_func_arg_alias(third_arg);
31374 vec![first_arg, second_arg, third_arg]
31375 } else {
31376 vec![first_arg, second_arg]
31377 };
31378 while self.match_token(TokenType::Comma) {
31380 let arg = self.parse_expression()?;
31381 args.push(self.try_clickhouse_func_arg_alias(arg));
31382 }
31383 self.expect(TokenType::RParen)?;
31384 if matches!(
31385 self.config.dialect,
31386 Some(crate::dialects::DialectType::Snowflake)
31387 ) && args.len() == 3
31388 {
31389 if let Some(unit) = self.try_parse_date_part_unit_expr(&args[0]) {
31390 return Ok(Some(Expression::DateDiff(Box::new(DateDiffFunc {
31391 this: args[2].clone(),
31392 expression: args[1].clone(),
31393 unit: Some(unit),
31394 }))));
31395 }
31396 }
31397 Ok(Some(Expression::Function(Box::new(Function {
31398 name: name.to_string(),
31399 args,
31400 distinct: false,
31401 trailing_comments: Vec::new(),
31402 use_bracket_syntax: false,
31403 no_parens: false,
31404 quoted: false,
31405 span: None,
31406 inferred_type: None,
31407 }))))
31408 }
31409 (crate::function_registry::TypedParseKind::Variadic, "RANDOM") => {
31410 if self.check(TokenType::RParen) {
31412 self.expect(TokenType::RParen)?;
31413 Ok(Some(Expression::Random(Random)))
31414 } else {
31415 let first = self.parse_expression()?;
31416 if self.match_token(TokenType::Comma) {
31417 let second = self.parse_expression()?;
31418 self.expect(TokenType::RParen)?;
31419 Ok(Some(Expression::Rand(Box::new(Rand {
31420 seed: None,
31421 lower: Some(Box::new(first)),
31422 upper: Some(Box::new(second)),
31423 }))))
31424 } else {
31425 self.expect(TokenType::RParen)?;
31426 Ok(Some(Expression::Rand(Box::new(Rand {
31427 seed: Some(Box::new(first)),
31428 lower: None,
31429 upper: None,
31430 }))))
31431 }
31432 }
31433 }
31434 (crate::function_registry::TypedParseKind::Variadic, "RAND") => {
31435 let seed = if self.check(TokenType::RParen) {
31436 None
31437 } else {
31438 Some(Box::new(self.parse_expression()?))
31439 };
31440 self.expect(TokenType::RParen)?;
31441 Ok(Some(Expression::Rand(Box::new(Rand {
31442 seed,
31443 lower: None,
31444 upper: None,
31445 }))))
31446 }
31447 (crate::function_registry::TypedParseKind::Variadic, "PI") => {
31448 self.expect(TokenType::RParen)?;
31449 Ok(Some(Expression::Pi(Pi)))
31450 }
31451 (crate::function_registry::TypedParseKind::Variadic, "LAST_DAY") => {
31452 let this = self.parse_expression()?;
31453 let unit = if self.match_token(TokenType::Comma) {
31454 Some(self.parse_datetime_field()?)
31455 } else {
31456 None
31457 };
31458 self.expect(TokenType::RParen)?;
31459 Ok(Some(Expression::LastDay(Box::new(LastDayFunc {
31460 this,
31461 unit,
31462 }))))
31463 }
31464 (crate::function_registry::TypedParseKind::Variadic, "POSITION") => {
31465 let expr = self
31466 .parse_position()?
31467 .ok_or_else(|| self.parse_error("Expected expression in POSITION"))?;
31468 self.expect(TokenType::RParen)?;
31469 Ok(Some(expr))
31470 }
31471 (crate::function_registry::TypedParseKind::Variadic, "STRPOS") => {
31472 let this = self.parse_expression()?;
31473 self.expect(TokenType::Comma)?;
31474 let substr = self.parse_expression()?;
31475 let occurrence = if self.match_token(TokenType::Comma) {
31476 Some(Box::new(self.parse_expression()?))
31477 } else {
31478 None
31479 };
31480 self.expect(TokenType::RParen)?;
31481 Ok(Some(Expression::StrPosition(Box::new(StrPosition {
31482 this: Box::new(this),
31483 substr: Some(Box::new(substr)),
31484 position: None,
31485 occurrence,
31486 }))))
31487 }
31488 (crate::function_registry::TypedParseKind::Variadic, "LOCATE") => {
31489 if self.check(TokenType::RParen) {
31490 self.skip();
31491 return Ok(Some(Expression::Function(Box::new(Function {
31492 name: name.to_string(),
31493 args: vec![],
31494 distinct: false,
31495 trailing_comments: Vec::new(),
31496 use_bracket_syntax: false,
31497 no_parens: false,
31498 quoted: false,
31499 span: None,
31500 inferred_type: None,
31501 }))));
31502 }
31503 let first = self.parse_expression()?;
31504 if !self.check(TokenType::Comma) && self.check(TokenType::RParen) {
31505 self.skip();
31506 return Ok(Some(Expression::Function(Box::new(Function {
31507 name: name.to_string(),
31508 args: vec![first],
31509 distinct: false,
31510 trailing_comments: Vec::new(),
31511 use_bracket_syntax: false,
31512 no_parens: false,
31513 quoted: false,
31514 span: None,
31515 inferred_type: None,
31516 }))));
31517 }
31518 self.expect(TokenType::Comma)?;
31519 let second = self.parse_expression()?;
31520 let position = if self.match_token(TokenType::Comma) {
31521 Some(Box::new(self.parse_expression()?))
31522 } else {
31523 None
31524 };
31525 self.expect(TokenType::RParen)?;
31526 Ok(Some(Expression::StrPosition(Box::new(StrPosition {
31527 this: Box::new(second),
31528 substr: Some(Box::new(first)),
31529 position,
31530 occurrence: None,
31531 }))))
31532 }
31533 (crate::function_registry::TypedParseKind::Variadic, "INSTR") => {
31534 let first = self.parse_expression()?;
31535 self.expect(TokenType::Comma)?;
31536 let second = self.parse_expression()?;
31537 let position = if self.match_token(TokenType::Comma) {
31538 Some(Box::new(self.parse_expression()?))
31539 } else {
31540 None
31541 };
31542 self.expect(TokenType::RParen)?;
31543 Ok(Some(Expression::StrPosition(Box::new(StrPosition {
31544 this: Box::new(first),
31545 substr: Some(Box::new(second)),
31546 position,
31547 occurrence: None,
31548 }))))
31549 }
31550 (crate::function_registry::TypedParseKind::Variadic, "NORMALIZE") => {
31551 let this = self.parse_expression()?;
31552 let form = if self.match_token(TokenType::Comma) {
31553 Some(Box::new(self.parse_expression()?))
31554 } else {
31555 None
31556 };
31557 self.expect(TokenType::RParen)?;
31558 Ok(Some(Expression::Normalize(Box::new(Normalize {
31559 this: Box::new(this),
31560 form,
31561 is_casefold: None,
31562 }))))
31563 }
31564 (crate::function_registry::TypedParseKind::Variadic, "INITCAP") => {
31565 let this = self.parse_expression()?;
31566 let delimiter = if self.match_token(TokenType::Comma) {
31567 Some(Box::new(self.parse_expression()?))
31568 } else {
31569 None
31570 };
31571 self.expect(TokenType::RParen)?;
31572 if let Some(delim) = delimiter {
31573 Ok(Some(Expression::Function(Box::new(Function::new(
31574 "INITCAP".to_string(),
31575 vec![this, *delim],
31576 )))))
31577 } else {
31578 Ok(Some(Expression::Initcap(Box::new(UnaryFunc::new(this)))))
31579 }
31580 }
31581 (crate::function_registry::TypedParseKind::Variadic, "FLOOR") => {
31582 let this = self.parse_expression()?;
31583 let to = if self.match_token(TokenType::To) {
31584 self.parse_var()?
31585 } else {
31586 None
31587 };
31588 let scale = if to.is_none() && self.match_token(TokenType::Comma) {
31589 Some(self.parse_expression()?)
31590 } else {
31591 None
31592 };
31593 if self.check(TokenType::Comma) {
31594 let mut args = vec![this];
31595 if let Some(s) = scale {
31596 args.push(s);
31597 }
31598 while self.match_token(TokenType::Comma) {
31599 args.push(self.parse_expression()?);
31600 }
31601 self.expect(TokenType::RParen)?;
31602 return Ok(Some(Expression::Function(Box::new(Function {
31603 name: name.to_string(),
31604 args,
31605 distinct: false,
31606 trailing_comments: Vec::new(),
31607 use_bracket_syntax: false,
31608 no_parens: false,
31609 quoted: false,
31610 span: None,
31611 inferred_type: None,
31612 }))));
31613 }
31614 self.expect(TokenType::RParen)?;
31615 Ok(Some(Expression::Floor(Box::new(FloorFunc {
31616 this,
31617 scale,
31618 to,
31619 }))))
31620 }
31621 (crate::function_registry::TypedParseKind::Variadic, "LOG") => {
31622 let first = self.parse_expression()?;
31623 if self.match_token(TokenType::Comma) {
31624 let second = self.parse_expression()?;
31625 self.expect(TokenType::RParen)?;
31626 let (value, base) = if self.log_base_first() {
31627 (second, first)
31628 } else {
31629 (first, second)
31630 };
31631 Ok(Some(Expression::Log(Box::new(LogFunc {
31632 this: value,
31633 base: Some(base),
31634 }))))
31635 } else {
31636 self.expect(TokenType::RParen)?;
31637 if self.log_defaults_to_ln() {
31638 Ok(Some(Expression::Ln(Box::new(UnaryFunc::new(first)))))
31639 } else {
31640 Ok(Some(Expression::Log(Box::new(LogFunc {
31641 this: first,
31642 base: None,
31643 }))))
31644 }
31645 }
31646 }
31647 (crate::function_registry::TypedParseKind::Variadic, "FLATTEN") => {
31648 let args = self.parse_function_arguments()?;
31649 self.expect(TokenType::RParen)?;
31650 Ok(Some(Expression::Function(Box::new(Function {
31651 name: name.to_string(),
31652 args,
31653 distinct: false,
31654 trailing_comments: Vec::new(),
31655 use_bracket_syntax: false,
31656 no_parens: false,
31657 quoted: false,
31658 span: None,
31659 inferred_type: None,
31660 }))))
31661 }
31662 (crate::function_registry::TypedParseKind::Variadic, "ARRAY_INTERSECT") => {
31663 let mut expressions = vec![self.parse_expression()?];
31664 while self.match_token(TokenType::Comma) {
31665 expressions.push(self.parse_expression()?);
31666 }
31667 self.expect(TokenType::RParen)?;
31668 Ok(Some(Expression::ArrayIntersect(Box::new(VarArgFunc {
31669 expressions,
31670 original_name: Some(name.to_string()),
31671 inferred_type: None,
31672 }))))
31673 }
31674 (crate::function_registry::TypedParseKind::Variadic, "CURRENT_SCHEMAS") => {
31675 let args = if self.check(TokenType::RParen) {
31676 Vec::new()
31677 } else {
31678 vec![self.parse_expression()?]
31679 };
31680 self.expect(TokenType::RParen)?;
31681 Ok(Some(Expression::CurrentSchemas(Box::new(CurrentSchemas {
31682 this: args.into_iter().next().map(Box::new),
31683 }))))
31684 }
31685 (crate::function_registry::TypedParseKind::Variadic, "COALESCE") => {
31686 let args = if self.check(TokenType::RParen) {
31687 Vec::new()
31688 } else {
31689 self.parse_expression_list()?
31690 };
31691 self.expect(TokenType::RParen)?;
31692 Ok(Some(Expression::Coalesce(Box::new(
31693 crate::expressions::VarArgFunc {
31694 original_name: None,
31695 expressions: args,
31696 inferred_type: None,
31697 },
31698 ))))
31699 }
31700 (crate::function_registry::TypedParseKind::Variadic, "IFNULL") => {
31701 let args = self.parse_expression_list()?;
31702 self.expect(TokenType::RParen)?;
31703 if args.len() >= 2 {
31704 Ok(Some(Expression::Coalesce(Box::new(
31705 crate::expressions::VarArgFunc {
31706 original_name: Some("IFNULL".to_string()),
31707 expressions: args,
31708 inferred_type: None,
31709 },
31710 ))))
31711 } else {
31712 Ok(Some(Expression::Function(Box::new(Function {
31713 name: name.to_string(),
31714 args,
31715 distinct: false,
31716 trailing_comments: Vec::new(),
31717 use_bracket_syntax: false,
31718 no_parens: false,
31719 quoted: false,
31720 span: None,
31721 inferred_type: None,
31722 }))))
31723 }
31724 }
31725 (crate::function_registry::TypedParseKind::Variadic, "NVL") => {
31726 let args = self.parse_expression_list()?;
31727 self.expect(TokenType::RParen)?;
31728 if args.len() > 2 {
31729 Ok(Some(Expression::Function(Box::new(Function {
31730 name: "COALESCE".to_string(),
31731 args,
31732 distinct: false,
31733 trailing_comments: Vec::new(),
31734 use_bracket_syntax: false,
31735 no_parens: false,
31736 quoted: false,
31737 span: None,
31738 inferred_type: None,
31739 }))))
31740 } else if args.len() == 2 {
31741 Ok(Some(Expression::Nvl(Box::new(
31742 crate::expressions::BinaryFunc {
31743 original_name: Some("NVL".to_string()),
31744 this: args[0].clone(),
31745 expression: args[1].clone(),
31746 inferred_type: None,
31747 },
31748 ))))
31749 } else {
31750 Ok(Some(Expression::Function(Box::new(Function {
31751 name: name.to_string(),
31752 args,
31753 distinct: false,
31754 trailing_comments: Vec::new(),
31755 use_bracket_syntax: false,
31756 no_parens: false,
31757 quoted: false,
31758 span: None,
31759 inferred_type: None,
31760 }))))
31761 }
31762 }
31763 (crate::function_registry::TypedParseKind::Variadic, "NVL2") => {
31764 let args = self.parse_expression_list()?;
31765 self.expect(TokenType::RParen)?;
31766 if args.len() >= 3 {
31767 Ok(Some(Expression::Nvl2(Box::new(
31768 crate::expressions::Nvl2Func {
31769 this: args[0].clone(),
31770 true_value: args[1].clone(),
31771 false_value: args[2].clone(),
31772 inferred_type: None,
31773 },
31774 ))))
31775 } else {
31776 Ok(Some(Expression::Function(Box::new(Function {
31777 name: name.to_string(),
31778 args,
31779 distinct: false,
31780 trailing_comments: Vec::new(),
31781 use_bracket_syntax: false,
31782 no_parens: false,
31783 quoted: false,
31784 span: None,
31785 inferred_type: None,
31786 }))))
31787 }
31788 }
31789 (crate::function_registry::TypedParseKind::Variadic, "EXTRACT") => {
31790 if matches!(
31791 self.config.dialect,
31792 Some(crate::dialects::DialectType::ClickHouse)
31793 ) && (self.check(TokenType::Identifier)
31794 || self.check(TokenType::Var)
31795 || self.peek().token_type.is_keyword()
31796 || self.check(TokenType::String)
31797 || self.check(TokenType::Number))
31798 && (self.check_next(TokenType::Comma)
31799 || self.check_next(TokenType::LParen)
31800 || self.check_next(TokenType::Var)
31801 || self.check_next(TokenType::Identifier))
31802 {
31803 let args = self.parse_function_arguments()?;
31804 self.expect(TokenType::RParen)?;
31805 return Ok(Some(Expression::Function(Box::new(Function {
31806 name: name.to_string(),
31807 args,
31808 distinct: false,
31809 trailing_comments: Vec::new(),
31810 use_bracket_syntax: false,
31811 no_parens: false,
31812 quoted: false,
31813 span: None,
31814 inferred_type: None,
31815 }))));
31816 }
31817
31818 if self.check(TokenType::String) {
31819 let args = self.parse_expression_list()?;
31820 self.expect(TokenType::RParen)?;
31821 return Ok(Some(Expression::Function(Box::new(Function {
31822 name: name.to_string(),
31823 args,
31824 distinct: false,
31825 trailing_comments: Vec::new(),
31826 use_bracket_syntax: false,
31827 no_parens: false,
31828 quoted: false,
31829 span: None,
31830 inferred_type: None,
31831 }))));
31832 }
31833
31834 let field = self.parse_datetime_field()?;
31835 if !self.match_token(TokenType::From) && !self.match_token(TokenType::Comma) {
31836 return Err(self.parse_error("Expected FROM or comma after EXTRACT field"));
31837 }
31838 let this = self.parse_expression()?;
31839 let this = self.try_clickhouse_func_arg_alias(this);
31840 self.expect(TokenType::RParen)?;
31841 Ok(Some(Expression::Extract(Box::new(ExtractFunc {
31842 this,
31843 field,
31844 }))))
31845 }
31846 (crate::function_registry::TypedParseKind::Variadic, "STRUCT") => {
31847 let args = if self.check(TokenType::RParen) {
31848 Vec::new()
31849 } else {
31850 self.parse_struct_args()?
31851 };
31852 self.expect(TokenType::RParen)?;
31853 Ok(Some(Expression::Function(Box::new(Function {
31854 name: name.to_string(),
31855 args,
31856 distinct: false,
31857 trailing_comments: Vec::new(),
31858 use_bracket_syntax: false,
31859 no_parens: false,
31860 quoted: false,
31861 span: None,
31862 inferred_type: None,
31863 }))))
31864 }
31865 (crate::function_registry::TypedParseKind::Variadic, "CHAR") => {
31866 let args = self.parse_expression_list()?;
31867 let charset = if self.match_token(TokenType::Using) {
31868 if !self.is_at_end() {
31869 let charset_token = self.advance();
31870 Some(charset_token.text.clone())
31871 } else {
31872 None
31873 }
31874 } else {
31875 None
31876 };
31877 self.expect(TokenType::RParen)?;
31878 if charset.is_some() {
31879 Ok(Some(Expression::CharFunc(Box::new(
31880 crate::expressions::CharFunc {
31881 args,
31882 charset,
31883 name: None,
31884 },
31885 ))))
31886 } else {
31887 Ok(Some(Expression::Function(Box::new(Function {
31888 name: name.to_string(),
31889 args,
31890 distinct: false,
31891 trailing_comments: Vec::new(),
31892 use_bracket_syntax: false,
31893 no_parens: false,
31894 quoted: false,
31895 span: None,
31896 inferred_type: None,
31897 }))))
31898 }
31899 }
31900 (crate::function_registry::TypedParseKind::Variadic, "CHR") => {
31901 let args = self.parse_expression_list()?;
31902 let charset = if self.match_token(TokenType::Using) {
31903 if !self.is_at_end() {
31904 let charset_token = self.advance();
31905 Some(charset_token.text.clone())
31906 } else {
31907 None
31908 }
31909 } else {
31910 None
31911 };
31912 self.expect(TokenType::RParen)?;
31913 if charset.is_some() {
31914 Ok(Some(Expression::CharFunc(Box::new(
31915 crate::expressions::CharFunc {
31916 args,
31917 charset,
31918 name: Some("CHR".to_string()),
31919 },
31920 ))))
31921 } else {
31922 Ok(Some(Expression::Function(Box::new(Function {
31923 name: name.to_string(),
31924 args,
31925 distinct: false,
31926 trailing_comments: Vec::new(),
31927 use_bracket_syntax: false,
31928 no_parens: false,
31929 quoted: false,
31930 span: None,
31931 inferred_type: None,
31932 }))))
31933 }
31934 }
31935 (crate::function_registry::TypedParseKind::Variadic, "RANGE_N") => {
31936 let this = self.parse_bitwise_or()?;
31937 self.expect(TokenType::Between)?;
31938 let mut expressions = Vec::new();
31939 while !self.check(TokenType::Each) && !self.check(TokenType::RParen) {
31940 expressions.push(self.parse_expression()?);
31941 if !self.match_token(TokenType::Comma) {
31942 break;
31943 }
31944 }
31945 let each = if self.match_token(TokenType::Each) {
31946 Some(Box::new(self.parse_expression()?))
31947 } else {
31948 None
31949 };
31950 self.expect(TokenType::RParen)?;
31951 Ok(Some(Expression::RangeN(Box::new(RangeN {
31952 this: Box::new(this),
31953 expressions,
31954 each,
31955 }))))
31956 }
31957 (crate::function_registry::TypedParseKind::Variadic, "XMLTABLE") => {
31958 if let Some(xml_table) = self.parse_xml_table()? {
31959 self.expect(TokenType::RParen)?;
31960 Ok(Some(xml_table))
31961 } else {
31962 Err(self.parse_error("Failed to parse XMLTABLE"))
31963 }
31964 }
31965 (crate::function_registry::TypedParseKind::Variadic, "XMLELEMENT") => {
31966 if let Some(elem) = self.parse_xml_element()? {
31967 self.expect(TokenType::RParen)?;
31968 Ok(Some(elem))
31969 } else {
31970 self.expect(TokenType::RParen)?;
31971 Ok(Some(Expression::Function(Box::new(Function {
31972 name: name.to_string(),
31973 args: Vec::new(),
31974 distinct: false,
31975 trailing_comments: Vec::new(),
31976 use_bracket_syntax: false,
31977 no_parens: false,
31978 quoted: false,
31979 span: None,
31980 inferred_type: None,
31981 }))))
31982 }
31983 }
31984 (crate::function_registry::TypedParseKind::Variadic, "XMLATTRIBUTES") => {
31985 let mut attrs = Vec::new();
31986 if !self.check(TokenType::RParen) {
31987 loop {
31988 let expr = self.parse_expression()?;
31989 if self.match_token(TokenType::As) {
31990 let alias_ident = self.expect_identifier_or_keyword_with_quoted()?;
31991 attrs.push(Expression::Alias(Box::new(Alias {
31992 this: expr,
31993 alias: alias_ident,
31994 column_aliases: Vec::new(),
31995 pre_alias_comments: Vec::new(),
31996 trailing_comments: Vec::new(),
31997 inferred_type: None,
31998 })));
31999 } else {
32000 attrs.push(expr);
32001 }
32002 if !self.match_token(TokenType::Comma) {
32003 break;
32004 }
32005 }
32006 }
32007 self.expect(TokenType::RParen)?;
32008 Ok(Some(Expression::Function(Box::new(Function {
32009 name: "XMLATTRIBUTES".to_string(),
32010 args: attrs,
32011 distinct: false,
32012 trailing_comments: Vec::new(),
32013 use_bracket_syntax: false,
32014 no_parens: false,
32015 quoted: false,
32016 span: None,
32017 inferred_type: None,
32018 }))))
32019 }
32020 (crate::function_registry::TypedParseKind::Variadic, "XMLCOMMENT") => {
32021 let args = if self.check(TokenType::RParen) {
32022 Vec::new()
32023 } else {
32024 self.parse_expression_list()?
32025 };
32026 self.expect(TokenType::RParen)?;
32027 Ok(Some(Expression::Function(Box::new(Function {
32028 name: "XMLCOMMENT".to_string(),
32029 args,
32030 distinct: false,
32031 trailing_comments: Vec::new(),
32032 use_bracket_syntax: false,
32033 no_parens: false,
32034 quoted: false,
32035 span: None,
32036 inferred_type: None,
32037 }))))
32038 }
32039 (crate::function_registry::TypedParseKind::Variadic, "MATCH") => {
32040 let expressions = if self.check(TokenType::Table)
32041 && !matches!(
32042 self.config.dialect,
32043 Some(crate::dialects::DialectType::ClickHouse)
32044 ) {
32045 self.skip();
32046 let table_name = self.expect_identifier_or_keyword()?;
32047 vec![Expression::Var(Box::new(Var {
32048 this: format!("TABLE {}", table_name),
32049 }))]
32050 } else {
32051 self.parse_expression_list()?
32052 };
32053
32054 self.expect(TokenType::RParen)?;
32055
32056 if !self.check_keyword_text("AGAINST") {
32057 return Ok(Some(Expression::Function(Box::new(Function {
32058 name: "MATCH".to_string(),
32059 args: expressions,
32060 distinct: false,
32061 trailing_comments: Vec::new(),
32062 use_bracket_syntax: false,
32063 no_parens: false,
32064 quoted: false,
32065 span: None,
32066 inferred_type: None,
32067 }))));
32068 }
32069
32070 self.skip();
32071 self.expect(TokenType::LParen)?;
32072 let search_expr = self.parse_primary()?;
32073
32074 let modifier = if self.match_text_seq(&["IN", "NATURAL", "LANGUAGE", "MODE"]) {
32075 if self.match_text_seq(&["WITH", "QUERY", "EXPANSION"]) {
32076 Some(Box::new(Expression::Var(Box::new(Var {
32077 this: "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION".to_string(),
32078 }))))
32079 } else {
32080 Some(Box::new(Expression::Var(Box::new(Var {
32081 this: "IN NATURAL LANGUAGE MODE".to_string(),
32082 }))))
32083 }
32084 } else if self.match_text_seq(&["IN", "BOOLEAN", "MODE"]) {
32085 Some(Box::new(Expression::Var(Box::new(Var {
32086 this: "IN BOOLEAN MODE".to_string(),
32087 }))))
32088 } else if self.match_text_seq(&["WITH", "QUERY", "EXPANSION"]) {
32089 Some(Box::new(Expression::Var(Box::new(Var {
32090 this: "WITH QUERY EXPANSION".to_string(),
32091 }))))
32092 } else {
32093 None
32094 };
32095
32096 self.expect(TokenType::RParen)?;
32097
32098 Ok(Some(Expression::MatchAgainst(Box::new(MatchAgainst {
32099 this: Box::new(search_expr),
32100 expressions,
32101 modifier,
32102 }))))
32103 }
32104 (crate::function_registry::TypedParseKind::Variadic, "TRANSFORM") => {
32105 let expressions = if self.check(TokenType::RParen) {
32106 Vec::new()
32107 } else {
32108 self.parse_function_args_with_lambda()?
32109 };
32110 self.expect(TokenType::RParen)?;
32111
32112 let row_format_before = if self.match_token(TokenType::Row) {
32113 self.parse_row()?
32114 } else {
32115 None
32116 };
32117
32118 let record_writer = if self.match_text_seq(&["RECORDWRITER"]) {
32119 Some(Box::new(self.parse_expression()?))
32120 } else {
32121 None
32122 };
32123
32124 if self.match_token(TokenType::Using) {
32125 let command_script = Some(Box::new(self.parse_expression()?));
32126 let schema = if self.match_token(TokenType::As) {
32127 self.parse_schema()?
32128 } else {
32129 None
32130 };
32131
32132 let row_format_after = if self.match_token(TokenType::Row) {
32133 self.parse_row()?
32134 } else {
32135 None
32136 };
32137
32138 let record_reader = if self.match_text_seq(&["RECORDREADER"]) {
32139 Some(Box::new(self.parse_expression()?))
32140 } else {
32141 None
32142 };
32143
32144 Ok(Some(Expression::QueryTransform(Box::new(QueryTransform {
32145 expressions,
32146 command_script,
32147 schema: schema.map(Box::new),
32148 row_format_before: row_format_before.map(Box::new),
32149 record_writer,
32150 row_format_after: row_format_after.map(Box::new),
32151 record_reader,
32152 }))))
32153 } else {
32154 Ok(Some(Expression::Function(Box::new(Function {
32155 name: name.to_string(),
32156 args: expressions,
32157 distinct: false,
32158 trailing_comments: Vec::new(),
32159 use_bracket_syntax: false,
32160 no_parens: false,
32161 quoted,
32162 span: None,
32163 inferred_type: None,
32164 }))))
32165 }
32166 }
32167 (crate::function_registry::TypedParseKind::Variadic, "CONVERT") => {
32168 let is_try = upper_name == "TRY_CONVERT";
32169 let is_tsql = matches!(
32170 self.config.dialect,
32171 Some(crate::dialects::DialectType::TSQL)
32172 | Some(crate::dialects::DialectType::Fabric)
32173 );
32174
32175 if is_tsql {
32176 let saved = self.current;
32177 let orig_type_text = if self.current < self.tokens.len() {
32178 self.tokens[self.current].text.to_ascii_uppercase()
32179 } else {
32180 String::new()
32181 };
32182 let dt = self.parse_data_type();
32183 if let Ok(mut dt) = dt {
32184 if self.match_token(TokenType::Comma) {
32185 if orig_type_text == "NVARCHAR" || orig_type_text == "NCHAR" {
32186 dt = match dt {
32187 crate::expressions::DataType::VarChar { length, .. } => {
32188 if let Some(len) = length {
32189 crate::expressions::DataType::Custom {
32190 name: format!("{}({})", orig_type_text, len),
32191 }
32192 } else {
32193 crate::expressions::DataType::Custom {
32194 name: orig_type_text.clone(),
32195 }
32196 }
32197 }
32198 crate::expressions::DataType::Char { length } => {
32199 if let Some(len) = length {
32200 crate::expressions::DataType::Custom {
32201 name: format!("{}({})", orig_type_text, len),
32202 }
32203 } else {
32204 crate::expressions::DataType::Custom {
32205 name: orig_type_text.clone(),
32206 }
32207 }
32208 }
32209 other => other,
32210 };
32211 }
32212 let value = self.parse_expression()?;
32213 let style = if self.match_token(TokenType::Comma) {
32214 Some(self.parse_expression()?)
32215 } else {
32216 None
32217 };
32218 self.expect(TokenType::RParen)?;
32219 let func_name = if is_try { "TRY_CONVERT" } else { "CONVERT" };
32220 let mut args = vec![Expression::DataType(dt), value];
32221 if let Some(s) = style {
32222 args.push(s);
32223 }
32224 return Ok(Some(Expression::Function(Box::new(Function {
32225 name: func_name.to_string(),
32226 args,
32227 distinct: false,
32228 trailing_comments: Vec::new(),
32229 use_bracket_syntax: false,
32230 no_parens: false,
32231 quoted: false,
32232 span: None,
32233 inferred_type: None,
32234 }))));
32235 }
32236 self.current = saved;
32237 } else {
32238 self.current = saved;
32239 }
32240 }
32241
32242 let this = self.parse_expression()?;
32243 if self.match_token(TokenType::Using) {
32244 let charset = self.expect_identifier()?;
32245 self.expect(TokenType::RParen)?;
32246 Ok(Some(Expression::Cast(Box::new(Cast {
32247 this,
32248 to: DataType::CharacterSet { name: charset },
32249 trailing_comments: Vec::new(),
32250 double_colon_syntax: false,
32251 format: None,
32252 default: None,
32253 inferred_type: None,
32254 }))))
32255 } else if self.match_token(TokenType::Comma) {
32256 let mut args = vec![this];
32257 args.push(self.parse_expression()?);
32258 while self.match_token(TokenType::Comma) {
32259 args.push(self.parse_expression()?);
32260 }
32261 self.expect(TokenType::RParen)?;
32262 let func_name = if is_try { "TRY_CONVERT" } else { "CONVERT" };
32263 Ok(Some(Expression::Function(Box::new(Function {
32264 name: func_name.to_string(),
32265 args,
32266 distinct: false,
32267 trailing_comments: Vec::new(),
32268 use_bracket_syntax: false,
32269 no_parens: false,
32270 quoted: false,
32271 span: None,
32272 inferred_type: None,
32273 }))))
32274 } else {
32275 self.expect(TokenType::RParen)?;
32276 let func_name = if is_try { "TRY_CONVERT" } else { "CONVERT" };
32277 Ok(Some(Expression::Function(Box::new(Function {
32278 name: func_name.to_string(),
32279 args: vec![this],
32280 distinct: false,
32281 trailing_comments: Vec::new(),
32282 use_bracket_syntax: false,
32283 no_parens: false,
32284 quoted: false,
32285 span: None,
32286 inferred_type: None,
32287 }))))
32288 }
32289 }
32290 (crate::function_registry::TypedParseKind::Variadic, "TRIM") => {
32291 let (position, position_explicit) = if self.match_token(TokenType::Leading) {
32292 (TrimPosition::Leading, true)
32293 } else if self.match_token(TokenType::Trailing) {
32294 (TrimPosition::Trailing, true)
32295 } else if self.match_token(TokenType::Both) {
32296 (TrimPosition::Both, true)
32297 } else {
32298 (TrimPosition::Both, false)
32299 };
32300
32301 if position_explicit || self.check(TokenType::From) {
32302 if self.match_token(TokenType::From) {
32303 let this = self.parse_expression()?;
32304 self.expect(TokenType::RParen)?;
32305 Ok(Some(Expression::Trim(Box::new(TrimFunc {
32306 this,
32307 characters: None,
32308 position,
32309 sql_standard_syntax: true,
32310 position_explicit,
32311 }))))
32312 } else {
32313 let first_expr = self.parse_bitwise_or()?;
32314 let first_expr = self.try_clickhouse_func_arg_alias(first_expr);
32315 if self.match_token(TokenType::From) {
32316 let this = self.parse_bitwise_or()?;
32317 let this = self.try_clickhouse_func_arg_alias(this);
32318 self.expect(TokenType::RParen)?;
32319 Ok(Some(Expression::Trim(Box::new(TrimFunc {
32320 this,
32321 characters: Some(first_expr),
32322 position,
32323 sql_standard_syntax: true,
32324 position_explicit,
32325 }))))
32326 } else {
32327 self.expect(TokenType::RParen)?;
32328 Ok(Some(Expression::Trim(Box::new(TrimFunc {
32329 this: first_expr,
32330 characters: None,
32331 position,
32332 sql_standard_syntax: true,
32333 position_explicit,
32334 }))))
32335 }
32336 }
32337 } else {
32338 let first_expr = self.parse_expression()?;
32339 let first_expr = self.try_clickhouse_func_arg_alias(first_expr);
32340 if self.match_token(TokenType::From) {
32341 let this = self.parse_expression()?;
32342 let this = self.try_clickhouse_func_arg_alias(this);
32343 self.expect(TokenType::RParen)?;
32344 Ok(Some(Expression::Trim(Box::new(TrimFunc {
32345 this,
32346 characters: Some(first_expr),
32347 position: TrimPosition::Both,
32348 sql_standard_syntax: true,
32349 position_explicit: false,
32350 }))))
32351 } else if self.match_token(TokenType::Comma) {
32352 let second_expr = self.parse_expression()?;
32353 self.expect(TokenType::RParen)?;
32354 let trim_pattern_first = matches!(
32355 self.config.dialect,
32356 Some(crate::dialects::DialectType::Spark)
32357 );
32358 let (this, characters) = if trim_pattern_first {
32359 (second_expr, first_expr)
32360 } else {
32361 (first_expr, second_expr)
32362 };
32363 Ok(Some(Expression::Trim(Box::new(TrimFunc {
32364 this,
32365 characters: Some(characters),
32366 position: TrimPosition::Both,
32367 sql_standard_syntax: false,
32368 position_explicit: false,
32369 }))))
32370 } else {
32371 self.expect(TokenType::RParen)?;
32372 Ok(Some(Expression::Trim(Box::new(TrimFunc {
32373 this: first_expr,
32374 characters: None,
32375 position: TrimPosition::Both,
32376 sql_standard_syntax: false,
32377 position_explicit: false,
32378 }))))
32379 }
32380 }
32381 }
32382 (crate::function_registry::TypedParseKind::Variadic, "OVERLAY") => {
32383 if matches!(
32384 self.config.dialect,
32385 Some(crate::dialects::DialectType::ClickHouse)
32386 ) {
32387 let args = self.parse_function_arguments()?;
32388 self.expect(TokenType::RParen)?;
32389 return Ok(Some(Expression::Function(Box::new(Function {
32390 name: name.to_string(),
32391 args,
32392 distinct: false,
32393 trailing_comments: Vec::new(),
32394 use_bracket_syntax: false,
32395 no_parens: false,
32396 quoted: false,
32397 span: None,
32398 inferred_type: None,
32399 }))));
32400 }
32401
32402 let this = self.parse_expression()?;
32403 if self.match_token(TokenType::Placing) {
32404 let replacement = self.parse_expression()?;
32405 self.expect(TokenType::From)?;
32406 let from = self.parse_expression()?;
32407 let length = if self.match_token(TokenType::For) {
32408 Some(self.parse_expression()?)
32409 } else {
32410 None
32411 };
32412 self.expect(TokenType::RParen)?;
32413 Ok(Some(Expression::Overlay(Box::new(OverlayFunc {
32414 this,
32415 replacement,
32416 from,
32417 length,
32418 }))))
32419 } else if self.match_token(TokenType::Comma) {
32420 let replacement = self.parse_expression()?;
32421 if self.match_token(TokenType::Comma) {
32422 let from = self.parse_expression()?;
32423 let length = if self.match_token(TokenType::Comma) {
32424 Some(self.parse_expression()?)
32425 } else {
32426 None
32427 };
32428 self.expect(TokenType::RParen)?;
32429 Ok(Some(Expression::Overlay(Box::new(OverlayFunc {
32430 this,
32431 replacement,
32432 from,
32433 length,
32434 }))))
32435 } else {
32436 self.expect(TokenType::RParen)?;
32437 Ok(Some(Expression::Function(Box::new(Function {
32438 name: name.to_string(),
32439 args: vec![this, replacement],
32440 distinct: false,
32441 trailing_comments: Vec::new(),
32442 use_bracket_syntax: false,
32443 no_parens: false,
32444 quoted: false,
32445 span: None,
32446 inferred_type: None,
32447 }))))
32448 }
32449 } else {
32450 self.expect(TokenType::RParen)?;
32451 Ok(Some(Expression::Function(Box::new(Function {
32452 name: name.to_string(),
32453 args: vec![this],
32454 distinct: false,
32455 trailing_comments: Vec::new(),
32456 use_bracket_syntax: false,
32457 no_parens: false,
32458 quoted: false,
32459 span: None,
32460 inferred_type: None,
32461 }))))
32462 }
32463 }
32464 (crate::function_registry::TypedParseKind::Variadic, "CEIL") => {
32465 let this = self.parse_expression()?;
32466 let to = if self.match_token(TokenType::To) {
32468 self.parse_var()?
32470 } else {
32471 None
32472 };
32473 let decimals = if to.is_none() && self.match_token(TokenType::Comma) {
32474 Some(self.parse_expression()?)
32475 } else {
32476 None
32477 };
32478 self.expect(TokenType::RParen)?;
32479 Ok(Some(Expression::Ceil(Box::new(CeilFunc {
32480 this,
32481 decimals,
32482 to,
32483 }))))
32484 }
32485 (crate::function_registry::TypedParseKind::Variadic, "TIMESTAMP_FROM_PARTS")
32486 | (crate::function_registry::TypedParseKind::Variadic, "TIMESTAMP_NTZ_FROM_PARTS")
32487 | (crate::function_registry::TypedParseKind::Variadic, "TIMESTAMP_LTZ_FROM_PARTS")
32488 | (crate::function_registry::TypedParseKind::Variadic, "TIMESTAMP_TZ_FROM_PARTS")
32489 | (crate::function_registry::TypedParseKind::Variadic, "DATE_FROM_PARTS")
32490 | (crate::function_registry::TypedParseKind::Variadic, "TIME_FROM_PARTS") => {
32491 let args = self.parse_expression_list()?;
32492 self.expect(TokenType::RParen)?;
32493 Ok(Some(Expression::Function(Box::new(Function {
32494 name: name.to_string(),
32495 args,
32496 distinct: false,
32497 trailing_comments: Vec::new(),
32498 use_bracket_syntax: false,
32499 no_parens: false,
32500 quoted: false,
32501 span: None,
32502 inferred_type: None,
32503 }))))
32504 }
32505 (crate::function_registry::TypedParseKind::CastLike, "TRY_CAST") => {
32506 let this = self.parse_expression()?;
32507 self.expect(TokenType::As)?;
32508 let to = self.parse_data_type()?;
32509 self.expect(TokenType::RParen)?;
32510 Ok(Some(Expression::TryCast(Box::new(Cast {
32511 this,
32512 to,
32513 trailing_comments: Vec::new(),
32514 double_colon_syntax: false,
32515 format: None,
32516 default: None,
32517 inferred_type: None,
32518 }))))
32519 }
32520 (crate::function_registry::TypedParseKind::Conditional, "IF") => {
32521 if self.check(TokenType::RParen) {
32523 self.skip();
32524 return Ok(Some(Expression::Function(Box::new(Function {
32525 name: name.to_string(),
32526 args: vec![],
32527 distinct: false,
32528 trailing_comments: Vec::new(),
32529 use_bracket_syntax: false,
32530 no_parens: false,
32531 quoted: false,
32532 span: None,
32533 inferred_type: None,
32534 }))));
32535 }
32536 let args = self.parse_expression_list()?;
32537 self.expect(TokenType::RParen)?;
32538 let expr = if args.len() == 3 {
32539 Expression::IfFunc(Box::new(crate::expressions::IfFunc {
32540 original_name: Some(upper_name.to_string()),
32541 condition: args[0].clone(),
32542 true_value: args[1].clone(),
32543 false_value: Some(args[2].clone()),
32544 inferred_type: None,
32545 }))
32546 } else if args.len() == 2 {
32547 Expression::IfFunc(Box::new(crate::expressions::IfFunc {
32549 original_name: Some(upper_name.to_string()),
32550 condition: args[0].clone(),
32551 true_value: args[1].clone(),
32552 false_value: None,
32553 inferred_type: None,
32554 }))
32555 } else {
32556 return Err(self.parse_error("IF function requires 2 or 3 arguments"));
32557 };
32558 Ok(Some(expr))
32559 }
32560 _ => {
32561 self.try_parse_registry_grouped_typed_family(name, upper_name, canonical_upper_name)
32562 }
32563 }
32564 }
32565
32566 fn try_parse_registry_grouped_typed_family(
32568 &mut self,
32569 name: &str,
32570 upper_name: &str,
32571 canonical_upper_name: &str,
32572 ) -> Result<Option<Expression>> {
32573 use crate::function_registry::TypedDispatchGroup;
32574
32575 match crate::function_registry::typed_dispatch_group_by_name_upper(canonical_upper_name) {
32576 Some(TypedDispatchGroup::AggregateFamily) => self
32577 .parse_typed_aggregate_family(name, upper_name, canonical_upper_name)
32578 .map(Some),
32579 Some(TypedDispatchGroup::WindowFamily) => self
32580 .parse_typed_window_family(name, upper_name, canonical_upper_name)
32581 .map(Some),
32582 Some(TypedDispatchGroup::JsonFamily) => self
32583 .parse_typed_json_family(name, upper_name, canonical_upper_name)
32584 .map(Some),
32585 Some(TypedDispatchGroup::TranslateTeradataFamily) => {
32586 if matches!(
32587 self.config.dialect,
32588 Some(crate::dialects::DialectType::Teradata)
32589 ) {
32590 self.parse_typed_translate_teradata_family(
32591 name,
32592 upper_name,
32593 canonical_upper_name,
32594 )
32595 .map(Some)
32596 } else {
32597 Ok(None)
32598 }
32599 }
32600 None => Ok(None),
32601 }
32602 }
32603
32604 fn make_unquoted_function(name: &str, args: Vec<Expression>) -> Expression {
32605 Expression::Function(Box::new(Function {
32606 name: name.to_string(),
32607 args,
32608 distinct: false,
32609 trailing_comments: Vec::new(),
32610 use_bracket_syntax: false,
32611 no_parens: false,
32612 quoted: false,
32613 span: None,
32614 inferred_type: None,
32615 }))
32616 }
32617
32618 fn make_simple_aggregate(
32619 name: &str,
32620 args: Vec<Expression>,
32621 distinct: bool,
32622 filter: Option<Expression>,
32623 ) -> Expression {
32624 Expression::AggregateFunction(Box::new(AggregateFunction {
32625 name: name.to_string(),
32626 args,
32627 distinct,
32628 filter,
32629 order_by: Vec::new(),
32630 limit: None,
32631 ignore_nulls: None,
32632 inferred_type: None,
32633 }))
32634 }
32635
32636 fn try_parse_phase3_typed_function(
32638 &mut self,
32639 name: &str,
32640 _upper_name: &str,
32641 canonical_upper_name: &str,
32642 ) -> Result<Option<Expression>> {
32643 let Some(behavior) =
32644 crate::function_registry::parser_dispatch_behavior_by_name_upper(canonical_upper_name)
32645 else {
32646 return Ok(None);
32647 };
32648
32649 match behavior {
32650 crate::function_registry::ParserDispatchBehavior::ExprListFunction => {
32651 let args = self.parse_expression_list()?;
32652 self.expect(TokenType::RParen)?;
32653 Ok(Some(Self::make_unquoted_function(name, args)))
32654 }
32655 crate::function_registry::ParserDispatchBehavior::OptionalExprListFunction => {
32656 let args = if self.check(TokenType::RParen) {
32657 Vec::new()
32658 } else {
32659 self.parse_expression_list()?
32660 };
32661 self.expect(TokenType::RParen)?;
32662 Ok(Some(Self::make_unquoted_function(name, args)))
32663 }
32664 crate::function_registry::ParserDispatchBehavior::FunctionArgumentsFunction => {
32665 let args = self.parse_function_arguments()?;
32666 self.expect(TokenType::RParen)?;
32667 Ok(Some(Self::make_unquoted_function(name, args)))
32668 }
32669 crate::function_registry::ParserDispatchBehavior::ZeroArgFunction => {
32670 self.expect(TokenType::RParen)?;
32671 Ok(Some(Self::make_unquoted_function(name, Vec::new())))
32672 }
32673 crate::function_registry::ParserDispatchBehavior::ExprListMaybeAggregateByFilter => {
32674 let args = if self.check(TokenType::RParen) {
32675 Vec::new()
32676 } else {
32677 self.parse_expression_list()?
32678 };
32679 self.expect(TokenType::RParen)?;
32680 let filter = self.parse_filter_clause()?;
32681 if filter.is_some() {
32682 Ok(Some(Self::make_simple_aggregate(name, args, false, filter)))
32683 } else {
32684 Ok(Some(Self::make_unquoted_function(name, args)))
32685 }
32686 }
32687 crate::function_registry::ParserDispatchBehavior::ExprListMaybeAggregateByAggSuffix => {
32688 let args = self.parse_expression_list()?;
32689 self.expect(TokenType::RParen)?;
32690 let filter = self.parse_filter_clause()?;
32691 if canonical_upper_name.ends_with("_AGG") || filter.is_some() {
32692 Ok(Some(Self::make_simple_aggregate(name, args, false, filter)))
32693 } else {
32694 Ok(Some(Self::make_unquoted_function(name, args)))
32695 }
32696 }
32697 crate::function_registry::ParserDispatchBehavior::HashLike => {
32698 let args = self.parse_expression_list()?;
32699 self.expect(TokenType::RParen)?;
32700 let filter = self.parse_filter_clause()?;
32701 if canonical_upper_name == "HASH_AGG" || filter.is_some() {
32702 Ok(Some(Self::make_simple_aggregate(name, args, false, filter)))
32703 } else {
32704 Ok(Some(Self::make_unquoted_function(name, args)))
32705 }
32706 }
32707 crate::function_registry::ParserDispatchBehavior::HllAggregate => {
32708 let distinct = self.match_token(TokenType::Distinct);
32709 let args = if self.match_token(TokenType::Star) {
32710 vec![Expression::Star(Star {
32711 table: None,
32712 except: None,
32713 replace: None,
32714 rename: None,
32715 trailing_comments: Vec::new(),
32716 span: None,
32717 })]
32718 } else if self.check(TokenType::RParen) {
32719 Vec::new()
32720 } else {
32721 self.parse_expression_list()?
32722 };
32723 self.expect(TokenType::RParen)?;
32724 let filter = self.parse_filter_clause()?;
32725 Ok(Some(Self::make_simple_aggregate(
32726 name, args, distinct, filter,
32727 )))
32728 }
32729 crate::function_registry::ParserDispatchBehavior::PercentileAggregate => {
32730 let distinct = self.match_token(TokenType::Distinct);
32731 if !distinct {
32732 self.match_token(TokenType::All);
32733 }
32734 let args = self.parse_expression_list()?;
32735 self.expect(TokenType::RParen)?;
32736 let filter = self.parse_filter_clause()?;
32737 Ok(Some(Self::make_simple_aggregate(
32738 name, args, distinct, filter,
32739 )))
32740 }
32741 crate::function_registry::ParserDispatchBehavior::ExprListAggregate => {
32742 let args = self.parse_expression_list()?;
32743 self.expect(TokenType::RParen)?;
32744 let filter = self.parse_filter_clause()?;
32745 Ok(Some(Self::make_simple_aggregate(name, args, false, filter)))
32746 }
32747 crate::function_registry::ParserDispatchBehavior::UnaryAggregate => {
32748 let this = self.parse_expression()?;
32749 self.expect(TokenType::RParen)?;
32750 let filter = self.parse_filter_clause()?;
32751 Ok(Some(Self::make_simple_aggregate(
32752 name,
32753 vec![this],
32754 false,
32755 filter,
32756 )))
32757 }
32758 crate::function_registry::ParserDispatchBehavior::TranslateNonTeradata => {
32759 if matches!(
32760 self.config.dialect,
32761 Some(crate::dialects::DialectType::Teradata)
32762 ) {
32763 return Ok(None);
32764 }
32765 let args = self.parse_expression_list()?;
32766 self.expect(TokenType::RParen)?;
32767 Ok(Some(Self::make_unquoted_function(name, args)))
32768 }
32769 }
32770 }
32771
32772 fn parse_typed_function(
32775 &mut self,
32776 name: &str,
32777 upper_name: &str,
32778 quoted: bool,
32779 ) -> Result<Expression> {
32780 let canonical_upper_name =
32781 crate::function_registry::canonical_typed_function_name_upper(upper_name);
32782
32783 if canonical_upper_name == "TIME_TO_TIME_STR" {
32785 let arg = self.parse_expression()?;
32786 self.expect(TokenType::RParen)?;
32787 return Ok(Expression::Cast(Box::new(Cast {
32788 this: arg,
32789 to: DataType::Text,
32790 trailing_comments: Vec::new(),
32791 double_colon_syntax: false,
32792 format: None,
32793 default: None,
32794 inferred_type: None,
32795 })));
32796 }
32797
32798 if let Some(expr) =
32799 self.try_parse_registry_typed_function(name, upper_name, canonical_upper_name, quoted)?
32800 {
32801 return Ok(expr);
32802 }
32803 if let Some(expr) =
32804 self.try_parse_phase3_typed_function(name, upper_name, canonical_upper_name)?
32805 {
32806 return Ok(expr);
32807 }
32808
32809 self.parse_generic_function(name, quoted)
32810 }
32811
32812 fn parse_typed_aggregate_family(
32813 &mut self,
32814 name: &str,
32815 upper_name: &str,
32816 canonical_upper_name: &str,
32817 ) -> Result<Expression> {
32818 match canonical_upper_name {
32819 "COUNT" => {
32821 let (this, star, distinct) = if self.check(TokenType::RParen) {
32822 (None, false, false)
32823 } else if self.match_token(TokenType::Star) {
32824 (None, true, false)
32825 } else if self.match_token(TokenType::All) {
32826 (Some(self.parse_expression()?), false, false)
32828 } else if self.match_token(TokenType::Distinct) {
32829 let first_expr = self.parse_expression()?;
32830 if self.match_token(TokenType::Comma) {
32832 let mut args = vec![first_expr];
32833 loop {
32834 args.push(self.parse_expression()?);
32835 if !self.match_token(TokenType::Comma) {
32836 break;
32837 }
32838 }
32839 (
32841 Some(Expression::Tuple(Box::new(Tuple { expressions: args }))),
32842 false,
32843 true,
32844 )
32845 } else {
32846 (Some(first_expr), false, true)
32847 }
32848 } else {
32849 let first_expr = self.parse_expression()?;
32850 let first_expr = if matches!(
32852 self.config.dialect,
32853 Some(crate::dialects::DialectType::ClickHouse)
32854 ) && self.check(TokenType::As)
32855 {
32856 self.skip(); let alias = self.expect_identifier_or_keyword_with_quoted()?;
32858 Expression::Alias(Box::new(Alias {
32859 this: first_expr,
32860 alias,
32861 column_aliases: Vec::new(),
32862 pre_alias_comments: Vec::new(),
32863 trailing_comments: Vec::new(),
32864 inferred_type: None,
32865 }))
32866 } else {
32867 first_expr
32868 };
32869 if self.match_token(TokenType::Comma) {
32871 let mut args = vec![first_expr];
32872 loop {
32873 args.push(self.parse_expression()?);
32874 if !self.match_token(TokenType::Comma) {
32875 break;
32876 }
32877 }
32878 self.expect(TokenType::RParen)?;
32879 return Ok(Expression::Function(Box::new(Function {
32881 name: name.to_string(),
32882 args,
32883 distinct: false,
32884 trailing_comments: Vec::new(),
32885 use_bracket_syntax: false,
32886 no_parens: false,
32887 quoted: false,
32888 span: None,
32889 inferred_type: None,
32890 })));
32891 }
32892 (Some(first_expr), false, false)
32893 };
32894 let ignore_nulls = if self.match_token(TokenType::Ignore)
32896 && self.match_token(TokenType::Nulls)
32897 {
32898 Some(true)
32899 } else if self.match_token(TokenType::Respect) && self.match_token(TokenType::Nulls)
32900 {
32901 Some(false)
32902 } else {
32903 None
32904 };
32905 self.expect(TokenType::RParen)?;
32906 let filter = self.parse_filter_clause()?;
32907 let ignore_nulls = if ignore_nulls.is_some() {
32909 ignore_nulls
32910 } else if self.match_keywords(&[TokenType::Ignore, TokenType::Nulls]) {
32911 Some(true)
32912 } else if self.match_keywords(&[TokenType::Respect, TokenType::Nulls]) {
32913 Some(false)
32914 } else {
32915 None
32916 };
32917 Ok(Expression::Count(Box::new(CountFunc {
32918 this,
32919 star,
32920 distinct,
32921 filter,
32922 ignore_nulls,
32923 original_name: Some(name.to_string()),
32924 inferred_type: None,
32925 })))
32926 }
32927
32928 "LIST" => {
32930 let is_materialize = matches!(
32931 self.config.dialect,
32932 Some(crate::dialects::DialectType::Materialize)
32933 );
32934 if is_materialize && self.check(TokenType::Select) {
32935 let query = self.parse_select()?;
32936 self.expect(TokenType::RParen)?;
32937 return Ok(Expression::List(Box::new(List {
32938 expressions: vec![query],
32939 })));
32940 }
32941 let distinct = self.match_token(TokenType::Distinct);
32943 let args = if self.check(TokenType::RParen) {
32944 Vec::new()
32945 } else {
32946 self.parse_function_arguments()?
32947 };
32948 let order_by = if self.match_token(TokenType::Order) {
32949 self.expect(TokenType::By)?;
32950 self.parse_order_by_list()?
32951 } else {
32952 Vec::new()
32953 };
32954 let limit = if self.match_token(TokenType::Limit) {
32955 Some(Box::new(self.parse_expression()?))
32956 } else {
32957 None
32958 };
32959 self.expect(TokenType::RParen)?;
32960 let filter = self.parse_filter_clause()?;
32961
32962 if distinct || !order_by.is_empty() || limit.is_some() || filter.is_some() {
32963 Ok(Expression::AggregateFunction(Box::new(AggregateFunction {
32964 name: name.to_string(),
32965 args,
32966 distinct,
32967 filter,
32968 order_by,
32969 limit,
32970 ignore_nulls: None,
32971 inferred_type: None,
32972 })))
32973 } else {
32974 Ok(Expression::Function(Box::new(Function {
32975 name: name.to_string(),
32976 args,
32977 distinct: false,
32978 trailing_comments: Vec::new(),
32979 use_bracket_syntax: false,
32980 no_parens: false,
32981 quoted: false,
32982 span: None,
32983 inferred_type: None,
32984 })))
32985 }
32986 }
32987
32988 "MAP" => {
32990 let is_materialize = matches!(
32991 self.config.dialect,
32992 Some(crate::dialects::DialectType::Materialize)
32993 );
32994 if is_materialize && self.check(TokenType::Select) {
32995 let query = self.parse_select()?;
32996 self.expect(TokenType::RParen)?;
32997 return Ok(Expression::ToMap(Box::new(ToMap {
32998 this: Box::new(query),
32999 })));
33000 }
33001 let args = if self.check(TokenType::RParen) {
33003 Vec::new()
33004 } else {
33005 self.parse_function_arguments()?
33006 };
33007 self.expect(TokenType::RParen)?;
33008 Ok(Expression::Function(Box::new(Function {
33009 name: name.to_string(),
33010 args,
33011 distinct: false,
33012 trailing_comments: Vec::new(),
33013 use_bracket_syntax: false,
33014 no_parens: false,
33015 quoted: false,
33016 span: None,
33017 inferred_type: None,
33018 })))
33019 }
33020
33021 "ARRAY" => {
33024 if self.check(TokenType::Select) {
33026 let query = self.parse_select()?;
33027 self.expect(TokenType::RParen)?;
33028 return Ok(Expression::Function(Box::new(Function {
33031 name: name.to_string(),
33032 args: vec![query],
33033 distinct: false,
33034 trailing_comments: Vec::new(),
33035 use_bracket_syntax: false,
33036 no_parens: false,
33037 quoted: false,
33038 span: None,
33039 inferred_type: None,
33040 })));
33041 }
33042 if self.check(TokenType::LParen) {
33045 let saved_pos = self.current;
33048 self.skip(); if self.check(TokenType::Select) || self.check(TokenType::With) {
33052 let inner_query = self.parse_statement()?;
33053 self.expect(TokenType::RParen)?; let limit = if self.match_token(TokenType::Limit) {
33057 let expr = self.parse_expression()?;
33058 Some(Limit {
33059 this: expr,
33060 percent: false,
33061 comments: Vec::new(),
33062 })
33063 } else {
33064 None
33065 };
33066
33067 let offset = if self.match_token(TokenType::Offset) {
33068 let expr = self.parse_expression()?;
33069 let rows = if self.match_token(TokenType::Row)
33070 || self.match_token(TokenType::Rows)
33071 {
33072 Some(true)
33073 } else {
33074 None
33075 };
33076 Some(Offset { this: expr, rows })
33077 } else {
33078 None
33079 };
33080
33081 self.expect(TokenType::RParen)?; let subquery = Expression::Subquery(Box::new(Subquery {
33085 this: inner_query,
33086 alias: None,
33087 column_aliases: Vec::new(),
33088 order_by: None,
33089 limit,
33090 offset,
33091 lateral: false,
33092 modifiers_inside: false,
33093 trailing_comments: Vec::new(),
33094 distribute_by: None,
33095 sort_by: None,
33096 cluster_by: None,
33097 inferred_type: None,
33098 }));
33099
33100 return Ok(Expression::Function(Box::new(Function {
33101 name: name.to_string(),
33102 args: vec![subquery],
33103 distinct: false,
33104 trailing_comments: Vec::new(),
33105 use_bracket_syntax: false,
33106 no_parens: false,
33107 quoted: false,
33108 span: None,
33109 inferred_type: None,
33110 })));
33111 } else {
33112 self.current = saved_pos;
33114 }
33115 }
33116 let args = if self.check(TokenType::RParen) {
33119 Vec::new()
33120 } else {
33121 self.parse_function_arguments()?
33122 };
33123 self.expect(TokenType::RParen)?;
33124 Ok(Expression::Function(Box::new(Function {
33125 name: name.to_string(),
33126 args,
33127 distinct: false,
33128 trailing_comments: Vec::new(),
33129 use_bracket_syntax: false,
33130 no_parens: false,
33131 quoted: false,
33132 span: None,
33133 inferred_type: None,
33134 })))
33135 }
33136
33137 "SUM"
33140 | "AVG"
33141 | "MIN"
33142 | "MAX"
33143 | "ARRAY_AGG"
33144 | "ARRAY_CONCAT_AGG"
33145 | "STDDEV"
33146 | "STDDEV_POP"
33147 | "STDDEV_SAMP"
33148 | "VARIANCE"
33149 | "VAR_POP"
33150 | "VAR_SAMP"
33151 | "MEDIAN"
33152 | "MODE"
33153 | "FIRST"
33154 | "LAST"
33155 | "ANY_VALUE"
33156 | "APPROX_DISTINCT"
33157 | "APPROX_COUNT_DISTINCT"
33158 | "BIT_AND"
33159 | "BIT_OR"
33160 | "BIT_XOR" => {
33161 let distinct = if self.match_token(TokenType::Distinct) {
33162 true
33163 } else {
33164 self.match_token(TokenType::All); false
33166 };
33167
33168 if self.check(TokenType::RParen) {
33171 self.expect(TokenType::RParen)?;
33173 let filter = self.parse_filter_clause()?;
33174 let agg = AggFunc {
33175 ignore_nulls: None,
33176 this: Expression::Null(Null {}), distinct: false,
33178 filter,
33179 order_by: Vec::new(),
33180 having_max: None,
33181 name: Some(name.to_string()),
33182 limit: None,
33183 inferred_type: None,
33184 };
33185 return Ok(match upper_name {
33186 "MODE" => Expression::Mode(Box::new(agg)),
33187 _ => {
33188 if matches!(
33190 self.config.dialect,
33191 Some(crate::dialects::DialectType::ClickHouse)
33192 ) {
33193 Expression::Function(Box::new(Function {
33194 name: name.to_string(),
33195 args: Vec::new(),
33196 distinct: false,
33197 trailing_comments: Vec::new(),
33198 use_bracket_syntax: false,
33199 no_parens: false,
33200 quoted: false,
33201 span: None,
33202 inferred_type: None,
33203 }))
33204 } else {
33205 return Err(self.parse_error(format!(
33206 "{} cannot have zero arguments",
33207 upper_name
33208 )));
33209 }
33210 }
33211 });
33212 }
33213
33214 let first_arg = self.parse_expression_with_clickhouse_alias()?;
33215
33216 if self.match_token(TokenType::Comma) {
33218 let is_ignore_nulls_func = matches!(upper_name, "FIRST" | "LAST" | "ANY_VALUE");
33221
33222 let second_arg = self.parse_expression()?;
33223
33224 if is_ignore_nulls_func && self.check(TokenType::RParen) {
33226 if let Expression::Boolean(BooleanLiteral { value: true }) = &second_arg {
33227 self.expect(TokenType::RParen)?;
33229 let filter = self.parse_filter_clause()?;
33230 let agg = AggFunc {
33231 ignore_nulls: Some(true),
33232 this: first_arg,
33233 distinct,
33234 filter,
33235 order_by: Vec::new(),
33236 having_max: None,
33237 name: Some(name.to_string()),
33238 limit: None,
33239 inferred_type: None,
33240 };
33241 return Ok(match upper_name {
33242 "FIRST" => Expression::First(Box::new(agg)),
33243 "LAST" => Expression::Last(Box::new(agg)),
33244 "ANY_VALUE" => Expression::AnyValue(Box::new(agg)),
33245 _ => unreachable!(
33246 "function name already matched by is_ignore_nulls_func guard"
33247 ),
33248 });
33249 }
33250 }
33251
33252 let mut args = vec![first_arg, second_arg];
33254 while self.match_token(TokenType::Comma) {
33255 args.push(self.parse_expression()?);
33256 }
33257 self.expect(TokenType::RParen)?;
33258 Ok(Expression::Function(Box::new(Function {
33259 name: name.to_string(),
33260 args,
33261 distinct: false,
33262 trailing_comments: Vec::new(),
33263 use_bracket_syntax: false,
33264 no_parens: false,
33265 quoted: false,
33266 span: None,
33267 inferred_type: None,
33268 })))
33269 } else {
33270 let ignore_nulls = if self.match_token(TokenType::Ignore)
33272 && self.match_token(TokenType::Nulls)
33273 {
33274 Some(true)
33275 } else if self.match_token(TokenType::Respect)
33276 && self.match_token(TokenType::Nulls)
33277 {
33278 Some(false)
33279 } else {
33280 None
33281 };
33282
33283 let having_max = if self.match_token(TokenType::Having) {
33286 let is_max = if self.check_keyword_text("MAX") {
33287 self.skip();
33288 true
33289 } else if self.check_keyword_text("MIN") {
33290 self.skip();
33291 false
33292 } else {
33293 return Err(
33294 self.parse_error("Expected MAX or MIN after HAVING in aggregate")
33295 );
33296 };
33297 let expr = self.parse_expression()?;
33298 Some((Box::new(expr), is_max))
33299 } else {
33300 None
33301 };
33302
33303 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
33305 self.parse_order_by_list()?
33306 } else {
33307 Vec::new()
33308 };
33309 let limit = if self.match_token(TokenType::Limit) {
33312 let first = self.parse_expression()?;
33313 if self.match_token(TokenType::Comma) {
33314 let second = self.parse_expression()?;
33315 Some(Box::new(Expression::Tuple(Box::new(Tuple {
33317 expressions: vec![first, second],
33318 }))))
33319 } else {
33320 Some(Box::new(first))
33321 }
33322 } else {
33323 None
33324 };
33325 self.expect(TokenType::RParen)?;
33327 let filter = self.parse_filter_clause()?;
33328 let ignore_nulls = if ignore_nulls.is_some() {
33331 ignore_nulls
33332 } else if self.match_keywords(&[TokenType::Ignore, TokenType::Nulls]) {
33333 Some(true)
33334 } else if self.match_keywords(&[TokenType::Respect, TokenType::Nulls]) {
33335 Some(false)
33336 } else {
33337 None
33338 };
33339 let agg = AggFunc {
33340 ignore_nulls,
33341 this: first_arg,
33342 distinct,
33343 filter,
33344 order_by,
33345 having_max,
33346 name: Some(name.to_string()),
33347 limit,
33348 inferred_type: None,
33349 };
33350 Ok(match upper_name {
33351 "SUM" => Expression::Sum(Box::new(agg)),
33352 "AVG" => Expression::Avg(Box::new(agg)),
33353 "MIN" => Expression::Min(Box::new(agg)),
33354 "MAX" => Expression::Max(Box::new(agg)),
33355 "ARRAY_AGG" => Expression::ArrayAgg(Box::new(agg)),
33356 "ARRAY_CONCAT_AGG" => Expression::ArrayConcatAgg(Box::new(agg)),
33357 "STDDEV" => Expression::Stddev(Box::new(agg)),
33358 "STDDEV_POP" => Expression::StddevPop(Box::new(agg)),
33359 "STDDEV_SAMP" => Expression::StddevSamp(Box::new(agg)),
33360 "VARIANCE" => Expression::Variance(Box::new(agg)),
33361 "VAR_POP" => Expression::VarPop(Box::new(agg)),
33362 "VAR_SAMP" => Expression::VarSamp(Box::new(agg)),
33363 "MEDIAN" => Expression::Median(Box::new(agg)),
33364 "MODE" => Expression::Mode(Box::new(agg)),
33365 "FIRST" => Expression::First(Box::new(agg)),
33366 "LAST" => Expression::Last(Box::new(agg)),
33367 "ANY_VALUE" => Expression::AnyValue(Box::new(agg)),
33368 "APPROX_DISTINCT" => Expression::ApproxDistinct(Box::new(agg)),
33369 "APPROX_COUNT_DISTINCT" => Expression::ApproxCountDistinct(Box::new(agg)),
33370 "BIT_AND" => Expression::BitwiseAndAgg(Box::new(agg)),
33371 "BIT_OR" => Expression::BitwiseOrAgg(Box::new(agg)),
33372 "BIT_XOR" => Expression::BitwiseXorAgg(Box::new(agg)),
33373 _ => unreachable!("aggregate function name already matched in caller"),
33374 })
33375 }
33376 }
33377
33378 "STRING_AGG" => {
33380 let distinct = self.match_token(TokenType::Distinct);
33381 let this = self.parse_expression()?;
33382 let separator = if self.match_token(TokenType::Comma) {
33384 Some(self.parse_expression()?)
33385 } else {
33386 None
33387 };
33388 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
33389 Some(self.parse_order_by_list()?)
33390 } else {
33391 None
33392 };
33393 let limit = if self.match_token(TokenType::Limit) {
33395 Some(Box::new(self.parse_expression()?))
33396 } else {
33397 None
33398 };
33399 self.expect(TokenType::RParen)?;
33400 let filter = self.parse_filter_clause()?;
33401 Ok(Expression::StringAgg(Box::new(StringAggFunc {
33402 this,
33403 separator,
33404 order_by,
33405 distinct,
33406 filter,
33407 limit,
33408 inferred_type: None,
33409 })))
33410 }
33411
33412 "GROUP_CONCAT" => {
33416 let distinct = self.match_token(TokenType::Distinct);
33417 let first = self.parse_expression()?;
33418 let mut exprs = vec![first];
33420 while self.match_token(TokenType::Comma) {
33421 if self.check(TokenType::Order) || self.check(TokenType::Separator) {
33424 break;
33426 }
33427 exprs.push(self.parse_expression()?);
33428 }
33429 let this = if exprs.len() == 1 {
33431 exprs.pop().unwrap()
33432 } else {
33433 Expression::Function(Box::new(Function::new("CONCAT".to_string(), exprs)))
33434 };
33435 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
33437 Some(self.parse_order_by_list()?)
33438 } else {
33439 None
33440 };
33441 let separator = if self.match_token(TokenType::Separator) {
33443 Some(self.parse_expression()?)
33444 } else {
33445 None
33446 };
33447 self.expect(TokenType::RParen)?;
33448 let filter = self.parse_filter_clause()?;
33449 Ok(Expression::GroupConcat(Box::new(GroupConcatFunc {
33450 this,
33451 separator,
33452 order_by,
33453 distinct,
33454 filter,
33455 inferred_type: None,
33456 })))
33457 }
33458
33459 "LISTAGG" => {
33461 let distinct = self.match_token(TokenType::Distinct);
33463 let this = self.parse_expression()?;
33464 let separator = if self.match_token(TokenType::Comma) {
33465 Some(self.parse_expression()?)
33466 } else {
33467 None
33468 };
33469 let on_overflow = if self.match_token(TokenType::On) {
33471 if self.match_identifier("OVERFLOW") {
33472 if self.match_identifier("ERROR") {
33473 Some(ListAggOverflow::Error)
33474 } else if self.match_token(TokenType::Truncate) {
33475 let filler = if self.check(TokenType::String) {
33477 Some(self.parse_expression()?)
33478 } else {
33479 None
33480 };
33481 let with_count = if self.match_token(TokenType::With) {
33483 self.match_identifier("COUNT");
33484 true
33485 } else if self.match_identifier("WITHOUT") {
33486 self.match_identifier("COUNT");
33487 false
33488 } else {
33489 true };
33491 Some(ListAggOverflow::Truncate { filler, with_count })
33492 } else {
33493 None
33494 }
33495 } else {
33496 None
33497 }
33498 } else {
33499 None
33500 };
33501 self.expect(TokenType::RParen)?;
33502 Ok(Expression::ListAgg(Box::new(ListAggFunc {
33504 this,
33505 separator,
33506 on_overflow,
33507 order_by: None,
33508 distinct,
33509 filter: None,
33510 inferred_type: None,
33511 })))
33512 }
33513 _ => unreachable!(
33514 "phase-6 aggregate parser called with non-aggregate family name '{}'",
33515 canonical_upper_name
33516 ),
33517 }
33518 }
33519
33520 fn parse_typed_window_family(
33521 &mut self,
33522 name: &str,
33523 upper_name: &str,
33524 canonical_upper_name: &str,
33525 ) -> Result<Expression> {
33526 match canonical_upper_name {
33527 "ROW_NUMBER" => {
33529 if self.check(TokenType::RParen) {
33530 self.skip();
33531 Ok(Expression::RowNumber(RowNumber))
33532 } else {
33533 let args = self.parse_function_args_list()?;
33535 self.expect(TokenType::RParen)?;
33536 let trailing_comments = self.previous_trailing_comments().to_vec();
33537 Ok(Expression::Function(Box::new(Function {
33538 name: name.to_string(),
33539 args,
33540 distinct: false,
33541 trailing_comments,
33542 use_bracket_syntax: false,
33543 no_parens: false,
33544 quoted: false,
33545 span: None,
33546 inferred_type: None,
33547 })))
33548 }
33549 }
33550 "RANK" => {
33551 let (order_by, args) = if self.check(TokenType::RParen) {
33554 (None, Vec::new())
33556 } else if self.match_token(TokenType::Order) {
33557 self.expect(TokenType::By)?;
33559 (Some(self.parse_order_by()?.expressions), Vec::new())
33560 } else {
33561 let mut args = vec![self.parse_expression()?];
33563 while self.match_token(TokenType::Comma) {
33564 args.push(self.parse_expression()?);
33565 }
33566 (None, args)
33567 };
33568 self.expect(TokenType::RParen)?;
33569 Ok(Expression::Rank(Rank { order_by, args }))
33570 }
33571 "DENSE_RANK" => {
33572 let args = if self.check(TokenType::RParen) {
33574 Vec::new()
33575 } else {
33576 let mut args = vec![self.parse_expression()?];
33577 while self.match_token(TokenType::Comma) {
33578 args.push(self.parse_expression()?);
33579 }
33580 args
33581 };
33582 self.expect(TokenType::RParen)?;
33583 Ok(Expression::DenseRank(DenseRank { args }))
33584 }
33585 "PERCENT_RANK" => {
33586 let (order_by, args) = if self.check(TokenType::RParen) {
33589 (None, Vec::new())
33591 } else if self.match_token(TokenType::Order) {
33592 self.expect(TokenType::By)?;
33594 (Some(self.parse_order_by()?.expressions), Vec::new())
33595 } else {
33596 let mut args = vec![self.parse_expression()?];
33598 while self.match_token(TokenType::Comma) {
33599 args.push(self.parse_expression()?);
33600 }
33601 (None, args)
33602 };
33603 self.expect(TokenType::RParen)?;
33604 Ok(Expression::PercentRank(PercentRank { order_by, args }))
33605 }
33606 "CUME_DIST" => {
33607 let (order_by, args) = if self.check(TokenType::RParen) {
33610 (None, Vec::new())
33612 } else if self.match_token(TokenType::Order) {
33613 self.expect(TokenType::By)?;
33615 (Some(self.parse_order_by()?.expressions), Vec::new())
33616 } else {
33617 let mut args = vec![self.parse_expression()?];
33619 while self.match_token(TokenType::Comma) {
33620 args.push(self.parse_expression()?);
33621 }
33622 (None, args)
33623 };
33624 self.expect(TokenType::RParen)?;
33625 Ok(Expression::CumeDist(CumeDist { order_by, args }))
33626 }
33627
33628 "NTILE" => {
33630 let num_buckets = if self.check(TokenType::RParen) {
33632 None
33633 } else {
33634 Some(self.parse_expression()?)
33635 };
33636
33637 while matches!(
33639 self.config.dialect,
33640 Some(crate::dialects::DialectType::ClickHouse)
33641 ) && self.match_token(TokenType::Comma)
33642 {
33643 let _ = self.parse_expression()?;
33644 }
33645
33646 let order_by = if self.match_token(TokenType::Order) {
33648 self.expect(TokenType::By)?;
33649 Some(self.parse_order_by()?.expressions)
33650 } else {
33651 None
33652 };
33653 self.expect(TokenType::RParen)?;
33654 Ok(Expression::NTile(Box::new(NTileFunc {
33655 num_buckets,
33656 order_by,
33657 })))
33658 }
33659
33660 "LEAD" | "LAG" => {
33662 let this = self.parse_expression()?;
33663 let (offset, default) = if self.match_token(TokenType::Comma) {
33664 let off = self.parse_expression()?;
33665 let def = if self.match_token(TokenType::Comma) {
33666 Some(self.parse_expression()?)
33667 } else {
33668 None
33669 };
33670 (Some(off), def)
33671 } else {
33672 (None, None)
33673 };
33674 let ignore_nulls_inside = if self.match_token(TokenType::Ignore)
33676 && self.match_token(TokenType::Nulls)
33677 {
33678 Some(true)
33679 } else if self.match_token(TokenType::Respect) && self.match_token(TokenType::Nulls)
33680 {
33681 Some(false)
33682 } else {
33683 None
33684 };
33685 self.expect(TokenType::RParen)?;
33686 let ignore_nulls = if ignore_nulls_inside.is_some() {
33688 ignore_nulls_inside
33689 } else if self.match_keywords(&[TokenType::Ignore, TokenType::Nulls]) {
33690 Some(true)
33691 } else if self.match_keywords(&[TokenType::Respect, TokenType::Nulls]) {
33692 Some(false)
33693 } else {
33694 None
33695 };
33696 let func = LeadLagFunc {
33697 this,
33698 offset,
33699 default,
33700 ignore_nulls,
33701 };
33702 Ok(if upper_name == "LEAD" {
33703 Expression::Lead(Box::new(func))
33704 } else {
33705 Expression::Lag(Box::new(func))
33706 })
33707 }
33708
33709 "FIRST_VALUE" | "LAST_VALUE" => {
33711 let this = self.parse_expression()?;
33712 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
33714 self.parse_order_by_list()?
33715 } else {
33716 Vec::new()
33717 };
33718 let mut ignore_nulls_inside = if self.match_token(TokenType::Ignore)
33720 && self.match_token(TokenType::Nulls)
33721 {
33722 Some(true)
33723 } else if self.match_token(TokenType::Respect) && self.match_token(TokenType::Nulls)
33724 {
33725 Some(false) } else {
33727 None
33728 };
33729 if ignore_nulls_inside.is_none() && self.match_token(TokenType::Comma) {
33731 let second_arg = self.parse_expression()?;
33732 if let Expression::Boolean(BooleanLiteral { value: true }) = &second_arg {
33733 ignore_nulls_inside = Some(true);
33734 }
33735 }
33737 self.expect(TokenType::RParen)?;
33738 let ignore_nulls: Option<bool> = if ignore_nulls_inside.is_some() {
33740 ignore_nulls_inside
33741 } else if self.match_keywords(&[TokenType::Ignore, TokenType::Nulls]) {
33742 Some(true)
33743 } else if self.match_keywords(&[TokenType::Respect, TokenType::Nulls]) {
33744 Some(false)
33745 } else {
33746 None
33747 };
33748 let func = ValueFunc {
33749 this,
33750 ignore_nulls,
33751 order_by,
33752 };
33753 Ok(if upper_name == "FIRST_VALUE" {
33754 Expression::FirstValue(Box::new(func))
33755 } else {
33756 Expression::LastValue(Box::new(func))
33757 })
33758 }
33759
33760 "NTH_VALUE" => {
33762 let this = self.parse_expression()?;
33763 self.expect(TokenType::Comma)?;
33764 let offset = self.parse_expression()?;
33765 let ignore_nulls_inside = if self.match_token(TokenType::Ignore)
33767 && self.match_token(TokenType::Nulls)
33768 {
33769 Some(true)
33770 } else if self.match_token(TokenType::Respect) && self.match_token(TokenType::Nulls)
33771 {
33772 Some(false)
33773 } else {
33774 None
33775 };
33776 self.expect(TokenType::RParen)?;
33777 let from_first = if self.match_keywords(&[TokenType::From, TokenType::First]) {
33779 Some(true)
33780 } else if self.match_keywords(&[TokenType::From, TokenType::Last]) {
33781 Some(false)
33782 } else {
33783 None
33784 };
33785 let ignore_nulls: Option<bool> = if ignore_nulls_inside.is_some() {
33787 ignore_nulls_inside
33788 } else if self.match_keywords(&[TokenType::Ignore, TokenType::Nulls]) {
33789 Some(true)
33790 } else if self.match_keywords(&[TokenType::Respect, TokenType::Nulls]) {
33791 Some(false)
33792 } else {
33793 None
33794 };
33795 Ok(Expression::NthValue(Box::new(NthValueFunc {
33796 this,
33797 offset,
33798 ignore_nulls,
33799 from_first,
33800 })))
33801 }
33802 _ => unreachable!(
33803 "phase-6 window parser called with non-window family name '{}'",
33804 canonical_upper_name
33805 ),
33806 }
33807 }
33808
33809 fn parse_typed_json_family(
33810 &mut self,
33811 name: &str,
33812 upper_name: &str,
33813 canonical_upper_name: &str,
33814 ) -> Result<Expression> {
33815 match canonical_upper_name {
33816 "JSON_EXTRACT" | "JSON_EXTRACT_SCALAR" | "JSON_QUERY" | "JSON_VALUE" => {
33818 let this = self.parse_expression()?;
33819 let path = if self.match_token(TokenType::Comma) {
33821 self.parse_expression()?
33822 } else {
33823 Expression::Literal(Box::new(Literal::String("$".to_string())))
33825 };
33826
33827 if self.check(TokenType::Comma)
33830 && !self.check_identifier("WITH")
33831 && !self.check_identifier("WITHOUT")
33832 && !self.check_identifier("KEEP")
33833 && !self.check_identifier("OMIT")
33834 && !self.check_identifier("NULL")
33835 && !self.check_identifier("ERROR")
33836 && !self.check_identifier("EMPTY")
33837 && !self.check(TokenType::Returning)
33838 {
33839 let mut args = vec![this, path];
33840 while self.match_token(TokenType::Comma) {
33841 args.push(self.parse_expression()?);
33842 }
33843 self.expect(TokenType::RParen)?;
33844 let func_expr = Expression::Function(Box::new(Function {
33845 name: name.to_string(),
33846 args,
33847 distinct: false,
33848 trailing_comments: Vec::new(),
33849 use_bracket_syntax: false,
33850 no_parens: false,
33851 quoted: false,
33852 span: None,
33853 inferred_type: None,
33854 }));
33855 if matches!(
33857 self.config.dialect,
33858 Some(crate::dialects::DialectType::Exasol)
33859 ) && self.check_identifier("EMITS")
33860 {
33861 self.skip(); if let Some(schema) = self.parse_schema()? {
33863 return Ok(Expression::FunctionEmits(Box::new(FunctionEmits {
33864 this: func_expr,
33865 emits: schema,
33866 })));
33867 }
33868 }
33869 return Ok(func_expr);
33870 }
33871
33872 let mut wrapper_option: Option<String> = None;
33878 let mut quotes_option: Option<String> = None;
33879 let mut on_scalar_string = false;
33880 let mut on_error: Option<String> = None;
33881 let mut returning: Option<DataType> = None;
33882
33883 while !self.check(TokenType::RParen) {
33885 if self.match_text_seq(&["WITH", "UNCONDITIONAL", "ARRAY", "WRAPPER"]) {
33887 wrapper_option = Some("WITH UNCONDITIONAL ARRAY WRAPPER".to_string());
33888 } else if self.match_text_seq(&["WITH", "CONDITIONAL", "ARRAY", "WRAPPER"]) {
33889 wrapper_option = Some("WITH CONDITIONAL ARRAY WRAPPER".to_string());
33890 } else if self.match_text_seq(&["WITH", "UNCONDITIONAL", "WRAPPER"]) {
33891 wrapper_option = Some("WITH UNCONDITIONAL WRAPPER".to_string());
33892 } else if self.match_text_seq(&["WITH", "CONDITIONAL", "WRAPPER"]) {
33893 wrapper_option = Some("WITH CONDITIONAL WRAPPER".to_string());
33894 } else if self.match_text_seq(&["WITH", "ARRAY", "WRAPPER"]) {
33895 wrapper_option = Some("WITH ARRAY WRAPPER".to_string());
33896 } else if self.match_text_seq(&["WITH", "WRAPPER"]) {
33897 wrapper_option = Some("WITH WRAPPER".to_string());
33898 } else if self.match_text_seq(&["WITHOUT", "CONDITIONAL", "ARRAY", "WRAPPER"]) {
33900 wrapper_option = Some("WITHOUT CONDITIONAL ARRAY WRAPPER".to_string());
33901 } else if self.match_text_seq(&["WITHOUT", "CONDITIONAL", "WRAPPER"]) {
33902 wrapper_option = Some("WITHOUT CONDITIONAL WRAPPER".to_string());
33903 } else if self.match_text_seq(&["WITHOUT", "ARRAY", "WRAPPER"]) {
33904 wrapper_option = Some("WITHOUT ARRAY WRAPPER".to_string());
33905 } else if self.match_text_seq(&["WITHOUT", "WRAPPER"]) {
33906 wrapper_option = Some("WITHOUT WRAPPER".to_string());
33907 } else if self.match_text_seq(&["KEEP", "QUOTES"]) {
33908 quotes_option = Some("KEEP QUOTES".to_string());
33910 } else if self.match_text_seq(&["OMIT", "QUOTES", "ON", "SCALAR", "STRING"]) {
33911 quotes_option = Some("OMIT QUOTES".to_string());
33913 on_scalar_string = true;
33914 } else if self.match_text_seq(&["OMIT", "QUOTES"]) {
33915 quotes_option = Some("OMIT QUOTES".to_string());
33917 } else if self.match_text_seq(&["NULL", "ON", "ERROR"]) {
33918 on_error = Some("NULL ON ERROR".to_string());
33919 } else if self.match_text_seq(&["ERROR", "ON", "ERROR"]) {
33920 on_error = Some("ERROR ON ERROR".to_string());
33921 } else if self.match_text_seq(&["EMPTY", "ON", "ERROR"]) {
33922 on_error = Some("EMPTY ON ERROR".to_string());
33923 } else if self.match_token(TokenType::Returning) {
33924 returning = Some(self.parse_data_type()?);
33926 } else {
33927 break;
33929 }
33930 }
33931
33932 self.expect(TokenType::RParen)?;
33933 let func = JsonExtractFunc {
33934 this,
33935 path,
33936 returning,
33937 arrow_syntax: false,
33938 hash_arrow_syntax: false,
33939 wrapper_option,
33940 quotes_option,
33941 on_scalar_string,
33942 on_error,
33943 };
33944 Ok(match upper_name {
33945 "JSON_EXTRACT" => Expression::JsonExtract(Box::new(func)),
33946 "JSON_EXTRACT_SCALAR" => Expression::JsonExtractScalar(Box::new(func)),
33947 "JSON_QUERY" => Expression::JsonQuery(Box::new(func)),
33948 "JSON_VALUE" => Expression::JsonValue(Box::new(func)),
33949 _ => unreachable!("JSON function name already matched in caller"),
33950 })
33951 }
33952 "JSON_ARRAY_LENGTH" | "JSON_KEYS" | "JSON_TYPE" | "TO_JSON" | "PARSE_JSON" => {
33956 let this = self.parse_expression()?;
33957 let this = self.maybe_clickhouse_alias(this);
33959
33960 if self.match_token(TokenType::Comma) {
33962 let mut all_args = vec![this];
33964 let remaining = self.parse_function_arguments()?;
33965 all_args.extend(remaining);
33966 self.expect(TokenType::RParen)?;
33967 Ok(Expression::Function(Box::new(Function {
33968 name: name.to_string(),
33969 args: all_args,
33970 distinct: false,
33971 trailing_comments: Vec::new(),
33972 use_bracket_syntax: false,
33973 no_parens: false,
33974 quoted: false,
33975 span: None,
33976 inferred_type: None,
33977 })))
33978 } else {
33979 self.expect(TokenType::RParen)?;
33981 let func = UnaryFunc::new(this);
33982 Ok(match canonical_upper_name {
33983 "JSON_ARRAY_LENGTH" => Expression::JsonArrayLength(Box::new(func)),
33984 "JSON_KEYS" => Expression::JsonKeys(Box::new(func)),
33985 "JSON_TYPE" => Expression::JsonType(Box::new(func)),
33986 "TO_JSON" => Expression::ToJson(Box::new(func)),
33987 "PARSE_JSON" => Expression::ParseJson(Box::new(func)),
33988 _ => unreachable!("JSON function name already matched in caller"),
33989 })
33990 }
33991 }
33992
33993 "JSON_OBJECT" => {
33995 let mut pairs = Vec::new();
33996 let mut star = false;
33997 if !self.check(TokenType::RParen) {
33998 if self.check(TokenType::Star) && self.check_next(TokenType::RParen) {
34000 self.skip(); star = true;
34002 } else {
34003 loop {
34004 let has_key_keyword = self.match_token(TokenType::Key);
34006 let key = if let Some(s) = self.parse_string()? {
34008 s
34009 } else {
34010 self.parse_column()?.ok_or_else(|| {
34012 self.parse_error("Expected key expression in JSON_OBJECT")
34013 })?
34014 };
34015
34016 let has_separator = self.match_token(TokenType::Colon)
34018 || self.match_identifier("VALUE")
34019 || (has_key_keyword && self.match_token(TokenType::Is));
34020
34021 if has_separator {
34022 let value = self.parse_bitwise()?.ok_or_else(|| {
34023 self.parse_error("Expected value expression in JSON_OBJECT")
34024 })?;
34025 let value_with_format = if self.match_text_seq(&["FORMAT", "JSON"])
34027 {
34028 Expression::JSONFormat(Box::new(JSONFormat {
34029 this: Some(Box::new(value)),
34030 options: Vec::new(),
34031 is_json: None,
34032 to_json: None,
34033 }))
34034 } else {
34035 value
34036 };
34037 pairs.push((key, value_with_format));
34038 } else {
34039 if self.match_token(TokenType::Comma) {
34041 let value = self.parse_bitwise()?.ok_or_else(|| {
34042 self.parse_error("Expected value expression in JSON_OBJECT")
34043 })?;
34044 pairs.push((key, value));
34045 } else {
34046 return Err(self
34047 .parse_error("Expected value expression in JSON_OBJECT"));
34048 }
34049 }
34050 if !self.match_token(TokenType::Comma) {
34051 break;
34052 }
34053 }
34054 }
34055 }
34056 let null_handling = if self.match_token(TokenType::Null) {
34058 self.match_token(TokenType::On);
34059 self.match_token(TokenType::Null);
34060 Some(JsonNullHandling::NullOnNull)
34061 } else if self.match_identifier("ABSENT") {
34062 self.match_token(TokenType::On);
34063 self.match_token(TokenType::Null);
34064 Some(JsonNullHandling::AbsentOnNull)
34065 } else {
34066 None
34067 };
34068 let with_unique_keys = if self.match_token(TokenType::With) {
34069 self.match_token(TokenType::Unique);
34070 self.match_identifier("KEYS");
34071 true
34072 } else {
34073 false
34074 };
34075 let (returning_type, format_json, encoding) = if self
34077 .match_token(TokenType::Returning)
34078 {
34079 let return_type = self.parse_data_type()?;
34080 let has_format_json = if self.match_token(TokenType::Format) {
34082 let _ = self.match_token(TokenType::Json) || self.match_identifier("JSON");
34084 true
34085 } else {
34086 false
34087 };
34088 let enc = if self.match_identifier("ENCODING") {
34090 Some(self.expect_identifier_or_keyword()?)
34091 } else {
34092 None
34093 };
34094 (Some(return_type), has_format_json, enc)
34095 } else {
34096 (None, false, None)
34097 };
34098 self.expect(TokenType::RParen)?;
34099 Ok(Expression::JsonObject(Box::new(JsonObjectFunc {
34100 pairs,
34101 null_handling,
34102 with_unique_keys,
34103 returning_type,
34104 format_json,
34105 encoding,
34106 star,
34107 })))
34108 }
34109
34110 "JSON_ARRAY" => {
34113 let mut expressions = Vec::new();
34114 if !self.check(TokenType::RParen) {
34115 loop {
34116 let expr = self.parse_bitwise()?.unwrap_or(Expression::Null(Null));
34117 let expr_with_format = if self.match_text_seq(&["FORMAT", "JSON"]) {
34119 Expression::JSONFormat(Box::new(JSONFormat {
34120 this: Some(Box::new(expr)),
34121 options: Vec::new(),
34122 is_json: None,
34123 to_json: None,
34124 }))
34125 } else {
34126 expr
34127 };
34128 expressions.push(expr_with_format);
34129 if !self.match_token(TokenType::Comma) {
34130 break;
34131 }
34132 }
34133 }
34134 let null_handling = if self.match_text_seq(&["NULL", "ON", "NULL"]) {
34136 Some(Box::new(Expression::Var(Box::new(Var {
34137 this: "NULL ON NULL".to_string(),
34138 }))))
34139 } else if self.match_text_seq(&["ABSENT", "ON", "NULL"]) {
34140 Some(Box::new(Expression::Var(Box::new(Var {
34141 this: "ABSENT ON NULL".to_string(),
34142 }))))
34143 } else {
34144 None
34145 };
34146 let return_type = if self.match_token(TokenType::Returning) {
34148 let dt = self.parse_data_type()?;
34149 Some(Box::new(Expression::DataType(dt)))
34150 } else {
34151 None
34152 };
34153 let strict = if self.match_identifier("STRICT") {
34155 Some(Box::new(Expression::Boolean(BooleanLiteral {
34156 value: true,
34157 })))
34158 } else {
34159 None
34160 };
34161 self.expect(TokenType::RParen)?;
34162 Ok(Expression::JSONArray(Box::new(JSONArray {
34163 expressions,
34164 null_handling,
34165 return_type,
34166 strict,
34167 })))
34168 }
34169
34170 "JSON_ARRAYAGG" => {
34173 let this = self.parse_bitwise()?.unwrap_or(Expression::Null(Null));
34174 let this_with_format = if self.match_text_seq(&["FORMAT", "JSON"]) {
34176 Expression::JSONFormat(Box::new(JSONFormat {
34177 this: Some(Box::new(this)),
34178 options: Vec::new(),
34179 is_json: None,
34180 to_json: None,
34181 }))
34182 } else {
34183 this
34184 };
34185 let order = if self.match_token(TokenType::Order) {
34187 self.match_token(TokenType::By);
34188 let mut order_exprs = Vec::new();
34190 loop {
34191 if let Some(ordered) = self.parse_ordered_item()? {
34192 order_exprs.push(ordered);
34193 } else {
34194 break;
34195 }
34196 if !self.match_token(TokenType::Comma) {
34197 break;
34198 }
34199 }
34200 if !order_exprs.is_empty() {
34201 Some(Box::new(Expression::OrderBy(Box::new(OrderBy {
34202 expressions: order_exprs,
34203 siblings: false,
34204 comments: Vec::new(),
34205 }))))
34206 } else {
34207 None
34208 }
34209 } else {
34210 None
34211 };
34212 let null_handling = if self.match_text_seq(&["NULL", "ON", "NULL"]) {
34214 Some(Box::new(Expression::Var(Box::new(Var {
34215 this: "NULL ON NULL".to_string(),
34216 }))))
34217 } else if self.match_text_seq(&["ABSENT", "ON", "NULL"]) {
34218 Some(Box::new(Expression::Var(Box::new(Var {
34219 this: "ABSENT ON NULL".to_string(),
34220 }))))
34221 } else {
34222 None
34223 };
34224 let return_type = if self.match_token(TokenType::Returning) {
34226 let dt = self.parse_data_type()?;
34227 Some(Box::new(Expression::DataType(dt)))
34228 } else {
34229 None
34230 };
34231 let strict = if self.match_identifier("STRICT") {
34233 Some(Box::new(Expression::Boolean(BooleanLiteral {
34234 value: true,
34235 })))
34236 } else {
34237 None
34238 };
34239 self.expect(TokenType::RParen)?;
34240 Ok(Expression::JSONArrayAgg(Box::new(JSONArrayAgg {
34241 this: Box::new(this_with_format),
34242 order,
34243 null_handling,
34244 return_type,
34245 strict,
34246 })))
34247 }
34248
34249 "JSON_OBJECTAGG" => {
34252 let _has_key_keyword = self.match_token(TokenType::Key);
34254 let key = self.parse_column()?.unwrap_or(Expression::Null(Null));
34256
34257 let _ = self.match_token(TokenType::Colon)
34259 || self.match_token(TokenType::Comma)
34260 || self.match_identifier("VALUE");
34261
34262 let value = self.parse_bitwise()?.unwrap_or(Expression::Null(Null));
34263 let value_with_format = if self.match_text_seq(&["FORMAT", "JSON"]) {
34265 Expression::JSONFormat(Box::new(JSONFormat {
34266 this: Some(Box::new(value)),
34267 options: Vec::new(),
34268 is_json: None,
34269 to_json: None,
34270 }))
34271 } else {
34272 value
34273 };
34274 let null_handling = if self.match_text_seq(&["NULL", "ON", "NULL"]) {
34276 Some(Box::new(Expression::Var(Box::new(Var {
34277 this: "NULL ON NULL".to_string(),
34278 }))))
34279 } else if self.match_text_seq(&["ABSENT", "ON", "NULL"]) {
34280 Some(Box::new(Expression::Var(Box::new(Var {
34281 this: "ABSENT ON NULL".to_string(),
34282 }))))
34283 } else {
34284 None
34285 };
34286 let unique_keys = if self.match_text_seq(&["WITH", "UNIQUE"]) {
34288 self.match_identifier("KEYS");
34289 Some(Box::new(Expression::Boolean(BooleanLiteral {
34290 value: true,
34291 })))
34292 } else if self.match_text_seq(&["WITHOUT", "UNIQUE"]) {
34293 self.match_identifier("KEYS");
34294 Some(Box::new(Expression::Boolean(BooleanLiteral {
34295 value: false,
34296 })))
34297 } else {
34298 None
34299 };
34300 let return_type = if self.match_token(TokenType::Returning) {
34302 let dt = self.parse_data_type()?;
34303 Some(Box::new(Expression::DataType(dt)))
34304 } else {
34305 None
34306 };
34307 self.expect(TokenType::RParen)?;
34308 Ok(Expression::JSONObjectAgg(Box::new(JSONObjectAgg {
34309 expressions: vec![Expression::JSONKeyValue(Box::new(JSONKeyValue {
34310 this: Box::new(key),
34311 expression: Box::new(value_with_format),
34312 }))],
34313 null_handling,
34314 unique_keys,
34315 return_type,
34316 encoding: None,
34317 })))
34318 }
34319
34320 "JSON_TABLE" => {
34323 let this = self.parse_bitwise()?.unwrap_or(Expression::Null(Null));
34325 let this_with_format = if self.match_text_seq(&["FORMAT", "JSON"]) {
34327 Expression::JSONFormat(Box::new(JSONFormat {
34328 this: Some(Box::new(this)),
34329 options: Vec::new(),
34330 is_json: None,
34331 to_json: None,
34332 }))
34333 } else {
34334 this
34335 };
34336
34337 let path = if self.match_token(TokenType::Comma) {
34339 if let Some(s) = self.parse_string()? {
34340 Some(Box::new(s))
34341 } else {
34342 None
34343 }
34344 } else {
34345 None
34346 };
34347
34348 let error_handling =
34351 if self.match_identifier("ERROR") && self.match_text_seq(&["ON", "ERROR"]) {
34352 Some(Box::new(Expression::Var(Box::new(Var {
34353 this: "ERROR ON ERROR".to_string(),
34354 }))))
34355 } else if self.match_text_seq(&["NULL", "ON", "ERROR"]) {
34356 Some(Box::new(Expression::Var(Box::new(Var {
34357 this: "NULL ON ERROR".to_string(),
34358 }))))
34359 } else {
34360 None
34361 };
34362
34363 let empty_handling =
34365 if self.match_identifier("ERROR") && self.match_text_seq(&["ON", "EMPTY"]) {
34366 Some(Box::new(Expression::Var(Box::new(Var {
34367 this: "ERROR ON EMPTY".to_string(),
34368 }))))
34369 } else if self.match_text_seq(&["NULL", "ON", "EMPTY"]) {
34370 Some(Box::new(Expression::Var(Box::new(Var {
34371 this: "NULL ON EMPTY".to_string(),
34372 }))))
34373 } else {
34374 None
34375 };
34376
34377 let schema = self.parse_json_table_columns()?;
34379
34380 self.expect(TokenType::RParen)?;
34381
34382 Ok(Expression::JSONTable(Box::new(JSONTable {
34383 this: Box::new(this_with_format),
34384 schema: schema.map(Box::new),
34385 path,
34386 error_handling,
34387 empty_handling,
34388 })))
34389 }
34390 _ => unreachable!(
34391 "phase-6 json parser called with non-json family name '{}'",
34392 canonical_upper_name
34393 ),
34394 }
34395 }
34396
34397 fn parse_typed_translate_teradata_family(
34398 &mut self,
34399 name: &str,
34400 _upper_name: &str,
34401 canonical_upper_name: &str,
34402 ) -> Result<Expression> {
34403 match canonical_upper_name {
34404 "TRANSLATE"
34406 if matches!(
34407 self.config.dialect,
34408 Some(crate::dialects::DialectType::Teradata)
34409 ) =>
34410 {
34411 let this = self.parse_expression()?;
34412 if self.match_token(TokenType::Using) {
34413 let expression = self.parse_expression()?;
34414 let with_error = if self.match_text_seq(&["WITH", "ERROR"]) {
34415 Some(Box::new(Expression::Boolean(BooleanLiteral {
34416 value: true,
34417 })))
34418 } else {
34419 None
34420 };
34421 self.expect(TokenType::RParen)?;
34422 Ok(Expression::TranslateCharacters(Box::new(
34423 TranslateCharacters {
34424 this: Box::new(this),
34425 expression: Box::new(expression),
34426 with_error,
34427 },
34428 )))
34429 } else {
34430 let mut args = vec![this];
34431 if self.match_token(TokenType::Comma) {
34432 let mut rest = self.parse_expression_list()?;
34433 args.append(&mut rest);
34434 }
34435 self.expect(TokenType::RParen)?;
34436 Ok(Expression::Function(Box::new(Function {
34437 name: name.to_string(),
34438 args,
34439 distinct: false,
34440 trailing_comments: Vec::new(),
34441 use_bracket_syntax: false,
34442 no_parens: false,
34443 quoted: false,
34444 span: None,
34445 inferred_type: None,
34446 })))
34447 }
34448 }
34449
34450 _ => unreachable!(
34451 "phase-6 translate parser called with non-translate family name '{}'",
34452 canonical_upper_name
34453 ),
34454 }
34455 }
34456
34457 fn parse_generic_function(&mut self, name: &str, quoted: bool) -> Result<Expression> {
34459 let is_known_agg = Self::is_aggregate_function(name);
34460
34461 let (args, distinct) = if self.check(TokenType::RParen) {
34462 (Vec::new(), false)
34463 } else if self.check(TokenType::Star) {
34464 if self.check_next_identifier("COLUMNS")
34466 && self
34467 .tokens
34468 .get(self.current + 2)
34469 .map(|t| t.token_type == TokenType::LParen)
34470 .unwrap_or(false)
34471 {
34472 (self.parse_function_arguments()?, false)
34474 } else {
34475 self.skip(); let star = self.parse_star_modifiers(None)?;
34479 let mut args = vec![Expression::Star(star)];
34480 if self.match_token(TokenType::Comma) {
34482 let rest = self.parse_function_arguments()?;
34483 args.extend(rest);
34484 }
34485 (args, false)
34486 }
34487 } else if self.check(TokenType::Distinct)
34488 && !self.check_next(TokenType::Comma)
34489 && !self.check_next(TokenType::RParen)
34490 {
34491 self.skip(); (self.parse_function_arguments()?, true)
34495 } else if is_known_agg && self.match_token(TokenType::All) {
34496 (self.parse_function_arguments()?, false)
34498 } else {
34499 (self.parse_function_arguments()?, false)
34500 };
34501
34502 let (ignore_nulls, order_by, agg_limit) = if is_known_agg {
34504 let ignore_nulls = if self.match_token(TokenType::Ignore)
34505 && self.match_token(TokenType::Nulls)
34506 {
34507 Some(true)
34508 } else if self.match_token(TokenType::Respect) && self.match_token(TokenType::Nulls) {
34509 Some(false)
34510 } else {
34511 None
34512 };
34513
34514 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
34515 self.parse_order_by_list()?
34516 } else {
34517 Vec::new()
34518 };
34519 let limit = if self.match_token(TokenType::Limit) {
34520 Some(Box::new(self.parse_expression()?))
34521 } else {
34522 None
34523 };
34524 (ignore_nulls, order_by, limit)
34525 } else {
34526 (None, Vec::new(), None)
34527 };
34528
34529 if matches!(
34531 self.config.dialect,
34532 Some(crate::dialects::DialectType::ClickHouse)
34533 ) && self.check(TokenType::Settings)
34534 && self.current + 2 < self.tokens.len()
34535 && (self.tokens[self.current + 1].token_type == TokenType::Var
34536 || self.tokens[self.current + 1].token_type == TokenType::Identifier)
34537 && self.tokens[self.current + 2].token_type == TokenType::Eq
34538 {
34539 self.skip(); loop {
34541 let _key = if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
34542 self.advance().text
34543 } else {
34544 break;
34545 };
34546 if self.match_token(TokenType::Eq) {
34547 let _value = self.parse_primary()?;
34548 }
34549 if !self.match_token(TokenType::Comma) {
34550 break;
34551 }
34552 }
34553 }
34554
34555 self.expect(TokenType::RParen)?;
34556 let trailing_comments = self.previous_trailing_comments().to_vec();
34557
34558 if self.match_identifier("WITHIN") {
34560 if self.match_identifier("GROUP") {
34561 self.expect(TokenType::LParen)?;
34562 self.expect(TokenType::Order)?;
34563 self.expect(TokenType::By)?;
34564 let within_order = self.parse_order_by_list()?;
34565 self.expect(TokenType::RParen)?;
34566
34567 let func_expr = Expression::AggregateFunction(Box::new(AggregateFunction {
34568 name: name.to_string(),
34569 args,
34570 distinct,
34571 filter: None,
34572 order_by: Vec::new(),
34573 limit: None,
34574 ignore_nulls: None,
34575 inferred_type: None,
34576 }));
34577
34578 let within = Expression::WithinGroup(Box::new(WithinGroup {
34579 this: func_expr,
34580 order_by: within_order,
34581 }));
34582
34583 let filter = self.parse_filter_clause()?;
34585 if let Some(filter_expr) = filter {
34586 return Ok(Expression::AggregateFunction(Box::new(AggregateFunction {
34587 name: format!("__WITHIN_GROUP_{}", name),
34588 args: vec![within, filter_expr],
34589 distinct: false,
34590 filter: None,
34591 order_by: Vec::new(),
34592 limit: None,
34593 ignore_nulls: None,
34594 inferred_type: None,
34595 })));
34596 }
34597
34598 return Ok(within);
34599 }
34600 }
34601
34602 let filter = self.parse_filter_clause()?;
34603
34604 let ignore_nulls = if ignore_nulls.is_some() {
34606 ignore_nulls
34607 } else if self.match_keywords(&[TokenType::Ignore, TokenType::Nulls]) {
34608 Some(true)
34609 } else if self.match_keywords(&[TokenType::Respect, TokenType::Nulls]) {
34610 Some(false)
34611 } else {
34612 None
34613 };
34614
34615 if filter.is_some() || is_known_agg || ignore_nulls.is_some() {
34616 Ok(Expression::AggregateFunction(Box::new(AggregateFunction {
34617 name: name.to_string(),
34618 args,
34619 distinct,
34620 filter,
34621 order_by,
34622 limit: agg_limit,
34623 ignore_nulls,
34624 inferred_type: None,
34625 })))
34626 } else {
34627 let mut func = Function::new(name.to_string(), args);
34628 func.distinct = distinct;
34629 func.trailing_comments = trailing_comments;
34630 func.quoted = quoted;
34631 Ok(Expression::Function(Box::new(func)))
34632 }
34633 }
34634
34635 fn maybe_clickhouse_alias(&mut self, expr: Expression) -> Expression {
34637 if matches!(
34638 self.config.dialect,
34639 Some(crate::dialects::DialectType::ClickHouse)
34640 ) && self.check(TokenType::As)
34641 && !self.check_next(TokenType::RParen)
34642 && !self.check_next(TokenType::Comma)
34643 {
34644 let next_idx = self.current + 1;
34645 let is_alias = next_idx < self.tokens.len()
34646 && matches!(
34647 self.tokens[next_idx].token_type,
34648 TokenType::Identifier | TokenType::Var | TokenType::QuotedIdentifier
34649 );
34650 if is_alias {
34651 self.skip(); let alias_token = self.advance();
34653 let alias_name = Identifier {
34654 name: alias_token.text.clone(),
34655 quoted: alias_token.token_type == TokenType::QuotedIdentifier,
34656 trailing_comments: Vec::new(),
34657 span: None,
34658 };
34659 return Expression::Alias(Box::new(crate::expressions::Alias {
34660 this: expr,
34661 alias: alias_name,
34662 column_aliases: Vec::new(),
34663 pre_alias_comments: Vec::new(),
34664 trailing_comments: Vec::new(),
34665 inferred_type: None,
34666 }));
34667 }
34668 }
34669 expr
34670 }
34671
34672 fn parse_expression_with_clickhouse_alias(&mut self) -> Result<Expression> {
34675 let expr = self.parse_expression()?;
34676 Ok(self.maybe_clickhouse_alias(expr))
34677 }
34678
34679 fn parse_function_arguments(&mut self) -> Result<Vec<Expression>> {
34682 let mut args = Vec::new();
34683
34684 loop {
34685 if matches!(
34688 self.config.dialect,
34689 Some(crate::dialects::DialectType::ClickHouse)
34690 ) && self.check(TokenType::Settings)
34691 && self.current + 2 < self.tokens.len()
34692 && (self.tokens[self.current + 1].token_type == TokenType::Var
34693 || self.tokens[self.current + 1].token_type == TokenType::Identifier)
34694 && self.tokens[self.current + 2].token_type == TokenType::Eq
34695 {
34696 break; }
34698
34699 if matches!(
34701 self.config.dialect,
34702 Some(crate::dialects::DialectType::ClickHouse)
34703 ) && (self.check(TokenType::Select) || self.check(TokenType::With))
34704 {
34705 let query = self.parse_statement()?;
34706 args.push(query);
34707 if !self.match_token(TokenType::Comma) {
34708 break;
34709 }
34710 continue;
34711 }
34712
34713 let is_table_or_model_arg = if !self.is_at_end() {
34716 self.check(TokenType::Table) || self.peek().text.eq_ignore_ascii_case("MODEL")
34717 } else {
34718 false
34719 };
34720 let arg = if is_table_or_model_arg {
34721 let prefix = self.peek().text.to_ascii_uppercase();
34722 let saved_pos = self.current;
34723 self.skip(); if !self.is_at_end()
34728 && !self.check(TokenType::FArrow)
34729 && !self.check(TokenType::ColonEq)
34730 {
34731 if let Some(table_expr) = self.parse_table_parts()? {
34733 Expression::TableArgument(Box::new(TableArgument {
34734 prefix,
34735 this: table_expr,
34736 }))
34737 } else {
34738 self.current = saved_pos;
34740 self.parse_expression()?
34741 }
34742 } else {
34743 self.current = saved_pos;
34745 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
34746 let ident_token = self.advance();
34747 let ident_name = ident_token.text.clone();
34748 if self.match_token(TokenType::FArrow) {
34749 let value = self.parse_expression()?;
34750 Expression::NamedArgument(Box::new(NamedArgument {
34751 name: Identifier::new(ident_name),
34752 value,
34753 separator: NamedArgSeparator::DArrow,
34754 }))
34755 } else if self.match_token(TokenType::ColonEq) {
34756 let value = self.parse_expression()?;
34757 Expression::NamedArgument(Box::new(NamedArgument {
34758 name: Identifier::new(ident_name),
34759 value,
34760 separator: NamedArgSeparator::ColonEq,
34761 }))
34762 } else {
34763 self.current = saved_pos;
34764 self.parse_expression()?
34765 }
34766 } else {
34767 self.parse_expression()?
34768 }
34769 }
34770 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
34771 let saved_pos = self.current;
34776
34777 let ident_token = self.advance();
34779 let ident_name = ident_token.text.clone();
34780
34781 if ident_name.eq_ignore_ascii_case("VARIADIC")
34784 && matches!(
34785 self.config.dialect,
34786 Some(crate::dialects::DialectType::PostgreSQL)
34787 | Some(crate::dialects::DialectType::Redshift)
34788 )
34789 {
34790 self.current = saved_pos;
34791 self.parse_expression()?
34792 }
34793 else if !self.is_at_end()
34796 && self.is_type_keyword()
34797 && !self.check(TokenType::FArrow)
34798 && !self.check(TokenType::ColonEq)
34799 {
34800 let type_annotation = self.parse_data_type()?;
34802
34803 if self.match_token(TokenType::Arrow) {
34805 let body = self.parse_expression()?;
34807 Expression::Lambda(Box::new(LambdaExpr {
34808 parameters: vec![Identifier::new(ident_name)],
34809 body,
34810 colon: false,
34811 parameter_types: vec![Some(type_annotation)],
34812 }))
34813 } else {
34814 self.current = saved_pos;
34816 self.parse_expression()?
34817 }
34818 }
34819 else if self.match_token(TokenType::Arrow) {
34821 let body = self.parse_expression()?;
34822 Expression::Lambda(Box::new(LambdaExpr {
34823 parameters: vec![Identifier::new(ident_name)],
34824 body,
34825 colon: false,
34826 parameter_types: Vec::new(),
34827 }))
34828 }
34829 else if self.match_token(TokenType::FArrow) {
34831 let value = self.parse_expression()?;
34833 Expression::NamedArgument(Box::new(NamedArgument {
34834 name: Identifier::new(ident_name),
34835 value,
34836 separator: NamedArgSeparator::DArrow,
34837 }))
34838 } else if self.match_token(TokenType::ColonEq) {
34839 let value = self.parse_expression()?;
34841 Expression::NamedArgument(Box::new(NamedArgument {
34842 name: Identifier::new(ident_name),
34843 value,
34844 separator: NamedArgSeparator::ColonEq,
34845 }))
34846 } else {
34847 self.current = saved_pos;
34849 self.parse_expression()?
34850 }
34851 } else {
34852 self.parse_expression()?
34854 };
34855
34856 let arg = if matches!(
34858 self.config.dialect,
34859 Some(crate::dialects::DialectType::ClickHouse)
34860 ) && self.check(TokenType::As)
34861 && !self.check_next(TokenType::RParen)
34862 && !self.check_next(TokenType::Comma)
34863 {
34864 let next_idx = self.current + 1;
34866 let after_alias_idx = self.current + 2;
34867 let is_alias_token = next_idx < self.tokens.len()
34868 && (matches!(
34869 self.tokens[next_idx].token_type,
34870 TokenType::Identifier | TokenType::Var | TokenType::QuotedIdentifier
34871 ) || self.tokens[next_idx].token_type.is_keyword());
34872 let is_alias = is_alias_token
34874 && after_alias_idx < self.tokens.len()
34875 && matches!(
34876 self.tokens[after_alias_idx].token_type,
34877 TokenType::RParen | TokenType::Comma
34878 );
34879 if is_alias {
34880 self.skip(); let alias_token = self.advance();
34882 let alias_name = if alias_token.token_type == TokenType::QuotedIdentifier {
34883 let mut ident = Identifier::new(alias_token.text.clone());
34884 ident.quoted = true;
34885 ident
34886 } else {
34887 Identifier::new(alias_token.text.clone())
34888 };
34889 Expression::Alias(Box::new(crate::expressions::Alias {
34890 this: arg,
34891 alias: alias_name,
34892 column_aliases: Vec::new(),
34893 pre_alias_comments: Vec::new(),
34894 trailing_comments: Vec::new(),
34895 inferred_type: None,
34896 }))
34897 } else {
34898 arg
34899 }
34900 } else {
34901 arg
34902 };
34903
34904 let arg = self.try_clickhouse_implicit_alias(arg);
34906
34907 let trailing_comments = self.previous_trailing_comments().to_vec();
34909 let arg = if trailing_comments.is_empty() {
34910 arg
34911 } else {
34912 match &arg {
34913 Expression::Literal(_) | Expression::Boolean(_) | Expression::Null(_) => {
34914 Expression::Annotated(Box::new(Annotated {
34915 this: arg,
34916 trailing_comments,
34917 }))
34918 }
34919 _ => arg,
34920 }
34921 };
34922
34923 args.push(arg);
34924
34925 if !self.match_token(TokenType::Comma) {
34926 break;
34927 }
34928 while self.check(TokenType::Comma) {
34931 self.skip();
34932 }
34933 }
34934
34935 if matches!(
34937 self.config.dialect,
34938 Some(crate::dialects::DialectType::ClickHouse)
34939 ) && self.check(TokenType::Settings)
34940 && self.current + 2 < self.tokens.len()
34941 && (self.tokens[self.current + 1].token_type == TokenType::Var
34942 || self.tokens[self.current + 1].token_type == TokenType::Identifier)
34943 && self.tokens[self.current + 2].token_type == TokenType::Eq
34944 {
34945 self.skip(); loop {
34947 let _key = if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
34948 self.advance().text
34949 } else {
34950 break;
34951 };
34952 if self.match_token(TokenType::Eq) {
34953 let _value = self.parse_primary()?;
34954 }
34955 if !self.match_token(TokenType::Comma) {
34956 break;
34957 }
34958 }
34959 }
34960
34961 Ok(args)
34962 }
34963
34964 fn parse_filter_clause(&mut self) -> Result<Option<Expression>> {
34966 if self.match_token(TokenType::Filter) {
34967 self.expect(TokenType::LParen)?;
34968 self.match_token(TokenType::Where);
34970 let filter_expr = self.parse_expression()?;
34971 self.expect(TokenType::RParen)?;
34972 Ok(Some(filter_expr))
34973 } else {
34974 Ok(None)
34975 }
34976 }
34977
34978 fn parse_struct_args(&mut self) -> Result<Vec<Expression>> {
34980 let mut args = Vec::new();
34981
34982 loop {
34983 let expr = self.parse_expression()?;
34984
34985 if self.match_token(TokenType::As) {
34987 let alias = self.expect_identifier_or_keyword()?;
34988 args.push(Expression::Alias(Box::new(Alias {
34989 this: expr,
34990 alias: Identifier::new(alias),
34991 column_aliases: Vec::new(),
34992 pre_alias_comments: Vec::new(),
34993 trailing_comments: Vec::new(),
34994 inferred_type: None,
34995 })));
34996 } else {
34997 args.push(expr);
34998 }
34999
35000 if !self.match_token(TokenType::Comma) {
35001 break;
35002 }
35003 }
35004
35005 Ok(args)
35006 }
35007
35008 fn maybe_parse_over(&mut self, expr: Expression) -> Result<Expression> {
35010 let expr = self.maybe_parse_subscript(expr)?;
35011
35012 let expr = if matches!(
35015 self.config.dialect,
35016 Some(crate::dialects::DialectType::Oracle)
35017 ) {
35018 self.try_parse_oracle_interval_span(expr)?
35019 } else {
35020 expr
35021 };
35022
35023 let expr = if self.check(TokenType::Within) && self.check_next(TokenType::Group) {
35025 self.skip(); self.skip(); self.expect(TokenType::LParen)?;
35028 self.expect(TokenType::Order)?;
35029 self.expect(TokenType::By)?;
35030 let order_by = self.parse_order_by_list()?;
35031 self.expect(TokenType::RParen)?;
35032 Expression::WithinGroup(Box::new(WithinGroup {
35033 this: expr,
35034 order_by,
35035 }))
35036 } else {
35037 expr
35038 };
35039
35040 let expr = if self.match_token(TokenType::Filter) {
35043 self.expect(TokenType::LParen)?;
35044 self.expect(TokenType::Where)?;
35046 let filter_expr = self.parse_expression()?;
35047 self.expect(TokenType::RParen)?;
35048 Expression::Filter(Box::new(Filter {
35049 this: Box::new(expr),
35050 expression: Box::new(filter_expr),
35051 }))
35052 } else {
35053 expr
35054 };
35055
35056 let expr = if matches!(
35060 self.config.dialect,
35061 Some(crate::dialects::DialectType::ClickHouse)
35062 ) && (self.match_keywords(&[TokenType::Ignore, TokenType::Nulls])
35063 || self.match_keywords(&[TokenType::Respect, TokenType::Nulls]))
35064 {
35065 expr
35067 } else {
35068 expr
35069 };
35070
35071 let keep = if self.check(TokenType::Keep) && self.check_next(TokenType::LParen) {
35074 self.skip(); Some(self.parse_keep_clause()?)
35076 } else {
35077 None
35078 };
35079
35080 if self.match_token(TokenType::Over) {
35082 let over = self.parse_over_clause()?;
35083 Ok(Expression::WindowFunction(Box::new(WindowFunction {
35084 this: expr,
35085 over,
35086 keep,
35087 inferred_type: None,
35088 })))
35089 } else if keep.is_some() {
35090 Ok(Expression::WindowFunction(Box::new(WindowFunction {
35093 this: expr,
35094 over: Over {
35095 window_name: None,
35096 partition_by: Vec::new(),
35097 order_by: Vec::new(),
35098 frame: None,
35099 alias: None,
35100 },
35101 keep,
35102 inferred_type: None,
35103 })))
35104 } else {
35105 Ok(expr)
35106 }
35107 }
35108
35109 fn maybe_parse_clickhouse_parameterized_agg(&mut self, expr: Expression) -> Result<Expression> {
35111 if !matches!(
35112 self.config.dialect,
35113 Some(crate::dialects::DialectType::ClickHouse)
35114 ) {
35115 return Ok(expr);
35116 }
35117 if !self.check(TokenType::LParen) {
35118 return Ok(expr);
35119 }
35120
35121 let (name, quoted, params) = match expr {
35122 Expression::Function(func) => (func.name, func.quoted, func.args),
35123 Expression::AggregateFunction(agg) => {
35124 if agg.distinct
35125 || agg.filter.is_some()
35126 || !agg.order_by.is_empty()
35127 || agg.limit.is_some()
35128 || agg.ignore_nulls.is_some()
35129 {
35130 return Ok(Expression::AggregateFunction(agg));
35131 }
35132 (agg.name, false, agg.args)
35133 }
35134 _ => return Ok(expr),
35135 };
35136
35137 self.skip(); let distinct = self.match_token(TokenType::Distinct);
35140 let expressions = if self.check(TokenType::RParen) {
35141 Vec::new()
35142 } else {
35143 self.parse_function_arguments()?
35144 };
35145 self.expect(TokenType::RParen)?;
35146
35147 let ident = Identifier {
35148 name,
35149 quoted,
35150 trailing_comments: Vec::new(),
35151 span: None,
35152 };
35153
35154 let _ = distinct; Ok(Expression::CombinedParameterizedAgg(Box::new(
35158 CombinedParameterizedAgg {
35159 this: Box::new(Expression::Identifier(ident)),
35160 params,
35161 expressions,
35162 },
35163 )))
35164 }
35165
35166 fn parse_keep_clause(&mut self) -> Result<Keep> {
35168 self.expect(TokenType::LParen)?;
35169
35170 if !self.match_identifier("DENSE_RANK") {
35172 return Err(self.parse_error("Expected DENSE_RANK in KEEP clause"));
35173 }
35174
35175 let first = if self.match_token(TokenType::First) {
35177 true
35178 } else if self.match_token(TokenType::Last) {
35179 false
35180 } else {
35181 return Err(self.parse_error("Expected FIRST or LAST in KEEP clause"));
35182 };
35183
35184 self.expect(TokenType::Order)?;
35186 self.expect(TokenType::By)?;
35187
35188 let order_by = self.parse_order_by_list()?;
35189
35190 self.expect(TokenType::RParen)?;
35191
35192 Ok(Keep { first, order_by })
35193 }
35194
35195 fn parse_json_path_operand(&mut self) -> Result<Expression> {
35198 if self.check(TokenType::Dash) {
35200 let dash_pos = self.current;
35201 self.skip(); if self.check(TokenType::Number) {
35203 let token = self.advance();
35204 return Ok(Expression::Neg(Box::new(UnaryOp {
35205 this: Expression::Literal(Box::new(Literal::Number(token.text))),
35206 inferred_type: None,
35207 })));
35208 }
35209 self.current = dash_pos;
35211 }
35212
35213 if self.check(TokenType::Number) {
35215 let token = self.advance();
35216 if let Some(sep_pos) = token.text.find("::") {
35218 let num_part = &token.text[..sep_pos];
35219 let type_name = &token.text[sep_pos + 2..];
35220 let num_expr = Expression::Literal(Box::new(Literal::Number(num_part.to_string())));
35221 let data_type = match type_name {
35222 "BIGINT" => crate::expressions::DataType::BigInt { length: None },
35223 "SMALLINT" => crate::expressions::DataType::SmallInt { length: None },
35224 "TINYINT" => crate::expressions::DataType::TinyInt { length: None },
35225 "DOUBLE" => crate::expressions::DataType::Double {
35226 precision: None,
35227 scale: None,
35228 },
35229 "FLOAT" => crate::expressions::DataType::Float {
35230 precision: None,
35231 scale: None,
35232 real_spelling: false,
35233 },
35234 "DECIMAL" => crate::expressions::DataType::Decimal {
35235 precision: None,
35236 scale: None,
35237 },
35238 _ => crate::expressions::DataType::Custom {
35239 name: type_name.to_string(),
35240 },
35241 };
35242 return Ok(Expression::TryCast(Box::new(crate::expressions::Cast {
35243 this: num_expr,
35244 to: data_type,
35245 trailing_comments: Vec::new(),
35246 double_colon_syntax: false,
35247 format: None,
35248 default: None,
35249 inferred_type: None,
35250 })));
35251 }
35252 return Ok(Expression::Literal(Box::new(Literal::Number(token.text))));
35253 }
35254
35255 if self.check(TokenType::String) {
35257 let token = self.advance();
35258 return Ok(Expression::Literal(Box::new(Literal::String(token.text))));
35259 }
35260
35261 if self.match_token(TokenType::LParen) {
35263 let expr = self.parse_expression()?;
35264 self.expect(TokenType::RParen)?;
35265 return Ok(Expression::Paren(Box::new(Paren {
35266 this: expr,
35267 trailing_comments: Vec::new(),
35268 })));
35269 }
35270
35271 if self.match_token(TokenType::LBracket) {
35274 if self.match_token(TokenType::RBracket) {
35276 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
35277 expressions: Vec::new(),
35278 bracket_notation: true,
35279 use_list_keyword: false,
35280 })));
35281 }
35282
35283 let mut expressions = vec![self.parse_expression()?];
35285 while self.match_token(TokenType::Comma) {
35286 if self.check(TokenType::RBracket) {
35287 break;
35288 }
35289 expressions.push(self.parse_expression()?);
35290 }
35291 self.expect(TokenType::RBracket)?;
35292
35293 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
35294 expressions,
35295 bracket_notation: true,
35296 use_list_keyword: false,
35297 })));
35298 }
35299
35300 if self.is_identifier_token() {
35302 let first_ident = self.expect_identifier_with_quoted()?;
35303
35304 if self.match_token(TokenType::Dot) {
35306 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
35307 let second_ident = if self.is_identifier_token() {
35308 self.expect_identifier_with_quoted()?
35309 } else {
35310 let token = self.advance();
35311 Identifier::new(token.text)
35312 };
35313 return Ok(Expression::boxed_column(Column {
35314 name: second_ident,
35315 table: Some(first_ident),
35316 join_mark: false,
35317 trailing_comments: Vec::new(),
35318 span: None,
35319 inferred_type: None,
35320 }));
35321 }
35322 }
35323
35324 return Ok(Expression::boxed_column(Column {
35325 name: first_ident,
35326 table: None,
35327 join_mark: false,
35328 trailing_comments: Vec::new(),
35329 span: None,
35330 inferred_type: None,
35331 }));
35332 }
35333
35334 if self.is_safe_keyword_as_identifier() {
35336 let token = self.advance();
35337 let first_ident = Identifier::new(token.text);
35338
35339 if self.match_token(TokenType::Dot) {
35341 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
35342 let second_ident = if self.is_identifier_token() {
35343 self.expect_identifier_with_quoted()?
35344 } else {
35345 let token = self.advance();
35346 Identifier::new(token.text)
35347 };
35348 return Ok(Expression::boxed_column(Column {
35349 name: second_ident,
35350 table: Some(first_ident),
35351 join_mark: false,
35352 trailing_comments: Vec::new(),
35353 span: None,
35354 inferred_type: None,
35355 }));
35356 }
35357 }
35358
35359 return Ok(Expression::boxed_column(Column {
35360 name: first_ident,
35361 table: None,
35362 join_mark: false,
35363 trailing_comments: Vec::new(),
35364 span: None,
35365 inferred_type: None,
35366 }));
35367 }
35368
35369 Err(self.parse_error(format!(
35370 "Unexpected token in JSON path: {:?}",
35371 self.peek().token_type
35372 )))
35373 }
35374
35375 fn maybe_parse_subscript(&mut self, mut expr: Expression) -> Result<Expression> {
35377 loop {
35378 if matches!(
35383 self.config.dialect,
35384 Some(crate::dialects::DialectType::ClickHouse)
35385 ) && self.check(TokenType::LBracket)
35386 {
35387 let is_empty_bracket = self
35388 .peek_nth(1)
35389 .map_or(false, |t| t.token_type == TokenType::RBracket);
35390 if is_empty_bracket {
35391 let mut bracket_json_type: Option<DataType> = None;
35392 while self.check(TokenType::LBracket) {
35393 let is_empty = self
35394 .peek_nth(1)
35395 .map_or(false, |t| t.token_type == TokenType::RBracket);
35396 if is_empty {
35397 self.skip(); self.skip(); bracket_json_type = Some(DataType::Array {
35400 element_type: Box::new(bracket_json_type.unwrap_or(DataType::Json)),
35401 dimension: None,
35402 });
35403 } else {
35404 break;
35405 }
35406 }
35407 if let Some(json_type) = bracket_json_type {
35408 expr = Expression::JSONCast(Box::new(crate::expressions::JSONCast {
35409 this: Box::new(expr),
35410 to: json_type,
35411 }));
35412 continue;
35413 }
35414 }
35415 }
35416
35417 if self.match_token(TokenType::LBracket) {
35418 let array_constructor_type = match &expr {
35420 Expression::Column(col) if col.table.is_none() => {
35421 let upper = col.name.name.to_ascii_uppercase();
35422 if upper == "ARRAY" || upper == "LIST" {
35423 Some(upper)
35424 } else {
35425 None
35426 }
35427 }
35428 Expression::Identifier(id) => {
35429 let upper = id.name.to_ascii_uppercase();
35430 if upper == "ARRAY" || upper == "LIST" {
35431 Some(upper)
35432 } else {
35433 None
35434 }
35435 }
35436 _ => None,
35437 };
35438
35439 if let Some(constructor_type) = array_constructor_type {
35440 let use_list_keyword = constructor_type == "LIST";
35443 if self.check(TokenType::RBracket) {
35444 self.skip();
35446 expr = Expression::ArrayFunc(Box::new(ArrayConstructor {
35447 expressions: Vec::new(),
35448 bracket_notation: false, use_list_keyword,
35450 }));
35451 } else {
35452 let expressions = self.parse_expression_list()?;
35453 self.expect(TokenType::RBracket)?;
35454 expr = Expression::ArrayFunc(Box::new(ArrayConstructor {
35455 expressions,
35456 bracket_notation: false, use_list_keyword,
35458 }));
35459 }
35460 continue;
35461 }
35462
35463 let is_map_constructor = !matches!(
35467 self.config.dialect,
35468 Some(crate::dialects::DialectType::ClickHouse)
35469 ) && match &expr {
35470 Expression::Column(col) => {
35471 col.name.name.eq_ignore_ascii_case("MAP") && col.table.is_none()
35472 }
35473 Expression::Identifier(id) => id.name.eq_ignore_ascii_case("MAP"),
35474 _ => false,
35475 };
35476
35477 if is_map_constructor {
35478 let is_materialize = matches!(
35479 self.config.dialect,
35480 Some(crate::dialects::DialectType::Materialize)
35481 );
35482
35483 if is_materialize {
35485 if self.check(TokenType::RBracket) {
35486 self.skip();
35488 expr = Expression::ToMap(Box::new(ToMap {
35489 this: Box::new(Expression::Struct(Box::new(Struct {
35490 fields: Vec::new(),
35491 }))),
35492 }));
35493 continue;
35494 }
35495
35496 let mut entries = Vec::new();
35499 loop {
35500 let key = self.parse_expression()?;
35501 self.expect(TokenType::FArrow)?;
35502 let value = self.parse_expression()?;
35503 entries.push((
35505 None,
35506 Expression::PropertyEQ(Box::new(BinaryOp::new(key, value))),
35507 ));
35508
35509 if !self.match_token(TokenType::Comma) {
35510 break;
35511 }
35512 }
35513 self.expect(TokenType::RBracket)?;
35514
35515 expr = Expression::ToMap(Box::new(ToMap {
35516 this: Box::new(Expression::Struct(Box::new(Struct {
35517 fields: entries,
35518 }))),
35519 }));
35520 continue;
35521 }
35522
35523 let keys = self.parse_expression()?;
35525 self.expect(TokenType::Comma)?;
35526 let values = self.parse_expression()?;
35527 self.expect(TokenType::RBracket)?;
35528 expr = Expression::Function(Box::new(Function {
35529 name: "MAP".to_string(),
35530 args: vec![keys, values],
35531 distinct: false,
35532 trailing_comments: Vec::new(),
35533 use_bracket_syntax: true,
35534 no_parens: false,
35535 quoted: false,
35536 span: None,
35537 inferred_type: None,
35538 }));
35539 continue;
35540 }
35541
35542 if self.check(TokenType::Colon) {
35545 self.skip(); let end = self.parse_slice_element()?;
35548 let step = if self.match_token(TokenType::Colon) {
35550 self.parse_slice_element()?
35551 } else {
35552 None
35553 };
35554 self.expect(TokenType::RBracket)?;
35555 if step.is_some() {
35556 let slice = Expression::Slice(Box::new(Slice {
35558 this: None, expression: end.map(Box::new),
35560 step: step.map(Box::new),
35561 }));
35562 expr = Expression::Subscript(Box::new(Subscript {
35563 this: expr,
35564 index: slice,
35565 }));
35566 } else {
35567 expr = Expression::ArraySlice(Box::new(ArraySlice {
35568 this: expr,
35569 start: None,
35570 end,
35571 }));
35572 }
35573 } else {
35574 let start = self.parse_slice_element()?;
35575 if self.match_token(TokenType::Colon) {
35577 let end = self.parse_slice_element()?;
35578 let step = if self.match_token(TokenType::Colon) {
35580 self.parse_slice_element()?
35581 } else {
35582 None
35583 };
35584 self.expect(TokenType::RBracket)?;
35585 if step.is_some() {
35586 let slice = Expression::Slice(Box::new(Slice {
35588 this: start.map(Box::new),
35589 expression: end.map(Box::new),
35590 step: step.map(Box::new),
35591 }));
35592 expr = Expression::Subscript(Box::new(Subscript {
35593 this: expr,
35594 index: slice,
35595 }));
35596 } else {
35597 expr = Expression::ArraySlice(Box::new(ArraySlice {
35598 this: expr,
35599 start,
35600 end,
35601 }));
35602 }
35603 } else {
35604 self.expect(TokenType::RBracket)?;
35605 let index =
35607 start.unwrap_or_else(|| Expression::Null(crate::expressions::Null));
35608 expr = Expression::Subscript(Box::new(Subscript { this: expr, index }));
35609 }
35610 }
35611 } else if self.match_token(TokenType::DotColon) {
35612 let data_type = if matches!(
35615 self.config.dialect,
35616 Some(crate::dialects::DialectType::ClickHouse)
35617 ) && self.check(TokenType::QuotedIdentifier)
35618 {
35619 let type_text = self.advance().text.clone();
35620 self.parse_data_type_from_text(&type_text)?
35622 } else {
35623 self.parse_data_type()?
35624 };
35625 expr = Expression::JSONCast(Box::new(JSONCast {
35626 this: Box::new(expr),
35627 to: data_type,
35628 }));
35629 } else if self.match_token(TokenType::Dot) {
35630 if self.match_token(TokenType::Star) {
35632 let table_name = match &expr {
35634 Expression::Column(col) => {
35635 if let Some(ref table) = col.table {
35636 Some(Identifier::new(format!("{}.{}", table.name, col.name.name)))
35637 } else {
35638 Some(col.name.clone())
35639 }
35640 }
35641 Expression::Dot(d) => {
35642 fn dot_to_name_inner(expr: &Expression) -> String {
35643 match expr {
35644 Expression::Column(col) => {
35645 if let Some(ref table) = col.table {
35646 format!("{}.{}", table.name, col.name.name)
35647 } else {
35648 col.name.name.clone()
35649 }
35650 }
35651 Expression::Dot(d) => {
35652 format!("{}.{}", dot_to_name_inner(&d.this), d.field.name)
35653 }
35654 _ => String::new(),
35655 }
35656 }
35657 Some(Identifier::new(dot_to_name_inner(&Expression::Dot(
35658 d.clone(),
35659 ))))
35660 }
35661 _ => None,
35662 };
35663 if table_name.is_some() {
35664 let star = self.parse_star_modifiers(table_name)?;
35665 expr = Expression::Star(star);
35666 if matches!(
35668 self.config.dialect,
35669 Some(crate::dialects::DialectType::ClickHouse)
35670 ) {
35671 loop {
35672 if self.check(TokenType::Apply) {
35673 self.skip();
35674 let apply_expr = if self.match_token(TokenType::LParen) {
35675 let e = self.parse_expression()?;
35676 self.expect(TokenType::RParen)?;
35677 e
35678 } else {
35679 self.parse_expression()?
35680 };
35681 expr = Expression::Apply(Box::new(crate::expressions::Apply {
35682 this: Box::new(expr),
35683 expression: Box::new(apply_expr),
35684 }));
35685 } else if self.check(TokenType::Except)
35686 || self.check(TokenType::Exclude)
35687 {
35688 self.skip();
35689 self.match_identifier("STRICT");
35690 if self.match_token(TokenType::LParen) {
35691 loop {
35692 if self.check(TokenType::RParen) {
35693 break;
35694 }
35695 let _ = self.parse_expression()?;
35696 if !self.match_token(TokenType::Comma) {
35697 break;
35698 }
35699 }
35700 self.expect(TokenType::RParen)?;
35701 } else if self.is_identifier_token()
35702 || self.is_safe_keyword_as_identifier()
35703 {
35704 let _ = self.parse_expression()?;
35705 }
35706 } else if self.check(TokenType::Replace) {
35707 self.skip();
35708 self.match_identifier("STRICT");
35709 if self.match_token(TokenType::LParen) {
35710 loop {
35711 if self.check(TokenType::RParen) {
35712 break;
35713 }
35714 let _ = self.parse_expression()?;
35715 if self.match_token(TokenType::As) {
35716 if self.is_identifier_token()
35717 || self.is_safe_keyword_as_identifier()
35718 {
35719 self.skip();
35720 }
35721 }
35722 if !self.match_token(TokenType::Comma) {
35723 break;
35724 }
35725 }
35726 self.expect(TokenType::RParen)?;
35727 } else {
35728 let _ = self.parse_expression()?;
35729 if self.match_token(TokenType::As) {
35730 if self.is_identifier_token()
35731 || self.is_safe_keyword_as_identifier()
35732 {
35733 self.skip();
35734 }
35735 }
35736 }
35737 } else {
35738 break;
35739 }
35740 }
35741 }
35742 } else {
35743 expr = Expression::Dot(Box::new(DotAccess {
35745 this: expr,
35746 field: Identifier::new("*"),
35747 }));
35748 }
35749 } else if self.check(TokenType::Identifier)
35750 || self.check(TokenType::Var)
35751 || self.check(TokenType::QuotedIdentifier)
35752 || self.check_keyword()
35753 {
35754 let is_quoted = self.check(TokenType::QuotedIdentifier);
35755 let field_name = self.advance().text;
35756 if self.check(TokenType::LParen) && !is_quoted {
35758 self.skip(); let args = if self.check(TokenType::RParen) {
35761 Vec::new()
35762 } else {
35763 self.parse_expression_list()?
35764 };
35765 self.expect(TokenType::RParen)?;
35766 expr = Expression::MethodCall(Box::new(MethodCall {
35768 this: expr,
35769 method: Identifier::new(field_name),
35770 args,
35771 }));
35772 } else {
35773 let mut ident = Identifier::new(field_name);
35774 if is_quoted {
35775 ident.quoted = true;
35776 }
35777 expr = Expression::Dot(Box::new(DotAccess {
35778 this: expr,
35779 field: ident,
35780 }));
35781 }
35782 } else if self.check(TokenType::Number) {
35783 let field_name = self.advance().text;
35785 expr = Expression::Dot(Box::new(DotAccess {
35786 this: expr,
35787 field: Identifier::new(field_name),
35788 }));
35789 } else if matches!(
35790 self.config.dialect,
35791 Some(crate::dialects::DialectType::ClickHouse)
35792 ) && self.check(TokenType::Caret)
35793 {
35794 self.skip(); let mut field_name = "^".to_string();
35798 if self.check(TokenType::Identifier)
35799 || self.check(TokenType::Var)
35800 || self.check_keyword()
35801 {
35802 field_name.push_str(&self.advance().text);
35803 }
35804 expr = Expression::Dot(Box::new(DotAccess {
35805 this: expr,
35806 field: Identifier::new(field_name),
35807 }));
35808 } else if matches!(
35809 self.config.dialect,
35810 Some(crate::dialects::DialectType::ClickHouse)
35811 ) && self.check(TokenType::Colon)
35812 {
35813 self.skip(); let mut type_name = ":".to_string();
35817 if self.check(TokenType::Identifier)
35818 || self.check(TokenType::Var)
35819 || self.check_keyword()
35820 {
35821 type_name.push_str(&self.advance().text);
35822 }
35823 expr = Expression::Dot(Box::new(DotAccess {
35824 this: expr,
35825 field: Identifier::new(type_name),
35826 }));
35827 } else if matches!(
35828 self.config.dialect,
35829 Some(crate::dialects::DialectType::ClickHouse)
35830 ) && self.check(TokenType::Dash)
35831 && self
35832 .peek_nth(1)
35833 .is_some_and(|t| t.token_type == TokenType::Number)
35834 {
35835 self.skip(); let num = self.advance().text;
35838 expr = Expression::Dot(Box::new(DotAccess {
35839 this: expr,
35840 field: Identifier::new(format!("-{}", num)),
35841 }));
35842 } else {
35843 return Err(self.parse_error("Expected field name after dot"));
35844 }
35845 } else if self.match_token(TokenType::Collate) {
35846 let (collation, quoted, double_quoted) = if self.check(TokenType::String) {
35848 (self.advance().text, true, false)
35850 } else if self.check(TokenType::QuotedIdentifier) {
35851 (self.advance().text, false, true)
35853 } else {
35854 (self.expect_identifier_or_keyword()?, false, false)
35856 };
35857 expr = Expression::Collation(Box::new(CollationExpr {
35858 this: expr,
35859 collation,
35860 quoted,
35861 double_quoted,
35862 }));
35863 } else if self.check(TokenType::DColon)
35864 || self.check(TokenType::DColonDollar)
35865 || self.check(TokenType::DColonPercent)
35866 || self.check(TokenType::DColonQMark)
35867 {
35868 if matches!(
35871 self.config.dialect,
35872 Some(crate::dialects::DialectType::SingleStore)
35873 ) {
35874 if self.match_token(TokenType::DColon) {
35876 let path_key =
35878 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
35879 self.advance().text
35880 } else if self.check(TokenType::Number) {
35881 self.advance().text
35882 } else if self.check(TokenType::QuotedIdentifier) {
35883 self.advance().text
35884 } else {
35885 return Err(self.parse_error(
35886 "Expected identifier or number after :: in JSON path",
35887 ));
35888 };
35889 expr = Expression::Function(Box::new(Function::new(
35890 "JSON_EXTRACT_JSON".to_string(),
35891 vec![expr, Expression::string(&path_key)],
35892 )));
35893 } else if self.match_token(TokenType::DColonDollar) {
35894 let path_key =
35896 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
35897 self.advance().text
35898 } else if self.check(TokenType::Number) {
35899 self.advance().text
35900 } else {
35901 return Err(self.parse_error(
35902 "Expected identifier or number after ::$ in JSON path",
35903 ));
35904 };
35905 expr = Expression::Function(Box::new(Function::new(
35906 "JSON_EXTRACT_STRING".to_string(),
35907 vec![expr, Expression::string(&path_key)],
35908 )));
35909 } else if self.match_token(TokenType::DColonPercent) {
35910 let path_key =
35912 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
35913 self.advance().text
35914 } else if self.check(TokenType::Number) {
35915 self.advance().text
35916 } else {
35917 return Err(self.parse_error(
35918 "Expected identifier or number after ::% in JSON path",
35919 ));
35920 };
35921 expr = Expression::Function(Box::new(Function::new(
35922 "JSON_EXTRACT_DOUBLE".to_string(),
35923 vec![expr, Expression::string(&path_key)],
35924 )));
35925 } else if self.match_token(TokenType::DColonQMark) {
35926 let path_key =
35928 if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
35929 self.advance().text
35930 } else if self.check(TokenType::Number) {
35931 self.advance().text
35932 } else {
35933 return Err(self.parse_error(
35934 "Expected identifier or number after ::? in JSON path",
35935 ));
35936 };
35937 expr = Expression::Function(Box::new(Function::new(
35939 "__SS_JSON_PATH_QMARK__".to_string(),
35940 vec![expr, Expression::string(&path_key)],
35941 )));
35942 }
35943 } else {
35944 self.skip(); let data_type = self.parse_data_type_for_cast()?;
35948 expr = Expression::Cast(Box::new(Cast {
35949 this: expr,
35950 to: data_type,
35951 trailing_comments: Vec::new(),
35952 double_colon_syntax: true,
35953 format: None,
35954 default: None,
35955 inferred_type: None,
35956 }));
35957 }
35958 } else if self.match_token(TokenType::ColonGt) {
35959 let data_type = self.parse_data_type_for_cast()?;
35961 expr = Expression::Cast(Box::new(Cast {
35962 this: expr,
35963 to: data_type,
35964 trailing_comments: Vec::new(),
35965 double_colon_syntax: false, format: None,
35967 default: None,
35968 inferred_type: None,
35969 }));
35970 } else if self.match_token(TokenType::NColonGt) {
35971 let data_type = self.parse_data_type_for_cast()?;
35973 expr = Expression::TryCast(Box::new(Cast {
35974 this: expr,
35975 to: data_type,
35976 trailing_comments: Vec::new(),
35977 double_colon_syntax: false,
35978 format: None,
35979 default: None,
35980 inferred_type: None,
35981 }));
35982 } else if self.match_token(TokenType::QDColon) {
35983 let data_type = self.parse_data_type_for_cast()?;
35985 expr = Expression::TryCast(Box::new(Cast {
35986 this: expr,
35987 to: data_type,
35988 trailing_comments: Vec::new(),
35989 double_colon_syntax: true, format: None,
35991 default: None,
35992 inferred_type: None,
35993 }));
35994 } else if self.check(TokenType::Arrow)
35995 && !matches!(
35996 self.config.dialect,
35997 Some(crate::dialects::DialectType::ClickHouse)
35998 )
35999 {
36000 self.skip(); let path = self.parse_json_path_operand()?;
36004 expr = Expression::JsonExtract(Box::new(JsonExtractFunc {
36005 this: expr,
36006 path,
36007 returning: None,
36008 arrow_syntax: true,
36009 hash_arrow_syntax: false,
36010 wrapper_option: None,
36011 quotes_option: None,
36012 on_scalar_string: false,
36013 on_error: None,
36014 }));
36015 } else if self.match_token(TokenType::DArrow) {
36016 let path = self.parse_json_path_operand()?;
36019 expr = Expression::JsonExtractScalar(Box::new(JsonExtractFunc {
36020 this: expr,
36021 path,
36022 returning: None,
36023 arrow_syntax: true,
36024 hash_arrow_syntax: false,
36025 wrapper_option: None,
36026 quotes_option: None,
36027 on_scalar_string: false,
36028 on_error: None,
36029 }));
36030 } else if self.match_token(TokenType::HashArrow) {
36031 let path = self.parse_json_path_operand()?;
36034 expr = Expression::JsonExtractPath(Box::new(JsonPathFunc {
36035 this: expr,
36036 paths: vec![path],
36037 }));
36038 } else if self.match_token(TokenType::DHashArrow) {
36039 let path = self.parse_json_path_operand()?;
36043 expr = Expression::JsonExtractScalar(Box::new(JsonExtractFunc {
36044 this: expr,
36045 path,
36046 returning: None,
36047 arrow_syntax: false, hash_arrow_syntax: true, wrapper_option: None,
36050 quotes_option: None,
36051 on_scalar_string: false,
36052 on_error: None,
36053 }));
36054 } else if self.check_join_marker() {
36055 if let Expression::Column(col) = &mut expr {
36058 self.skip(); self.skip(); self.skip(); col.join_mark = true;
36062 break;
36064 }
36065 else {
36067 break;
36068 }
36069 } else {
36070 break;
36071 }
36072 }
36073 Ok(expr)
36074 }
36075
36076 fn check_join_marker(&self) -> bool {
36078 self.check(TokenType::LParen)
36079 && self
36080 .peek_nth(1)
36081 .map_or(false, |t| t.token_type == TokenType::Plus)
36082 && self
36083 .peek_nth(2)
36084 .map_or(false, |t| t.token_type == TokenType::RParen)
36085 }
36086
36087 fn parse_over_clause(&mut self) -> Result<Over> {
36089 if !self.check(TokenType::LParen) {
36091 let window_name = self.expect_identifier_or_keyword()?;
36093 return Ok(Over {
36094 window_name: Some(Identifier::new(window_name)),
36095 partition_by: Vec::new(),
36096 order_by: Vec::new(),
36097 frame: None,
36098 alias: None,
36099 });
36100 }
36101
36102 self.expect(TokenType::LParen)?;
36103
36104 let window_name = if (self.check(TokenType::Identifier)
36107 || self.check(TokenType::Var)
36108 || self.check_keyword())
36109 && !self.check(TokenType::Partition)
36110 && !self.check(TokenType::Order)
36111 && !self.check(TokenType::Rows)
36112 && !self.check(TokenType::Range)
36113 && !self.check(TokenType::Groups)
36114 && !self.check(TokenType::Distribute)
36115 && !self.check(TokenType::Sort)
36116 {
36117 let pos = self.current;
36119 let name = self.advance().text;
36120 if self.check(TokenType::Order)
36122 || self.check(TokenType::Partition)
36123 || self.check(TokenType::Rows)
36124 || self.check(TokenType::Range)
36125 || self.check(TokenType::Groups)
36126 || self.check(TokenType::RParen)
36127 || self.check(TokenType::Distribute)
36128 || self.check(TokenType::Sort)
36129 {
36130 Some(Identifier::new(name))
36131 } else {
36132 self.current = pos;
36134 None
36135 }
36136 } else {
36137 None
36138 };
36139
36140 let partition_by = if self.match_keywords(&[TokenType::Partition, TokenType::By]) {
36142 self.parse_expression_list()?
36143 } else if self.match_keywords(&[TokenType::Distribute, TokenType::By]) {
36144 self.parse_expression_list()?
36146 } else {
36147 Vec::new()
36148 };
36149
36150 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By])
36152 || self.match_keywords(&[TokenType::Sort, TokenType::By])
36153 {
36154 let mut exprs = Vec::new();
36155 loop {
36156 let expr = self.parse_expression()?;
36157 let (desc, explicit_asc) = if self.match_token(TokenType::Desc) {
36158 (true, false)
36159 } else if self.match_token(TokenType::Asc) {
36160 (false, true)
36161 } else {
36162 (false, false)
36163 };
36164 if self.match_token(TokenType::Collate) {
36166 if self.check(TokenType::String) {
36168 self.skip();
36169 } else if self.check(TokenType::QuotedIdentifier) {
36170 self.skip();
36171 } else {
36172 let _ = self.expect_identifier_or_keyword();
36173 }
36174 }
36175 let nulls_first = if self.match_token(TokenType::Nulls) {
36176 if self.match_token(TokenType::First) {
36177 Some(true)
36178 } else if self.match_token(TokenType::Last) {
36179 Some(false)
36180 } else {
36181 return Err(self.parse_error("Expected FIRST or LAST after NULLS"));
36182 }
36183 } else {
36184 None
36185 };
36186 let with_fill = if matches!(
36188 self.config.dialect,
36189 Some(crate::dialects::DialectType::ClickHouse)
36190 ) && self.check(TokenType::With)
36191 && self.current + 1 < self.tokens.len()
36192 && self.tokens[self.current + 1]
36193 .text
36194 .eq_ignore_ascii_case("FILL")
36195 {
36196 self.skip(); self.skip(); let from_ = if self.match_token(TokenType::From) {
36199 Some(Box::new(self.parse_or()?))
36200 } else {
36201 None
36202 };
36203 let to = if self.match_text_seq(&["TO"]) {
36204 Some(Box::new(self.parse_or()?))
36205 } else {
36206 None
36207 };
36208 let step = if self.match_text_seq(&["STEP"]) {
36209 Some(Box::new(self.parse_or()?))
36210 } else {
36211 None
36212 };
36213 let staleness = if self.match_text_seq(&["STALENESS"]) {
36214 Some(Box::new(self.parse_or()?))
36215 } else {
36216 None
36217 };
36218 let interpolate = if self.match_text_seq(&["INTERPOLATE"]) {
36219 if self.match_token(TokenType::LParen) {
36220 let items = self.parse_expression_list()?;
36221 self.expect(TokenType::RParen)?;
36222 if items.len() == 1 {
36223 Some(Box::new(items.into_iter().next().unwrap()))
36224 } else {
36225 Some(Box::new(Expression::Tuple(Box::new(
36226 crate::expressions::Tuple { expressions: items },
36227 ))))
36228 }
36229 } else {
36230 None
36231 }
36232 } else {
36233 None
36234 };
36235 Some(Box::new(WithFill {
36236 from_,
36237 to,
36238 step,
36239 staleness,
36240 interpolate,
36241 }))
36242 } else {
36243 None
36244 };
36245 exprs.push(Ordered {
36246 this: expr,
36247 desc,
36248 nulls_first,
36249 explicit_asc,
36250 with_fill,
36251 });
36252 if !self.match_token(TokenType::Comma) {
36253 break;
36254 }
36255 }
36256 exprs
36257 } else {
36258 Vec::new()
36259 };
36260
36261 let frame = self.parse_window_frame()?;
36263
36264 self.expect(TokenType::RParen)?;
36265
36266 Ok(Over {
36267 window_name,
36268 partition_by,
36269 order_by,
36270 frame,
36271 alias: None,
36272 })
36273 }
36274
36275 fn parse_window_frame(&mut self) -> Result<Option<WindowFrame>> {
36277 let (kind, kind_text) = if self.match_token(TokenType::Rows) {
36278 (
36279 WindowFrameKind::Rows,
36280 self.tokens[self.current - 1].text.clone(),
36281 )
36282 } else if self.match_token(TokenType::Range) {
36283 (
36284 WindowFrameKind::Range,
36285 self.tokens[self.current - 1].text.clone(),
36286 )
36287 } else if self.match_token(TokenType::Groups) {
36288 (
36289 WindowFrameKind::Groups,
36290 self.tokens[self.current - 1].text.clone(),
36291 )
36292 } else {
36293 return Ok(None);
36294 };
36295
36296 let (start, start_side_text, end, end_side_text) = if self.match_token(TokenType::Between) {
36298 let (start, st) = self.parse_window_frame_bound()?;
36299 self.expect(TokenType::And)?;
36300 let (end, et) = self.parse_window_frame_bound()?;
36301 (start, st, Some(end), et)
36302 } else {
36303 let (start, st) = self.parse_window_frame_bound()?;
36304 (start, st, None, None)
36305 };
36306
36307 let exclude = if self.match_token(TokenType::Exclude) {
36309 if self.match_token(TokenType::Current) {
36310 self.expect(TokenType::Row)?;
36311 Some(WindowFrameExclude::CurrentRow)
36312 } else if self.match_token(TokenType::Group) {
36313 Some(WindowFrameExclude::Group)
36314 } else if self.match_token(TokenType::Ties) {
36315 Some(WindowFrameExclude::Ties)
36316 } else if self.match_token(TokenType::No) {
36317 self.expect(TokenType::Others)?;
36318 Some(WindowFrameExclude::NoOthers)
36319 } else {
36320 return Err(self
36321 .parse_error("Expected CURRENT ROW, GROUP, TIES, or NO OTHERS after EXCLUDE"));
36322 }
36323 } else {
36324 None
36325 };
36326
36327 Ok(Some(WindowFrame {
36328 kind,
36329 start,
36330 end,
36331 exclude,
36332 kind_text: Some(kind_text),
36333 start_side_text,
36334 end_side_text,
36335 }))
36336 }
36337
36338 fn parse_window_frame_bound(&mut self) -> Result<(WindowFrameBound, Option<String>)> {
36340 if self.match_token(TokenType::Current) {
36341 self.expect(TokenType::Row)?;
36342 Ok((WindowFrameBound::CurrentRow, None))
36343 } else if self.match_token(TokenType::Unbounded) {
36344 if self.match_token(TokenType::Preceding) {
36345 let text = self.tokens[self.current - 1].text.clone();
36346 Ok((WindowFrameBound::UnboundedPreceding, Some(text)))
36347 } else if self.match_token(TokenType::Following) {
36348 let text = self.tokens[self.current - 1].text.clone();
36349 Ok((WindowFrameBound::UnboundedFollowing, Some(text)))
36350 } else {
36351 Err(self.parse_error("Expected PRECEDING or FOLLOWING after UNBOUNDED"))
36352 }
36353 } else if self.match_token(TokenType::Preceding) {
36354 let text = self.tokens[self.current - 1].text.clone();
36355 if self.check(TokenType::RParen) || self.check(TokenType::Comma) {
36358 Ok((WindowFrameBound::BarePreceding, Some(text)))
36359 } else {
36360 let expr = self.parse_primary()?;
36361 Ok((WindowFrameBound::Preceding(Box::new(expr)), Some(text)))
36362 }
36363 } else if self.match_token(TokenType::Following) {
36364 let text = self.tokens[self.current - 1].text.clone();
36365 if self.check(TokenType::RParen) || self.check(TokenType::Comma) {
36368 Ok((WindowFrameBound::BareFollowing, Some(text)))
36369 } else {
36370 let expr = self.parse_primary()?;
36371 Ok((WindowFrameBound::Following(Box::new(expr)), Some(text)))
36372 }
36373 } else {
36374 let expr = self.parse_addition()?;
36377 if self.match_token(TokenType::Preceding) {
36378 let text = self.tokens[self.current - 1].text.clone();
36379 Ok((WindowFrameBound::Preceding(Box::new(expr)), Some(text)))
36380 } else if self.match_token(TokenType::Following) {
36381 let text = self.tokens[self.current - 1].text.clone();
36382 Ok((WindowFrameBound::Following(Box::new(expr)), Some(text)))
36383 } else {
36384 Ok((WindowFrameBound::Value(Box::new(expr)), None))
36387 }
36388 }
36389 }
36390
36391 fn try_parse_interval(&mut self) -> Result<Option<Expression>> {
36393 self.try_parse_interval_internal(true)
36394 }
36395
36396 fn try_parse_interval_internal(&mut self, match_interval: bool) -> Result<Option<Expression>> {
36400 let start_pos = self.current;
36401
36402 if match_interval {
36404 if !self.check(TokenType::Interval) {
36405 return Ok(None);
36406 }
36407 self.expect(TokenType::Interval)?;
36408
36409 if self.check(TokenType::Eq)
36411 || self.check(TokenType::Neq)
36412 || self.check(TokenType::Lt)
36413 || self.check(TokenType::Gt)
36414 || self.check(TokenType::Lte)
36415 || self.check(TokenType::Gte)
36416 || self.check(TokenType::And)
36417 || self.check(TokenType::Or)
36418 || self.check(TokenType::Is)
36419 || self.check(TokenType::In)
36420 || self.check(TokenType::Like)
36421 || self.check(TokenType::ILike)
36422 || self.check(TokenType::Between)
36423 || self.check(TokenType::Then)
36424 || self.check(TokenType::Else)
36425 || self.check(TokenType::When)
36426 || self.check(TokenType::End)
36427 || self.check(TokenType::Comma)
36428 || self.check(TokenType::RParen)
36429 || self.check(TokenType::DColon)
36430 {
36431 self.current = start_pos;
36433 return Ok(None);
36434 }
36435 }
36436
36437 let value = if self.check(TokenType::String) {
36447 let token = self.advance();
36448 Some(Expression::Literal(Box::new(Literal::String(token.text))))
36449 } else if !self.is_at_end() && !self.is_statement_terminator() {
36450 Some(self.parse_addition()?)
36451 } else {
36452 None
36453 };
36454
36455 if let Some(ref val) = value {
36461 if let Expression::Column(col) = val {
36462 if col.table.is_none() {
36464 let is_quoted = col.name.quoted;
36466 if !is_quoted {
36467 if !self.is_valid_interval_unit() && !self.check(TokenType::As) {
36469 self.current = start_pos;
36471 return Ok(None);
36472 }
36473 }
36474 }
36475 } else if let Expression::Identifier(id) = val {
36476 let is_quoted = id.quoted;
36478 if !is_quoted {
36479 if !self.is_valid_interval_unit() && !self.check(TokenType::As) {
36481 self.current = start_pos;
36483 return Ok(None);
36484 }
36485 }
36486 }
36487 } else if self.is_at_end() || self.is_statement_terminator() {
36488 self.current = start_pos;
36490 return Ok(None);
36491 }
36492
36493 let mut unit = self.try_parse_interval_unit()?;
36495
36496 let is_generic = self.config.dialect.is_none()
36500 || matches!(
36501 self.config.dialect,
36502 Some(crate::dialects::DialectType::Generic)
36503 );
36504 let value = if unit.is_none() && is_generic {
36505 if let Some(Expression::Literal(ref lit)) = value {
36506 if let Literal::String(ref s) = lit.as_ref() {
36507 let trimmed = s.trim();
36508 let mut split_pos = None;
36510 let mut found_space = false;
36511 let bytes = trimmed.as_bytes();
36512 let mut i = 0;
36513 if i < bytes.len() && bytes[i] == b'-' {
36515 i += 1;
36516 }
36517 let digit_start = i;
36519 while i < bytes.len() && bytes[i].is_ascii_digit() {
36520 i += 1;
36521 }
36522 if i > digit_start {
36523 if i < bytes.len() && bytes[i] == b'.' {
36525 i += 1;
36526 while i < bytes.len() && bytes[i].is_ascii_digit() {
36527 i += 1;
36528 }
36529 }
36530 let space_start = i;
36532 while i < bytes.len() && bytes[i].is_ascii_whitespace() {
36533 i += 1;
36534 }
36535 if i > space_start {
36536 found_space = true;
36537 split_pos = Some(i);
36538 }
36539 }
36540 if found_space {
36541 if let Some(pos) = split_pos {
36542 let unit_text = &trimmed[pos..];
36543 if !unit_text.is_empty()
36545 && unit_text.chars().all(|c| c.is_ascii_alphabetic())
36546 {
36547 let num_part = trimmed[..pos].trim_end().to_string();
36548 let unit_upper = unit_text.to_ascii_uppercase();
36549 if let Some(parsed_unit) =
36551 Self::parse_interval_unit_from_string(&unit_upper)
36552 {
36553 let is_plural = unit_upper.ends_with('S');
36555 unit = Some(IntervalUnitSpec::Simple {
36556 unit: parsed_unit,
36557 use_plural: is_plural,
36558 });
36559 Some(Expression::Literal(Box::new(Literal::String(num_part))))
36560 } else {
36561 value
36562 }
36563 } else {
36564 value
36565 }
36566 } else {
36567 value
36568 }
36569 } else {
36570 value
36571 }
36572 } else {
36573 None
36574 }
36575 } else {
36576 value
36577 }
36578 } else {
36579 value
36580 };
36581
36582 let value = match value {
36587 Some(Expression::Literal(lit))
36588 if unit.is_some() && matches!(lit.as_ref(), Literal::Number(_)) =>
36589 {
36590 let Literal::Number(n) = lit.as_ref() else {
36591 unreachable!()
36592 };
36593 Some(Expression::Literal(Box::new(Literal::String(n.clone()))))
36594 }
36595 other => other,
36596 };
36597
36598 let interval = Expression::Interval(Box::new(Interval { this: value, unit }));
36599
36600 let before_plus = self.current;
36606 let has_plus = self.match_token(TokenType::Plus);
36607
36608 if self.check(TokenType::String) || self.check(TokenType::Number) {
36610 if let Some(next_interval) = self.try_parse_interval_internal(false)? {
36612 return Ok(Some(Expression::Add(Box::new(BinaryOp::new(
36613 interval,
36614 next_interval,
36615 )))));
36616 }
36617 }
36618
36619 if has_plus {
36621 self.current = before_plus;
36622 }
36623
36624 Ok(Some(interval))
36625 }
36626
36627 fn is_valid_interval_unit(&self) -> bool {
36629 if self.is_at_end() {
36630 return false;
36631 }
36632 let text = self.peek().text.to_ascii_uppercase();
36633 matches!(
36634 text.as_str(),
36635 "YEAR"
36636 | "YEARS"
36637 | "MONTH"
36638 | "MONTHS"
36639 | "DAY"
36640 | "DAYS"
36641 | "HOUR"
36642 | "HOURS"
36643 | "MINUTE"
36644 | "MINUTES"
36645 | "SECOND"
36646 | "SECONDS"
36647 | "MILLISECOND"
36648 | "MILLISECONDS"
36649 | "MICROSECOND"
36650 | "MICROSECONDS"
36651 | "NANOSECOND"
36652 | "NANOSECONDS"
36653 | "WEEK"
36654 | "WEEKS"
36655 | "QUARTER"
36656 | "QUARTERS"
36657 )
36658 }
36659
36660 fn is_statement_terminator(&self) -> bool {
36662 if self.is_at_end() {
36663 return true;
36664 }
36665 matches!(
36666 self.peek().token_type,
36667 TokenType::Semicolon
36668 | TokenType::RParen
36669 | TokenType::RBracket
36670 | TokenType::Comma
36671 | TokenType::From
36672 | TokenType::Where
36673 | TokenType::GroupBy
36674 | TokenType::Having
36675 | TokenType::OrderBy
36676 | TokenType::Limit
36677 | TokenType::Union
36678 | TokenType::Intersect
36679 | TokenType::Except
36680 | TokenType::End
36681 | TokenType::Then
36682 | TokenType::Else
36683 | TokenType::When
36684 )
36685 }
36686
36687 fn try_parse_interval_unit(&mut self) -> Result<Option<IntervalUnitSpec>> {
36689 if self.is_function_start() {
36691 let func = self.parse_primary()?;
36692 return Ok(Some(IntervalUnitSpec::Expr(Box::new(func))));
36693 }
36694
36695 if let Some((unit, use_plural)) = self.try_parse_simple_interval_unit()? {
36697 if self.check_keyword_text("TO") {
36700 let saved = self.current;
36701 self.skip(); if let Some((end_unit, _)) = self.try_parse_simple_interval_unit()? {
36703 return Ok(Some(IntervalUnitSpec::Span(IntervalSpan {
36704 this: unit,
36705 expression: end_unit,
36706 })));
36707 } else {
36708 self.current = saved;
36710 }
36711 }
36712 return Ok(Some(IntervalUnitSpec::Simple { unit, use_plural }));
36713 }
36714
36715 Ok(None)
36717 }
36718
36719 fn parse_interval_unit_from_string(s: &str) -> Option<IntervalUnit> {
36721 let base = if s.ends_with('S') && s.len() > 1 {
36723 &s[..s.len() - 1]
36724 } else {
36725 s
36726 };
36727 match base {
36728 "YEAR" => Some(IntervalUnit::Year),
36729 "MONTH" => Some(IntervalUnit::Month),
36730 "DAY" => Some(IntervalUnit::Day),
36731 "HOUR" => Some(IntervalUnit::Hour),
36732 "MINUTE" => Some(IntervalUnit::Minute),
36733 "SECOND" => Some(IntervalUnit::Second),
36734 "MILLISECOND" => Some(IntervalUnit::Millisecond),
36735 "MICROSECOND" => Some(IntervalUnit::Microsecond),
36736 "QUARTER" => Some(IntervalUnit::Quarter),
36737 "WEEK" => Some(IntervalUnit::Week),
36738 _ => None,
36739 }
36740 }
36741
36742 fn try_parse_simple_interval_unit(&mut self) -> Result<Option<(IntervalUnit, bool)>> {
36744 if self.is_at_end() {
36745 return Ok(None);
36746 }
36747
36748 let text_upper = self.peek().text.to_ascii_uppercase();
36749 let result = match text_upper.as_str() {
36750 "YEAR" => Some((IntervalUnit::Year, false)),
36751 "YEARS" => Some((IntervalUnit::Year, true)),
36752 "MONTH" => Some((IntervalUnit::Month, false)),
36753 "MONTHS" => Some((IntervalUnit::Month, true)),
36754 "DAY" => Some((IntervalUnit::Day, false)),
36755 "DAYS" => Some((IntervalUnit::Day, true)),
36756 "HOUR" => Some((IntervalUnit::Hour, false)),
36757 "HOURS" => Some((IntervalUnit::Hour, true)),
36758 "MINUTE" => Some((IntervalUnit::Minute, false)),
36759 "MINUTES" => Some((IntervalUnit::Minute, true)),
36760 "SECOND" => Some((IntervalUnit::Second, false)),
36761 "SECONDS" => Some((IntervalUnit::Second, true)),
36762 "MILLISECOND" => Some((IntervalUnit::Millisecond, false)),
36763 "MILLISECONDS" => Some((IntervalUnit::Millisecond, true)),
36764 "MICROSECOND" => Some((IntervalUnit::Microsecond, false)),
36765 "MICROSECONDS" => Some((IntervalUnit::Microsecond, true)),
36766 "NANOSECOND" => Some((IntervalUnit::Nanosecond, false)),
36767 "NANOSECONDS" => Some((IntervalUnit::Nanosecond, true)),
36768 "QUARTER" => Some((IntervalUnit::Quarter, false)),
36769 "QUARTERS" => Some((IntervalUnit::Quarter, true)),
36770 "WEEK" => Some((IntervalUnit::Week, false)),
36771 "WEEKS" => Some((IntervalUnit::Week, true)),
36772 _ => None,
36773 };
36774
36775 if result.is_some() {
36776 self.skip(); }
36778
36779 Ok(result)
36780 }
36781
36782 fn is_function_start(&self) -> bool {
36784 if self.is_at_end() {
36785 return false;
36786 }
36787 let token_type = self.peek().token_type;
36788
36789 if NO_PAREN_FUNCTIONS.contains(&token_type) {
36791 if !matches!(
36792 self.config.dialect,
36793 Some(crate::dialects::DialectType::ClickHouse)
36794 ) || token_type != TokenType::CurrentTimestamp
36795 {
36796 return true;
36797 }
36798 }
36799
36800 if matches!(
36802 token_type,
36803 TokenType::Cast | TokenType::TryCast | TokenType::SafeCast
36804 ) {
36805 return true;
36806 }
36807
36808 let text_upper = self.peek().text.to_ascii_uppercase();
36811 if crate::function_registry::is_no_paren_function_name_upper(text_upper.as_str()) {
36812 if !matches!(
36813 self.config.dialect,
36814 Some(crate::dialects::DialectType::ClickHouse)
36815 ) || text_upper.as_str() != "CURRENT_TIMESTAMP"
36816 {
36817 return true;
36818 }
36819 }
36820
36821 if self.is_identifier_token() && self.check_next(TokenType::LParen) {
36823 return true;
36824 }
36825
36826 false
36827 }
36828
36829 fn try_parse_oracle_interval_span(&mut self, expr: Expression) -> Result<Expression> {
36834 let start_pos = self.current;
36835
36836 let start_unit_name = if !self.is_at_end() {
36838 let text = self.peek().text.to_ascii_uppercase();
36839 if matches!(
36840 text.as_str(),
36841 "DAY" | "HOUR" | "MINUTE" | "SECOND" | "YEAR" | "MONTH"
36842 ) {
36843 Some(text)
36844 } else {
36845 None
36846 }
36847 } else {
36848 None
36849 };
36850
36851 if start_unit_name.is_none() {
36852 return Ok(expr);
36853 }
36854
36855 let start_unit_name = start_unit_name.unwrap();
36856 self.skip(); let start_unit = if self.match_token(TokenType::LParen) {
36860 let precision = self.parse_expression()?;
36862 self.expect(TokenType::RParen)?;
36863 Expression::Anonymous(Box::new(Anonymous {
36865 this: Box::new(Expression::Identifier(Identifier {
36866 name: start_unit_name.clone(),
36867 quoted: false,
36868 trailing_comments: Vec::new(),
36869 span: None,
36870 })),
36871 expressions: vec![precision],
36872 }))
36873 } else {
36874 Expression::Var(Box::new(Var {
36876 this: start_unit_name,
36877 }))
36878 };
36879
36880 if !self.match_keyword("TO") {
36882 self.current = start_pos;
36884 return Ok(expr);
36885 }
36886
36887 let end_unit_name = if !self.is_at_end() {
36889 let text = self.peek().text.to_ascii_uppercase();
36890 if matches!(
36891 text.as_str(),
36892 "DAY" | "HOUR" | "MINUTE" | "SECOND" | "YEAR" | "MONTH"
36893 ) {
36894 Some(text)
36895 } else {
36896 None
36897 }
36898 } else {
36899 None
36900 };
36901
36902 let end_unit_name = match end_unit_name {
36903 Some(name) => name,
36904 None => {
36905 self.current = start_pos;
36907 return Ok(expr);
36908 }
36909 };
36910
36911 self.skip(); let end_unit = if self.match_token(TokenType::LParen) {
36915 let precision = self.parse_expression()?;
36917 self.expect(TokenType::RParen)?;
36918 Expression::Anonymous(Box::new(Anonymous {
36920 this: Box::new(Expression::Identifier(Identifier {
36921 name: end_unit_name.clone(),
36922 quoted: false,
36923 trailing_comments: Vec::new(),
36924 span: None,
36925 })),
36926 expressions: vec![precision],
36927 }))
36928 } else {
36929 Expression::Var(Box::new(Var {
36931 this: end_unit_name,
36932 }))
36933 };
36934
36935 Ok(Expression::Interval(Box::new(Interval {
36937 this: Some(expr),
36938 unit: Some(IntervalUnitSpec::ExprSpan(IntervalSpanExpr {
36939 this: Box::new(start_unit),
36940 expression: Box::new(end_unit),
36941 })),
36942 })))
36943 }
36944
36945 fn check_typed_column_list(&self) -> bool {
36951 if self.is_at_end() {
36954 return false;
36955 }
36956
36957 let has_identifier = self.check(TokenType::Identifier)
36959 || self.check(TokenType::QuotedIdentifier)
36960 || self.check(TokenType::Var);
36961
36962 if !has_identifier {
36963 return false;
36964 }
36965
36966 let next_pos = self.current + 1;
36968 if next_pos >= self.tokens.len() {
36969 return false;
36970 }
36971
36972 let next_token = &self.tokens[next_pos];
36973
36974 if next_token.token_type == TokenType::Comma || next_token.token_type == TokenType::RParen {
36976 return false;
36977 }
36978
36979 TYPE_TOKENS.contains(&next_token.token_type)
36982 || next_token.token_type == TokenType::Identifier
36983 || next_token.token_type == TokenType::Var
36984 }
36985
36986 fn is_no_paren_function(&self) -> bool {
36988 if self.is_at_end() {
36989 return false;
36990 }
36991 let token_type = self.peek().token_type;
36992 if NO_PAREN_FUNCTIONS.contains(&token_type) {
36993 if !matches!(
36994 self.config.dialect,
36995 Some(crate::dialects::DialectType::ClickHouse)
36996 ) || token_type != TokenType::CurrentTimestamp
36997 {
36998 return true;
36999 }
37000 }
37001 let text_upper = self.peek().text.to_ascii_uppercase();
37002 if crate::function_registry::is_no_paren_function_name_upper(text_upper.as_str()) {
37003 if !matches!(
37004 self.config.dialect,
37005 Some(crate::dialects::DialectType::ClickHouse)
37006 ) || text_upper.as_str() != "CURRENT_TIMESTAMP"
37007 {
37008 return true;
37009 }
37010 }
37011 false
37012 }
37013
37014 fn match_keyword(&mut self, keyword: &str) -> bool {
37016 if self.is_at_end() {
37017 return false;
37018 }
37019 if self.peek().text.eq_ignore_ascii_case(keyword) {
37020 self.skip();
37021 true
37022 } else {
37023 false
37024 }
37025 }
37026
37027 fn match_text_seq(&mut self, keywords: &[&str]) -> bool {
37029 for (i, &kw) in keywords.iter().enumerate() {
37030 if self.current + i >= self.tokens.len() {
37031 return false;
37032 }
37033 if !self.tokens[self.current + i].text.eq_ignore_ascii_case(kw) {
37034 return false;
37035 }
37036 }
37037 self.current += keywords.len();
37038 true
37039 }
37040
37041 fn check_text_seq(&self, keywords: &[&str]) -> bool {
37043 for (i, &kw) in keywords.iter().enumerate() {
37044 if self.current + i >= self.tokens.len() {
37045 return false;
37046 }
37047 if !self.tokens[self.current + i].text.eq_ignore_ascii_case(kw) {
37048 return false;
37049 }
37050 }
37051 true
37052 }
37053
37054 fn match_texts(&mut self, texts: &[&str]) -> bool {
37056 if self.is_at_end() {
37057 return false;
37058 }
37059 for text in texts {
37060 if self.peek().text.eq_ignore_ascii_case(text) {
37061 self.skip();
37062 return true;
37063 }
37064 }
37065 false
37066 }
37067
37068 fn parse_case(&mut self) -> Result<Expression> {
37070 self.expect(TokenType::Case)?;
37071 let case_comments = self.previous_trailing_comments().to_vec();
37073
37074 let operand = if !self.check(TokenType::When) {
37076 Some(self.parse_expression()?)
37077 } else {
37078 None
37079 };
37080
37081 let mut whens = Vec::new();
37082 while self.match_token(TokenType::When) {
37083 let condition = self.parse_expression()?;
37084 self.expect(TokenType::Then)?;
37085 let mut result = self.parse_expression()?;
37086 if matches!(
37089 self.config.dialect,
37090 Some(crate::dialects::DialectType::ClickHouse)
37091 ) && self.match_token(TokenType::As)
37092 {
37093 let alias = self.expect_identifier_or_keyword()?;
37094 result = Expression::Alias(Box::new(Alias {
37095 this: result,
37096 alias: Identifier::new(alias),
37097 column_aliases: Vec::new(),
37098 pre_alias_comments: Vec::new(),
37099 trailing_comments: Vec::new(),
37100 inferred_type: None,
37101 }));
37102 }
37103 whens.push((condition, result));
37104 }
37105
37106 let else_ = if self.match_token(TokenType::Else) {
37107 Some(self.parse_expression()?)
37108 } else {
37109 None
37110 };
37111
37112 self.expect(TokenType::End)?;
37113
37114 Ok(Expression::Case(Box::new(Case {
37115 operand,
37116 whens,
37117 else_,
37118 comments: case_comments,
37119 inferred_type: None,
37120 })))
37121 }
37122
37123 fn parse_cast(&mut self) -> Result<Expression> {
37125 self.expect(TokenType::Cast)?;
37126 self.expect(TokenType::LParen)?;
37127 let expr = self.parse_or()?;
37131
37132 let expr = if matches!(
37134 self.config.dialect,
37135 Some(crate::dialects::DialectType::ClickHouse)
37136 ) && self.match_token(TokenType::Parameter)
37137 {
37138 if self.check(TokenType::Colon) {
37139 return Err(
37140 self.parse_error("Expected true expression after ? in ClickHouse ternary")
37141 );
37142 }
37143 let true_value = self.parse_or()?;
37144 let false_value = if self.match_token(TokenType::Colon) {
37145 self.parse_or()?
37146 } else {
37147 Expression::Null(Null)
37148 };
37149 Expression::IfFunc(Box::new(IfFunc {
37150 original_name: None,
37151 condition: expr,
37152 true_value,
37153 false_value: Some(false_value),
37154 inferred_type: None,
37155 }))
37156 } else {
37157 expr
37158 };
37159
37160 let expr = self.try_clickhouse_implicit_alias(expr);
37162
37163 if matches!(
37165 self.config.dialect,
37166 Some(crate::dialects::DialectType::ClickHouse)
37167 ) && self.match_token(TokenType::Comma)
37168 {
37169 let type_expr = self.parse_expression()?;
37171 let type_expr = self.try_clickhouse_func_arg_alias(type_expr);
37173 self.expect(TokenType::RParen)?;
37174 let _trailing_comments = self.previous_trailing_comments().to_vec();
37175 return Ok(Expression::CastToStrType(Box::new(CastToStrType {
37176 this: Box::new(expr),
37177 to: Some(Box::new(type_expr)),
37178 })));
37179 }
37180
37181 self.expect(TokenType::As)?;
37182
37183 let expr = if matches!(
37186 self.config.dialect,
37187 Some(crate::dialects::DialectType::ClickHouse)
37188 ) && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
37189 && self
37190 .peek_nth(1)
37191 .map_or(false, |t| t.token_type == TokenType::As)
37192 {
37193 let alias = self.expect_identifier_or_keyword_with_quoted()?;
37194 self.expect(TokenType::As)?;
37195 Expression::Alias(Box::new(Alias::new(expr, alias)))
37196 } else if matches!(
37197 self.config.dialect,
37198 Some(crate::dialects::DialectType::ClickHouse)
37199 ) && (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
37200 && self
37201 .peek_nth(1)
37202 .map_or(false, |t| t.token_type == TokenType::Comma)
37203 {
37204 let alias = self.expect_identifier_or_keyword_with_quoted()?;
37206 let expr = Expression::Alias(Box::new(Alias::new(expr, alias)));
37207 self.expect(TokenType::Comma)?;
37208 let type_expr = self.parse_expression()?;
37209 let type_expr = self.try_clickhouse_func_arg_alias(type_expr);
37210 self.expect(TokenType::RParen)?;
37211 let _trailing_comments = self.previous_trailing_comments().to_vec();
37212 return Ok(Expression::CastToStrType(Box::new(CastToStrType {
37213 this: Box::new(expr),
37214 to: Some(Box::new(type_expr)),
37215 })));
37216 } else {
37217 expr
37218 };
37219
37220 if matches!(
37222 self.config.dialect,
37223 Some(crate::dialects::DialectType::Teradata)
37224 ) && self.match_token(TokenType::Format)
37225 {
37226 let format = Some(Box::new(self.parse_expression()?));
37227 self.expect(TokenType::RParen)?;
37228 let trailing_comments = self.previous_trailing_comments().to_vec();
37229 return Ok(Expression::Cast(Box::new(Cast {
37230 this: expr,
37231 to: DataType::Unknown,
37232 trailing_comments,
37233 double_colon_syntax: false,
37234 format,
37235 default: None,
37236 inferred_type: None,
37237 })));
37238 }
37239
37240 let data_type = self.parse_data_type()?;
37241
37242 let default = if self.match_token(TokenType::Default) {
37245 let default_val = self.parse_primary()?;
37246 if !self.match_text_seq(&["ON", "CONVERSION", "ERROR"]) {
37248 return Err(self.parse_error("Expected ON CONVERSION ERROR"));
37249 }
37250 Some(Box::new(default_val))
37251 } else {
37252 None
37253 };
37254
37255 let format = if self.match_token(TokenType::Format) {
37259 let wrapped = self.match_token(TokenType::LParen);
37260 let fmt_expr = self.parse_primary()?;
37261 if wrapped {
37262 self.expect(TokenType::RParen)?;
37263 }
37264 let fmt_with_tz = if self.match_text_seq(&["AT", "TIME", "ZONE"]) {
37266 let zone = self.parse_primary()?;
37267 Expression::AtTimeZone(Box::new(crate::expressions::AtTimeZone {
37268 this: fmt_expr,
37269 zone,
37270 }))
37271 } else {
37272 fmt_expr
37273 };
37274 Some(Box::new(fmt_with_tz))
37275 } else if self.match_token(TokenType::Comma) {
37276 Some(Box::new(self.parse_expression()?))
37278 } else {
37279 None
37280 };
37281
37282 self.expect(TokenType::RParen)?;
37283 let trailing_comments = self.previous_trailing_comments().to_vec();
37284
37285 Ok(Expression::Cast(Box::new(Cast {
37286 this: expr,
37287 to: data_type,
37288 trailing_comments,
37289 double_colon_syntax: false,
37290 format,
37291 default,
37292 inferred_type: None,
37293 })))
37294 }
37295
37296 fn parse_try_cast(&mut self) -> Result<Expression> {
37298 self.expect(TokenType::TryCast)?;
37299 self.expect(TokenType::LParen)?;
37300 let expr = self.parse_or()?;
37301 self.expect(TokenType::As)?;
37302 let data_type = self.parse_data_type()?;
37303
37304 let format = if self.match_token(TokenType::Format) {
37306 Some(Box::new(self.parse_expression()?))
37307 } else {
37308 None
37309 };
37310
37311 self.expect(TokenType::RParen)?;
37312 let trailing_comments = self.previous_trailing_comments().to_vec();
37313
37314 Ok(Expression::TryCast(Box::new(Cast {
37315 this: expr,
37316 to: data_type,
37317 trailing_comments,
37318 double_colon_syntax: false,
37319 format,
37320 default: None,
37321 inferred_type: None,
37322 })))
37323 }
37324
37325 fn parse_safe_cast(&mut self) -> Result<Expression> {
37327 self.expect(TokenType::SafeCast)?;
37328 self.expect(TokenType::LParen)?;
37329 let expr = self.parse_or()?;
37330 self.expect(TokenType::As)?;
37331 let data_type = self.parse_data_type()?;
37332
37333 let format = if self.match_token(TokenType::Format) {
37335 Some(Box::new(self.parse_expression()?))
37336 } else {
37337 None
37338 };
37339
37340 self.expect(TokenType::RParen)?;
37341 let trailing_comments = self.previous_trailing_comments().to_vec();
37342
37343 Ok(Expression::SafeCast(Box::new(Cast {
37344 this: expr,
37345 to: data_type,
37346 trailing_comments,
37347 double_colon_syntax: false,
37348 format,
37349 default: None,
37350 inferred_type: None,
37351 })))
37352 }
37353
37354 fn parse_data_type(&mut self) -> Result<DataType> {
37356 if self.check(TokenType::Geometry) {
37359 let _token = self.advance();
37360 let (subtype, srid) = self.parse_spatial_type_args()?;
37361 return Ok(DataType::Geometry { subtype, srid });
37362 }
37363 let mut raw_name = self.expect_identifier_or_keyword()?;
37365 while self.match_token(TokenType::Dot) {
37367 let part = self.expect_identifier_or_keyword()?;
37368 raw_name.push('.');
37369 raw_name.push_str(&part);
37370 }
37371 let mut name = raw_name.to_ascii_uppercase();
37372
37373 if name == "NATIONAL" {
37375 let next_upper = if !self.is_at_end() {
37376 self.peek().text.to_ascii_uppercase()
37377 } else {
37378 String::new()
37379 };
37380 if next_upper == "CHAR" || next_upper == "CHARACTER" {
37381 self.skip(); name = "NCHAR".to_string();
37383 if next_upper == "CHARACTER" && self.check_identifier("VARYING") {
37385 self.skip(); let length = if self.match_token(TokenType::LParen) {
37387 if self.check(TokenType::RParen) {
37388 self.skip();
37389 None
37390 } else {
37391 let n = self.expect_number()? as u32;
37392 self.expect(TokenType::RParen)?;
37393 Some(n)
37394 }
37395 } else {
37396 None
37397 };
37398 return Ok(DataType::VarChar {
37399 length,
37400 parenthesized_length: false,
37401 });
37402 }
37403 }
37404 }
37405
37406 let base_type = match name.as_str() {
37407 "INT" | "INTEGER" => {
37408 let length = if self.match_token(TokenType::LParen) {
37410 if self.check(TokenType::RParen) {
37411 self.skip();
37412 None
37413 } else {
37414 let n = self.expect_number()? as u32;
37415 self.expect(TokenType::RParen)?;
37416 Some(n)
37417 }
37418 } else {
37419 None
37420 };
37421 let integer_spelling = name == "INTEGER";
37422 Ok(DataType::Int {
37423 length,
37424 integer_spelling,
37425 })
37426 }
37427 "BIGINT" => {
37428 let length = if self.match_token(TokenType::LParen) {
37430 if self.check(TokenType::RParen) {
37431 self.skip();
37432 None
37433 } else {
37434 let n = self.expect_number()? as u32;
37435 self.expect(TokenType::RParen)?;
37436 Some(n)
37437 }
37438 } else {
37439 None
37440 };
37441 Ok(DataType::BigInt { length })
37442 }
37443 "SMALLINT" => {
37444 let length = if self.match_token(TokenType::LParen) {
37445 if self.check(TokenType::RParen) {
37446 self.skip();
37447 None
37448 } else {
37449 let n = self.expect_number()? as u32;
37450 self.expect(TokenType::RParen)?;
37451 Some(n)
37452 }
37453 } else {
37454 None
37455 };
37456 Ok(DataType::SmallInt { length })
37457 }
37458 "TINYINT" => {
37459 let length = if self.match_token(TokenType::LParen) {
37460 if self.check(TokenType::RParen) {
37461 self.skip();
37462 None
37463 } else {
37464 let n = self.expect_number()? as u32;
37465 self.expect(TokenType::RParen)?;
37466 Some(n)
37467 }
37468 } else {
37469 None
37470 };
37471 Ok(DataType::TinyInt { length })
37472 }
37473 "FLOAT" | "REAL" => {
37474 let real_spelling = name == "REAL";
37475 let (precision, scale) = if self.match_token(TokenType::LParen) {
37477 let p = self.expect_number()? as u32;
37478 let s = if self.match_token(TokenType::Comma) {
37479 Some(self.expect_number()? as u32)
37480 } else {
37481 None
37482 };
37483 self.expect(TokenType::RParen)?;
37484 (Some(p), s)
37485 } else {
37486 (None, None)
37487 };
37488 Ok(DataType::Float {
37489 precision,
37490 scale,
37491 real_spelling,
37492 })
37493 }
37494 "BINARY_FLOAT" => {
37495 Ok(DataType::Float {
37497 precision: None,
37498 scale: None,
37499 real_spelling: false,
37500 })
37501 }
37502 "BINARY_DOUBLE" => {
37503 Ok(DataType::Double {
37505 precision: None,
37506 scale: None,
37507 })
37508 }
37509 "DOUBLE" => {
37510 let _ = self.match_identifier("PRECISION");
37512 let (precision, scale) = if self.match_token(TokenType::LParen) {
37514 let p = self.expect_number()? as u32;
37515 let s = if self.match_token(TokenType::Comma) {
37516 Some(self.expect_number()? as u32)
37517 } else {
37518 None
37519 };
37520 self.expect(TokenType::RParen)?;
37521 (Some(p), s)
37522 } else {
37523 (None, None)
37524 };
37525 Ok(DataType::Double { precision, scale })
37526 }
37527 "DECIMAL" | "NUMERIC" => {
37528 let (precision, scale) = if self.match_token(TokenType::LParen) {
37529 let p = self.expect_number()? as u32;
37530 let s = if self.match_token(TokenType::Comma) {
37531 Some(self.expect_number()? as u32)
37532 } else {
37533 None
37534 };
37535 self.expect(TokenType::RParen)?;
37536 (Some(p), s)
37537 } else {
37538 (None, None)
37539 };
37540 Ok(DataType::Decimal { precision, scale })
37541 }
37542 "BOOLEAN" | "BOOL" => Ok(DataType::Boolean),
37543 "CHAR" | "CHARACTER" | "NCHAR" => {
37544 let is_nchar = name == "NCHAR";
37545 if self.match_identifier("LARGE") && self.match_identifier("OBJECT") {
37547 return Ok(DataType::Text);
37548 }
37549 if self.match_identifier("VARYING") {
37551 let length = if self.match_token(TokenType::LParen) {
37552 if self.check(TokenType::RParen) {
37553 self.skip();
37554 None
37555 } else {
37556 let n = self.expect_number()? as u32;
37557 self.expect(TokenType::RParen)?;
37558 Some(n)
37559 }
37560 } else {
37561 None
37562 };
37563 Ok(DataType::VarChar {
37564 length,
37565 parenthesized_length: false,
37566 })
37567 } else {
37568 let length = if self.match_token(TokenType::LParen) {
37569 if self.check(TokenType::RParen) {
37571 self.skip(); None
37573 } else {
37574 let n = self.expect_number()? as u32;
37575 self.expect(TokenType::RParen)?;
37576 Some(n)
37577 }
37578 } else {
37579 None
37580 };
37581 if length.is_none()
37585 && self.match_identifier("CHARACTER")
37586 && self.match_token(TokenType::Set)
37587 {
37588 let charset = self.expect_identifier_or_keyword()?;
37589 return Ok(DataType::CharacterSet { name: charset });
37590 }
37591 if is_nchar {
37594 let name = if let Some(len) = length {
37595 format!("NCHAR({})", len)
37596 } else {
37597 "NCHAR".to_string()
37598 };
37599 return Ok(DataType::Custom { name });
37600 }
37601 Ok(DataType::Char { length })
37602 }
37603 }
37604 "VARCHAR" | "NVARCHAR" => {
37605 let is_nvarchar = name == "NVARCHAR";
37606 if self.match_token(TokenType::LParen) {
37607 if self.check(TokenType::RParen) {
37609 self.skip(); if is_nvarchar {
37611 return Ok(DataType::Custom {
37612 name: "NVARCHAR".to_string(),
37613 });
37614 }
37615 Ok(DataType::VarChar {
37616 length: None,
37617 parenthesized_length: false,
37618 })
37619 } else if self.check_identifier("MAX") {
37620 self.skip(); self.expect(TokenType::RParen)?;
37623 let type_name = if is_nvarchar {
37624 "NVARCHAR(MAX)"
37625 } else {
37626 "VARCHAR(MAX)"
37627 };
37628 Ok(DataType::Custom {
37629 name: type_name.to_string(),
37630 })
37631 } else {
37632 let parenthesized_length = self.match_token(TokenType::LParen);
37634 let n = self.expect_number()? as u32;
37635 if parenthesized_length {
37636 self.expect(TokenType::RParen)?;
37637 }
37638 self.expect(TokenType::RParen)?;
37639 if is_nvarchar {
37641 return Ok(DataType::Custom {
37642 name: format!("NVARCHAR({})", n),
37643 });
37644 }
37645 Ok(DataType::VarChar {
37646 length: Some(n),
37647 parenthesized_length,
37648 })
37649 }
37650 } else {
37651 if is_nvarchar {
37652 return Ok(DataType::Custom {
37653 name: "NVARCHAR".to_string(),
37654 });
37655 }
37656 Ok(DataType::VarChar {
37657 length: None,
37658 parenthesized_length: false,
37659 })
37660 }
37661 }
37662 "TEXT" | "NTEXT" => {
37663 if self.match_token(TokenType::LParen) {
37665 let n = self.expect_number()? as u32;
37666 self.expect(TokenType::RParen)?;
37667 Ok(DataType::TextWithLength { length: n })
37668 } else {
37669 Ok(DataType::Text)
37670 }
37671 }
37672 "STRING" => {
37673 let length = if self.match_token(TokenType::LParen) {
37675 let n = self.expect_number()? as u32;
37676 self.expect(TokenType::RParen)?;
37677 Some(n)
37678 } else {
37679 None
37680 };
37681 Ok(DataType::String { length })
37682 }
37683 "DATE" => Ok(DataType::Date),
37684 "TIME" => {
37685 if matches!(
37687 self.config.dialect,
37688 Some(crate::dialects::DialectType::ClickHouse)
37689 ) && self.check(TokenType::LParen)
37690 && self.current + 1 < self.tokens.len()
37691 && self.tokens[self.current + 1].token_type == TokenType::String
37692 {
37693 self.skip(); let args = self.parse_custom_type_args_balanced()?;
37695 self.expect(TokenType::RParen)?;
37696 return Ok(DataType::Custom {
37697 name: format!("Time({})", args),
37698 });
37699 }
37700 let precision = if self.match_token(TokenType::LParen) {
37701 if self.check(TokenType::RParen) {
37702 self.skip();
37703 None
37704 } else {
37705 let p = self.expect_number()? as u32;
37706 self.expect(TokenType::RParen)?;
37707 Some(p)
37708 }
37709 } else {
37710 None
37711 };
37712 let timezone = if self.match_token(TokenType::With) {
37714 self.match_keyword("TIME");
37715 self.match_keyword("ZONE");
37716 true
37717 } else if self.match_keyword("WITHOUT") {
37718 self.match_keyword("TIME");
37719 self.match_keyword("ZONE");
37720 false
37721 } else {
37722 false
37723 };
37724 Ok(DataType::Time {
37725 precision,
37726 timezone,
37727 })
37728 }
37729 "TIMETZ" => {
37730 let precision = if self.match_token(TokenType::LParen) {
37731 let p = self.expect_number()? as u32;
37732 self.expect(TokenType::RParen)?;
37733 Some(p)
37734 } else {
37735 None
37736 };
37737 Ok(DataType::Time {
37738 precision,
37739 timezone: true,
37740 })
37741 }
37742 "TIMESTAMP" => {
37743 let precision = if self.match_token(TokenType::LParen) {
37745 let p = self.expect_number()? as u32;
37746 self.expect(TokenType::RParen)?;
37747 Some(p)
37748 } else {
37749 None
37750 };
37751 if self.match_token(TokenType::With) {
37754 if self.match_token(TokenType::Local) {
37757 self.match_keyword("TIME");
37758 self.match_keyword("ZONE");
37759 Ok(DataType::Custom {
37761 name: "TIMESTAMPLTZ".to_string(),
37762 })
37763 } else {
37764 self.match_keyword("TIME");
37765 self.match_keyword("ZONE");
37766 Ok(DataType::Timestamp {
37767 precision,
37768 timezone: true,
37769 })
37770 }
37771 } else if self.match_keyword("WITHOUT") {
37772 self.match_keyword("TIME");
37773 self.match_keyword("ZONE");
37774 Ok(DataType::Timestamp {
37775 precision,
37776 timezone: false,
37777 })
37778 } else {
37779 Ok(DataType::Timestamp {
37780 precision,
37781 timezone: false,
37782 })
37783 }
37784 }
37785 "TIMESTAMPTZ" => {
37786 let precision = if self.match_token(TokenType::LParen) {
37787 let p = self.expect_number()? as u32;
37788 self.expect(TokenType::RParen)?;
37789 Some(p)
37790 } else {
37791 None
37792 };
37793 Ok(DataType::Timestamp {
37794 precision,
37795 timezone: true,
37796 })
37797 }
37798 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
37799 let precision = if self.match_token(TokenType::LParen) {
37800 let p = self.expect_number()? as u32;
37801 self.expect(TokenType::RParen)?;
37802 Some(p)
37803 } else {
37804 None
37805 };
37806 let name = if let Some(p) = precision {
37807 format!("TIMESTAMPLTZ({})", p)
37808 } else {
37809 "TIMESTAMPLTZ".to_string()
37810 };
37811 Ok(DataType::Custom { name })
37812 }
37813 "INTERVAL" => {
37814 let unit = if (self.check(TokenType::Identifier)
37817 || self.check(TokenType::Var)
37818 || self.check_keyword())
37819 && !self.check(TokenType::Generated)
37820 && !self.check(TokenType::As)
37821 && !self.check(TokenType::Not)
37822 && !self.check(TokenType::Null)
37823 && !self.check(TokenType::Default)
37824 && !self.check(TokenType::PrimaryKey)
37825 && !self.check(TokenType::Unique)
37826 && !self.check(TokenType::Check)
37827 && !self.check(TokenType::Constraint)
37828 && !self.check(TokenType::References)
37829 && !self.check(TokenType::Collate)
37830 && !self.check(TokenType::Comment)
37831 && !self.check(TokenType::RParen)
37832 && !self.check(TokenType::Comma)
37833 {
37834 Some(self.advance().text.to_ascii_uppercase())
37835 } else {
37836 None
37837 };
37838 let to = if self.match_token(TokenType::To) {
37840 if self.check(TokenType::Identifier)
37841 || self.check(TokenType::Var)
37842 || self.check_keyword()
37843 {
37844 Some(self.advance().text.to_ascii_uppercase())
37845 } else {
37846 None
37847 }
37848 } else {
37849 None
37850 };
37851 Ok(DataType::Interval { unit, to })
37852 }
37853 "JSON" => {
37854 if matches!(
37855 self.config.dialect,
37856 Some(crate::dialects::DialectType::ClickHouse)
37857 ) && self.match_token(TokenType::LParen)
37858 {
37859 let args = self.parse_custom_type_args_balanced()?;
37861 self.expect(TokenType::RParen)?;
37862 let args = Self::uppercase_json_type_skip_keyword(&args);
37865 Ok(DataType::Custom {
37866 name: format!("JSON({})", args),
37867 })
37868 } else {
37869 Ok(DataType::Json)
37870 }
37871 }
37872 "JSONB" => Ok(DataType::JsonB),
37873 "UUID" => Ok(DataType::Uuid),
37874 "BLOB" => Ok(DataType::Blob),
37875 "BYTEA" => Ok(DataType::VarBinary { length: None }),
37876 "BIT" => {
37877 let length = if self.match_token(TokenType::LParen) {
37878 let n = self.expect_number()? as u32;
37879 self.expect(TokenType::RParen)?;
37880 Some(n)
37881 } else {
37882 None
37883 };
37884 Ok(DataType::Bit { length })
37885 }
37886 "VARBIT" | "BIT VARYING" => {
37887 let length = if self.match_token(TokenType::LParen) {
37888 let n = self.expect_number()? as u32;
37889 self.expect(TokenType::RParen)?;
37890 Some(n)
37891 } else {
37892 None
37893 };
37894 Ok(DataType::VarBit { length })
37895 }
37896 "BINARY" => {
37897 if self.match_identifier("LARGE") && self.match_identifier("OBJECT") {
37899 return Ok(DataType::Blob);
37900 }
37901 if self.match_identifier("VARYING") {
37903 let length = if self.match_token(TokenType::LParen) {
37904 let len = self.expect_number()? as u32;
37905 self.expect(TokenType::RParen)?;
37906 Some(len)
37907 } else {
37908 None
37909 };
37910 Ok(DataType::VarBinary { length })
37911 } else {
37912 let length = if self.match_token(TokenType::LParen) {
37913 let len = self.expect_number()? as u32;
37914 self.expect(TokenType::RParen)?;
37915 Some(len)
37916 } else {
37917 None
37918 };
37919 Ok(DataType::Binary { length })
37920 }
37921 }
37922 "VARBINARY" => {
37923 let length = if self.match_token(TokenType::LParen) {
37924 let len = self.expect_number()? as u32;
37925 self.expect(TokenType::RParen)?;
37926 Some(len)
37927 } else {
37928 None
37929 };
37930 Ok(DataType::VarBinary { length })
37931 }
37932 "ARRAY" => {
37934 if self.match_token(TokenType::Lt) {
37935 let element_type = self.parse_data_type()?;
37937 self.expect_gt()?;
37938 Ok(DataType::Array {
37939 element_type: Box::new(element_type),
37940 dimension: None,
37941 })
37942 } else if self.match_token(TokenType::LParen) {
37943 let element_type = self.parse_data_type()?;
37945 self.expect(TokenType::RParen)?;
37946 Ok(DataType::Array {
37947 element_type: Box::new(element_type),
37948 dimension: None,
37949 })
37950 } else {
37951 Ok(DataType::Custom {
37953 name: "ARRAY".to_string(),
37954 })
37955 }
37956 }
37957 "MAP" => {
37958 if self.match_token(TokenType::Lt) {
37959 let key_type = self.parse_data_type()?;
37961 self.expect(TokenType::Comma)?;
37962 let value_type = self.parse_data_type()?;
37963 self.expect_gt()?;
37964 Ok(DataType::Map {
37965 key_type: Box::new(key_type),
37966 value_type: Box::new(value_type),
37967 })
37968 } else if self.match_token(TokenType::LBracket) {
37969 let key_type = self.parse_data_type()?;
37971 self.expect(TokenType::FArrow)?;
37972 let value_type = self.parse_data_type()?;
37973 self.expect(TokenType::RBracket)?;
37974 Ok(DataType::Map {
37975 key_type: Box::new(key_type),
37976 value_type: Box::new(value_type),
37977 })
37978 } else if self.match_token(TokenType::LParen) {
37979 let key_type = self.parse_data_type()?;
37981 self.expect(TokenType::Comma)?;
37982 let value_type = self.parse_data_type()?;
37983 self.expect(TokenType::RParen)?;
37984 Ok(DataType::Map {
37985 key_type: Box::new(key_type),
37986 value_type: Box::new(value_type),
37987 })
37988 } else {
37989 Ok(DataType::Custom {
37991 name: "MAP".to_string(),
37992 })
37993 }
37994 }
37995 "VECTOR" => {
37998 if self.match_token(TokenType::LParen) {
37999 if self.check(TokenType::Number) {
38000 let dimension = self.expect_number()? as u32;
38002 let element_type = if self.match_token(TokenType::Comma) {
38003 let type_alias = self.expect_identifier_or_keyword()?;
38005 let mapped_type = match type_alias.to_ascii_uppercase().as_str() {
38006 "I8" => DataType::TinyInt { length: None },
38007 "I16" => DataType::SmallInt { length: None },
38008 "I32" => DataType::Int {
38009 length: None,
38010 integer_spelling: false,
38011 },
38012 "I64" => DataType::BigInt { length: None },
38013 "F32" => DataType::Float {
38014 precision: None,
38015 scale: None,
38016 real_spelling: false,
38017 },
38018 "F64" => DataType::Double {
38019 precision: None,
38020 scale: None,
38021 },
38022 _ => DataType::Custom {
38023 name: type_alias.to_string(),
38024 },
38025 };
38026 Some(Box::new(mapped_type))
38027 } else {
38028 None
38030 };
38031 self.expect(TokenType::RParen)?;
38032 Ok(DataType::Vector {
38033 element_type,
38034 dimension: Some(dimension),
38035 })
38036 } else {
38037 let element_type = self.parse_data_type()?;
38039 self.expect(TokenType::Comma)?;
38040 let dimension = self.expect_number()? as u32;
38041 self.expect(TokenType::RParen)?;
38042 Ok(DataType::Vector {
38043 element_type: Some(Box::new(element_type)),
38044 dimension: Some(dimension),
38045 })
38046 }
38047 } else {
38048 Ok(DataType::Custom {
38049 name: "VECTOR".to_string(),
38050 })
38051 }
38052 }
38053 "OBJECT" => {
38055 if self.match_token(TokenType::LParen) {
38056 if matches!(
38058 self.config.dialect,
38059 Some(crate::dialects::DialectType::ClickHouse)
38060 ) && self.check(TokenType::String)
38061 {
38062 let arg = self.advance().text;
38063 self.expect(TokenType::RParen)?;
38064 return Ok(DataType::Custom {
38065 name: format!("Object('{}')", arg),
38066 });
38067 }
38068 let mut fields = Vec::new();
38069 if !self.check(TokenType::RParen) {
38070 loop {
38071 let field_name = self.expect_identifier_or_keyword()?;
38072 let field_type = self.parse_data_type()?;
38073 let not_null = if self.match_keyword("NOT") {
38075 self.match_keyword("NULL");
38077 true
38078 } else {
38079 false
38080 };
38081 fields.push((field_name, field_type, not_null));
38082 if !self.match_token(TokenType::Comma) {
38083 break;
38084 }
38085 }
38086 }
38087 self.expect(TokenType::RParen)?;
38088 let modifier = if self.match_keyword("RENAME") {
38090 if self.match_keyword("FIELDS") {
38091 Some("RENAME FIELDS".to_string())
38092 } else {
38093 Some("RENAME".to_string())
38094 }
38095 } else if self.match_keyword("ADD") {
38096 if self.match_keyword("FIELDS") {
38097 Some("ADD FIELDS".to_string())
38098 } else {
38099 Some("ADD".to_string())
38100 }
38101 } else {
38102 None
38103 };
38104 Ok(DataType::Object { fields, modifier })
38105 } else {
38106 Ok(DataType::Custom {
38107 name: "OBJECT".to_string(),
38108 })
38109 }
38110 }
38111 "STRUCT" => {
38112 if self.match_token(TokenType::Lt) {
38113 let fields = self.parse_struct_type_fields(false)?;
38115 self.expect_gt()?;
38116 Ok(DataType::Struct {
38117 fields,
38118 nested: false,
38119 })
38120 } else if self.match_token(TokenType::LParen) {
38121 let fields = self.parse_struct_type_fields(true)?;
38123 self.expect(TokenType::RParen)?;
38124 Ok(DataType::Struct {
38125 fields,
38126 nested: true,
38127 })
38128 } else {
38129 Ok(DataType::Custom {
38131 name: "STRUCT".to_string(),
38132 })
38133 }
38134 }
38135 "ROW" => {
38136 if self.match_token(TokenType::LParen) {
38138 let fields = self.parse_struct_type_fields(true)?;
38139 self.expect(TokenType::RParen)?;
38140 Ok(DataType::Struct {
38141 fields,
38142 nested: true,
38143 })
38144 } else {
38145 Ok(DataType::Custom {
38146 name: "ROW".to_string(),
38147 })
38148 }
38149 }
38150 "RECORD" => {
38151 if self.match_token(TokenType::LParen) {
38153 let fields = self.parse_struct_type_fields(true)?;
38154 self.expect(TokenType::RParen)?;
38155 Ok(DataType::Struct {
38157 fields,
38158 nested: true,
38159 })
38160 } else {
38161 Ok(DataType::Custom {
38162 name: "RECORD".to_string(),
38163 })
38164 }
38165 }
38166 "ENUM" => {
38167 if self.match_token(TokenType::LParen) {
38171 let mut values = Vec::new();
38172 let mut assignments = Vec::new();
38173 if !self.check(TokenType::RParen) {
38174 loop {
38175 let val = if matches!(
38176 self.config.dialect,
38177 Some(crate::dialects::DialectType::ClickHouse)
38178 ) && self.check(TokenType::Null)
38179 {
38180 self.skip();
38181 "NULL".to_string()
38182 } else {
38183 self.expect_string()?
38184 };
38185 values.push(val);
38186 if self.match_token(TokenType::Eq) {
38188 let negative = self.match_token(TokenType::Dash);
38189 let num_token = self.advance();
38190 let val = if negative {
38191 format!("-{}", num_token.text)
38192 } else {
38193 num_token.text.clone()
38194 };
38195 assignments.push(Some(val));
38196 } else {
38197 assignments.push(None);
38198 }
38199 if !self.match_token(TokenType::Comma) {
38200 break;
38201 }
38202 }
38203 }
38204 self.expect(TokenType::RParen)?;
38205 Ok(DataType::Enum {
38206 values,
38207 assignments,
38208 })
38209 } else {
38210 Ok(DataType::Custom {
38211 name: "ENUM".to_string(),
38212 })
38213 }
38214 }
38215 "SET" => {
38216 if self.match_token(TokenType::LParen) {
38218 let mut values = Vec::new();
38219 if !self.check(TokenType::RParen) {
38220 loop {
38221 let val = self.expect_string()?;
38222 values.push(val);
38223 if !self.match_token(TokenType::Comma) {
38224 break;
38225 }
38226 }
38227 }
38228 self.expect(TokenType::RParen)?;
38229 Ok(DataType::Set { values })
38230 } else {
38231 Ok(DataType::Custom {
38232 name: "SET".to_string(),
38233 })
38234 }
38235 }
38236 "UNION" if self.check(TokenType::LParen) => {
38237 self.skip(); let struct_fields = self.parse_struct_type_fields(true)?;
38240 self.expect(TokenType::RParen)?;
38241 let fields: Vec<(String, DataType)> = struct_fields
38243 .into_iter()
38244 .map(|f| (f.name, f.data_type))
38245 .collect();
38246 Ok(DataType::Union { fields })
38247 }
38248 "GEOMETRY" => {
38250 let (subtype, srid) = self.parse_spatial_type_args()?;
38251 Ok(DataType::Geometry { subtype, srid })
38252 }
38253 "GEOGRAPHY" => {
38254 let (subtype, srid) = self.parse_spatial_type_args()?;
38255 Ok(DataType::Geography { subtype, srid })
38256 }
38257 "POINT" | "LINESTRING" | "POLYGON" | "MULTIPOINT" | "MULTILINESTRING"
38259 | "MULTIPOLYGON" | "GEOMETRYCOLLECTION" => {
38260 let srid = if self.match_identifier("SRID") {
38262 Some(self.expect_number()? as u32)
38263 } else {
38264 None
38265 };
38266 Ok(DataType::Geometry {
38267 subtype: Some(name),
38268 srid,
38269 })
38270 }
38271 "ANY" => {
38273 if self.match_token(TokenType::Type) {
38274 Ok(DataType::Custom {
38275 name: "ANY TYPE".to_string(),
38276 })
38277 } else {
38278 Ok(DataType::Custom {
38279 name: "ANY".to_string(),
38280 })
38281 }
38282 }
38283 "LONG" => {
38285 if self.match_identifier("VARCHAR") {
38286 Ok(DataType::Text)
38287 } else {
38288 Ok(DataType::Custom {
38289 name: "LONG".to_string(),
38290 })
38291 }
38292 }
38293 "SIGNED" | "UNSIGNED" => {
38296 if self.check_identifier("INTEGER")
38298 || self.check_keyword_text("INTEGER")
38299 || self.check_keyword_text("INT")
38300 {
38301 self.skip();
38302 }
38303 Ok(DataType::Custom { name })
38304 }
38305 "NULLABLE" => {
38307 self.expect(TokenType::LParen)?;
38308 let inner = self.parse_data_type()?;
38309 self.expect(TokenType::RParen)?;
38310 Ok(DataType::Nullable {
38311 inner: Box::new(inner),
38312 })
38313 }
38314 _ => {
38315 let is_known = convert_name_is_known_custom(&name);
38320 let custom_name = if is_known {
38321 name.clone()
38322 } else {
38323 raw_name.clone()
38324 };
38325 if self.match_token(TokenType::LParen) {
38326 if matches!(
38327 self.config.dialect,
38328 Some(crate::dialects::DialectType::ClickHouse)
38329 ) {
38330 let args = self.parse_custom_type_args_balanced()?;
38331 self.expect(TokenType::RParen)?;
38332 Ok(DataType::Custom {
38333 name: format!("{}({})", custom_name, args),
38334 })
38335 } else {
38336 let mut args = Vec::new();
38337 let mut after_comma = true; loop {
38339 if self.check(TokenType::RParen) {
38340 break;
38341 }
38342 let token = self.advance();
38343 if !after_comma && !args.is_empty() {
38346 if let Some(last) = args.last_mut() {
38347 *last = format!("{} {}", last, token.text);
38348 }
38349 } else {
38350 args.push(token.text.clone());
38351 }
38352 after_comma = self.match_token(TokenType::Comma);
38353 }
38354 self.expect(TokenType::RParen)?;
38355 Ok(DataType::Custom {
38357 name: format!("{}({})", custom_name, args.join(", ")),
38358 })
38359 }
38360 } else {
38361 Ok(DataType::Custom { name: custom_name })
38362 }
38363 }
38364 }?;
38365
38366 let mut result_type = base_type;
38370
38371 let is_materialize = matches!(
38373 self.config.dialect,
38374 Some(crate::dialects::DialectType::Materialize)
38375 );
38376 if is_materialize {
38377 while self.check_identifier("LIST") || self.check(TokenType::List) {
38378 self.skip(); result_type = DataType::List {
38380 element_type: Box::new(result_type),
38381 };
38382 }
38383 }
38384
38385 let result_type = self.maybe_parse_array_dimensions(result_type)?;
38387
38388 if matches!(
38393 self.config.dialect,
38394 Some(crate::dialects::DialectType::ClickHouse)
38395 ) {
38396 return Ok(Self::clickhouse_mark_non_nullable(result_type));
38397 }
38398
38399 Ok(result_type)
38400 }
38401
38402 fn clickhouse_mark_non_nullable(dt: DataType) -> DataType {
38405 match dt {
38406 DataType::Text => DataType::Custom {
38407 name: "String".to_string(),
38408 },
38409 DataType::VarChar { .. } => DataType::Custom {
38410 name: "String".to_string(),
38411 },
38412 DataType::Char { .. } => DataType::Custom {
38413 name: "String".to_string(),
38414 },
38415 DataType::String { .. } => DataType::Custom {
38416 name: "String".to_string(),
38417 },
38418 _ => dt,
38419 }
38420 }
38421
38422 fn parse_data_type_for_cast(&mut self) -> Result<DataType> {
38428 let supports_array_type_suffix = matches!(
38432 self.config.dialect,
38433 Some(crate::dialects::DialectType::DuckDB)
38434 | Some(crate::dialects::DialectType::PostgreSQL)
38435 | Some(crate::dialects::DialectType::Redshift)
38436 );
38437
38438 let is_quoted = self.check(TokenType::QuotedIdentifier);
38440 let raw_name = self.expect_identifier_or_keyword()?;
38441 if is_quoted {
38442 let known_type = self.convert_name_to_type(&raw_name);
38444 if let Ok(ref dt) = known_type {
38445 if !matches!(dt, DataType::Custom { .. }) {
38446 return known_type;
38447 }
38448 }
38449 return Ok(DataType::Custom {
38451 name: format!("\"{}\"", raw_name),
38452 });
38453 }
38454 let name = raw_name.to_ascii_uppercase();
38455
38456 let base_type = match name.as_str() {
38458 "ARRAY" => {
38459 if self.match_token(TokenType::Lt) {
38460 let element_type = self.parse_data_type()?;
38461 self.expect_gt()?;
38462 DataType::Array {
38463 element_type: Box::new(element_type),
38464 dimension: None,
38465 }
38466 } else if self.match_token(TokenType::LParen) {
38467 let element_type = self.parse_data_type_for_cast()?;
38469 self.expect(TokenType::RParen)?;
38470 DataType::Array {
38471 element_type: Box::new(element_type),
38472 dimension: None,
38473 }
38474 } else {
38475 DataType::Custom { name }
38476 }
38477 }
38478 "MAP" => {
38479 if self.match_token(TokenType::Lt) {
38480 let key_type = self.parse_data_type()?;
38481 self.expect(TokenType::Comma)?;
38482 let value_type = self.parse_data_type()?;
38483 self.expect_gt()?;
38484 DataType::Map {
38485 key_type: Box::new(key_type),
38486 value_type: Box::new(value_type),
38487 }
38488 } else if self.match_token(TokenType::LParen) {
38489 let key_type = self.parse_data_type_for_cast()?;
38491 self.expect(TokenType::Comma)?;
38492 let value_type = self.parse_data_type_for_cast()?;
38493 self.expect(TokenType::RParen)?;
38494 DataType::Map {
38495 key_type: Box::new(key_type),
38496 value_type: Box::new(value_type),
38497 }
38498 } else if self.match_token(TokenType::LBracket) {
38499 let key_type = self.parse_data_type_for_cast()?;
38501 self.expect(TokenType::FArrow)?;
38502 let value_type = self.parse_data_type_for_cast()?;
38503 self.expect(TokenType::RBracket)?;
38504 DataType::Map {
38505 key_type: Box::new(key_type),
38506 value_type: Box::new(value_type),
38507 }
38508 } else {
38509 DataType::Custom { name }
38510 }
38511 }
38512 "STRUCT" => {
38513 if self.match_token(TokenType::Lt) {
38514 let fields = self.parse_struct_type_fields(false)?;
38515 self.expect_gt()?;
38516 DataType::Struct {
38517 fields,
38518 nested: false,
38519 }
38520 } else if self.match_token(TokenType::LParen) {
38521 let fields = self.parse_struct_type_fields(true)?;
38522 self.expect(TokenType::RParen)?;
38523 DataType::Struct {
38524 fields,
38525 nested: true,
38526 }
38527 } else {
38528 DataType::Custom { name }
38529 }
38530 }
38531 "ROW" => {
38532 if self.match_token(TokenType::LParen) {
38533 let fields = self.parse_struct_type_fields(true)?;
38534 self.expect(TokenType::RParen)?;
38535 DataType::Struct {
38536 fields,
38537 nested: true,
38538 }
38539 } else {
38540 DataType::Custom { name }
38541 }
38542 }
38543 "RECORD" => {
38544 if self.match_token(TokenType::LParen) {
38546 let fields = self.parse_struct_type_fields(true)?;
38547 self.expect(TokenType::RParen)?;
38548 DataType::Struct {
38549 fields,
38550 nested: true,
38551 }
38552 } else {
38553 DataType::Custom { name }
38554 }
38555 }
38556 "DOUBLE" => {
38558 let _ = self.match_identifier("PRECISION");
38560 let (precision, scale) = if self.match_token(TokenType::LParen) {
38562 let p = Some(self.expect_number()? as u32);
38563 let s = if self.match_token(TokenType::Comma) {
38564 Some(self.expect_number()? as u32)
38565 } else {
38566 None
38567 };
38568 self.expect(TokenType::RParen)?;
38569 (p, s)
38570 } else {
38571 (None, None)
38572 };
38573 DataType::Double { precision, scale }
38574 }
38575 "CHARACTER" | "CHAR" | "NCHAR" => {
38576 if self.match_identifier("VARYING") {
38578 let length = if self.match_token(TokenType::LParen) {
38579 let len = Some(self.expect_number()? as u32);
38580 self.expect(TokenType::RParen)?;
38581 len
38582 } else {
38583 None
38584 };
38585 DataType::VarChar {
38586 length,
38587 parenthesized_length: false,
38588 }
38589 } else {
38590 let length = if self.match_token(TokenType::LParen) {
38591 let len = Some(self.expect_number()? as u32);
38592 self.expect(TokenType::RParen)?;
38593 len
38594 } else {
38595 None
38596 };
38597 if length.is_none()
38599 && self.match_identifier("CHARACTER")
38600 && self.match_token(TokenType::Set)
38601 {
38602 let charset = self.expect_identifier_or_keyword()?;
38603 return Ok(DataType::CharacterSet { name: charset });
38604 }
38605 DataType::Char { length }
38606 }
38607 }
38608 "TIME" => {
38609 let precision = if self.match_token(TokenType::LParen) {
38611 let p = Some(self.expect_number()? as u32);
38612 self.expect(TokenType::RParen)?;
38613 p
38614 } else {
38615 None
38616 };
38617 let timezone = if self.match_token(TokenType::With) {
38618 self.match_keyword("TIME");
38619 self.match_keyword("ZONE");
38620 true
38621 } else if self.match_keyword("WITHOUT") {
38622 self.match_keyword("TIME");
38623 self.match_keyword("ZONE");
38624 false
38625 } else {
38626 false
38627 };
38628 DataType::Time {
38629 precision,
38630 timezone,
38631 }
38632 }
38633 "TIMETZ" => {
38634 let precision = if self.match_token(TokenType::LParen) {
38635 let p = Some(self.expect_number()? as u32);
38636 self.expect(TokenType::RParen)?;
38637 p
38638 } else {
38639 None
38640 };
38641 DataType::Time {
38642 precision,
38643 timezone: true,
38644 }
38645 }
38646 "TIMESTAMP" => {
38647 let precision = if self.match_token(TokenType::LParen) {
38649 let p = Some(self.expect_number()? as u32);
38650 self.expect(TokenType::RParen)?;
38651 p
38652 } else {
38653 None
38654 };
38655 if self.match_token(TokenType::With) {
38657 if self.match_token(TokenType::Local) {
38659 self.match_keyword("TIME");
38660 self.match_keyword("ZONE");
38661 DataType::Custom {
38663 name: "TIMESTAMPLTZ".to_string(),
38664 }
38665 } else {
38666 self.match_keyword("TIME");
38667 self.match_keyword("ZONE");
38668 DataType::Timestamp {
38669 precision,
38670 timezone: true,
38671 }
38672 }
38673 } else if self.match_keyword("WITHOUT") {
38674 self.match_keyword("TIME");
38675 self.match_keyword("ZONE");
38676 DataType::Timestamp {
38677 precision,
38678 timezone: false,
38679 }
38680 } else {
38681 DataType::Timestamp {
38682 precision,
38683 timezone: false,
38684 }
38685 }
38686 }
38687 "TIMESTAMPTZ" => {
38688 let precision = if self.match_token(TokenType::LParen) {
38689 let p = self.expect_number()? as u32;
38690 self.expect(TokenType::RParen)?;
38691 Some(p)
38692 } else {
38693 None
38694 };
38695 DataType::Timestamp {
38696 precision,
38697 timezone: true,
38698 }
38699 }
38700 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
38701 let precision = if self.match_token(TokenType::LParen) {
38702 let p = self.expect_number()? as u32;
38703 self.expect(TokenType::RParen)?;
38704 Some(p)
38705 } else {
38706 None
38707 };
38708 let dt_name = if let Some(p) = precision {
38709 format!("TIMESTAMPLTZ({})", p)
38710 } else {
38711 "TIMESTAMPLTZ".to_string()
38712 };
38713 DataType::Custom { name: dt_name }
38714 }
38715 "INTERVAL" => {
38716 let unit = if (self.check(TokenType::Identifier)
38718 || self.check(TokenType::Var)
38719 || self.check_keyword())
38720 && !self.check(TokenType::RParen)
38721 && !self.check(TokenType::Comma)
38722 && !self.check(TokenType::As)
38723 && !self.check(TokenType::Not)
38724 && !self.check(TokenType::Null)
38725 {
38726 Some(self.advance().text.to_ascii_uppercase())
38727 } else {
38728 None
38729 };
38730 let to = if self.match_token(TokenType::To) {
38732 if self.check(TokenType::Identifier)
38733 || self.check(TokenType::Var)
38734 || self.check_keyword()
38735 {
38736 Some(self.advance().text.to_ascii_uppercase())
38737 } else {
38738 None
38739 }
38740 } else {
38741 None
38742 };
38743 DataType::Interval { unit, to }
38744 }
38745 "VARCHAR" | "NVARCHAR" => {
38747 let is_nvarchar = name == "NVARCHAR";
38748 if self.match_token(TokenType::LParen) {
38749 if self.check(TokenType::RParen) {
38750 self.skip();
38751 DataType::VarChar {
38752 length: None,
38753 parenthesized_length: false,
38754 }
38755 } else if self.check_identifier("MAX") {
38756 self.skip();
38757 self.expect(TokenType::RParen)?;
38758 let type_name = if is_nvarchar {
38759 "NVARCHAR(MAX)"
38760 } else {
38761 "VARCHAR(MAX)"
38762 };
38763 DataType::Custom {
38764 name: type_name.to_string(),
38765 }
38766 } else {
38767 let n = self.expect_number()? as u32;
38768 self.expect(TokenType::RParen)?;
38769 DataType::VarChar {
38770 length: Some(n),
38771 parenthesized_length: false,
38772 }
38773 }
38774 } else {
38775 DataType::VarChar {
38776 length: None,
38777 parenthesized_length: false,
38778 }
38779 }
38780 }
38781 "VARBINARY" => {
38783 if self.match_token(TokenType::LParen) {
38784 if self.check(TokenType::RParen) {
38785 self.skip();
38786 DataType::VarBinary { length: None }
38787 } else if self.check_identifier("MAX") {
38788 self.skip();
38789 self.expect(TokenType::RParen)?;
38790 DataType::Custom {
38791 name: "VARBINARY(MAX)".to_string(),
38792 }
38793 } else {
38794 let n = self.expect_number()? as u32;
38795 self.expect(TokenType::RParen)?;
38796 DataType::VarBinary { length: Some(n) }
38797 }
38798 } else {
38799 DataType::VarBinary { length: None }
38800 }
38801 }
38802 "DECIMAL" | "NUMERIC" | "NUMBER" => {
38804 if self.match_token(TokenType::LParen) {
38805 let precision = Some(self.expect_number()? as u32);
38806 let scale = if self.match_token(TokenType::Comma) {
38807 Some(self.expect_number()? as u32)
38808 } else {
38809 None
38810 };
38811 self.expect(TokenType::RParen)?;
38812 DataType::Decimal { precision, scale }
38813 } else {
38814 DataType::Decimal {
38815 precision: None,
38816 scale: None,
38817 }
38818 }
38819 }
38820 "INT" | "INTEGER" => {
38822 let length = if self.match_token(TokenType::LParen) {
38823 let n = Some(self.expect_number()? as u32);
38824 self.expect(TokenType::RParen)?;
38825 n
38826 } else {
38827 None
38828 };
38829 DataType::Int {
38830 length,
38831 integer_spelling: name == "INTEGER",
38832 }
38833 }
38834 "BIGINT" => {
38835 let length = if self.match_token(TokenType::LParen) {
38836 let n = Some(self.expect_number()? as u32);
38837 self.expect(TokenType::RParen)?;
38838 n
38839 } else {
38840 None
38841 };
38842 DataType::BigInt { length }
38843 }
38844 "SMALLINT" => {
38845 let length = if self.match_token(TokenType::LParen) {
38846 let n = Some(self.expect_number()? as u32);
38847 self.expect(TokenType::RParen)?;
38848 n
38849 } else {
38850 None
38851 };
38852 DataType::SmallInt { length }
38853 }
38854 "TINYINT" => {
38855 let length = if self.match_token(TokenType::LParen) {
38856 let n = Some(self.expect_number()? as u32);
38857 self.expect(TokenType::RParen)?;
38858 n
38859 } else {
38860 None
38861 };
38862 DataType::TinyInt { length }
38863 }
38864 "FLOAT" | "REAL" | "BINARY_FLOAT" => {
38866 let (precision, scale) = if self.match_token(TokenType::LParen) {
38867 let n = Some(self.expect_number()? as u32);
38868 let s = if self.match_token(TokenType::Comma) {
38869 Some(self.expect_number()? as u32)
38870 } else {
38871 None
38872 };
38873 self.expect(TokenType::RParen)?;
38874 (n, s)
38875 } else {
38876 (None, None)
38877 };
38878 DataType::Float {
38879 precision,
38880 scale,
38881 real_spelling: name == "REAL",
38882 }
38883 }
38884 "BINARY_DOUBLE" => DataType::Double {
38885 precision: None,
38886 scale: None,
38887 },
38888 "BINARY" => {
38890 let length = if self.match_token(TokenType::LParen) {
38891 let n = Some(self.expect_number()? as u32);
38892 self.expect(TokenType::RParen)?;
38893 n
38894 } else {
38895 None
38896 };
38897 DataType::Binary { length }
38898 }
38899 "SIGNED" | "UNSIGNED" => {
38903 if self.check_identifier("INTEGER")
38905 || self.check_keyword_text("INTEGER")
38906 || self.check_keyword_text("INT")
38907 {
38908 self.skip();
38909 }
38910 DataType::Custom { name }
38911 }
38912 "NULLABLE" => {
38914 self.expect(TokenType::LParen)?;
38915 let inner = self.parse_data_type_for_cast()?;
38916 self.expect(TokenType::RParen)?;
38917 DataType::Nullable {
38918 inner: Box::new(inner),
38919 }
38920 }
38921 _ => {
38925 let base = self.convert_name_to_type(&name)?;
38926 if matches!(
38929 self.config.dialect,
38930 Some(crate::dialects::DialectType::ClickHouse)
38931 ) && self.check(TokenType::LParen)
38932 && (matches!(
38933 base,
38934 DataType::Custom { .. } | DataType::Json | DataType::JsonB
38935 ))
38936 {
38937 self.skip(); let args = self.parse_custom_type_args_balanced()?;
38939 self.expect(TokenType::RParen)?;
38940 let base_name = match &base {
38941 DataType::Json => "JSON".to_string(),
38942 DataType::JsonB => "JSONB".to_string(),
38943 DataType::Custom { name } => name.clone(),
38944 _ => unreachable!(),
38945 };
38946 DataType::Custom {
38947 name: format!("{}({})", base_name, args),
38948 }
38949 } else if matches!(base, DataType::Custom { .. }) && self.check(TokenType::Dot) {
38950 let mut type_name = raw_name.to_string();
38955 while self.match_token(TokenType::Dot) {
38956 let tok = self.advance();
38957 type_name = format!("{}.{}", type_name, tok.text);
38958 }
38959 DataType::Custom { name: type_name }
38960 } else if matches!(base, DataType::Custom { .. }) && self.config.dialect.is_none() {
38961 DataType::Custom {
38963 name: raw_name.to_string(),
38964 }
38965 } else {
38966 base
38967 }
38968 }
38969 };
38970
38971 let is_materialize = matches!(
38973 self.config.dialect,
38974 Some(crate::dialects::DialectType::Materialize)
38975 );
38976 let mut result_type = base_type;
38977 if is_materialize {
38978 while self.check_identifier("LIST") || self.check(TokenType::List) {
38979 self.skip(); result_type = DataType::List {
38981 element_type: Box::new(result_type),
38982 };
38983 }
38984 }
38985
38986 if supports_array_type_suffix {
38989 self.maybe_parse_array_dimensions(result_type)
38990 } else {
38991 Ok(result_type)
38992 }
38993 }
38994
38995 fn parse_custom_type_args_balanced(&mut self) -> Result<String> {
38997 let mut depth = 0usize;
38998 let mut out = String::new();
38999 let mut prev_wordish = false;
39000
39001 while !self.is_at_end() {
39002 if self.check(TokenType::RParen) && depth == 0 {
39003 break;
39004 }
39005
39006 let token = self.advance();
39007 match token.token_type {
39008 TokenType::LParen => {
39009 out.push('(');
39010 depth += 1;
39011 prev_wordish = false;
39012 }
39013 TokenType::RParen => {
39014 if depth == 0 {
39015 break;
39016 }
39017 depth -= 1;
39018 out.push(')');
39019 prev_wordish = true;
39020 }
39021 TokenType::Comma => {
39022 out.push_str(", ");
39023 prev_wordish = false;
39024 }
39025 TokenType::Eq => {
39026 out.push_str(" = ");
39027 prev_wordish = false;
39028 }
39029 TokenType::Plus => {
39030 out.push_str(" + ");
39031 prev_wordish = false;
39032 }
39033 TokenType::Dash => {
39034 out.push('-');
39035 prev_wordish = false;
39036 }
39037 TokenType::Dot => {
39038 out.push('.');
39039 prev_wordish = false;
39040 }
39041 TokenType::String | TokenType::DollarString => {
39042 if prev_wordish {
39043 out.push(' ');
39044 }
39045 let escaped = token.text.replace('\'', "''");
39046 out.push('\'');
39047 out.push_str(&escaped);
39048 out.push('\'');
39049 prev_wordish = true;
39050 }
39051 TokenType::Number | TokenType::Parameter => {
39052 if prev_wordish {
39053 out.push(' ');
39054 }
39055 out.push_str(&token.text);
39056 prev_wordish = true;
39057 }
39058 TokenType::QuotedIdentifier => {
39059 if prev_wordish {
39060 out.push(' ');
39061 }
39062 out.push('"');
39063 out.push_str(&token.text);
39064 out.push('"');
39065 prev_wordish = true;
39066 }
39067 _ => {
39068 if prev_wordish {
39069 out.push(' ');
39070 }
39071 out.push_str(&token.text);
39072 prev_wordish = true;
39073 }
39074 }
39075 }
39076
39077 Ok(out)
39078 }
39079
39080 fn uppercase_json_type_skip_keyword(args: &str) -> String {
39083 let mut result = String::with_capacity(args.len());
39085 let mut rest = args;
39086 let mut at_start = true;
39087 while !rest.is_empty() {
39088 if at_start
39089 && rest.len() >= 5
39090 && rest[..4].eq_ignore_ascii_case("skip")
39091 && rest.as_bytes()[4] == b' '
39092 {
39093 result.push_str("SKIP");
39094 rest = &rest[4..];
39095 at_start = false;
39096 } else if rest.starts_with(", ") {
39097 result.push_str(", ");
39098 rest = &rest[2..];
39099 at_start = true;
39100 } else {
39101 result.push(rest.as_bytes()[0] as char);
39102 rest = &rest[1..];
39103 at_start = false;
39104 }
39105 }
39106 result
39107 }
39108
39109 fn parse_data_type_from_text(&mut self, text: &str) -> Result<DataType> {
39113 use crate::tokens::Tokenizer;
39114 let tokenizer = Tokenizer::default();
39115 let tokens = tokenizer.tokenize(text)?;
39116 if tokens.is_empty() {
39117 return Ok(DataType::Custom {
39118 name: text.to_string(),
39119 });
39120 }
39121 let saved_tokens = std::mem::replace(&mut self.tokens, tokens);
39123 let saved_current = std::mem::replace(&mut self.current, 0);
39124 let result = self.parse_data_type();
39125 self.tokens = saved_tokens;
39127 self.current = saved_current;
39128 result
39129 }
39130
39131 fn parse_data_type_optional(&mut self) -> Result<Option<DataType>> {
39134 if !self.check(TokenType::Identifier)
39136 && !self.check(TokenType::Var)
39137 && !self.check_keyword()
39138 {
39139 return Ok(None);
39140 }
39141
39142 if self.check_identifier("PATH") {
39144 return Ok(None);
39145 }
39146
39147 if matches!(
39149 self.config.dialect,
39150 Some(crate::dialects::DialectType::ClickHouse)
39151 ) && (self.check_identifier("ALIAS")
39152 || self.check_identifier("EPHEMERAL")
39153 || self.check(TokenType::Materialized))
39154 {
39155 return Ok(None);
39156 }
39157
39158 let saved_pos = self.current;
39159 match self.parse_data_type() {
39160 Ok(dt) => Ok(Some(dt)),
39161 Err(_) => {
39162 self.current = saved_pos;
39163 Ok(None)
39164 }
39165 }
39166 }
39167
39168 fn data_type_to_string(&self, dt: &DataType) -> String {
39170 match dt {
39171 DataType::Int {
39172 length: Some(n),
39173 integer_spelling: true,
39174 } => format!("INTEGER({})", n),
39175 DataType::Int {
39176 length: Some(n), ..
39177 } => format!("INT({})", n),
39178 DataType::Int {
39179 length: None,
39180 integer_spelling: true,
39181 } => "INTEGER".to_string(),
39182 DataType::Int { length: None, .. } => "INT".to_string(),
39183 DataType::BigInt { length: Some(n) } => format!("BIGINT({})", n),
39184 DataType::BigInt { length: None } => "BIGINT".to_string(),
39185 DataType::SmallInt { length: Some(n) } => format!("SMALLINT({})", n),
39186 DataType::SmallInt { length: None } => "SMALLINT".to_string(),
39187 DataType::TinyInt { length: Some(n) } => format!("TINYINT({})", n),
39188 DataType::TinyInt { length: None } => "TINYINT".to_string(),
39189 DataType::Float {
39190 precision: Some(p),
39191 scale: Some(s),
39192 ..
39193 } => format!("FLOAT({}, {})", p, s),
39194 DataType::Float {
39195 precision: Some(p),
39196 scale: None,
39197 ..
39198 } => format!("FLOAT({})", p),
39199 DataType::Float {
39200 precision: None, ..
39201 } => "FLOAT".to_string(),
39202 DataType::Double {
39203 precision: Some(p),
39204 scale: Some(s),
39205 } => format!("DOUBLE({}, {})", p, s),
39206 DataType::Double {
39207 precision: Some(p),
39208 scale: None,
39209 } => format!("DOUBLE({})", p),
39210 DataType::Double {
39211 precision: None, ..
39212 } => "DOUBLE".to_string(),
39213 DataType::Decimal {
39214 precision: Some(p),
39215 scale: Some(s),
39216 } => format!("DECIMAL({}, {})", p, s),
39217 DataType::Decimal {
39218 precision: Some(p),
39219 scale: None,
39220 } => format!("DECIMAL({})", p),
39221 DataType::Decimal {
39222 precision: None, ..
39223 } => "DECIMAL".to_string(),
39224 DataType::VarChar {
39225 length: Some(n), ..
39226 } => format!("VARCHAR({})", n),
39227 DataType::VarChar { length: None, .. } => "VARCHAR".to_string(),
39228 DataType::Char { length: Some(n) } => format!("CHAR({})", n),
39229 DataType::Char { length: None } => "CHAR".to_string(),
39230 DataType::Text => "TEXT".to_string(),
39231 DataType::Boolean => "BOOLEAN".to_string(),
39232 DataType::Date => "DATE".to_string(),
39233 DataType::Time {
39234 precision: Some(p), ..
39235 } => format!("TIME({})", p),
39236 DataType::Time {
39237 precision: None, ..
39238 } => "TIME".to_string(),
39239 DataType::Timestamp {
39240 precision: Some(p),
39241 timezone: true,
39242 } => format!("TIMESTAMPTZ({})", p),
39243 DataType::Timestamp {
39244 precision: Some(p),
39245 timezone: false,
39246 } => format!("TIMESTAMP({})", p),
39247 DataType::Timestamp {
39248 precision: None,
39249 timezone: true,
39250 } => "TIMESTAMPTZ".to_string(),
39251 DataType::Timestamp {
39252 precision: None,
39253 timezone: false,
39254 } => "TIMESTAMP".to_string(),
39255 DataType::Json => "JSON".to_string(),
39256 DataType::JsonB => "JSONB".to_string(),
39257 DataType::Binary { length: Some(n) } => format!("BINARY({})", n),
39258 DataType::Binary { length: None } => "BINARY".to_string(),
39259 DataType::VarBinary { length: Some(n) } => format!("VARBINARY({})", n),
39260 DataType::VarBinary { length: None } => "VARBINARY".to_string(),
39261 DataType::String { length: Some(n) } => format!("STRING({})", n),
39262 DataType::String { length: None } => "STRING".to_string(),
39263 DataType::Array { element_type, .. } => {
39264 format!("ARRAY({})", self.data_type_to_string(element_type))
39265 }
39266 DataType::Nullable { inner } => {
39267 format!("Nullable({})", self.data_type_to_string(inner))
39268 }
39269 DataType::Custom { name } => name.clone(),
39270 _ => format!("{:?}", dt),
39271 }
39272 }
39273
39274 fn maybe_parse_array_dimensions(&mut self, base_type: DataType) -> Result<DataType> {
39276 let mut current_type = base_type;
39277
39278 if self.check_identifier("ARRAY") {
39280 self.skip(); let dimension = if self.match_token(TokenType::LBracket) {
39283 let dim = if self.check(TokenType::Number) {
39284 let n = self.expect_number()? as u32;
39285 Some(n)
39286 } else {
39287 None
39288 };
39289 self.expect(TokenType::RBracket)?;
39290 dim
39291 } else {
39292 None
39293 };
39294 current_type = DataType::Array {
39295 element_type: Box::new(current_type),
39296 dimension,
39297 };
39298 }
39299
39300 while self.match_token(TokenType::LBracket) {
39302 let dimension = if self.check(TokenType::Number) {
39304 let n = self.expect_number()? as u32;
39305 Some(n)
39306 } else {
39307 None
39308 };
39309 self.expect(TokenType::RBracket)?;
39310
39311 current_type = DataType::Array {
39312 element_type: Box::new(current_type),
39313 dimension,
39314 };
39315 }
39316
39317 Ok(current_type)
39318 }
39319
39320 fn parse_spatial_type_args(&mut self) -> Result<(Option<String>, Option<u32>)> {
39322 if self.match_token(TokenType::LParen) {
39323 if self.check(TokenType::Number) {
39325 let n = self.expect_number()? as u32;
39327 self.expect(TokenType::RParen)?;
39328 return Ok((None, Some(n)));
39329 }
39330 let subtype = Some(self.expect_identifier()?.to_ascii_uppercase());
39332
39333 let srid = if self.match_token(TokenType::Comma) {
39335 Some(self.expect_number()? as u32)
39336 } else {
39337 None
39338 };
39339
39340 self.expect(TokenType::RParen)?;
39341 Ok((subtype, srid))
39342 } else {
39343 Ok((None, None))
39344 }
39345 }
39346
39347 fn parse_struct_type_fields(&mut self, paren_style: bool) -> Result<Vec<StructField>> {
39351 let mut fields = Vec::new();
39352 if (paren_style && self.check(TokenType::RParen))
39354 || (!paren_style && (self.check(TokenType::Gt) || self.check(TokenType::GtGt)))
39355 {
39356 return Ok(fields);
39357 }
39358 loop {
39359 let is_quoted = self.check(TokenType::QuotedIdentifier);
39362 let first = self.expect_identifier_or_keyword()?;
39363 let first_upper = first.to_ascii_uppercase();
39364
39365 let is_parametric_type = (first_upper == "ARRAY"
39367 || first_upper == "MAP"
39368 || first_upper == "STRUCT"
39369 || first_upper == "ROW")
39370 && (self.check(TokenType::Lt) || self.check(TokenType::LParen));
39371
39372 let (field_name, field_type) = if is_parametric_type {
39373 let field_type = self.parse_data_type_from_name(&first_upper)?;
39375 (String::new(), field_type)
39376 } else if self.check(TokenType::Comma)
39377 || self.match_identifier("OPTIONS") || (paren_style && self.check(TokenType::RParen))
39379 || (!paren_style && (self.check(TokenType::Gt) || self.check(TokenType::GtGt)))
39380 {
39381 if self.previous().text.eq_ignore_ascii_case("OPTIONS") {
39383 self.current -= 1;
39384 }
39385 let field_type = self.convert_name_to_type(&first)?;
39387 (String::new(), field_type)
39388 } else if self.is_identifier_token()
39389 || self.is_safe_keyword_as_identifier()
39390 || self.check(TokenType::Lt)
39391 || self.check(TokenType::LParen)
39392 || self.check(TokenType::Colon)
39393 {
39394 self.match_token(TokenType::Colon);
39397 let field_type = self.parse_data_type()?;
39398 let field_name = if is_quoted {
39400 format!("\"{}\"", first)
39401 } else {
39402 first
39403 };
39404 (field_name, field_type)
39405 } else {
39406 let field_type = self.convert_name_to_type(&first)?;
39408 (String::new(), field_type)
39409 };
39410
39411 let comment = if self.match_token(TokenType::Comment) {
39413 Some(self.expect_string()?)
39414 } else {
39415 None
39416 };
39417
39418 let options = if self.match_identifier("OPTIONS") {
39420 self.parse_options_list()?
39421 } else {
39422 Vec::new()
39423 };
39424
39425 fields.push(StructField::with_options_and_comment(
39426 field_name, field_type, options, comment,
39427 ));
39428
39429 if !self.match_token(TokenType::Comma) {
39430 break;
39431 }
39432 }
39433 Ok(fields)
39434 }
39435
39436 fn parse_data_type_from_name(&mut self, name: &str) -> Result<DataType> {
39439 match name {
39440 "ARRAY" => {
39441 if self.match_token(TokenType::Lt) {
39442 let element_type = self.parse_data_type()?;
39443 self.expect_gt()?;
39444 Ok(DataType::Array {
39445 element_type: Box::new(element_type),
39446 dimension: None,
39447 })
39448 } else {
39449 Ok(DataType::Custom {
39450 name: "ARRAY".to_string(),
39451 })
39452 }
39453 }
39454 "MAP" => {
39455 if self.match_token(TokenType::Lt) {
39456 let key_type = self.parse_data_type()?;
39457 self.expect(TokenType::Comma)?;
39458 let value_type = self.parse_data_type()?;
39459 self.expect_gt()?;
39460 Ok(DataType::Map {
39461 key_type: Box::new(key_type),
39462 value_type: Box::new(value_type),
39463 })
39464 } else {
39465 Ok(DataType::Custom {
39466 name: "MAP".to_string(),
39467 })
39468 }
39469 }
39470 "STRUCT" => {
39471 if self.match_token(TokenType::Lt) {
39472 let fields = self.parse_struct_type_fields(false)?;
39473 self.expect_gt()?;
39474 Ok(DataType::Struct {
39475 fields,
39476 nested: false,
39477 })
39478 } else if self.match_token(TokenType::LParen) {
39479 let fields = self.parse_struct_type_fields(true)?;
39480 self.expect(TokenType::RParen)?;
39481 Ok(DataType::Struct {
39482 fields,
39483 nested: true,
39484 })
39485 } else {
39486 Ok(DataType::Custom {
39487 name: "STRUCT".to_string(),
39488 })
39489 }
39490 }
39491 "ROW" => {
39492 if self.match_token(TokenType::LParen) {
39493 let fields = self.parse_struct_type_fields(true)?;
39494 self.expect(TokenType::RParen)?;
39495 Ok(DataType::Struct {
39496 fields,
39497 nested: true,
39498 })
39499 } else {
39500 Ok(DataType::Custom {
39501 name: "ROW".to_string(),
39502 })
39503 }
39504 }
39505 _ => Ok(DataType::Custom {
39506 name: name.to_string(),
39507 }),
39508 }
39509 }
39510
39511 fn convert_name_to_type(&self, name: &str) -> Result<DataType> {
39514 let upper = name.to_ascii_uppercase();
39515 Ok(match upper.as_str() {
39516 "INT" => DataType::Int {
39517 length: None,
39518 integer_spelling: false,
39519 },
39520 "INTEGER" => DataType::Int {
39521 length: None,
39522 integer_spelling: true,
39523 },
39524 "BIGINT" => DataType::BigInt { length: None },
39525 "SMALLINT" => DataType::SmallInt { length: None },
39526 "TINYINT" => DataType::TinyInt { length: None },
39527 "FLOAT" | "BINARY_FLOAT" => DataType::Float {
39528 precision: None,
39529 scale: None,
39530 real_spelling: false,
39531 },
39532 "REAL" => DataType::Float {
39533 precision: None,
39534 scale: None,
39535 real_spelling: true,
39536 },
39537 "DOUBLE" | "BINARY_DOUBLE" => DataType::Double {
39538 precision: None,
39539 scale: None,
39540 },
39541 "DECIMAL" | "NUMERIC" => DataType::Decimal {
39542 precision: None,
39543 scale: None,
39544 },
39545 "BOOLEAN" | "BOOL" => DataType::Boolean,
39546 "CHAR" | "CHARACTER" | "NCHAR" => DataType::Char { length: None },
39547 "VARCHAR" | "NVARCHAR" => DataType::VarChar {
39548 length: None,
39549 parenthesized_length: false,
39550 },
39551 "TEXT" | "STRING" | "NTEXT" => DataType::Text,
39552 "DATE" => DataType::Date,
39553 "TIME" => DataType::Time {
39554 precision: None,
39555 timezone: false,
39556 },
39557 "TIMETZ" => DataType::Time {
39558 precision: None,
39559 timezone: true,
39560 },
39561 "TIMESTAMP" => DataType::Timestamp {
39562 precision: None,
39563 timezone: false,
39564 },
39565 "INTERVAL" => DataType::Interval {
39566 unit: None,
39567 to: None,
39568 },
39569 "JSON" => DataType::Json,
39570 "JSONB" => DataType::JsonB,
39571 "UUID" => DataType::Uuid,
39572 "BLOB" => DataType::Blob,
39573 "BYTEA" => DataType::VarBinary { length: None },
39574 "BINARY" => DataType::Binary { length: None },
39575 "VARBINARY" => DataType::VarBinary { length: None },
39576 "BIT" => DataType::Bit { length: None },
39577 "VARBIT" => DataType::VarBit { length: None },
39578 _ => DataType::Custom {
39579 name: name.to_string(),
39580 },
39581 })
39582 }
39583
39584 fn parse_star_modifiers(&mut self, table: Option<Identifier>) -> Result<Star> {
39590 self.parse_star_modifiers_with_comments(table, Vec::new())
39591 }
39592
39593 fn parse_star_modifiers_with_comments(
39595 &mut self,
39596 table: Option<Identifier>,
39597 star_trailing_comments: Vec<String>,
39598 ) -> Result<Star> {
39599 let mut except = None;
39600 let mut replace = None;
39601 let mut rename = None;
39602
39603 if self.match_token(TokenType::Exclude) || self.match_token(TokenType::Except) {
39605 let _ = self.match_text_seq(&["STRICT"]);
39607 let mut columns = Vec::new();
39608 if self.match_token(TokenType::LParen) {
39609 loop {
39611 let col = if self.check(TokenType::String) {
39614 self.advance().text
39615 } else if self.is_safe_keyword_as_identifier() {
39616 self.advance().text
39617 } else {
39618 self.expect_identifier()?
39619 };
39620 if self.match_token(TokenType::Dot) {
39622 let subcol = if self.is_safe_keyword_as_identifier() {
39623 self.advance().text
39624 } else {
39625 self.expect_identifier()?
39626 };
39627 columns.push(Identifier::new(format!("{}.{}", col, subcol)));
39628 } else {
39629 columns.push(Identifier::new(col));
39630 }
39631 if !self.match_token(TokenType::Comma) {
39632 break;
39633 }
39634 }
39635 self.expect(TokenType::RParen)?;
39636 } else {
39637 loop {
39640 let col = if self.check(TokenType::String) {
39641 self.advance().text
39642 } else if self.is_safe_keyword_as_identifier() {
39643 self.advance().text
39644 } else {
39645 self.expect_identifier()?
39646 };
39647 columns.push(Identifier::new(col));
39648 if !matches!(
39651 self.config.dialect,
39652 Some(crate::dialects::DialectType::ClickHouse)
39653 ) || !self.check(TokenType::Comma)
39654 || !matches!(
39655 self.peek_nth(1).map(|t| t.token_type),
39656 Some(TokenType::Identifier)
39657 | Some(TokenType::QuotedIdentifier)
39658 | Some(TokenType::Var)
39659 | Some(TokenType::String)
39660 )
39661 {
39662 break;
39663 }
39664 self.skip(); }
39666 }
39667 except = Some(columns);
39668 }
39669
39670 if self.match_token(TokenType::Replace) {
39672 let _ = self.match_text_seq(&["STRICT"]);
39674 let mut replacements = Vec::new();
39675 if self.match_token(TokenType::LParen) {
39676 loop {
39677 let expr = self.parse_expression()?;
39678 self.expect(TokenType::As)?;
39679 let alias = self.expect_identifier_or_keyword()?;
39680 replacements.push(Alias::new(expr, Identifier::new(alias)));
39681 if !self.match_token(TokenType::Comma) {
39682 break;
39683 }
39684 }
39685 self.expect(TokenType::RParen)?;
39686 } else if matches!(
39687 self.config.dialect,
39688 Some(crate::dialects::DialectType::ClickHouse)
39689 ) {
39690 let expr = self.parse_expression()?;
39693 self.expect(TokenType::As)?;
39694 let alias = self.expect_identifier_or_keyword()?;
39695 replacements.push(Alias::new(expr, Identifier::new(alias)));
39696 } else {
39697 return Err(self.parse_error("Expected LParen after REPLACE"));
39698 }
39699 replace = Some(replacements);
39700 }
39701
39702 if self.match_token(TokenType::Rename) {
39704 let mut renames = Vec::new();
39705 if self.match_token(TokenType::LParen) {
39706 loop {
39707 let old_name = self.expect_identifier()?;
39708 self.expect(TokenType::As)?;
39709 let new_name = self.expect_identifier()?;
39710 renames.push((Identifier::new(old_name), Identifier::new(new_name)));
39711 if !self.match_token(TokenType::Comma) {
39712 break;
39713 }
39714 }
39715 self.expect(TokenType::RParen)?;
39716 } else {
39717 let old_name = self.expect_identifier()?;
39719 self.expect(TokenType::As)?;
39720 let new_name = self.expect_identifier()?;
39721 renames.push((Identifier::new(old_name), Identifier::new(new_name)));
39722 }
39723 rename = Some(renames);
39724 }
39725
39726 Ok(Star {
39727 table,
39728 except,
39729 replace,
39730 rename,
39731 trailing_comments: star_trailing_comments,
39732 span: None,
39733 })
39734 }
39735
39736 #[inline]
39740 fn is_at_end(&self) -> bool {
39741 self.current >= self.tokens.len()
39742 }
39743
39744 fn is_at_query_modifier_or_end(&self) -> bool {
39747 if self.is_at_end() {
39748 return true;
39749 }
39750 matches!(
39751 self.peek().token_type,
39752 TokenType::Having
39753 | TokenType::Qualify
39754 | TokenType::Window
39755 | TokenType::Order
39756 | TokenType::Limit
39757 | TokenType::Fetch
39758 | TokenType::Offset
39759 | TokenType::For
39760 | TokenType::Lock
39761 | TokenType::Union
39762 | TokenType::Except
39763 | TokenType::Intersect
39764 | TokenType::RParen
39765 | TokenType::Semicolon
39766 | TokenType::Where
39767 )
39768 }
39769
39770 fn parse_error(&self, message: impl Into<String>) -> Error {
39772 let span = self.peek().span;
39773 Error::parse(message, span.line, span.column, span.start, span.end)
39774 }
39775
39776 #[inline]
39779 fn peek(&self) -> &Token {
39780 if self.current >= self.tokens.len() {
39781 self.tokens.last().expect("Token list should not be empty")
39785 } else {
39786 &self.tokens[self.current]
39787 }
39788 }
39789
39790 fn peek_nth(&self, n: usize) -> Option<&Token> {
39792 let idx = self.current + n;
39793 if idx < self.tokens.len() {
39794 Some(&self.tokens[idx])
39795 } else {
39796 None
39797 }
39798 }
39799
39800 #[inline]
39802 fn advance(&mut self) -> Token {
39803 if self.current >= self.tokens.len() {
39804 return self
39807 .tokens
39808 .last()
39809 .cloned()
39810 .expect("Token list should not be empty");
39811 }
39812 let token = self.tokens[self.current].clone();
39813 self.current += 1;
39814 token
39815 }
39816
39817 #[inline]
39819 fn skip(&mut self) {
39820 if self.current < self.tokens.len() {
39821 self.current += 1;
39822 }
39823 }
39824
39825 fn previous(&self) -> &Token {
39827 &self.tokens[self.current - 1]
39828 }
39829
39830 fn previous_trailing_comments(&self) -> &[String] {
39832 if self.current > 0 {
39833 &self.tokens[self.current - 1].trailing_comments
39834 } else {
39835 &[]
39836 }
39837 }
39838
39839 fn previous_token_type(&self) -> Option<TokenType> {
39841 if self.current > 0 {
39842 Some(self.tokens[self.current - 1].token_type.clone())
39843 } else {
39844 None
39845 }
39846 }
39847
39848 fn maybe_wrap_in_subquery(&self, inner: Expression) -> Expression {
39852 if matches!(
39853 &inner,
39854 Expression::Select(_)
39855 | Expression::Union(_)
39856 | Expression::Intersect(_)
39857 | Expression::Except(_)
39858 ) {
39859 Expression::Subquery(Box::new(Subquery {
39860 this: inner,
39861 alias: None,
39862 column_aliases: Vec::new(),
39863 order_by: None,
39864 limit: None,
39865 offset: None,
39866 distribute_by: None,
39867 sort_by: None,
39868 cluster_by: None,
39869 lateral: false,
39870 modifiers_inside: false,
39871 trailing_comments: Vec::new(),
39872 inferred_type: None,
39873 }))
39874 } else {
39875 inner
39876 }
39877 }
39878
39879 fn clear_rightmost_trailing_comments(expr: &mut Expression) {
39885 match expr {
39886 Expression::Column(col) => col.trailing_comments.clear(),
39887 Expression::And(op) | Expression::Or(op) => {
39888 Self::clear_rightmost_trailing_comments(&mut op.right);
39889 }
39890 Expression::Not(op) => {
39891 Self::clear_rightmost_trailing_comments(&mut op.this);
39892 }
39893 Expression::Eq(op)
39895 | Expression::Neq(op)
39896 | Expression::Lt(op)
39897 | Expression::Lte(op)
39898 | Expression::Gt(op)
39899 | Expression::Gte(op)
39900 | Expression::Add(op)
39901 | Expression::Sub(op)
39902 | Expression::Mul(op)
39903 | Expression::Div(op) => {
39904 Self::clear_rightmost_trailing_comments(&mut op.right);
39905 }
39906 _ => {}
39910 }
39911 }
39912
39913 fn current_leading_comments(&self) -> &[String] {
39915 if !self.is_at_end() {
39916 &self.tokens[self.current].comments
39917 } else {
39918 &[]
39919 }
39920 }
39921
39922 fn tokens_to_sql(&self, start: usize, end: usize) -> String {
39924 let mut result = String::new();
39925 let mut prev_line: Option<usize> = None;
39926 let mut prev_end_offset: Option<usize> = None;
39927
39928 for t in &self.tokens[start..end] {
39929 let is_new_line = prev_line.is_some() && t.span.line > prev_line.unwrap();
39931
39932 if is_new_line {
39935 result.push('\n');
39936 let text_len = t.text.chars().count();
39940 let start_col = t.span.column.saturating_sub(text_len);
39941 let start_col = if t.token_type == TokenType::String {
39943 start_col.saturating_sub(2)
39944 } else {
39945 start_col
39946 };
39947 let indent = if start_col > 1 { start_col - 1 } else { 0 };
39948 for _ in 0..indent {
39949 result.push(' ');
39950 }
39951 } else if !result.is_empty() {
39952 let had_space = prev_end_offset.map_or(false, |prev_end| t.span.start > prev_end);
39954 if had_space {
39955 result.push(' ');
39956 }
39957 }
39958
39959 if t.token_type == TokenType::String {
39960 result.push('\'');
39962 result.push_str(&t.text.replace('\'', "''"));
39963 result.push('\'');
39964 } else {
39965 result.push_str(&t.text);
39966 }
39967
39968 prev_line = Some(t.span.line);
39969 prev_end_offset = Some(t.span.end);
39970 }
39971 result
39972 }
39973
39974 fn tokens_to_sql_stage_format(&self, start: usize, end: usize) -> String {
39978 let mut result = String::new();
39979 let mut prev_token_type: Option<TokenType> = None;
39980 let mut i = start;
39981
39982 while i < end {
39983 let t = &self.tokens[i];
39984
39985 if (t.token_type == TokenType::Var || t.token_type == TokenType::Identifier)
39988 && t.text.eq_ignore_ascii_case("FILE_FORMAT")
39989 && i + 1 < end
39990 && self.tokens[i + 1].token_type == TokenType::Eq
39991 && (i + 2 >= end || self.tokens[i + 2].token_type != TokenType::LParen)
39992 {
39993 if !result.is_empty() && prev_token_type != Some(TokenType::LParen) {
39995 result.push(' ');
39996 }
39997 result.push_str("FILE_FORMAT=(FORMAT_NAME=");
39998
39999 i += 2;
40001
40002 while i < end {
40004 let val = &self.tokens[i];
40005 if val.token_type == TokenType::String {
40006 result.push('\'');
40008 result.push_str(&val.text.replace('\'', "''"));
40009 result.push('\'');
40010 i += 1;
40011 break;
40012 } else if val.token_type == TokenType::Var
40013 || val.token_type == TokenType::Identifier
40014 {
40015 result.push_str(&val.text);
40017 i += 1;
40018 if i < end && self.tokens[i].token_type == TokenType::Dot {
40020 result.push('.');
40021 i += 1;
40022 if i < end {
40024 result.push_str(&self.tokens[i].text);
40025 i += 1;
40026 }
40027 }
40028 break;
40029 } else {
40030 break;
40031 }
40032 }
40033 result.push(')');
40034 prev_token_type = Some(TokenType::RParen);
40035 continue;
40036 }
40037
40038 let needs_space = !result.is_empty()
40040 && prev_token_type != Some(TokenType::LParen)
40041 && prev_token_type != Some(TokenType::Eq)
40042 && prev_token_type != Some(TokenType::Dot)
40043 && t.token_type != TokenType::Comma
40044 && t.token_type != TokenType::RParen
40045 && t.token_type != TokenType::LParen
40046 && t.token_type != TokenType::Eq
40047 && t.token_type != TokenType::Dot;
40048
40049 if needs_space {
40050 result.push(' ');
40051 }
40052
40053 if t.token_type == TokenType::String {
40054 result.push('\'');
40055 result.push_str(&t.text.replace('\'', "''"));
40056 result.push('\'');
40057 } else {
40058 result.push_str(&t.text);
40059 }
40060
40061 prev_token_type = Some(t.token_type);
40062 i += 1;
40063 }
40064 result
40065 }
40066
40067 fn tokens_to_sql_uppercased(&self, start: usize, end: usize) -> String {
40069 let mut result = String::new();
40070 let mut prev_token_type: Option<TokenType> = None;
40071 let mut prev_token_text: Option<String> = None;
40072
40073 for t in &self.tokens[start..end] {
40074 let is_lparen_after_keyword = t.token_type == TokenType::LParen
40079 && prev_token_type.map_or(false, |p: TokenType| {
40080 match p {
40082 TokenType::PrimaryKey | TokenType::ForeignKey | TokenType::Unique
40083 | TokenType::Check | TokenType::Index | TokenType::Key
40084 | TokenType::Constraint | TokenType::References
40085 | TokenType::Not | TokenType::Null
40086 | TokenType::Default | TokenType::Values | TokenType::In
40087 | TokenType::Exists | TokenType::Select | TokenType::From
40088 | TokenType::Where | TokenType::Having | TokenType::Using
40089 | TokenType::On | TokenType::Set | TokenType::Into
40090 | TokenType::Table | TokenType::View | TokenType::Create
40091 | TokenType::Insert | TokenType::Update | TokenType::Delete
40092 | TokenType::Join | TokenType::Left | TokenType::Right
40093 | TokenType::Inner | TokenType::Outer | TokenType::Full
40094 | TokenType::Cross | TokenType::Case | TokenType::When
40095 | TokenType::Then | TokenType::Else | TokenType::End
40096 | TokenType::If | TokenType::Partition | TokenType::Over
40097 | TokenType::Between | TokenType::Like | TokenType::Replace
40098 | TokenType::Grant | TokenType::Revoke
40099 => true,
40100 _ => false,
40101 }
40102 })
40103 || (t.token_type == TokenType::LParen
40106 && prev_token_text.as_ref().map_or(false, |text| {
40107 let upper = text.to_ascii_uppercase();
40108 matches!(upper.as_str(),
40109 "CLUSTERED" | "NONCLUSTERED" | "HASH" | "RANGE"
40110 | "INCLUDE" | "FILLFACTOR" | "PAD_INDEX"
40111 )
40112 }));
40113 let needs_space = !result.is_empty()
40114 && prev_token_type != Some(TokenType::LParen)
40115 && prev_token_type != Some(TokenType::Dot)
40116 && t.token_type != TokenType::Comma
40117 && t.token_type != TokenType::RParen
40118 && t.token_type != TokenType::Dot
40119 && (t.token_type != TokenType::LParen || is_lparen_after_keyword);
40120
40121 if prev_token_type == Some(TokenType::Comma) {
40123 result.push(' ');
40124 } else if needs_space {
40125 result.push(' ');
40126 }
40127
40128 if t.token_type == TokenType::String {
40129 result.push('\'');
40131 result.push_str(&t.text.replace('\'', "''"));
40132 result.push('\'');
40133 } else if t.token_type.is_keyword() {
40134 result.push_str(&t.text.to_ascii_uppercase());
40136 } else {
40137 result.push_str(&t.text);
40139 }
40140
40141 prev_token_type = Some(t.token_type);
40142 prev_token_text = Some(t.text.clone());
40143 }
40144 result
40145 }
40146
40147 #[inline]
40149 fn check(&self, token_type: TokenType) -> bool {
40150 if self.is_at_end() {
40151 false
40152 } else {
40153 self.peek().token_type == token_type
40154 }
40155 }
40156
40157 fn check_keyword(&self) -> bool {
40159 if self.is_at_end() {
40160 false
40161 } else {
40162 self.peek().token_type.is_keyword()
40163 }
40164 }
40165
40166 fn is_unpivot_clause_start(&self) -> bool {
40169 if !self.check(TokenType::Unpivot) {
40170 return false;
40171 }
40172 let next_idx = self.current + 1;
40173 if next_idx >= self.tokens.len() {
40174 return false;
40175 }
40176 let next = &self.tokens[next_idx];
40177 if next.token_type == TokenType::LParen {
40178 return true;
40179 }
40180 let next_text = next.text.to_ascii_uppercase();
40182 next_text == "INCLUDE" || next_text == "EXCLUDE"
40183 }
40184
40185 fn check_keyword_text(&self, keyword: &str) -> bool {
40187 if self.is_at_end() {
40188 false
40189 } else {
40190 self.peek().text.eq_ignore_ascii_case(keyword)
40191 }
40192 }
40193
40194 fn check_from_keyword(&self) -> bool {
40196 self.check(TokenType::From)
40197 }
40198
40199 fn check_next(&self, token_type: TokenType) -> bool {
40201 if self.current + 1 >= self.tokens.len() {
40202 false
40203 } else {
40204 self.tokens[self.current + 1].token_type == token_type
40205 }
40206 }
40207
40208 fn check_next_identifier(&self, name: &str) -> bool {
40210 if self.current + 1 >= self.tokens.len() {
40211 false
40212 } else {
40213 let token = &self.tokens[self.current + 1];
40214 (token.token_type == TokenType::Var || token.token_type == TokenType::Identifier)
40215 && token.text.eq_ignore_ascii_case(name)
40216 }
40217 }
40218
40219 fn match_identifier(&mut self, text: &str) -> bool {
40222 if (self.check(TokenType::Identifier)
40223 || self.check(TokenType::Var)
40224 || self.check(TokenType::QuotedIdentifier))
40225 && self.peek().text.eq_ignore_ascii_case(text)
40226 {
40227 self.skip();
40228 true
40229 } else {
40230 false
40231 }
40232 }
40233
40234 fn check_identifier(&self, text: &str) -> bool {
40237 if self.is_at_end() {
40238 return false;
40239 }
40240 (self.check(TokenType::Identifier)
40241 || self.check(TokenType::Var)
40242 || self.check(TokenType::QuotedIdentifier))
40243 && self.peek().text.eq_ignore_ascii_case(text)
40244 }
40245
40246 fn is_percent_modifier(&self) -> bool {
40251 if self.is_at_end() {
40252 return false;
40253 }
40254 if self.peek().text.eq_ignore_ascii_case("PERCENT") {
40255 return true;
40256 }
40257 if self.peek().text == "%" {
40259 let next_idx = self.current + 1;
40260 if next_idx >= self.tokens.len() {
40261 return true; }
40263 let next_type = self.tokens[next_idx].token_type;
40264 return matches!(
40265 next_type,
40266 TokenType::Offset
40267 | TokenType::Semicolon
40268 | TokenType::RParen
40269 | TokenType::From
40270 | TokenType::Where
40271 | TokenType::GroupBy
40272 | TokenType::OrderBy
40273 | TokenType::Having
40274 | TokenType::Union
40275 | TokenType::Intersect
40276 | TokenType::Except
40277 | TokenType::Comma
40278 | TokenType::With ) || next_idx >= self.tokens.len();
40280 }
40281 false
40282 }
40283
40284 fn is_safe_keyword_as_identifier(&self) -> bool {
40287 if self.is_at_end() {
40288 return false;
40289 }
40290 let token_type = self.peek().token_type;
40291 let is_structural = matches!(
40293 token_type,
40294 TokenType::From
40295 | TokenType::Where
40296 | TokenType::Select
40297 | TokenType::Insert
40298 | TokenType::Delete
40299 | TokenType::Create
40300 | TokenType::Drop
40301 | TokenType::Alter
40302 | TokenType::Join
40303 | TokenType::Inner
40304 | TokenType::Cross
40305 | TokenType::On
40306 | TokenType::GroupBy
40307 | TokenType::OrderBy
40308 | TokenType::Having
40309 | TokenType::With
40310 | TokenType::Union
40311 | TokenType::Intersect
40312 | TokenType::Except
40313 | TokenType::Qualify
40314 | TokenType::Into
40315 | TokenType::Set
40316 | TokenType::Using
40317 | TokenType::Lateral
40318 | TokenType::Natural
40319 );
40320 if matches!(
40322 self.config.dialect,
40323 Some(crate::dialects::DialectType::ClickHouse)
40324 ) {
40325 let is_ch_structural = matches!(
40326 token_type,
40327 TokenType::From
40328 | TokenType::Where
40329 | TokenType::Select
40330 | TokenType::Create
40331 | TokenType::Drop
40332 | TokenType::Alter
40333 | TokenType::On
40334 | TokenType::GroupBy
40335 | TokenType::OrderBy
40336 | TokenType::Having
40337 | TokenType::With
40338 | TokenType::Union
40339 | TokenType::Intersect
40340 | TokenType::Except
40341 | TokenType::Into
40342 | TokenType::Using
40343 | TokenType::Lateral
40344 | TokenType::Natural
40345 );
40346 if matches!(token_type, TokenType::RLike | TokenType::Values) {
40348 return true;
40349 }
40350 return self.peek().token_type.is_keyword() && !is_ch_structural;
40351 }
40352 self.peek().token_type.is_keyword() && !is_structural
40354 }
40355
40356 fn is_last_expression_token(&self, _token_type: TokenType) -> bool {
40360 let next_idx = self.current + 1;
40362 if next_idx >= self.tokens.len() {
40363 return true; }
40365 let next_type = self.tokens[next_idx].token_type;
40366 matches!(
40368 next_type,
40369 TokenType::From
40370 | TokenType::Where
40371 | TokenType::GroupBy
40372 | TokenType::OrderBy
40373 | TokenType::Having
40374 | TokenType::Limit
40375 | TokenType::Union
40376 | TokenType::Intersect
40377 | TokenType::Except
40378 | TokenType::Semicolon
40379 | TokenType::RParen
40380 | TokenType::Comma
40381 )
40382 }
40383
40384 fn is_type_keyword(&self) -> bool {
40386 if self.is_at_end() {
40387 return false;
40388 }
40389 let token = self.peek();
40390 let text_upper = token.text.to_ascii_uppercase();
40393 matches!(
40394 text_upper.as_str(),
40395 "INT"
40396 | "INTEGER"
40397 | "BIGINT"
40398 | "SMALLINT"
40399 | "TINYINT"
40400 | "DOUBLE"
40401 | "FLOAT"
40402 | "DECIMAL"
40403 | "NUMERIC"
40404 | "REAL"
40405 | "VARCHAR"
40406 | "CHAR"
40407 | "TEXT"
40408 | "STRING"
40409 | "NVARCHAR"
40410 | "NCHAR"
40411 | "BOOLEAN"
40412 | "BOOL"
40413 | "DATE"
40414 | "TIME"
40415 | "TIMESTAMP"
40416 | "DATETIME"
40417 | "INTERVAL"
40418 | "BINARY"
40419 | "VARBINARY"
40420 | "BLOB"
40421 | "ARRAY"
40422 | "MAP"
40423 | "STRUCT"
40424 | "OBJECT"
40425 | "VARIANT"
40426 | "JSON"
40427 | "NUMBER"
40428 | "VARCHAR2"
40429 )
40430 }
40431
40432 fn is_command_keyword_as_alias(&self) -> bool {
40436 if self.is_at_end() {
40437 return false;
40438 }
40439 let token_type = self.peek().token_type;
40440 if matches!(token_type, TokenType::Format) {
40442 return !matches!(
40443 self.config.dialect,
40444 Some(crate::dialects::DialectType::ClickHouse)
40445 );
40446 }
40447 if matches!(
40449 token_type,
40450 TokenType::Get
40451 | TokenType::Put
40452 | TokenType::Copy
40453 | TokenType::Show
40454 | TokenType::Rename
40455 | TokenType::Enum
40456 | TokenType::Sample
40457 | TokenType::Collate
40458 | TokenType::Add
40459 ) {
40460 return true;
40461 }
40462 if matches!(
40465 self.config.dialect,
40466 Some(crate::dialects::DialectType::Spark)
40467 | Some(crate::dialects::DialectType::Hive)
40468 | Some(crate::dialects::DialectType::Databricks)
40469 ) && matches!(token_type, TokenType::Limit | TokenType::Offset)
40470 {
40471 let next = self.current + 1;
40472 let next_is_value = next < self.tokens.len()
40473 && matches!(
40474 self.tokens[next].token_type,
40475 TokenType::Number
40476 | TokenType::LParen
40477 | TokenType::Var
40478 | TokenType::Parameter
40479 | TokenType::All
40480 );
40481 if !next_is_value {
40482 return true;
40483 }
40484 }
40485 false
40486 }
40487
40488 fn can_be_alias_keyword(&self) -> bool {
40492 if self.is_at_end() {
40493 return false;
40494 }
40495 let token_type = self.peek().token_type;
40496 matches!(
40498 token_type,
40499 TokenType::Left
40500 | TokenType::Right
40501 | TokenType::Outer
40502 | TokenType::Full
40503 | TokenType::Only
40504 | TokenType::Next
40505 | TokenType::All
40506 | TokenType::If
40507 ) || self.is_safe_keyword_as_identifier()
40508 }
40509
40510 fn match_token(&mut self, token_type: TokenType) -> bool {
40512 if self.check(token_type) {
40513 self.skip();
40514 true
40515 } else {
40516 false
40517 }
40518 }
40519
40520 fn match_keywords(&mut self, keywords: &[TokenType]) -> bool {
40522 for (i, &kw) in keywords.iter().enumerate() {
40524 if self.current + i >= self.tokens.len() {
40525 return false;
40526 }
40527 if self.tokens[self.current + i].token_type != kw {
40528 return false;
40529 }
40530 }
40531
40532 self.current += keywords.len();
40534 true
40535 }
40536
40537 fn expect(&mut self, token_type: TokenType) -> Result<Token> {
40539 if self.check(token_type) {
40540 Ok(self.advance())
40541 } else {
40542 let got = if self.is_at_end() {
40543 "end of input".to_string()
40544 } else {
40545 format!("{:?}", self.peek().token_type)
40546 };
40547 let got_text = if self.is_at_end() {
40548 "".to_string()
40549 } else {
40550 self.peek().text.clone()
40551 };
40552 let start = self.current.saturating_sub(3);
40553 let end = (self.current + 4).min(self.tokens.len());
40554 let context = self.tokens_to_sql(start, end).replace('\n', " ");
40555 Err(self.parse_error(format!(
40556 "Expected {:?}, got {} ('{}') near [{}]",
40557 token_type, got, got_text, context
40558 )))
40559 }
40560 }
40561
40562 fn expect_gt(&mut self) -> Result<Token> {
40565 if self.check(TokenType::Gt) {
40566 Ok(self.advance())
40567 } else if self.check(TokenType::GtGt) {
40568 let token = self.peek().clone();
40571 self.tokens[self.current] = Token {
40572 token_type: TokenType::Gt,
40573 text: ">".to_string(),
40574 span: Span {
40575 start: token.span.start + 1,
40576 end: token.span.end,
40577 line: token.span.line,
40578 column: token.span.column + 1,
40579 },
40580 comments: Vec::new(),
40581 trailing_comments: Vec::new(),
40582 };
40583 Ok(Token {
40584 token_type: TokenType::Gt,
40585 text: ">".to_string(),
40586 span: Span {
40587 start: token.span.start,
40588 end: token.span.start + 1,
40589 line: token.span.line,
40590 column: token.span.column,
40591 },
40592 comments: token.comments,
40593 trailing_comments: Vec::new(),
40594 })
40595 } else {
40596 Err(self.parse_error(format!(
40597 "Expected Gt, got {:?}",
40598 if self.is_at_end() {
40599 "end of input".to_string()
40600 } else {
40601 format!("{:?}", self.peek().token_type)
40602 }
40603 )))
40604 }
40605 }
40606
40607 fn expect_string(&mut self) -> Result<String> {
40609 if self.check(TokenType::String) || self.check(TokenType::DollarString) {
40610 Ok(self.advance().text)
40611 } else {
40612 Err(self.parse_error(format!(
40613 "Expected string, got {:?}",
40614 if self.is_at_end() {
40615 "end of input".to_string()
40616 } else {
40617 format!("{:?}", self.peek().token_type)
40618 }
40619 )))
40620 }
40621 }
40622
40623 fn is_identifier_token(&self) -> bool {
40625 self.check(TokenType::Var)
40626 || self.check(TokenType::Identifier)
40627 || self.check(TokenType::QuotedIdentifier)
40628 }
40629
40630 fn is_stage_reference(&self) -> bool {
40633 self.check(TokenType::DAt)
40634 || (self.check(TokenType::Var) && self.peek().text.starts_with('@'))
40635 }
40636
40637 fn is_mysql_numeric_identifier(&self) -> bool {
40640 if !self.check(TokenType::Number)
40641 || !matches!(
40642 self.config.dialect,
40643 Some(crate::dialects::DialectType::MySQL)
40644 )
40645 {
40646 return false;
40647 }
40648 if self.current + 1 < self.tokens.len() {
40650 let curr = &self.tokens[self.current];
40651 let next = &self.tokens[self.current + 1];
40652 let connected = curr.span.end == next.span.start;
40655 connected
40656 && (next.token_type == TokenType::Var || next.token_type == TokenType::Identifier)
40657 } else {
40658 false
40659 }
40660 }
40661
40662 fn parse_mysql_numeric_identifier(&mut self) -> Identifier {
40665 let num_token = self.advance();
40666 let mut name = num_token.text.clone();
40667 while !self.is_at_end()
40669 && self.is_connected()
40670 && (self.check(TokenType::Var) || self.check(TokenType::Identifier))
40671 {
40672 let tok = self.advance();
40673 name.push_str(&tok.text);
40674 }
40675 Identifier {
40676 name,
40677 quoted: true,
40679 trailing_comments: Vec::new(),
40680 span: None,
40681 }
40682 }
40683
40684 fn is_mysql_charset_introducer(text: &str) -> bool {
40686 matches!(
40687 text,
40688 "_ARMSCII8"
40689 | "_ASCII"
40690 | "_BIG5"
40691 | "_BINARY"
40692 | "_CP1250"
40693 | "_CP1251"
40694 | "_CP1256"
40695 | "_CP1257"
40696 | "_CP850"
40697 | "_CP852"
40698 | "_CP866"
40699 | "_CP932"
40700 | "_DEC8"
40701 | "_EUCJPMS"
40702 | "_EUCKR"
40703 | "_GB18030"
40704 | "_GB2312"
40705 | "_GBK"
40706 | "_GEOSTD8"
40707 | "_GREEK"
40708 | "_HEBREW"
40709 | "_HP8"
40710 | "_KEYBCS2"
40711 | "_KOI8R"
40712 | "_KOI8U"
40713 | "_LATIN1"
40714 | "_LATIN2"
40715 | "_LATIN5"
40716 | "_LATIN7"
40717 | "_MACCE"
40718 | "_MACROMAN"
40719 | "_SJIS"
40720 | "_SWE7"
40721 | "_TIS620"
40722 | "_UCS2"
40723 | "_UJIS"
40724 | "_UTF8"
40725 | "_UTF16"
40726 | "_UTF16LE"
40727 | "_UTF32"
40728 | "_UTF8MB3"
40729 | "_UTF8MB4"
40730 )
40731 }
40732
40733 fn is_identifier_or_keyword_token(&self) -> bool {
40735 self.is_identifier_token() || self.check_keyword()
40736 }
40737
40738 fn expect_identifier_with_quoted(&mut self) -> Result<Identifier> {
40740 if self.is_mysql_numeric_identifier() {
40741 return Ok(self.parse_mysql_numeric_identifier());
40742 }
40743 if self.is_identifier_token() {
40744 let token = self.advance();
40745 let quoted = token.token_type == TokenType::QuotedIdentifier;
40746 Ok(Identifier {
40747 name: token.text,
40748 quoted,
40749 trailing_comments: Vec::new(),
40750 span: None,
40751 })
40752 } else if self.check(TokenType::LBrace)
40753 && matches!(
40754 self.config.dialect,
40755 Some(crate::dialects::DialectType::ClickHouse)
40756 )
40757 {
40758 if let Some(param_expr) = self.parse_clickhouse_braced_parameter()? {
40759 if let Expression::Parameter(param) = ¶m_expr {
40760 let name = format!(
40761 "{{{}: {}}}",
40762 param.name.as_deref().unwrap_or(""),
40763 param.expression.as_deref().unwrap_or("")
40764 );
40765 return Ok(Identifier {
40766 name,
40767 quoted: false,
40768 trailing_comments: Vec::new(),
40769 span: None,
40770 });
40771 }
40772 }
40773 Err(self.parse_error("Expected identifier, got LBrace"))
40774 } else {
40775 Err(self.parse_error(format!(
40776 "Expected identifier, got {:?}",
40777 if self.is_at_end() {
40778 "end of input".to_string()
40779 } else {
40780 format!("{:?}", self.peek().token_type)
40781 }
40782 )))
40783 }
40784 }
40785
40786 fn parse_identifier_parts(&mut self) -> Result<Vec<Identifier>> {
40788 let first = self.expect_identifier_with_quoted()?;
40789 let mut parts = vec![first];
40790 while self.match_token(TokenType::Dot) {
40791 parts.push(self.expect_identifier_with_quoted()?);
40792 }
40793 Ok(parts)
40794 }
40795
40796 fn expect_identifier_or_keyword_with_quoted(&mut self) -> Result<Identifier> {
40798 if self.is_mysql_numeric_identifier() {
40800 return Ok(self.parse_mysql_numeric_identifier());
40801 }
40802 if self.check(TokenType::Parameter) {
40805 let token = self.advance();
40806 let name = if token.text.chars().all(|c| c.is_ascii_digit()) && !token.text.is_empty() {
40809 format!("${}", token.text)
40810 } else {
40811 "?".to_string()
40813 };
40814 return Ok(Identifier {
40815 name,
40816 quoted: false,
40817 trailing_comments: Vec::new(),
40818 span: None,
40819 });
40820 }
40821 if self.is_identifier_or_keyword_token() {
40822 let token = self.advance();
40823 let quoted = token.token_type == TokenType::QuotedIdentifier;
40824 Ok(Identifier {
40825 name: token.text,
40826 quoted,
40827 trailing_comments: Vec::new(),
40828 span: None,
40829 })
40830 } else if self.check(TokenType::LBrace)
40831 && matches!(
40832 self.config.dialect,
40833 Some(crate::dialects::DialectType::ClickHouse)
40834 )
40835 {
40836 if let Some(param_expr) = self.parse_clickhouse_braced_parameter()? {
40838 if let Expression::Parameter(param) = ¶m_expr {
40840 let name = format!(
40841 "{{{}: {}}}",
40842 param.name.as_deref().unwrap_or(""),
40843 param.expression.as_deref().unwrap_or("")
40844 );
40845 return Ok(Identifier {
40846 name,
40847 quoted: false,
40848 trailing_comments: Vec::new(),
40849 span: None,
40850 });
40851 }
40852 }
40853 Err(self.parse_error("Expected identifier, got LBrace"))
40854 } else {
40855 Err(self.parse_error(format!(
40856 "Expected identifier, got {:?}",
40857 if self.is_at_end() {
40858 "end of input".to_string()
40859 } else {
40860 format!("{:?}", self.peek().token_type)
40861 }
40862 )))
40863 }
40864 }
40865
40866 fn expect_identifier(&mut self) -> Result<String> {
40868 if self.is_identifier_token() {
40869 Ok(self.advance().text)
40870 } else if self.check(TokenType::LBrace)
40871 && matches!(
40872 self.config.dialect,
40873 Some(crate::dialects::DialectType::ClickHouse)
40874 )
40875 {
40876 if let Some(param_expr) = self.parse_clickhouse_braced_parameter()? {
40877 if let Expression::Parameter(param) = ¶m_expr {
40878 return Ok(format!(
40879 "{{{}: {}}}",
40880 param.name.as_deref().unwrap_or(""),
40881 param.expression.as_deref().unwrap_or("")
40882 ));
40883 }
40884 }
40885 Err(self.parse_error("Expected identifier, got LBrace"))
40886 } else {
40887 Err(self.parse_error(format!(
40888 "Expected identifier, got {:?}",
40889 if self.is_at_end() {
40890 "end of input".to_string()
40891 } else {
40892 format!("{:?}", self.peek().token_type)
40893 }
40894 )))
40895 }
40896 }
40897
40898 fn expect_identifier_or_keyword(&mut self) -> Result<String> {
40900 if self.is_identifier_or_keyword_token() {
40901 Ok(self.advance().text)
40902 } else if self.check(TokenType::LBrace)
40903 && matches!(
40904 self.config.dialect,
40905 Some(crate::dialects::DialectType::ClickHouse)
40906 )
40907 {
40908 if let Some(param_expr) = self.parse_clickhouse_braced_parameter()? {
40909 if let Expression::Parameter(param) = ¶m_expr {
40910 return Ok(format!(
40911 "{{{}: {}}}",
40912 param.name.as_deref().unwrap_or(""),
40913 param.expression.as_deref().unwrap_or("")
40914 ));
40915 }
40916 }
40917 Err(self.parse_error("Expected identifier, got LBrace"))
40918 } else {
40919 Err(self.parse_error(format!(
40920 "Expected identifier, got {:?}",
40921 if self.is_at_end() {
40922 "end of input".to_string()
40923 } else {
40924 format!("{:?}", self.peek().token_type)
40925 }
40926 )))
40927 }
40928 }
40929
40930 fn expect_identifier_or_safe_keyword(&mut self) -> Result<String> {
40933 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
40934 Ok(self.advance().text)
40935 } else if self.check(TokenType::LBrace)
40936 && matches!(
40937 self.config.dialect,
40938 Some(crate::dialects::DialectType::ClickHouse)
40939 )
40940 {
40941 if let Some(param_expr) = self.parse_clickhouse_braced_parameter()? {
40942 if let Expression::Parameter(param) = ¶m_expr {
40943 return Ok(format!(
40944 "{{{}: {}}}",
40945 param.name.as_deref().unwrap_or(""),
40946 param.expression.as_deref().unwrap_or("")
40947 ));
40948 }
40949 }
40950 Err(self.parse_error("Expected identifier, got LBrace"))
40951 } else {
40952 Err(self.parse_error(format!(
40953 "Expected identifier, got {:?}",
40954 if self.is_at_end() {
40955 "end of input".to_string()
40956 } else {
40957 format!("{:?}", self.peek().token_type)
40958 }
40959 )))
40960 }
40961 }
40962
40963 fn expect_identifier_or_safe_keyword_with_quoted(&mut self) -> Result<Identifier> {
40965 if self.is_mysql_numeric_identifier() {
40966 return Ok(self.parse_mysql_numeric_identifier());
40967 }
40968 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
40969 let token = self.advance();
40970 let quoted = token.token_type == TokenType::QuotedIdentifier;
40971 Ok(Identifier {
40972 name: token.text,
40973 quoted,
40974 trailing_comments: Vec::new(),
40975 span: None,
40976 })
40977 } else {
40978 Err(self.parse_error(format!(
40979 "Expected identifier, got {:?}",
40980 if self.is_at_end() {
40981 "end of input".to_string()
40982 } else {
40983 format!("{:?}", self.peek().token_type)
40984 }
40985 )))
40986 }
40987 }
40988
40989 fn expect_identifier_or_alias_keyword_with_quoted(&mut self) -> Result<Identifier> {
40990 let ch_keyword = matches!(
40992 self.config.dialect,
40993 Some(crate::dialects::DialectType::ClickHouse)
40994 ) && self.peek().token_type.is_keyword();
40995 if self.is_identifier_token()
40996 || self.can_be_alias_keyword()
40997 || self.is_safe_keyword_as_identifier()
40998 || ch_keyword
40999 {
41000 let token = self.advance();
41001 let quoted = token.token_type == TokenType::QuotedIdentifier;
41002 Ok(Identifier {
41003 name: token.text,
41004 quoted,
41005 trailing_comments: Vec::new(),
41006 span: None,
41007 })
41008 } else if self.check(TokenType::String)
41009 && matches!(
41010 self.config.dialect,
41011 Some(crate::dialects::DialectType::DuckDB)
41012 )
41013 {
41014 let token = self.advance();
41016 Ok(Identifier {
41017 name: token.text,
41018 quoted: true,
41019 trailing_comments: Vec::new(),
41020 span: None,
41021 })
41022 } else {
41023 Err(self.parse_error(format!(
41024 "Expected identifier, got {:?}",
41025 if self.is_at_end() {
41026 "end of input".to_string()
41027 } else {
41028 format!("{:?}", self.peek().token_type)
41029 }
41030 )))
41031 }
41032 }
41033
41034 fn expect_number(&mut self) -> Result<i64> {
41036 let negative = self.match_token(TokenType::Dash);
41037 if self.check(TokenType::Number) {
41038 let text = self.advance().text;
41039 let val = text
41040 .parse::<i64>()
41041 .map_err(|_| self.parse_error(format!("Invalid number: {}", text)))?;
41042 Ok(if negative { -val } else { val })
41043 } else {
41044 Err(self.parse_error("Expected number"))
41045 }
41046 }
41047
41048 fn parse_expression_list_with_capacity(
41051 &mut self,
41052 capacity_hint: usize,
41053 ) -> Result<Vec<Expression>> {
41054 let mut expressions = Vec::with_capacity(capacity_hint);
41055
41056 loop {
41057 let expr = if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
41060 let start_pos = self.current;
41061 let name = self.expect_identifier_or_keyword_with_quoted()?;
41062
41063 if self.match_token(TokenType::FArrow) {
41064 let value = self.parse_expression()?;
41066 Expression::NamedArgument(Box::new(NamedArgument {
41067 name,
41068 value,
41069 separator: NamedArgSeparator::DArrow,
41070 }))
41071 } else if self.match_token(TokenType::ColonEq) {
41072 let value = self.parse_expression()?;
41074 Expression::NamedArgument(Box::new(NamedArgument {
41075 name,
41076 value,
41077 separator: NamedArgSeparator::ColonEq,
41078 }))
41079 } else {
41080 self.current = start_pos;
41082 self.parse_expression()?
41083 }
41084 } else {
41085 self.parse_expression()?
41086 };
41087
41088 let expr = if self.check(TokenType::As) {
41090 let as_pos = self.current;
41091 self.skip(); if self.is_identifier_token()
41094 || self.is_safe_keyword_as_identifier()
41095 || (matches!(
41096 self.config.dialect,
41097 Some(crate::dialects::DialectType::ClickHouse)
41098 ) && self.peek().token_type.is_keyword())
41099 {
41100 let alias = self.expect_identifier_or_keyword_with_quoted()?;
41101 let alias_expr = Expression::Alias(Box::new(Alias {
41102 this: expr,
41103 alias,
41104 column_aliases: Vec::new(),
41105 pre_alias_comments: Vec::new(),
41106 trailing_comments: Vec::new(),
41107 inferred_type: None,
41108 }));
41109 if matches!(
41112 self.config.dialect,
41113 Some(crate::dialects::DialectType::ClickHouse)
41114 ) && matches!(
41115 self.peek().token_type,
41116 TokenType::Lt
41117 | TokenType::Gt
41118 | TokenType::Lte
41119 | TokenType::Gte
41120 | TokenType::Eq
41121 | TokenType::Neq
41122 | TokenType::Plus
41123 | TokenType::Dash
41124 | TokenType::Star
41125 | TokenType::Slash
41126 | TokenType::Percent
41127 | TokenType::And
41128 | TokenType::Or
41129 | TokenType::Like
41130 | TokenType::Not
41131 | TokenType::In
41132 | TokenType::Is
41133 | TokenType::Between
41134 ) {
41135 let op_token = self.advance();
41137 let right = self.parse_expression()?;
41138 match op_token.token_type {
41139 TokenType::Lt => {
41140 Expression::Lt(Box::new(BinaryOp::new(alias_expr, right)))
41141 }
41142 TokenType::Gt => {
41143 Expression::Gt(Box::new(BinaryOp::new(alias_expr, right)))
41144 }
41145 TokenType::Lte => {
41146 Expression::Lte(Box::new(BinaryOp::new(alias_expr, right)))
41147 }
41148 TokenType::Gte => {
41149 Expression::Gte(Box::new(BinaryOp::new(alias_expr, right)))
41150 }
41151 TokenType::Eq => {
41152 Expression::Eq(Box::new(BinaryOp::new(alias_expr, right)))
41153 }
41154 TokenType::Neq => {
41155 Expression::Neq(Box::new(BinaryOp::new(alias_expr, right)))
41156 }
41157 TokenType::Plus => {
41158 Expression::Add(Box::new(BinaryOp::new(alias_expr, right)))
41159 }
41160 TokenType::Dash => {
41161 Expression::Sub(Box::new(BinaryOp::new(alias_expr, right)))
41162 }
41163 TokenType::Star => {
41164 Expression::Mul(Box::new(BinaryOp::new(alias_expr, right)))
41165 }
41166 TokenType::Slash => {
41167 Expression::Div(Box::new(BinaryOp::new(alias_expr, right)))
41168 }
41169 TokenType::Percent => {
41170 Expression::Mod(Box::new(BinaryOp::new(alias_expr, right)))
41171 }
41172 TokenType::And => {
41173 Expression::And(Box::new(BinaryOp::new(alias_expr, right)))
41174 }
41175 TokenType::Or => {
41176 Expression::Or(Box::new(BinaryOp::new(alias_expr, right)))
41177 }
41178 _ => alias_expr, }
41180 } else {
41181 alias_expr
41182 }
41183 } else {
41184 self.current = as_pos;
41186 expr
41187 }
41188 } else {
41189 expr
41190 };
41191
41192 let trailing_comments = self.previous_trailing_comments().to_vec();
41195 let expr = if trailing_comments.is_empty() {
41196 expr
41197 } else {
41198 match &expr {
41200 Expression::Literal(_) | Expression::Boolean(_) | Expression::Null(_) => {
41201 Expression::Annotated(Box::new(Annotated {
41202 this: expr,
41203 trailing_comments,
41204 }))
41205 }
41206 _ => expr,
41208 }
41209 };
41210 expressions.push(expr);
41211
41212 if !self.match_token(TokenType::Comma) {
41213 break;
41214 }
41215 if matches!(
41217 self.config.dialect,
41218 Some(crate::dialects::DialectType::ClickHouse)
41219 ) && self.check(TokenType::RParen)
41220 {
41221 break;
41222 }
41223 }
41224
41225 Ok(expressions)
41226 }
41227
41228 fn parse_expression_list(&mut self) -> Result<Vec<Expression>> {
41231 self.parse_expression_list_with_capacity(0)
41232 }
41233
41234 fn estimate_expression_list_capacity_until_rparen(&self) -> usize {
41239 if self.current >= self.tokens.len() || self.check(TokenType::RParen) {
41240 return 0;
41241 }
41242
41243 let mut idx = self.current;
41244 let mut paren_depth = 0usize;
41245 let mut bracket_depth = 0usize;
41246 let mut brace_depth = 0usize;
41247 let mut commas = 0usize;
41248 let mut has_any_token = false;
41249
41250 while idx < self.tokens.len() {
41251 let token_type = self.tokens[idx].token_type;
41252 match token_type {
41253 TokenType::LParen => paren_depth += 1,
41254 TokenType::RParen => {
41255 if paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 {
41256 break;
41257 }
41258 paren_depth = paren_depth.saturating_sub(1);
41259 }
41260 TokenType::LBracket => bracket_depth += 1,
41261 TokenType::RBracket => bracket_depth = bracket_depth.saturating_sub(1),
41262 TokenType::LBrace => brace_depth += 1,
41263 TokenType::RBrace => brace_depth = brace_depth.saturating_sub(1),
41264 TokenType::Comma if paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 => {
41265 commas += 1;
41266 }
41267 _ => {}
41268 }
41269 has_any_token = true;
41270 idx += 1;
41271 }
41272
41273 if has_any_token {
41274 commas + 1
41275 } else {
41276 0
41277 }
41278 }
41279
41280 fn parse_function_args_with_lambda(&mut self) -> Result<Vec<Expression>> {
41283 let mut expressions = Vec::new();
41284
41285 loop {
41286 let expr = if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
41288 let saved_pos = self.current;
41289 let ident_token = self.advance();
41290 let ident_name = ident_token.text.clone();
41291
41292 if self.match_token(TokenType::Arrow) {
41294 let body = self.parse_expression()?;
41295 Expression::Lambda(Box::new(LambdaExpr {
41296 parameters: vec![Identifier::new(ident_name)],
41297 body,
41298 colon: false,
41299 parameter_types: Vec::new(),
41300 }))
41301 }
41302 else if !self.is_at_end()
41304 && self.is_type_keyword()
41305 && !self.check(TokenType::FArrow)
41306 && !self.check(TokenType::ColonEq)
41307 {
41308 let type_annotation = self.parse_data_type()?;
41309 if self.match_token(TokenType::Arrow) {
41310 let body = self.parse_expression()?;
41311 Expression::Lambda(Box::new(LambdaExpr {
41312 parameters: vec![Identifier::new(ident_name)],
41313 body,
41314 colon: false,
41315 parameter_types: vec![Some(type_annotation)],
41316 }))
41317 } else {
41318 self.current = saved_pos;
41319 self.parse_expression()?
41320 }
41321 } else {
41322 self.current = saved_pos;
41324 self.parse_expression()?
41325 }
41326 } else {
41327 self.parse_expression()?
41328 };
41329
41330 expressions.push(expr);
41331 if !self.match_token(TokenType::Comma) {
41332 break;
41333 }
41334 }
41335
41336 Ok(expressions)
41337 }
41338
41339 fn parse_values_expression_list(&mut self) -> Result<Vec<Expression>> {
41342 let mut expressions = Vec::new();
41343
41344 loop {
41345 let expr = if self.match_token(TokenType::Default) {
41347 Expression::Var(Box::new(crate::expressions::Var {
41348 this: "DEFAULT".to_string(),
41349 }))
41350 } else {
41351 self.parse_expression()?
41352 };
41353
41354 let trailing_comments = self.previous_trailing_comments().to_vec();
41356 let expr = if !trailing_comments.is_empty() {
41357 match &expr {
41358 Expression::Literal(_) | Expression::Boolean(_) | Expression::Null(_) => {
41359 Expression::Annotated(Box::new(crate::expressions::Annotated {
41360 this: expr,
41361 trailing_comments,
41362 }))
41363 }
41364 _ => expr,
41365 }
41366 } else {
41367 expr
41368 };
41369
41370 let expr_with_alias = if self.match_token(TokenType::As) {
41372 let alias = self.expect_identifier_or_keyword_with_quoted()?;
41373 Expression::Alias(Box::new(Alias::new(expr, alias)))
41374 } else {
41375 expr
41376 };
41377
41378 expressions.push(expr_with_alias);
41379
41380 if !self.match_token(TokenType::Comma) {
41381 break;
41382 }
41383 if self.check(TokenType::RParen) {
41385 break;
41386 }
41387 }
41388
41389 Ok(expressions)
41390 }
41391
41392 fn parse_identifier_list(&mut self) -> Result<Vec<Identifier>> {
41394 let mut identifiers = Vec::new();
41395
41396 loop {
41397 let quoted = self.check(TokenType::QuotedIdentifier);
41400 let mut name = self.expect_identifier_or_safe_keyword()?;
41401 if matches!(
41404 self.config.dialect,
41405 Some(crate::dialects::DialectType::ClickHouse)
41406 ) {
41407 while self.match_token(TokenType::Dot) {
41408 let sub_id = self.expect_identifier_or_keyword_with_quoted()?;
41409 name = format!("{}.{}", name, sub_id.name);
41410 }
41411 }
41412 let trailing_comments = self.previous_trailing_comments().to_vec();
41413 identifiers.push(Identifier {
41414 name,
41415 quoted,
41416 trailing_comments,
41417 span: None,
41418 });
41419
41420 if !self.match_token(TokenType::Comma) {
41421 break;
41422 }
41423 if matches!(
41425 self.config.dialect,
41426 Some(crate::dialects::DialectType::ClickHouse)
41427 ) && self.check(TokenType::RParen)
41428 {
41429 break;
41430 }
41431 }
41432
41433 Ok(identifiers)
41434 }
41435
41436 fn parse_using_column_list(&mut self) -> Result<Vec<Identifier>> {
41439 let mut identifiers = Vec::new();
41440
41441 loop {
41442 if matches!(
41444 self.config.dialect,
41445 Some(crate::dialects::DialectType::ClickHouse)
41446 ) && self.match_token(TokenType::Star)
41447 {
41448 identifiers.push(Identifier::new("*".to_string()));
41449 if !self.match_token(TokenType::Comma) {
41450 break;
41451 }
41452 continue;
41453 }
41454 let quoted = self.check(TokenType::QuotedIdentifier);
41456 let mut name = self.expect_identifier_or_safe_keyword()?;
41457 let mut final_quoted = quoted;
41458
41459 while self.match_token(TokenType::Dot) {
41462 final_quoted = self.check(TokenType::QuotedIdentifier);
41463 name = self.expect_identifier_or_safe_keyword()?;
41464 }
41465
41466 if matches!(
41468 self.config.dialect,
41469 Some(crate::dialects::DialectType::ClickHouse)
41470 ) && self.match_token(TokenType::As)
41471 {
41472 final_quoted = self.check(TokenType::QuotedIdentifier);
41474 name = self.expect_identifier_or_safe_keyword()?;
41475 }
41476
41477 let trailing_comments = self.previous_trailing_comments().to_vec();
41478 identifiers.push(Identifier {
41479 name,
41480 quoted: final_quoted,
41481 trailing_comments,
41482 span: None,
41483 });
41484
41485 if !self.match_token(TokenType::Comma) {
41486 break;
41487 }
41488 }
41489
41490 Ok(identifiers)
41491 }
41492
41493 fn parse_index_identifier_list(&mut self) -> Result<Vec<Identifier>> {
41496 let mut identifiers = Vec::new();
41497
41498 loop {
41499 let quoted = self.check(TokenType::QuotedIdentifier);
41500 let name = self.expect_identifier_or_safe_keyword()?;
41501 let trailing_comments = self.previous_trailing_comments().to_vec();
41502
41503 let mut display_name = name.clone();
41505 if self.match_token(TokenType::LParen) {
41506 if self.check(TokenType::Number) {
41507 let len = self.advance().text;
41508 display_name = format!("{}({})", name, len);
41509 }
41510 self.expect(TokenType::RParen)?;
41511 }
41512
41513 if self.match_token(TokenType::Desc) {
41515 display_name = format!("{} DESC", display_name);
41516 } else if self.match_token(TokenType::Asc) {
41517 display_name = format!("{} ASC", display_name);
41518 }
41519
41520 identifiers.push(Identifier {
41521 name: display_name,
41522 quoted,
41523 trailing_comments,
41524 span: None,
41525 });
41526
41527 if !self.match_token(TokenType::Comma) {
41528 break;
41529 }
41530 }
41531
41532 Ok(identifiers)
41533 }
41534 #[allow(unused_variables, unused_mut)]
41542 pub fn parse_add_column(&mut self) -> Result<Option<Expression>> {
41543 if self.match_texts(&["FIRST", "AFTER"]) {
41544 return Ok(None);
41546 }
41547 Ok(None)
41548 }
41549
41550 pub fn parse_alias(&mut self) -> Result<Option<Expression>> {
41554 let _explicit = self.match_token(TokenType::Alias);
41556
41557 if let Some(alias_expr) = self.parse_id_var()? {
41559 let alias_ident = match alias_expr {
41560 Expression::Identifier(id) => id,
41561 _ => return Ok(None),
41562 };
41563 return Ok(Some(Expression::Identifier(alias_ident)));
41565 }
41566
41567 Ok(None)
41568 }
41569
41570 pub fn parse_alias_with_expr(
41572 &mut self,
41573 this: Option<Expression>,
41574 ) -> Result<Option<Expression>> {
41575 if this.is_none() {
41576 return Ok(None);
41577 }
41578 let expr = this.unwrap();
41579
41580 let has_as = self.match_token(TokenType::Alias) || self.match_token(TokenType::As);
41583
41584 if has_as && self.match_token(TokenType::LParen) {
41586 let mut column_aliases = Vec::new();
41587 loop {
41588 if let Some(col_expr) = self.parse_id_var()? {
41589 if let Expression::Identifier(id) = col_expr {
41590 column_aliases.push(id);
41591 }
41592 } else {
41593 break;
41594 }
41595 if !self.match_token(TokenType::Comma) {
41596 break;
41597 }
41598 }
41599 self.match_token(TokenType::RParen);
41600
41601 if !column_aliases.is_empty() {
41602 return Ok(Some(Expression::Alias(Box::new(Alias {
41603 this: expr,
41604 alias: Identifier::new(String::new()), column_aliases,
41606 pre_alias_comments: Vec::new(),
41607 trailing_comments: Vec::new(),
41608 inferred_type: None,
41609 }))));
41610 }
41611 }
41612
41613 if let Some(alias_expr) = self.parse_id_var()? {
41615 let alias_ident = match alias_expr {
41616 Expression::Identifier(id) => id,
41617 _ => return Ok(Some(expr)),
41618 };
41619 return Ok(Some(Expression::Alias(Box::new(Alias {
41620 this: expr,
41621 alias: alias_ident,
41622 column_aliases: Vec::new(),
41623 pre_alias_comments: Vec::new(),
41624 trailing_comments: Vec::new(),
41625 inferred_type: None,
41626 }))));
41627 }
41628
41629 Ok(Some(expr))
41630 }
41631
41632 #[allow(unused_variables, unused_mut)]
41634 pub fn parse_alter_diststyle(&mut self) -> Result<Option<Expression>> {
41637 if self.match_texts(&["ALL", "EVEN", "AUTO"]) {
41639 let style = self.previous().text.to_ascii_uppercase();
41640 return Ok(Some(Expression::DistStyleProperty(Box::new(
41641 DistStyleProperty {
41642 this: Box::new(Expression::Identifier(Identifier::new(style))),
41643 },
41644 ))));
41645 }
41646
41647 if self.match_text_seq(&["KEY", "DISTKEY"]) {
41649 if let Some(column) = self.parse_column()? {
41650 return Ok(Some(Expression::DistStyleProperty(Box::new(
41651 DistStyleProperty {
41652 this: Box::new(column),
41653 },
41654 ))));
41655 }
41656 }
41657
41658 Ok(None)
41659 }
41660
41661 pub fn parse_alter_session(&mut self) -> Result<Option<Expression>> {
41664 if self.match_token(TokenType::Set) {
41666 let mut expressions = Vec::new();
41667 loop {
41668 if let Some(item) = self.parse_set_item_assignment()? {
41669 expressions.push(item);
41670 }
41671 if !self.match_token(TokenType::Comma) {
41672 break;
41673 }
41674 }
41675 return Ok(Some(Expression::AlterSession(Box::new(AlterSession {
41676 expressions,
41677 unset: None,
41678 }))));
41679 }
41680
41681 if self.match_text_seq(&["UNSET"]) {
41683 let mut expressions = Vec::new();
41684 loop {
41685 if let Some(var) = self.parse_id_var()? {
41686 expressions.push(var);
41688 }
41689 if !self.match_token(TokenType::Comma) {
41690 break;
41691 }
41692 }
41693 return Ok(Some(Expression::AlterSession(Box::new(AlterSession {
41694 expressions,
41695 unset: Some(Box::new(Expression::Boolean(BooleanLiteral {
41696 value: true,
41697 }))),
41698 }))));
41699 }
41700
41701 Ok(None)
41702 }
41703
41704 pub fn parse_alter_sortkey(&mut self) -> Result<Option<Expression>> {
41707 self.parse_alter_sortkey_impl(None)
41708 }
41709
41710 pub fn parse_alter_sortkey_impl(
41712 &mut self,
41713 compound: Option<bool>,
41714 ) -> Result<Option<Expression>> {
41715 if compound == Some(true) {
41717 self.match_text_seq(&["SORTKEY"]);
41718 }
41719
41720 if self.check(TokenType::LParen) {
41722 let wrapped = self.parse_wrapped_id_vars()?;
41723 let expressions = if let Some(Expression::Tuple(t)) = wrapped {
41725 t.expressions
41726 } else {
41727 Vec::new()
41728 };
41729 return Ok(Some(Expression::AlterSortKey(Box::new(AlterSortKey {
41730 this: None,
41731 expressions,
41732 compound: compound
41733 .map(|c| Box::new(Expression::Boolean(BooleanLiteral { value: c }))),
41734 }))));
41735 }
41736
41737 if self.match_texts(&["AUTO", "NONE"]) {
41739 let style = self.previous().text.to_ascii_uppercase();
41740 return Ok(Some(Expression::AlterSortKey(Box::new(AlterSortKey {
41741 this: Some(Box::new(Expression::Identifier(Identifier::new(style)))),
41742 expressions: Vec::new(),
41743 compound: compound
41744 .map(|c| Box::new(Expression::Boolean(BooleanLiteral { value: c }))),
41745 }))));
41746 }
41747
41748 Ok(None)
41749 }
41750
41751 pub fn parse_alter_table_add(&mut self) -> Result<Option<Expression>> {
41754 self.match_text_seq(&["ADD"]);
41756
41757 let kind = if self.match_identifier("FULLTEXT") {
41760 Some("FULLTEXT".to_string())
41761 } else if self.match_identifier("SPATIAL") {
41762 Some("SPATIAL".to_string())
41763 } else {
41764 None
41765 };
41766
41767 if self.check(TokenType::Index) || self.check(TokenType::Key) || kind.is_some() {
41768 let use_key_keyword = if self.match_token(TokenType::Key) {
41770 true
41771 } else {
41772 self.match_token(TokenType::Index);
41773 false
41774 };
41775
41776 let name = if !self.check(TokenType::LParen) && !self.check(TokenType::Using) {
41778 Some(self.expect_identifier_with_quoted()?)
41779 } else {
41780 None
41781 };
41782
41783 self.expect(TokenType::LParen)?;
41785 let columns = self.parse_index_identifier_list()?;
41786 self.expect(TokenType::RParen)?;
41787
41788 let modifiers = self.parse_constraint_modifiers();
41790
41791 return Ok(Some(Expression::AlterTable(Box::new(AlterTable {
41792 name: TableRef::new(""),
41793 actions: vec![AlterTableAction::AddConstraint(TableConstraint::Index {
41794 name,
41795 columns,
41796 kind,
41797 modifiers,
41798 use_key_keyword,
41799 expression: None,
41800 index_type: None,
41801 granularity: None,
41802 })],
41803 if_exists: false,
41804 algorithm: None,
41805 lock: None,
41806 with_check: None,
41807 partition: None,
41808 on_cluster: None,
41809 table_modifier: None,
41810 }))));
41811 }
41812
41813 if self.check(TokenType::PrimaryKey)
41815 || self.check(TokenType::ForeignKey)
41816 || self.check(TokenType::Unique)
41817 || self.check(TokenType::Check)
41818 || self.check(TokenType::Constraint)
41819 {
41820 if let Some(constraint) = self.parse_constraint()? {
41822 return Ok(Some(Expression::Constraint(Box::new(Constraint {
41823 this: Box::new(constraint),
41824 expressions: Vec::new(),
41825 }))));
41826 }
41827 }
41828
41829 if self.match_text_seq(&["COLUMNS"]) {
41831 if let Some(schema) = self.parse_schema()? {
41833 return Ok(Some(schema));
41834 }
41835 }
41836
41837 let exists = self.match_keywords(&[TokenType::If, TokenType::Not, TokenType::Exists]);
41839 if self.match_token(TokenType::Partition) {
41840 self.expect(TokenType::LParen)?;
41842 let mut partition_exprs = Vec::new();
41843 loop {
41844 if let Some(expr) = self.parse_conjunction()? {
41845 partition_exprs.push(expr);
41846 }
41847 if !self.match_token(TokenType::Comma) {
41848 break;
41849 }
41850 }
41851 self.expect(TokenType::RParen)?;
41852
41853 let partition = Expression::Partition(Box::new(crate::expressions::Partition {
41854 expressions: partition_exprs,
41855 subpartition: false,
41856 }));
41857
41858 let location = if self.match_text_seq(&["LOCATION"]) {
41859 self.parse_property()?
41860 } else {
41861 None
41862 };
41863 return Ok(Some(Expression::AddPartition(Box::new(AddPartition {
41864 this: Box::new(partition),
41865 exists,
41866 location: location.map(Box::new),
41867 }))));
41868 }
41869
41870 if let Some(column) = self.parse_add_column()? {
41872 return Ok(Some(column));
41873 }
41874
41875 Ok(None)
41876 }
41877
41878 pub fn parse_alter_table_alter(&mut self) -> Result<Option<Expression>> {
41881 self.match_token(TokenType::Column);
41883
41884 let column = match self.parse_field()? {
41886 Some(c) => c,
41887 None => return Ok(None),
41888 };
41889
41890 if self.match_keywords(&[TokenType::Drop, TokenType::Default]) {
41892 return Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
41893 this: Box::new(column),
41894 dtype: None,
41895 collate: None,
41896 using: None,
41897 default: None,
41898 drop: Some(Box::new(Expression::Boolean(BooleanLiteral {
41899 value: true,
41900 }))),
41901 allow_null: None,
41902 comment: None,
41903 visible: None,
41904 rename_to: None,
41905 }))));
41906 }
41907
41908 if self.match_keywords(&[TokenType::Set, TokenType::Default]) {
41910 let default_val = self.parse_disjunction()?;
41911 return Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
41912 this: Box::new(column),
41913 dtype: None,
41914 collate: None,
41915 using: None,
41916 default: default_val.map(Box::new),
41917 drop: None,
41918 allow_null: None,
41919 comment: None,
41920 visible: None,
41921 rename_to: None,
41922 }))));
41923 }
41924
41925 if self.match_token(TokenType::Comment) {
41927 let comment_val = self.parse_string()?;
41928 return Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
41929 this: Box::new(column),
41930 dtype: None,
41931 collate: None,
41932 using: None,
41933 default: None,
41934 drop: None,
41935 allow_null: None,
41936 comment: comment_val.map(Box::new),
41937 visible: None,
41938 rename_to: None,
41939 }))));
41940 }
41941
41942 if self.match_text_seq(&["DROP", "NOT", "NULL"]) {
41944 return Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
41945 this: Box::new(column),
41946 dtype: None,
41947 collate: None,
41948 using: None,
41949 default: None,
41950 drop: Some(Box::new(Expression::Boolean(BooleanLiteral {
41951 value: true,
41952 }))),
41953 allow_null: Some(Box::new(Expression::Boolean(BooleanLiteral {
41954 value: true,
41955 }))),
41956 comment: None,
41957 visible: None,
41958 rename_to: None,
41959 }))));
41960 }
41961
41962 if self.match_text_seq(&["SET", "NOT", "NULL"]) {
41964 return Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
41965 this: Box::new(column),
41966 dtype: None,
41967 collate: None,
41968 using: None,
41969 default: None,
41970 drop: None,
41971 allow_null: Some(Box::new(Expression::Boolean(BooleanLiteral {
41972 value: false,
41973 }))),
41974 comment: None,
41975 visible: None,
41976 rename_to: None,
41977 }))));
41978 }
41979
41980 if self.match_text_seq(&["SET", "VISIBLE"]) {
41982 return Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
41983 this: Box::new(column),
41984 dtype: None,
41985 collate: None,
41986 using: None,
41987 default: None,
41988 drop: None,
41989 allow_null: None,
41990 comment: None,
41991 visible: Some(Box::new(Expression::Identifier(Identifier::new(
41992 "VISIBLE".to_string(),
41993 )))),
41994 rename_to: None,
41995 }))));
41996 }
41997
41998 if self.match_text_seq(&["SET", "INVISIBLE"]) {
42000 return Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
42001 this: Box::new(column),
42002 dtype: None,
42003 collate: None,
42004 using: None,
42005 default: None,
42006 drop: None,
42007 allow_null: None,
42008 comment: None,
42009 visible: Some(Box::new(Expression::Identifier(Identifier::new(
42010 "INVISIBLE".to_string(),
42011 )))),
42012 rename_to: None,
42013 }))));
42014 }
42015
42016 self.match_text_seq(&["SET", "DATA"]);
42018 self.match_text_seq(&["TYPE"]);
42019
42020 let dtype = self.parse_types()?;
42021 let collate = if self.match_token(TokenType::Collate) {
42022 self.parse_term()?
42023 } else {
42024 None
42025 };
42026 let using = if self.match_token(TokenType::Using) {
42027 self.parse_disjunction()?
42028 } else {
42029 None
42030 };
42031
42032 Ok(Some(Expression::AlterColumn(Box::new(AlterColumn {
42033 this: Box::new(column),
42034 dtype: dtype.map(Box::new),
42035 collate: collate.map(Box::new),
42036 using: using.map(Box::new),
42037 default: None,
42038 drop: None,
42039 allow_null: None,
42040 comment: None,
42041 visible: None,
42042 rename_to: None,
42043 }))))
42044 }
42045
42046 pub fn parse_alter_table_drop(&mut self) -> Result<Option<Expression>> {
42050 let exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
42052
42053 if self.check(TokenType::Partition) {
42055 return self.parse_drop_partition_with_exists(exists);
42056 }
42057
42058 if self.match_keywords(&[TokenType::ForeignKey, TokenType::Key]) {
42060 let name = self.expect_identifier_with_quoted()?;
42061 return Ok(Some(Expression::AlterTable(Box::new(AlterTable {
42062 name: TableRef::new(""),
42063 actions: vec![AlterTableAction::DropForeignKey { name }],
42064 if_exists: false,
42065 algorithm: None,
42066 lock: None,
42067 with_check: None,
42068 partition: None,
42069 on_cluster: None,
42070 table_modifier: None,
42071 }))));
42072 }
42073
42074 if self.check_identifier("COLUMNS") && self.check_next(TokenType::LParen) {
42076 self.skip(); self.expect(TokenType::LParen)?;
42078 let mut columns = Vec::new();
42079 loop {
42080 if let Some(col) = self.parse_identifier()? {
42081 columns.push(col);
42082 }
42083 if !self.match_token(TokenType::Comma) {
42084 break;
42085 }
42086 }
42087 self.expect(TokenType::RParen)?;
42088 if columns.is_empty() {
42089 return Ok(None);
42090 } else if columns.len() == 1 {
42091 return Ok(Some(columns.remove(0)));
42092 } else {
42093 return Ok(Some(Expression::Tuple(Box::new(Tuple {
42094 expressions: columns,
42095 }))));
42096 }
42097 }
42098
42099 let mut columns = Vec::new();
42101
42102 if let Some(col) = self.parse_drop_column()? {
42104 columns.push(col);
42105 }
42106
42107 while self.match_token(TokenType::Comma) {
42109 self.match_token(TokenType::Drop);
42111 if let Some(col) = self.parse_drop_column()? {
42112 columns.push(col);
42113 }
42114 }
42115
42116 if columns.is_empty() {
42117 Ok(None)
42118 } else if columns.len() == 1 {
42119 Ok(Some(columns.remove(0)))
42120 } else {
42121 Ok(Some(Expression::Tuple(Box::new(Tuple {
42123 expressions: columns,
42124 }))))
42125 }
42126 }
42127
42128 pub fn parse_alter_table_rename(&mut self) -> Result<Option<Expression>> {
42131 if self.match_token(TokenType::Column) {
42133 let exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
42134 let old_column = match self.parse_column()? {
42135 Some(c) => c,
42136 None => return Ok(None),
42137 };
42138
42139 if !self.match_text_seq(&["TO"]) {
42140 return Ok(None);
42141 }
42142
42143 let new_column = self.parse_column()?;
42144
42145 return Ok(Some(Expression::RenameColumn(Box::new(RenameColumn {
42146 this: Box::new(old_column),
42147 to: new_column.map(Box::new),
42148 exists,
42149 }))));
42150 }
42151
42152 if self.match_text_seq(&["TO"]) {
42154 let new_table = self.parse_table()?;
42156 return Ok(new_table);
42157 }
42158
42159 if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
42162 let old_column = match self.parse_column()? {
42163 Some(c) => c,
42164 None => return Ok(None),
42165 };
42166
42167 if self.match_text_seq(&["TO"]) {
42168 let new_column = self.parse_column()?;
42169 return Ok(Some(Expression::RenameColumn(Box::new(RenameColumn {
42170 this: Box::new(old_column),
42171 to: new_column.map(Box::new),
42172 exists: false,
42173 }))));
42174 } else {
42175 return Err(self.parse_error("Expected COLUMN or TO after RENAME"));
42177 }
42178 }
42179
42180 Ok(None)
42181 }
42182
42183 pub fn parse_alter_table_set(&mut self) -> Result<Option<Expression>> {
42186 let mut alter_set = AlterSet {
42187 expressions: Vec::new(),
42188 option: None,
42189 tablespace: None,
42190 access_method: None,
42191 file_format: None,
42192 copy_options: None,
42193 tag: None,
42194 location: None,
42195 serde: None,
42196 };
42197
42198 if self.match_token(TokenType::Authorization) {
42200 let mut auth_text = "AUTHORIZATION ".to_string();
42201 if self.match_texts(&["ROLE"]) {
42202 auth_text.push_str("ROLE ");
42203 }
42204 let user = self.expect_identifier()?;
42205 auth_text.push_str(&user);
42206 alter_set.option = Some(Box::new(Expression::Identifier(Identifier::new(auth_text))));
42207 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42208 }
42209
42210 if self.match_text_seq(&["PROPERTIES"]) {
42212 let mut assignments = Vec::new();
42213 loop {
42214 let key = if self.check(TokenType::String) {
42216 self.parse_string()?.unwrap_or(Expression::Null(Null))
42217 } else {
42218 let name = self.expect_identifier()?;
42219 Expression::Identifier(Identifier::new(name))
42220 };
42221 self.expect(TokenType::Eq)?;
42222 let value = if self.match_token(TokenType::Default) {
42224 Expression::Identifier(Identifier::new("DEFAULT".to_string()))
42225 } else {
42226 self.parse_expression()?
42227 };
42228 assignments.push(Expression::Eq(Box::new(BinaryOp {
42229 left: key,
42230 right: value,
42231 left_comments: Vec::new(),
42232 operator_comments: Vec::new(),
42233 trailing_comments: Vec::new(),
42234 inferred_type: None,
42235 })));
42236 if !self.match_token(TokenType::Comma) {
42237 break;
42238 }
42239 }
42240 alter_set.expressions = assignments;
42241 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42242 }
42243
42244 if self.check(TokenType::LParen) || self.match_text_seq(&["TABLE", "PROPERTIES"]) {
42246 let assignments = self.parse_wrapped_csv_assignments()?;
42247 alter_set.expressions = assignments;
42248 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42249 }
42250
42251 if self.match_text_seq(&["FILESTREAM_ON"]) {
42253 if let Some(assignment) = self.parse_assignment()? {
42254 alter_set.expressions = vec![assignment];
42255 }
42256 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42257 }
42258
42259 if self.match_texts(&["LOGGED", "UNLOGGED"]) {
42261 let option = self.previous().text.to_ascii_uppercase();
42262 alter_set.option = Some(Box::new(Expression::Identifier(Identifier::new(option))));
42263 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42264 }
42265
42266 if self.match_text_seq(&["WITHOUT"]) {
42268 if self.match_texts(&["CLUSTER", "OIDS"]) {
42269 let option = format!("WITHOUT {}", self.previous().text.to_ascii_uppercase());
42270 alter_set.option = Some(Box::new(Expression::Identifier(Identifier::new(option))));
42271 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42272 }
42273 }
42274
42275 if self.match_text_seq(&["LOCATION"]) {
42277 let loc = self.parse_field()?;
42278 alter_set.location = loc.map(Box::new);
42279 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42280 }
42281
42282 if self.match_text_seq(&["ACCESS", "METHOD"]) {
42284 let method = self.parse_field()?;
42285 alter_set.access_method = method.map(Box::new);
42286 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42287 }
42288
42289 if self.match_text_seq(&["TABLESPACE"]) {
42291 let tablespace = self.parse_field()?;
42292 alter_set.tablespace = tablespace.map(Box::new);
42293 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42294 }
42295
42296 if self.match_text_seq(&["FILE", "FORMAT"]) || self.match_text_seq(&["FILEFORMAT"]) {
42298 let format = self.parse_field()?;
42299 alter_set.file_format = format.map(Box::new);
42300 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42301 }
42302
42303 if self.match_text_seq(&["STAGE_FILE_FORMAT"]) {
42305 let options = self.parse_wrapped_options()?;
42306 alter_set.file_format = options.map(Box::new);
42307 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42308 }
42309
42310 if self.match_text_seq(&["STAGE_COPY_OPTIONS"]) {
42312 let options = self.parse_wrapped_options()?;
42313 alter_set.copy_options = options.map(Box::new);
42314 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42315 }
42316
42317 if self.match_text_seq(&["TAG"]) || self.match_text_seq(&["TAGS"]) {
42319 let mut tags = Vec::new();
42320 loop {
42321 if let Some(assignment) = self.parse_assignment()? {
42322 tags.push(assignment);
42323 }
42324 if !self.match_token(TokenType::Comma) {
42325 break;
42326 }
42327 }
42328 if !tags.is_empty() {
42329 alter_set.tag = Some(Box::new(Expression::Tuple(Box::new(Tuple {
42330 expressions: tags,
42331 }))));
42332 }
42333 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42334 }
42335
42336 if self.match_text_seq(&["SERDE"]) {
42338 let serde = self.parse_field()?;
42339 alter_set.serde = serde.map(Box::new);
42340
42341 let properties = self.parse_wrapped()?;
42343 if let Some(props) = properties {
42344 alter_set.expressions = vec![props];
42345 }
42346 return Ok(Some(Expression::AlterSet(Box::new(alter_set))));
42347 }
42348
42349 Ok(None)
42350 }
42351
42352 fn parse_wrapped_csv_assignments(&mut self) -> Result<Vec<Expression>> {
42354 if !self.match_token(TokenType::LParen) {
42355 return Ok(Vec::new());
42356 }
42357 let mut assignments = Vec::new();
42358 loop {
42359 if let Some(assignment) = self.parse_assignment()? {
42360 assignments.push(assignment);
42361 }
42362 if !self.match_token(TokenType::Comma) {
42363 break;
42364 }
42365 }
42366 self.expect(TokenType::RParen)?;
42367 Ok(assignments)
42368 }
42369
42370 #[allow(unused_variables, unused_mut)]
42373 pub fn parse_analyze(&mut self) -> Result<Option<Expression>> {
42376 if self.is_at_end() {
42378 return Ok(Some(Expression::Analyze(Box::new(Analyze {
42379 kind: None,
42380 this: None,
42381 options: Vec::new(),
42382 mode: None,
42383 partition: None,
42384 expression: None,
42385 properties: Vec::new(),
42386 columns: Vec::new(),
42387 }))));
42388 }
42389
42390 let mut options = Vec::new();
42393 let analyze_styles = [
42394 "VERBOSE",
42395 "SKIP_LOCKED",
42396 "BUFFER_USAGE_LIMIT",
42397 "FULL",
42398 "SAMPLE",
42399 ];
42400 while self.match_texts(&analyze_styles) {
42401 let style = self.previous().text.to_ascii_uppercase();
42402 if style == "BUFFER_USAGE_LIMIT" {
42403 if let Some(num) = self.parse_number()? {
42405 options.push(Expression::Identifier(Identifier::new(format!(
42406 "BUFFER_USAGE_LIMIT {}",
42407 if let Expression::Literal(lit) = &num {
42408 if let Literal::Number(n) = lit.as_ref() {
42409 n.clone()
42410 } else {
42411 String::new()
42412 }
42413 } else {
42414 String::new()
42415 }
42416 ))));
42417 }
42418 } else {
42419 options.push(Expression::Identifier(Identifier::new(style)));
42420 }
42421 }
42422
42423 let mut this: Option<Expression> = None;
42424 let mut kind: Option<String> = None;
42425 let mut inner_expression: Option<Expression> = None;
42426
42427 if self.match_token(TokenType::Table) {
42429 kind = Some("TABLE".to_string());
42430 this = self.parse_table_parts()?;
42431 } else if self.match_token(TokenType::Index) {
42432 kind = Some("INDEX".to_string());
42433 this = self.parse_table_parts()?;
42434 } else if self.match_text_seq(&["TABLES"]) {
42435 kind = Some("TABLES".to_string());
42436 if self.match_token(TokenType::From) || self.match_token(TokenType::In) {
42437 let dir = self.previous().text.to_ascii_uppercase();
42438 kind = Some(format!("TABLES {}", dir));
42439 let db_name = self.expect_identifier()?;
42441 this = Some(Expression::Identifier(Identifier::new(db_name)));
42442 }
42443 } else if self.match_text_seq(&["DATABASE"]) {
42444 kind = Some("DATABASE".to_string());
42445 this = self.parse_table_parts()?;
42446 } else if self.match_text_seq(&["CLUSTER"]) {
42447 kind = Some("CLUSTER".to_string());
42448 this = self.parse_table_parts()?;
42449 } else if self.match_texts(&["LOCAL", "NO_WRITE_TO_BINLOG"]) {
42450 let opt_text = self.previous().text.to_ascii_uppercase();
42452 options.push(Expression::Identifier(Identifier::new(opt_text)));
42453 if self.match_token(TokenType::Table) {
42454 kind = Some("TABLE".to_string());
42455 }
42456 this = self.parse_table_parts()?;
42457 } else if self.match_text_seq(&["COMPUTE"]) {
42458 inner_expression = self.parse_analyze_statistics()?;
42461 } else if self.match_text_seq(&["DELETE"]) {
42462 inner_expression = self.parse_analyze_delete()?;
42463 } else if self.match_text_seq(&["VALIDATE"]) {
42464 inner_expression = self.parse_analyze_validate()?;
42465 } else if self.match_text_seq(&["LIST"]) {
42466 inner_expression = self.parse_analyze_list()?;
42467 } else if self.match_text_seq(&["DROP"]) {
42468 inner_expression = self.parse_analyze_histogram()?;
42469 } else if self.match_text_seq(&["UPDATE"]) {
42470 inner_expression = self.parse_analyze_histogram()?;
42471 } else if self.match_texts(&["ALL", "PREDICATE"]) {
42472 inner_expression = self.parse_analyze_columns()?;
42473 } else {
42474 this = self.parse_table_parts()?;
42476 }
42477
42478 let columns = if this.is_some() && self.match_token(TokenType::LParen) {
42480 let mut cols = Vec::new();
42481 loop {
42482 cols.push(self.expect_identifier_or_keyword()?);
42483 if !self.match_token(TokenType::Comma) {
42484 break;
42485 }
42486 }
42487 self.expect(TokenType::RParen)?;
42488 cols
42489 } else {
42490 Vec::new()
42491 };
42492
42493 let partition = self.parse_partition()?;
42495
42496 let mut mode = None;
42498 let mut properties = Vec::new();
42499
42500 if self.match_text_seq(&["WITH", "SYNC", "MODE"]) {
42501 mode = Some(Box::new(Expression::Identifier(Identifier::new(
42502 "WITH SYNC MODE".to_string(),
42503 ))));
42504 } else if self.match_text_seq(&["WITH", "ASYNC", "MODE"]) {
42505 mode = Some(Box::new(Expression::Identifier(Identifier::new(
42506 "WITH ASYNC MODE".to_string(),
42507 ))));
42508 } else if self.match_text_seq(&["WITH"]) {
42509 if self.match_token(TokenType::LParen) {
42511 loop {
42512 let key = self.parse_id_var()?;
42514 if key.is_none() {
42515 break;
42516 }
42517
42518 if self.match_token(TokenType::Eq) {
42520 let value = self.parse_primary()?;
42522 if let Some(k) = key {
42523 properties.push(Expression::Property(Box::new(Property {
42524 this: Box::new(k),
42525 value: Some(Box::new(value)),
42526 })));
42527 }
42528 } else if let Some(k) = key {
42529 properties.push(Expression::Property(Box::new(Property {
42531 this: Box::new(k),
42532 value: None,
42533 })));
42534 }
42535
42536 if !self.match_token(TokenType::Comma) {
42537 break;
42538 }
42539 }
42540 self.expect(TokenType::RParen)?;
42541 }
42542 }
42543
42544 if inner_expression.is_none() {
42547 if self.match_text_seq(&["COMPUTE"]) {
42548 inner_expression = self.parse_analyze_statistics()?;
42549 } else if self.match_text_seq(&["DELETE"]) {
42550 inner_expression = self.parse_analyze_delete()?;
42551 } else if self.match_text_seq(&["VALIDATE"]) {
42552 inner_expression = self.parse_analyze_validate()?;
42553 } else if self.match_text_seq(&["LIST"]) {
42554 inner_expression = self.parse_analyze_list()?;
42555 } else if self.match_text_seq(&["DROP"]) {
42556 inner_expression = self.parse_analyze_histogram()?;
42557 } else if self.match_text_seq(&["UPDATE"]) {
42558 inner_expression = self.parse_analyze_histogram()?;
42559 } else if self.match_texts(&["ALL", "PREDICATE"]) {
42560 inner_expression = self.parse_analyze_columns()?;
42562 }
42563 }
42564
42565 if properties.is_empty() && self.match_text_seq(&["PROPERTIES"]) {
42568 if self.match_token(TokenType::LParen) {
42569 loop {
42570 let key = if self.check(TokenType::String) {
42572 self.skip();
42573 let key_str = self.previous().text.clone();
42574 Expression::Literal(Box::new(Literal::String(key_str)))
42575 } else {
42576 self.parse_id_var()?
42577 .unwrap_or(Expression::Identifier(Identifier::new(String::new())))
42578 };
42579
42580 if self.match_token(TokenType::Eq) {
42582 let value = self.parse_primary()?;
42584 properties.push(Expression::Property(Box::new(Property {
42585 this: Box::new(key),
42586 value: Some(Box::new(value)),
42587 })));
42588 } else {
42589 properties.push(Expression::Property(Box::new(Property {
42591 this: Box::new(key),
42592 value: None,
42593 })));
42594 }
42595
42596 if !self.match_token(TokenType::Comma) {
42597 break;
42598 }
42599 }
42600 self.expect(TokenType::RParen)?;
42601 }
42602 }
42603
42604 Ok(Some(Expression::Analyze(Box::new(Analyze {
42605 kind,
42606 this: this.map(Box::new),
42607 options,
42608 mode,
42609 partition: partition.map(Box::new),
42610 expression: inner_expression.map(Box::new),
42611 properties,
42612 columns,
42613 }))))
42614 }
42615
42616 pub fn parse_analyze_columns(&mut self) -> Result<Option<Expression>> {
42620 let prev_text = self.previous().text.to_ascii_uppercase();
42621 if self.match_text_seq(&["COLUMNS"]) {
42622 return Ok(Some(Expression::Identifier(Identifier::new(format!(
42623 "{} COLUMNS",
42624 prev_text
42625 )))));
42626 }
42627 Ok(None)
42628 }
42629
42630 pub fn parse_analyze_delete(&mut self) -> Result<Option<Expression>> {
42633 let kind = if self.match_text_seq(&["SYSTEM"]) {
42634 Some("SYSTEM".to_string())
42635 } else {
42636 None
42637 };
42638
42639 if self.match_text_seq(&["STATISTICS"]) {
42640 return Ok(Some(Expression::AnalyzeDelete(Box::new(AnalyzeDelete {
42641 kind,
42642 }))));
42643 }
42644
42645 Ok(None)
42646 }
42647
42648 pub fn parse_analyze_histogram(&mut self) -> Result<Option<Expression>> {
42651 let action = self.previous().text.to_ascii_uppercase(); let mut expressions = Vec::new();
42653 let mut update_options: Option<Box<Expression>> = None;
42654 let mut expression: Option<Box<Expression>> = None;
42655
42656 if !self.match_text_seq(&["HISTOGRAM", "ON"]) {
42657 return Ok(None);
42658 }
42659
42660 loop {
42662 if let Some(col) = self.parse_column_reference()? {
42663 expressions.push(col);
42664 } else {
42665 break;
42666 }
42667 if !self.match_token(TokenType::Comma) {
42668 break;
42669 }
42670 }
42671
42672 if self.match_text_seq(&["USING", "DATA"]) {
42674 if self.check(TokenType::String) {
42675 let tok = self.advance();
42676 expression = Some(Box::new(Expression::Identifier(Identifier::new(format!(
42677 "USING DATA '{}'",
42678 tok.text
42679 )))));
42680 } else {
42681 expression = Some(Box::new(Expression::Identifier(Identifier::new(
42682 "USING DATA".to_string(),
42683 ))));
42684 }
42685 }
42686
42687 let mut mode_str: Option<String> = None;
42692 let mut buckets_str: Option<String> = None;
42693
42694 if self.match_token(TokenType::With) {
42695 if self.match_texts(&["SYNC", "ASYNC"]) {
42696 let mode = self.previous().text.to_ascii_uppercase();
42697 if self.match_text_seq(&["MODE"]) {
42698 mode_str = Some(format!("WITH {} MODE", mode));
42699 }
42700 if self.match_token(TokenType::With) {
42702 if let Some(num) = self.parse_number()? {
42703 if self.match_text_seq(&["BUCKETS"]) {
42704 let num_str = if let Expression::Literal(lit) = &num {
42705 if let Literal::Number(n) = lit.as_ref() {
42706 n.clone()
42707 } else {
42708 String::new()
42709 }
42710 } else {
42711 String::new()
42712 };
42713 buckets_str = Some(format!("WITH {} BUCKETS", num_str));
42714 }
42715 }
42716 }
42717 } else if let Some(num) = self.parse_number()? {
42718 if self.match_text_seq(&["BUCKETS"]) {
42719 let num_str = if let Expression::Literal(lit) = &num {
42720 if let Literal::Number(n) = lit.as_ref() {
42721 n.clone()
42722 } else {
42723 String::new()
42724 }
42725 } else {
42726 String::new()
42727 };
42728 buckets_str = Some(format!("WITH {} BUCKETS", num_str));
42729 }
42730 }
42731 }
42732
42733 match (mode_str, buckets_str) {
42735 (Some(m), Some(b)) => {
42736 expression = Some(Box::new(Expression::Identifier(Identifier::new(format!(
42737 "{} {}",
42738 m, b
42739 )))));
42740 }
42741 (Some(m), None) => {
42742 expression = Some(Box::new(Expression::Identifier(Identifier::new(m))));
42743 }
42744 (None, Some(b)) => {
42745 expression = Some(Box::new(Expression::Identifier(Identifier::new(b))));
42746 }
42747 (None, None) => {}
42748 }
42749
42750 if self.match_texts(&["MANUAL", "AUTO"]) {
42752 let mode = self.previous().text.to_ascii_uppercase();
42753 if self.check(TokenType::Update) {
42754 update_options = Some(Box::new(Expression::Identifier(Identifier::new(mode))));
42755 self.skip(); }
42757 }
42758
42759 Ok(Some(Expression::AnalyzeHistogram(Box::new(
42760 AnalyzeHistogram {
42761 this: Box::new(Expression::Identifier(Identifier::new(action))),
42762 expressions,
42763 expression,
42764 update_options,
42765 },
42766 ))))
42767 }
42768
42769 pub fn parse_analyze_list(&mut self) -> Result<Option<Expression>> {
42772 if self.match_text_seq(&["CHAINED", "ROWS"]) {
42773 let expression = self.parse_into()?.map(Box::new);
42774 return Ok(Some(Expression::AnalyzeListChainedRows(Box::new(
42775 AnalyzeListChainedRows { expression },
42776 ))));
42777 }
42778 Ok(None)
42779 }
42780
42781 pub fn parse_analyze_statistics(&mut self) -> Result<Option<Expression>> {
42784 let kind = self.previous().text.to_ascii_uppercase();
42785 let option = if self.match_text_seq(&["DELTA"]) {
42786 Some(Box::new(Expression::Identifier(Identifier::new(
42787 "DELTA".to_string(),
42788 ))))
42789 } else {
42790 None
42791 };
42792
42793 if !self.match_text_seq(&["STATISTICS"]) {
42795 return Ok(None);
42796 }
42797
42798 let mut this: Option<Box<Expression>> = None;
42799 let mut expressions = Vec::new();
42800
42801 if self.match_text_seq(&["NOSCAN"]) {
42802 this = Some(Box::new(Expression::Identifier(Identifier::new(
42803 "NOSCAN".to_string(),
42804 ))));
42805 } else if self.match_token(TokenType::For) {
42806 if self.match_text_seq(&["ALL", "COLUMNS"]) {
42807 this = Some(Box::new(Expression::Identifier(Identifier::new(
42808 "FOR ALL COLUMNS".to_string(),
42809 ))));
42810 } else if self.match_text_seq(&["COLUMNS"]) {
42811 this = Some(Box::new(Expression::Identifier(Identifier::new(
42812 "FOR COLUMNS".to_string(),
42813 ))));
42814 loop {
42816 if let Some(col) = self.parse_column_reference()? {
42817 expressions.push(col);
42818 } else {
42819 break;
42820 }
42821 if !self.match_token(TokenType::Comma) {
42822 break;
42823 }
42824 }
42825 }
42826 } else if self.match_text_seq(&["SAMPLE"]) {
42827 if let Some(sample) = self.parse_number()? {
42829 let sample_kind = if self.match_token(TokenType::Percent) {
42830 Some("PERCENT".to_string())
42831 } else {
42832 None
42833 };
42834 expressions.push(Expression::AnalyzeSample(Box::new(AnalyzeSample {
42835 kind: sample_kind.unwrap_or_default(),
42836 sample: Some(Box::new(sample)),
42837 })));
42838 }
42839 }
42840
42841 Ok(Some(Expression::AnalyzeStatistics(Box::new(
42842 AnalyzeStatistics {
42843 kind,
42844 option,
42845 this,
42846 expressions,
42847 },
42848 ))))
42849 }
42850
42851 pub fn parse_analyze_validate(&mut self) -> Result<Option<Expression>> {
42854 let mut kind = String::new();
42855 let mut this: Option<Box<Expression>> = None;
42856 let mut expression: Option<Box<Expression>> = None;
42857
42858 if self.match_text_seq(&["REF", "UPDATE"]) {
42859 kind = "REF".to_string();
42860 this = Some(Box::new(Expression::Identifier(Identifier::new(
42861 "UPDATE".to_string(),
42862 ))));
42863 if self.match_text_seq(&["SET", "DANGLING", "TO", "NULL"]) {
42864 this = Some(Box::new(Expression::Identifier(Identifier::new(
42865 "UPDATE SET DANGLING TO NULL".to_string(),
42866 ))));
42867 }
42868 } else if self.match_text_seq(&["STRUCTURE"]) {
42869 kind = "STRUCTURE".to_string();
42870 if self.match_text_seq(&["CASCADE", "FAST"]) {
42871 this = Some(Box::new(Expression::Identifier(Identifier::new(
42872 "CASCADE FAST".to_string(),
42873 ))));
42874 } else if self.match_text_seq(&["CASCADE", "COMPLETE"]) {
42875 if self.match_texts(&["ONLINE", "OFFLINE"]) {
42876 let mode = self.previous().text.to_ascii_uppercase();
42877 this = Some(Box::new(Expression::Identifier(Identifier::new(format!(
42878 "CASCADE COMPLETE {}",
42879 mode
42880 )))));
42881 expression = self.parse_into()?.map(Box::new);
42882 }
42883 }
42884 }
42885
42886 if kind.is_empty() {
42887 return Ok(None);
42888 }
42889
42890 Ok(Some(Expression::AnalyzeValidate(Box::new(
42891 AnalyzeValidate {
42892 kind,
42893 this,
42894 expression,
42895 },
42896 ))))
42897 }
42898
42899 pub fn parse_attach_detach(&mut self, is_attach: bool) -> Result<Expression> {
42902 let _ = self.match_identifier("DATABASE") || self.match_token(TokenType::Database);
42906
42907 let exists = if is_attach {
42908 self.match_text_seq(&["IF", "NOT", "EXISTS"])
42909 } else {
42910 self.match_text_seq(&["IF", "EXISTS"])
42911 };
42912
42913 let this_expr = self.parse_expression()?;
42916
42917 let this = if self.match_token(TokenType::As) {
42919 let alias = self.expect_identifier_or_keyword_with_quoted()?;
42920 Expression::Alias(Box::new(Alias {
42921 this: this_expr,
42922 alias,
42923 column_aliases: Vec::new(),
42924 pre_alias_comments: Vec::new(),
42925 trailing_comments: Vec::new(),
42926 inferred_type: None,
42927 }))
42928 } else {
42929 this_expr
42930 };
42931
42932 if is_attach {
42933 let expressions = if self.match_token(TokenType::LParen) {
42935 let mut opts = Vec::new();
42936 loop {
42937 let key_name = self.advance().text.to_ascii_uppercase();
42939 let key = Expression::Identifier(Identifier::new(key_name));
42940 let value = if !self.check(TokenType::Comma) && !self.check(TokenType::RParen) {
42941 let val_token = self.advance();
42943 let val_expr = if val_token.token_type == TokenType::String {
42944 Expression::Literal(Box::new(Literal::String(val_token.text.clone())))
42945 } else if val_token.token_type == TokenType::True {
42946 Expression::Boolean(BooleanLiteral { value: true })
42947 } else if val_token.token_type == TokenType::False {
42948 Expression::Boolean(BooleanLiteral { value: false })
42949 } else {
42950 Expression::Identifier(Identifier::new(val_token.text.clone()))
42951 };
42952 Some(Box::new(val_expr))
42953 } else {
42954 None
42955 };
42956 opts.push(Expression::AttachOption(Box::new(AttachOption {
42957 this: Box::new(key),
42958 expression: value,
42959 })));
42960 if !self.match_token(TokenType::Comma) {
42961 break;
42962 }
42963 }
42964 self.expect(TokenType::RParen)?;
42965 opts
42966 } else {
42967 Vec::new()
42968 };
42969
42970 Ok(Expression::Attach(Box::new(Attach {
42971 this: Box::new(this),
42972 exists,
42973 expressions,
42974 })))
42975 } else {
42976 Ok(Expression::Detach(Box::new(Detach {
42977 this: Box::new(this),
42978 exists,
42979 })))
42980 }
42981 }
42982
42983 pub fn parse_install(&mut self, force: bool) -> Result<Expression> {
42986 let name = self.expect_identifier_or_keyword()?;
42988 let this = Expression::Identifier(Identifier::new(name));
42989
42990 let from_ = if self.match_token(TokenType::From) {
42991 Some(Box::new(self.parse_primary()?))
42993 } else {
42994 None
42995 };
42996
42997 Ok(Expression::Install(Box::new(Install {
42998 this: Box::new(this),
42999 from_,
43000 force: if force {
43001 Some(Box::new(Expression::Boolean(BooleanLiteral {
43002 value: true,
43003 })))
43004 } else {
43005 None
43006 },
43007 })))
43008 }
43009
43010 pub fn parse_force_statement(&mut self) -> Result<Expression> {
43013 if self.match_identifier("INSTALL") {
43014 return self.parse_install(true);
43015 }
43016 self.parse_as_command()?
43018 .ok_or_else(|| self.parse_error("Failed to parse FORCE statement"))
43019 }
43020
43021 pub fn parse_summarize_statement(&mut self) -> Result<Expression> {
43024 let is_table = self.match_token(TokenType::Table);
43026
43027 let this = if self.check(TokenType::Select) || self.check(TokenType::With) {
43029 self.parse_select()?
43030 } else if self.check(TokenType::String) {
43031 self.parse_primary()?
43032 } else {
43033 self.parse_table_parts()?
43035 .unwrap_or(Expression::Identifier(Identifier::new(String::new())))
43036 };
43037
43038 Ok(Expression::Summarize(Box::new(Summarize {
43039 this: Box::new(this),
43040 table: if is_table {
43041 Some(Box::new(Expression::Boolean(BooleanLiteral {
43042 value: true,
43043 })))
43044 } else {
43045 None
43046 },
43047 })))
43048 }
43049
43050 pub fn parse_deallocate_prepare(&mut self) -> Result<Expression> {
43053 self.skip(); if self.match_identifier("PREPARE") {
43057 let name = if !self.is_at_end() && !self.check(TokenType::Semicolon) {
43059 self.advance().text.clone()
43060 } else {
43061 String::new()
43062 };
43063
43064 let command_text = if name.is_empty() {
43066 "DEALLOCATE PREPARE".to_string()
43067 } else {
43068 format!("DEALLOCATE PREPARE {}", name)
43069 };
43070
43071 Ok(Expression::Command(Box::new(Command {
43072 this: command_text,
43073 })))
43074 } else {
43075 let mut parts = vec!["DEALLOCATE".to_string()];
43077 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
43078 let token = self.advance();
43079 parts.push(token.text.clone());
43080 }
43081 Ok(Expression::Command(Box::new(Command {
43082 this: parts.join(" "),
43083 })))
43084 }
43085 }
43086
43087 #[allow(unused_variables, unused_mut)]
43089 pub fn parse_as_command(&mut self) -> Result<Option<Expression>> {
43093 let start_text = if self.current > 0 {
43095 self.tokens
43096 .get(self.current - 1)
43097 .map(|t| t.text.clone())
43098 .unwrap_or_default()
43099 } else {
43100 String::new()
43101 };
43102
43103 let mut tokens_info: Vec<(String, TokenType)> = Vec::new();
43105 while !self.is_at_end() {
43106 let token = self.advance();
43107 tokens_info.push((token.text.clone(), token.token_type.clone()));
43108 }
43109
43110 let mut expression = String::new();
43112 for (i, (text, token_type)) in tokens_info.iter().enumerate() {
43113 if i > 0 {
43114 let prev_type = &tokens_info[i - 1].1;
43116 let needs_space = !Self::is_punctuation_token(prev_type)
43117 && !Self::is_punctuation_token(token_type);
43118 if needs_space {
43119 expression.push(' ');
43120 }
43121 }
43122 expression.push_str(text);
43123 }
43124
43125 Ok(Some(Expression::Command(Box::new(Command {
43126 this: if expression.is_empty() {
43127 start_text
43128 } else {
43129 format!("{} {}", start_text, expression)
43130 },
43131 }))))
43132 }
43133
43134 fn is_punctuation_token(token_type: &TokenType) -> bool {
43136 matches!(
43137 token_type,
43138 TokenType::Dot | TokenType::Colon | TokenType::DColon
43139 )
43140 }
43141
43142 fn fallback_to_command(&mut self, start_pos: usize) -> Result<Expression> {
43145 let start_span = self.tokens[start_pos].span.start;
43146 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
43148 self.skip();
43149 }
43150 let command_text = if let Some(ref source) = self.source {
43151 let end_span = if self.current > 0 {
43152 self.tokens[self.current - 1].span.end
43153 } else {
43154 start_span
43155 };
43156 source[start_span..end_span].trim().to_string()
43157 } else {
43158 let mut parts = Vec::new();
43160 for i in start_pos..self.current {
43161 if self.tokens[i].token_type == TokenType::String {
43162 parts.push(format!("'{}'", self.tokens[i].text.replace('\'', "''")));
43163 } else {
43164 parts.push(self.tokens[i].text.clone());
43165 }
43166 }
43167 parts.join(" ")
43168 };
43169 Ok(Expression::Command(Box::new(Command {
43170 this: command_text,
43171 })))
43172 }
43173
43174 pub fn parse_assignment(&mut self) -> Result<Option<Expression>> {
43177 let mut this = self.parse_disjunction()?;
43179
43180 while self.match_token(TokenType::ColonEq) {
43182 if let Some(left) = this {
43183 let right = self.parse_assignment()?;
43184 if let Some(right_expr) = right {
43185 this = Some(Expression::PropertyEQ(Box::new(BinaryOp {
43186 left,
43187 right: right_expr,
43188 left_comments: Vec::new(),
43189 operator_comments: Vec::new(),
43190 trailing_comments: Vec::new(),
43191 inferred_type: None,
43192 })));
43193 } else {
43194 this = Some(left);
43195 break;
43196 }
43197 } else {
43198 break;
43199 }
43200 }
43201
43202 if matches!(
43205 self.config.dialect,
43206 Some(crate::dialects::DialectType::ClickHouse)
43207 ) {
43208 if let Some(condition) = this {
43209 if self.match_token(TokenType::Parameter) {
43210 if self.check(TokenType::Colon) {
43211 return Err(self.parse_error(
43212 "Expected true expression after ? in ClickHouse ternary",
43213 ));
43214 }
43215 let true_value = self.parse_assignment()?.ok_or_else(|| {
43216 self.parse_error("Expected true expression after ? in ClickHouse ternary")
43217 })?;
43218 let false_value = if self.match_token(TokenType::Colon) {
43219 self.parse_assignment()?.unwrap_or(Expression::Null(Null))
43220 } else {
43221 Expression::Null(Null)
43222 };
43223 return Ok(Some(Expression::IfFunc(Box::new(IfFunc {
43224 original_name: None,
43225 condition,
43226 true_value,
43227 false_value: Some(false_value),
43228 inferred_type: None,
43229 }))));
43230 }
43231 this = Some(condition);
43232 }
43233 }
43234
43235 Ok(this)
43236 }
43237
43238 #[allow(unused_variables, unused_mut)]
43241 pub fn parse_auto_increment(&mut self) -> Result<Option<Expression>> {
43242 if self.match_text_seq(&["START"]) {
43243 return Ok(Some(Expression::GeneratedAsIdentityColumnConstraint(
43244 Box::new(GeneratedAsIdentityColumnConstraint {
43245 this: None,
43246 expression: None,
43247 on_null: None,
43248 start: None,
43249 increment: None,
43250 minvalue: None,
43251 maxvalue: None,
43252 cycle: None,
43253 order: None,
43254 }),
43255 )));
43256 }
43257 if self.match_text_seq(&["INCREMENT"]) {
43258 return Ok(None);
43260 }
43261 if self.match_text_seq(&["ORDER"]) {
43262 return Ok(None);
43264 }
43265 Ok(None)
43266 }
43267
43268 #[allow(unused_variables, unused_mut)]
43270 pub fn parse_auto_property(&mut self) -> Result<Option<Expression>> {
43271 if self.match_text_seq(&["REFRESH"]) {
43272 return Ok(None);
43274 }
43275 Ok(None)
43276 }
43277
43278 #[allow(unused_variables, unused_mut)]
43280 pub fn parse_between(&mut self) -> Result<Option<Expression>> {
43281 if self.match_text_seq(&["SYMMETRIC"]) {
43282 return Ok(None);
43284 }
43285 if self.match_text_seq(&["ASYMMETRIC"]) {
43286 return Ok(None);
43288 }
43289 Ok(None)
43290 }
43291
43292 pub fn parse_bitwise(&mut self) -> Result<Option<Expression>> {
43296 let start = self.current;
43297 match self.parse_bitwise_or() {
43298 Ok(expr) => Ok(Some(expr)),
43299 Err(_err) if self.current == start => Ok(None),
43300 Err(err) => Err(err),
43301 }
43302 }
43303
43304 #[allow(unused_variables, unused_mut)]
43306 pub fn parse_blockcompression(&mut self) -> Result<Option<Expression>> {
43307 if self.match_text_seq(&["ALWAYS"]) {
43308 return Ok(Some(Expression::BlockCompressionProperty(Box::new(
43309 BlockCompressionProperty {
43310 autotemp: None,
43311 always: None,
43312 default: None,
43313 manual: None,
43314 never: None,
43315 },
43316 ))));
43317 }
43318 if self.match_text_seq(&["MANUAL"]) {
43319 return Ok(None);
43321 }
43322 Ok(None)
43323 }
43324
43325 pub fn parse_boolean(&mut self) -> Result<Option<Expression>> {
43328 if self.match_token(TokenType::True) {
43329 return Ok(Some(Expression::Boolean(BooleanLiteral { value: true })));
43330 }
43331 if self.match_token(TokenType::False) {
43332 return Ok(Some(Expression::Boolean(BooleanLiteral { value: false })));
43333 }
43334 Ok(None)
43335 }
43336
43337 #[allow(unused_variables, unused_mut)]
43340 pub fn parse_bracket(&mut self) -> Result<Option<Expression>> {
43341 self.parse_bracket_with_expr(None)
43342 }
43343
43344 fn parse_bracket_with_expr(&mut self, this: Option<Expression>) -> Result<Option<Expression>> {
43346 let is_bracket = self.match_token(TokenType::LBracket);
43348 let is_brace = if !is_bracket {
43349 self.match_token(TokenType::LBrace)
43350 } else {
43351 false
43352 };
43353
43354 if !is_bracket && !is_brace {
43355 return Ok(this);
43356 }
43357
43358 let mut expressions: Vec<Expression> = Vec::new();
43360
43361 if is_bracket && !self.check(TokenType::RBracket) {
43362 let first_expr = if self.check(TokenType::Colon) {
43366 if let Some(slice) = self.parse_slice()? {
43369 slice
43370 } else {
43371 self.parse_expression()?
43372 }
43373 } else if let Ok(Some(expr)) = self.parse_bracket_key_value() {
43374 expr
43375 } else {
43376 let expr = self.parse_expression()?;
43378 if self.check(TokenType::Colon) {
43380 if let Some(slice) = self.parse_slice_with_this(Some(expr))? {
43381 slice
43382 } else {
43383 return Err(self.parse_error("Failed to parse slice"));
43384 }
43385 } else {
43386 expr
43387 }
43388 };
43389
43390 if self.match_token(TokenType::For) {
43392 let loop_var = self.parse_primary()?;
43394
43395 let position = if self.match_token(TokenType::Comma) {
43397 Some(self.parse_primary()?)
43398 } else {
43399 None
43400 };
43401
43402 if !self.match_token(TokenType::In) {
43404 return Err(self.parse_error("Expected IN in comprehension"));
43405 }
43406
43407 let iterator = self.parse_expression()?;
43409
43410 let condition = if self.match_token(TokenType::If) {
43412 Some(self.parse_expression()?)
43413 } else {
43414 None
43415 };
43416
43417 self.expect(TokenType::RBracket)?;
43419
43420 return Ok(Some(Expression::Comprehension(Box::new(Comprehension {
43422 this: Box::new(first_expr),
43423 expression: Box::new(loop_var),
43424 position: position.map(Box::new),
43425 iterator: Some(Box::new(iterator)),
43426 condition: condition.map(Box::new),
43427 }))));
43428 }
43429
43430 expressions.push(first_expr);
43431
43432 while self.match_token(TokenType::Comma) {
43434 if let Ok(Some(expr)) = self.parse_bracket_key_value() {
43435 expressions.push(expr);
43436 } else {
43437 match self.parse_expression() {
43438 Ok(expr) => expressions.push(expr),
43439 Err(_) => break,
43440 }
43441 }
43442 }
43443 } else if is_brace && !self.check(TokenType::RBrace) {
43444 loop {
43445 if let Ok(Some(expr)) = self.parse_bracket_key_value() {
43446 expressions.push(expr);
43447 } else {
43448 match self.parse_expression() {
43449 Ok(expr) => expressions.push(expr),
43450 Err(_) => break,
43451 }
43452 }
43453 if !self.match_token(TokenType::Comma) {
43454 break;
43455 }
43456 }
43457 }
43458
43459 if is_bracket {
43461 self.expect(TokenType::RBracket)?;
43462 } else if is_brace {
43463 self.expect(TokenType::RBrace)?;
43464 }
43465
43466 if is_brace {
43468 let fields: Vec<(Option<String>, Expression)> =
43471 expressions.into_iter().map(|e| (None, e)).collect();
43472 Ok(Some(Expression::Struct(Box::new(Struct { fields }))))
43473 } else if let Some(base_expr) = this {
43474 if expressions.len() == 1 {
43476 Ok(Some(Expression::Subscript(Box::new(Subscript {
43477 this: base_expr,
43478 index: expressions.remove(0),
43479 }))))
43480 } else {
43481 let mut result = base_expr;
43483 for expr in expressions {
43484 result = Expression::Subscript(Box::new(Subscript {
43485 this: result,
43486 index: expr,
43487 }));
43488 }
43489 Ok(Some(result))
43490 }
43491 } else {
43492 Ok(Some(Expression::Array(Box::new(Array { expressions }))))
43494 }
43495 }
43496
43497 #[allow(unused_variables, unused_mut)]
43500 pub fn parse_bracket_key_value(&mut self) -> Result<Option<Expression>> {
43501 let saved_pos = self.current;
43502
43503 if let Ok(key) = self.parse_primary() {
43505 if self.match_token(TokenType::Colon) || self.match_text_seq(&["=>"]) {
43507 match self.parse_expression() {
43508 Ok(value) => {
43509 let name = match &key {
43512 Expression::Identifier(id) => id.clone(),
43513 Expression::Literal(lit)
43514 if matches!(
43515 lit.as_ref(),
43516 crate::expressions::Literal::String(s)
43517 ) =>
43518 {
43519 let crate::expressions::Literal::String(s) = lit.as_ref() else {
43520 unreachable!()
43521 };
43522 Identifier::new(s.clone())
43523 }
43524 _ => Identifier::new("".to_string()),
43525 };
43526 return Ok(Some(Expression::NamedArgument(Box::new(NamedArgument {
43527 name,
43528 value,
43529 separator: NamedArgSeparator::DArrow, }))));
43531 }
43532 Err(_) => {
43533 self.current = saved_pos;
43534 return Ok(None);
43535 }
43536 }
43537 }
43538 self.current = saved_pos;
43539 }
43540
43541 Ok(None)
43542 }
43543
43544 #[allow(unused_variables, unused_mut)]
43547 pub fn parse_ceil_floor(&mut self) -> Result<Option<Expression>> {
43548 if self.match_text_seq(&["TO"]) {
43549 return Ok(None);
43551 }
43552 Ok(None)
43553 }
43554
43555 pub fn parse_changes(&mut self) -> Result<Option<Expression>> {
43558 if !self.match_text_seq(&["CHANGES", "(", "INFORMATION", "=>"]) {
43560 return Ok(None);
43561 }
43562
43563 let information = self.parse_var()?.map(Box::new);
43565
43566 self.match_token(TokenType::RParen);
43568
43569 let at_before = self.parse_historical_data()?.map(Box::new);
43571
43572 let end = self.parse_historical_data()?.map(Box::new);
43574
43575 Ok(Some(Expression::Changes(Box::new(Changes {
43576 information,
43577 at_before,
43578 end,
43579 }))))
43580 }
43581
43582 pub fn parse_char(&mut self) -> Result<Option<Expression>> {
43586 let mut args = Vec::new();
43588 loop {
43589 let expr = self.parse_expression()?;
43590 args.push(expr);
43591 if !self.match_token(TokenType::Comma) {
43592 break;
43593 }
43594 }
43595
43596 let charset = if self.match_token(TokenType::Using) {
43598 self.parse_var()?.map(|v| {
43599 if let Expression::Identifier(id) = v {
43600 id.name
43601 } else {
43602 String::new()
43603 }
43604 })
43605 } else {
43606 None
43607 };
43608
43609 if args.is_empty() {
43610 return Ok(None);
43611 }
43612
43613 if charset.is_some() || args.len() > 1 {
43616 Ok(Some(Expression::CharFunc(Box::new(
43617 crate::expressions::CharFunc {
43618 args,
43619 charset,
43620 name: None, },
43622 ))))
43623 } else {
43624 Ok(Some(Expression::Chr(Box::new(UnaryFunc::new(
43625 args.into_iter().next().unwrap(),
43626 )))))
43627 }
43628 }
43629
43630 #[allow(unused_variables, unused_mut)]
43632 pub fn parse_character_set(&mut self) -> Result<Option<Expression>> {
43635 self.match_token(TokenType::Eq);
43637
43638 let charset = self.parse_var_or_string()?;
43640 if charset.is_none() {
43641 return Ok(None);
43642 }
43643
43644 Ok(Some(Expression::CharacterSetProperty(Box::new(
43645 CharacterSetProperty {
43646 this: Box::new(charset.unwrap()),
43647 default: None,
43648 },
43649 ))))
43650 }
43651
43652 #[allow(unused_variables, unused_mut)]
43654 pub fn parse_checksum(&mut self) -> Result<Option<Expression>> {
43655 if self.match_text_seq(&["OFF"]) {
43656 return Ok(Some(Expression::ChecksumProperty(Box::new(
43657 ChecksumProperty {
43658 on: None,
43659 default: None,
43660 },
43661 ))));
43662 }
43663 Ok(None)
43664 }
43665
43666 #[allow(unused_variables, unused_mut)]
43669 pub fn parse_cluster(&mut self) -> Result<Option<Expression>> {
43670 let mut expressions: Vec<Ordered> = Vec::new();
43671
43672 loop {
43673 if let Some(ordered) = self.parse_ordered_item()? {
43675 expressions.push(ordered);
43676 } else {
43677 break;
43678 }
43679
43680 if !self.match_token(TokenType::Comma) {
43681 break;
43682 }
43683 }
43684
43685 if expressions.is_empty() {
43686 return Ok(None);
43687 }
43688
43689 Ok(Some(Expression::ClusterBy(Box::new(ClusterBy {
43690 expressions,
43691 }))))
43692 }
43693
43694 #[allow(unused_variables, unused_mut)]
43696 pub fn parse_clustered_by(&mut self) -> Result<Option<Expression>> {
43697 if self.match_text_seq(&["BY"]) {
43698 return Ok(Some(Expression::ClusteredByProperty(Box::new(
43699 ClusteredByProperty {
43700 expressions: Vec::new(),
43701 sorted_by: None,
43702 buckets: None,
43703 },
43704 ))));
43705 }
43706 if self.match_text_seq(&["SORTED", "BY"]) {
43707 return Ok(None);
43709 }
43710 Ok(None)
43711 }
43712
43713 pub fn parse_colon_as_variant_extract(
43716 &mut self,
43717 this: Expression,
43718 ) -> Result<Option<Expression>> {
43719 let mut json_path: Vec<(String, bool)> = Vec::new();
43722
43723 while self.match_token(TokenType::Colon) {
43724 if let Some(field) = self.parse_identifier()? {
43726 if let Expression::Identifier(ident) = field {
43727 json_path.push((
43728 ident.name.clone(),
43729 ident.quoted || ident.name.contains(' ') || ident.name.contains('\''),
43730 ));
43731 }
43732 }
43733
43734 while self.match_token(TokenType::Dot) {
43736 if let Some(subfield) = self.parse_identifier()? {
43737 if let Expression::Identifier(ident) = subfield {
43738 json_path.push((
43739 ident.name.clone(),
43740 ident.quoted || ident.name.contains(' ') || ident.name.contains('\''),
43741 ));
43742 }
43743 }
43744 }
43745 }
43746
43747 if json_path.is_empty() {
43748 return Ok(Some(this));
43749 }
43750
43751 let mut path_str = String::new();
43755 for (i, (segment, needs_bracket)) in json_path.iter().enumerate() {
43756 if *needs_bracket {
43757 path_str.push('[');
43759 path_str.push('"');
43760 path_str.push_str(segment);
43761 path_str.push('"');
43762 path_str.push(']');
43763 } else {
43764 if i > 0 {
43765 path_str.push('.');
43766 }
43767 path_str.push_str(segment);
43768 }
43769 }
43770
43771 Ok(Some(Expression::JSONExtract(Box::new(JSONExtract {
43772 this: Box::new(this),
43773 expression: Box::new(Expression::Literal(Box::new(Literal::String(path_str)))),
43774 only_json_types: None,
43775 expressions: Vec::new(),
43776 variant_extract: Some(Box::new(Expression::Boolean(BooleanLiteral {
43777 value: true,
43778 }))),
43779 json_query: None,
43780 option: None,
43781 quote: None,
43782 on_condition: None,
43783 requires_json: None,
43784 }))))
43785 }
43786
43787 pub fn parse_column(&mut self) -> Result<Option<Expression>> {
43790 let column_ref = self.parse_column_reference()?;
43792 if column_ref.is_some() {
43793 return self.parse_column_ops_with_expr(column_ref);
43795 }
43796 self.parse_bracket()
43798 }
43799
43800 #[allow(unused_variables, unused_mut)]
43803 pub fn parse_column_constraint(&mut self) -> Result<Option<Expression>> {
43804 let constraint_name = if self.match_token(TokenType::Constraint) {
43806 self.parse_id_var()?.and_then(|e| {
43807 if let Expression::Identifier(id) = e {
43808 Some(id)
43809 } else {
43810 None
43811 }
43812 })
43813 } else {
43814 None
43815 };
43816
43817 if self.match_text_seq(&["NOT", "NULL"]) {
43819 return Ok(Some(Expression::NotNullColumnConstraint(Box::new(
43820 NotNullColumnConstraint { allow_null: None },
43821 ))));
43822 }
43823
43824 if self.match_text_seq(&["NOT", "FOR", "REPLICATION"]) {
43826 return Ok(Some(Expression::Property(Box::new(
43827 crate::expressions::Property {
43828 this: Box::new(Expression::Identifier(Identifier::new(
43829 "NOT FOR REPLICATION".to_string(),
43830 ))),
43831 value: None,
43832 },
43833 ))));
43834 }
43835
43836 if self.match_text_seq(&["NULL"]) {
43838 return Ok(Some(Expression::NotNullColumnConstraint(Box::new(
43839 NotNullColumnConstraint {
43840 allow_null: Some(Box::new(Expression::Boolean(BooleanLiteral {
43841 value: true,
43842 }))),
43843 },
43844 ))));
43845 }
43846
43847 if self.match_text_seq(&["PRIMARY", "KEY"]) {
43849 return Ok(Some(Expression::PrimaryKeyColumnConstraint(Box::new(
43850 PrimaryKeyColumnConstraint {
43851 desc: None,
43852 options: Vec::new(),
43853 },
43854 ))));
43855 }
43856
43857 if self.match_text_seq(&["UNIQUE"]) {
43859 let _ = self.match_texts(&["KEY", "INDEX"]);
43861 let nulls = if self.match_text_seq(&["NULLS", "NOT", "DISTINCT"]) {
43863 Some(Box::new(Expression::Boolean(BooleanLiteral {
43864 value: true,
43865 })))
43866 } else {
43867 None
43868 };
43869 return Ok(Some(Expression::UniqueColumnConstraint(Box::new(
43870 UniqueColumnConstraint {
43871 this: None,
43872 index_type: None,
43873 on_conflict: None,
43874 nulls,
43875 options: Vec::new(),
43876 },
43877 ))));
43878 }
43879
43880 if self.match_text_seq(&["DEFAULT"]) {
43882 let default_value = self.parse_select_or_expression()?;
43883 if let Some(val) = default_value {
43884 return Ok(Some(Expression::DefaultColumnConstraint(Box::new(
43885 DefaultColumnConstraint {
43886 this: Box::new(val),
43887 for_column: None,
43888 },
43889 ))));
43890 }
43891 return Ok(None);
43892 }
43893
43894 if self.match_text_seq(&["CHECK"]) {
43896 if self.match_token(TokenType::LParen) {
43897 let expr = self.parse_select_or_expression()?;
43898 self.match_token(TokenType::RParen);
43899 if let Some(check_expr) = expr {
43900 return Ok(Some(Expression::CheckColumnConstraint(Box::new(
43901 CheckColumnConstraint {
43902 this: Box::new(check_expr),
43903 enforced: None,
43904 },
43905 ))));
43906 }
43907 }
43908 return Ok(None);
43909 }
43910
43911 if self.match_text_seq(&["REFERENCES"]) {
43913 let table = self.parse_table_parts()?;
43914 let columns = if self.match_token(TokenType::LParen) {
43915 let mut cols = Vec::new();
43916 loop {
43917 if let Some(col) = self.parse_id_var()? {
43918 cols.push(col);
43919 }
43920 if !self.match_token(TokenType::Comma) {
43921 break;
43922 }
43923 }
43924 self.match_token(TokenType::RParen);
43925 cols
43926 } else {
43927 Vec::new()
43928 };
43929
43930 return Ok(Some(Expression::ForeignKey(Box::new(ForeignKey {
43931 expressions: columns,
43932 reference: table.map(Box::new),
43933 delete: None,
43934 update: None,
43935 options: Vec::new(),
43936 }))));
43937 }
43938
43939 if self.match_texts(&["AUTO_INCREMENT", "AUTOINCREMENT", "IDENTITY"]) {
43941 let mut start = None;
43943 let mut increment = None;
43944
43945 if self.match_token(TokenType::LParen) {
43946 start = self.parse_bitwise()?;
43948 if self.match_token(TokenType::Comma) {
43949 increment = self.parse_bitwise()?;
43950 }
43951 self.expect(TokenType::RParen)?;
43952 } else if self.match_text_seq(&["START"]) {
43953 start = self.parse_bitwise()?;
43955 if self.match_text_seq(&["INCREMENT"]) {
43956 increment = self.parse_bitwise()?;
43957 }
43958 }
43959
43960 if start.is_some() || increment.is_some() {
43961 return Ok(Some(Expression::GeneratedAsIdentityColumnConstraint(
43962 Box::new(GeneratedAsIdentityColumnConstraint {
43963 this: Some(Box::new(Expression::Boolean(BooleanLiteral {
43964 value: false,
43965 }))),
43966 expression: None,
43967 on_null: None,
43968 start: start.map(Box::new),
43969 increment: increment.map(Box::new),
43970 minvalue: None,
43971 maxvalue: None,
43972 cycle: None,
43973 order: None,
43974 }),
43975 )));
43976 }
43977 return Ok(Some(Expression::AutoIncrementColumnConstraint(
43978 AutoIncrementColumnConstraint,
43979 )));
43980 }
43981
43982 if self.match_text_seq(&["COMMENT"]) {
43984 if let Some(comment) = self.parse_string()? {
43985 return Ok(Some(Expression::CommentColumnConstraint(
43987 CommentColumnConstraint,
43988 )));
43989 }
43990 return Ok(None);
43991 }
43992
43993 if self.match_text_seq(&["COLLATE"]) {
43995 if let Some(collation) = self.parse_id_var()? {
43996 return Ok(Some(Expression::CollateProperty(Box::new(
43997 CollateProperty {
43998 this: Box::new(collation),
43999 default: None,
44000 },
44001 ))));
44002 }
44003 return Ok(None);
44004 }
44005
44006 if matches!(
44008 self.config.dialect,
44009 Some(crate::dialects::DialectType::ClickHouse)
44010 ) {
44011 if self.match_texts(&["HIERARCHICAL", "IS_OBJECT_ID", "INJECTIVE"]) {
44012 let attr_name = self.previous().text.to_ascii_uppercase();
44013 return Ok(Some(Expression::Property(Box::new(
44014 crate::expressions::Property {
44015 this: Box::new(Expression::Identifier(Identifier::new(attr_name))),
44016 value: None,
44017 },
44018 ))));
44019 }
44020 if self.match_texts(&["EXPRESSION"]) {
44022 let expr = self.parse_expression()?;
44023 return Ok(Some(Expression::DefaultColumnConstraint(Box::new(
44024 DefaultColumnConstraint {
44025 this: Box::new(expr),
44026 for_column: None,
44027 },
44028 ))));
44029 }
44030 }
44031
44032 if self.match_text_seq(&["GENERATED"]) {
44034 let always = self.match_text_seq(&["ALWAYS"]);
44035 if !always {
44036 self.match_text_seq(&["BY", "DEFAULT"]);
44037 }
44038 let on_null = self.match_text_seq(&["ON", "NULL"]);
44039 if self.match_text_seq(&["AS", "IDENTITY"]) {
44040 return Ok(Some(Expression::GeneratedAsIdentityColumnConstraint(
44041 Box::new(GeneratedAsIdentityColumnConstraint {
44042 this: None,
44043 expression: None,
44044 on_null: if on_null {
44045 Some(Box::new(Expression::Boolean(BooleanLiteral {
44046 value: true,
44047 })))
44048 } else {
44049 None
44050 },
44051 start: None,
44052 increment: None,
44053 minvalue: None,
44054 maxvalue: None,
44055 cycle: None,
44056 order: None,
44057 }),
44058 )));
44059 }
44060 return Ok(None);
44061 }
44062
44063 if self.match_text_seq(&["PATH"]) {
44065 if let Some(path_expr) = self.parse_string()? {
44066 return Ok(Some(Expression::PathColumnConstraint(Box::new(
44067 PathColumnConstraint {
44068 this: Box::new(path_expr),
44069 },
44070 ))));
44071 }
44072 return Ok(None);
44073 }
44074
44075 if let Some(name) = constraint_name {
44077 return Ok(Some(Expression::Identifier(name)));
44078 }
44079
44080 Ok(None)
44081 }
44082
44083 #[allow(unused_variables, unused_mut)]
44086 pub fn parse_column_def_with_exists(&mut self) -> Result<Option<Expression>> {
44087 let start = self.current;
44088
44089 let _ = self.match_text_seq(&["COLUMN"]);
44091
44092 let not_exists = self.match_text_seq(&["IF", "NOT", "EXISTS"]);
44094 let exists = if !not_exists {
44095 self.match_text_seq(&["IF", "EXISTS"])
44096 } else {
44097 false
44098 };
44099
44100 let expression = self.parse_field_def()?;
44102
44103 if expression.is_none() {
44104 self.current = start;
44105 return Ok(None);
44106 }
44107
44108 if let Some(Expression::ColumnDef(ref _col_def)) = expression {
44110 return Ok(expression);
44113 }
44114
44115 self.current = start;
44117 Ok(None)
44118 }
44119
44120 pub fn parse_column_ops(&mut self) -> Result<Option<Expression>> {
44122 self.parse_column_ops_with_expr(None)
44123 }
44124
44125 pub fn parse_column_ops_with_expr(
44128 &mut self,
44129 this: Option<Expression>,
44130 ) -> Result<Option<Expression>> {
44131 let mut result = if let Some(expr) = this {
44133 if self.match_token(TokenType::LBracket) {
44134 let index = self.parse_disjunction()?;
44135 self.match_token(TokenType::RBracket);
44136 if let Some(idx) = index {
44137 Some(Expression::Subscript(Box::new(Subscript {
44138 this: expr,
44139 index: idx,
44140 })))
44141 } else {
44142 Some(expr)
44143 }
44144 } else {
44145 Some(expr)
44146 }
44147 } else {
44148 None
44149 };
44150
44151 while self.match_token(TokenType::Dot) {
44153 if result.is_none() {
44154 break;
44155 }
44156 if self.match_token(TokenType::Star) {
44158 let table_name = match &result {
44160 Some(Expression::Column(col)) if col.table.is_none() => Some(col.name.clone()),
44161 Some(Expression::Dot(dot)) => {
44162 fn dot_to_name(expr: &Expression) -> String {
44164 match expr {
44165 Expression::Column(col) => {
44166 if let Some(ref table) = col.table {
44167 format!("{}.{}", table.name, col.name.name)
44168 } else {
44169 col.name.name.clone()
44170 }
44171 }
44172 Expression::Dot(d) => {
44173 format!("{}.{}", dot_to_name(&d.this), d.field.name)
44174 }
44175 _ => String::new(),
44176 }
44177 }
44178 Some(Identifier::new(dot_to_name(&Expression::Dot(dot.clone()))))
44179 }
44180 _ => None,
44181 };
44182 let star = self.parse_star_modifiers(table_name)?;
44183 result = Some(Expression::Star(star));
44184 break;
44185 }
44186 if self.is_identifier_or_keyword_token()
44190 || self.check(TokenType::QuotedIdentifier)
44191 || (matches!(
44192 self.config.dialect,
44193 Some(crate::dialects::DialectType::ClickHouse)
44194 ) && self.check(TokenType::Number))
44195 {
44196 let token = self.advance();
44197 let field_ident = Identifier {
44198 name: token.text,
44199 quoted: token.token_type == TokenType::QuotedIdentifier,
44200 trailing_comments: Vec::new(),
44201 span: None,
44202 };
44203 result = Some(Expression::Dot(Box::new(DotAccess {
44204 this: result.take().unwrap(),
44205 field: field_ident,
44206 })));
44207 } else {
44208 break;
44209 }
44210 }
44211
44212 if self.match_token(TokenType::Exclamation) {
44214 if let Some(expr) = result.take() {
44215 let attr = self.parse_unary()?;
44218 result = Some(Expression::ModelAttribute(Box::new(ModelAttribute {
44219 this: Box::new(expr),
44220 expression: Box::new(attr),
44221 })));
44222 }
44223 }
44224
44225 if self.match_token(TokenType::DColon) {
44227 if let Some(type_expr) = self.parse_types()? {
44228 if let Some(expr) = result {
44229 let data_type = match type_expr {
44231 Expression::DataType(dt) => dt,
44232 _ => {
44233 result = Some(expr);
44234 return Ok(result);
44235 }
44236 };
44237 result = Some(Expression::Cast(Box::new(Cast {
44238 this: expr,
44239 to: data_type,
44240 trailing_comments: Vec::new(),
44241 double_colon_syntax: true,
44242 format: None,
44243 default: None,
44244 inferred_type: None,
44245 })));
44246 }
44247 }
44248 }
44249
44250 if matches!(
44252 self.config.dialect,
44253 Some(crate::dialects::DialectType::Teradata)
44254 ) && self.check(TokenType::LParen)
44255 && self.check_next(TokenType::Format)
44256 {
44257 self.skip(); self.skip(); let format = self.expect_string()?;
44260 self.expect(TokenType::RParen)?;
44261 if let Some(expr) = result.take() {
44262 result = Some(Expression::FormatPhrase(Box::new(FormatPhrase {
44263 this: Box::new(expr),
44264 format,
44265 })));
44266 }
44267 }
44268
44269 Ok(result)
44270 }
44271
44272 pub fn parse_column_reference(&mut self) -> Result<Option<Expression>> {
44275 if let Some(field) = self.parse_field()? {
44277 match &field {
44279 Expression::Identifier(id) => {
44280 return Ok(Some(Expression::boxed_column(Column {
44281 name: id.clone(),
44282 table: None,
44283 join_mark: false,
44284 trailing_comments: Vec::new(),
44285 span: None,
44286 inferred_type: None,
44287 })));
44288 }
44289 _ => return Ok(Some(field)),
44291 }
44292 }
44293 Ok(None)
44294 }
44295
44296 pub fn parse_command(&mut self) -> Result<Option<Expression>> {
44300 let command_text = self.previous().text.to_ascii_uppercase();
44302
44303 let mut tokens: Vec<(String, TokenType)> = vec![(command_text, TokenType::Var)];
44306 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
44307 let token = self.advance();
44308 let text = if token.token_type == TokenType::QuotedIdentifier {
44310 let quote_char = if self.config.dialect == Some(crate::dialects::DialectType::MySQL)
44314 || self.config.dialect == Some(crate::dialects::DialectType::SingleStore)
44315 || self.config.dialect == Some(crate::dialects::DialectType::Doris)
44316 || self.config.dialect == Some(crate::dialects::DialectType::StarRocks)
44317 {
44318 '`'
44319 } else {
44320 '"'
44321 };
44322 format!("{}{}{}", quote_char, token.text, quote_char)
44323 } else if token.token_type == TokenType::String {
44324 format!("'{}'", token.text)
44325 } else {
44326 token.text.clone()
44327 };
44328 tokens.push((text, token.token_type));
44329 }
44330
44331 Ok(Some(Expression::Command(Box::new(Command {
44332 this: self.join_command_tokens(tokens),
44333 }))))
44334 }
44335
44336 #[allow(unused_variables, unused_mut)]
44338 pub fn parse_commit_or_rollback(&mut self) -> Result<Option<Expression>> {
44339 if self.match_text_seq(&["TO"]) {
44340 return Ok(Some(Expression::Rollback(Box::new(Rollback {
44341 savepoint: None,
44342 this: None,
44343 }))));
44344 }
44345 if self.match_text_seq(&["SAVEPOINT"]) {
44346 return Ok(None);
44348 }
44349 Ok(None)
44350 }
44351
44352 #[allow(unused_variables, unused_mut)]
44354 pub fn parse_composite_key_property(&mut self) -> Result<Option<Expression>> {
44355 if self.match_text_seq(&["KEY"]) {
44356 return Ok(None);
44358 }
44359 Ok(None)
44360 }
44361
44362 pub fn parse_comprehension(&mut self, this: Option<Expression>) -> Result<Option<Expression>> {
44365 let start_index = self.current;
44366
44367 let expression = self.parse_column()?;
44369
44370 let position = if self.match_token(TokenType::Comma) {
44372 self.parse_column()?.map(Box::new)
44373 } else {
44374 None
44375 };
44376
44377 if !self.match_token(TokenType::In) {
44379 self.current = start_index.saturating_sub(1);
44381 return Ok(None);
44382 }
44383
44384 let iterator = self.parse_column()?.map(Box::new);
44386
44387 let condition = if self.match_text_seq(&["IF"]) {
44389 self.parse_disjunction()?.map(Box::new)
44390 } else {
44391 None
44392 };
44393
44394 match (this, expression) {
44396 (Some(t), Some(e)) => Ok(Some(Expression::Comprehension(Box::new(Comprehension {
44397 this: Box::new(t),
44398 expression: Box::new(e),
44399 position,
44400 iterator,
44401 condition,
44402 })))),
44403 _ => Ok(None),
44404 }
44405 }
44406
44407 pub fn parse_compress(&mut self) -> Result<Option<Expression>> {
44411 if self.check(TokenType::LParen) {
44413 self.skip(); let mut expressions = Vec::new();
44416 loop {
44417 if let Some(expr) = self.parse_bitwise()? {
44418 expressions.push(expr);
44419 } else {
44420 break;
44421 }
44422 if !self.match_token(TokenType::Comma) {
44423 break;
44424 }
44425 }
44426 self.expect(TokenType::RParen)?;
44427
44428 let this = if expressions.len() == 1 {
44430 Some(Box::new(expressions.into_iter().next().unwrap()))
44431 } else if expressions.is_empty() {
44432 None
44433 } else {
44434 Some(Box::new(Expression::Tuple(Box::new(Tuple { expressions }))))
44435 };
44436
44437 Ok(Some(Expression::CompressColumnConstraint(Box::new(
44438 CompressColumnConstraint { this },
44439 ))))
44440 } else {
44441 let this = self.parse_bitwise()?.map(Box::new);
44443 Ok(Some(Expression::CompressColumnConstraint(Box::new(
44444 CompressColumnConstraint { this },
44445 ))))
44446 }
44447 }
44448
44449 pub fn parse_conjunction(&mut self) -> Result<Option<Expression>> {
44453 match self.parse_and() {
44454 Ok(expr) => Ok(Some(expr)),
44455 Err(_) => Ok(None),
44456 }
44457 }
44458
44459 pub fn parse_connect_with_prior(&mut self) -> Result<Option<Expression>> {
44463 let connect = self.parse_connect_expression()?;
44465 Ok(Some(connect))
44466 }
44467
44468 pub fn parse_constraint(&mut self) -> Result<Option<Expression>> {
44471 if !self.match_token(TokenType::Constraint) {
44473 return self.parse_unnamed_constraint();
44475 }
44476
44477 let name = self.parse_id_var()?;
44479 if name.is_none() {
44480 return Ok(None);
44481 }
44482
44483 let expressions = self.parse_unnamed_constraints()?;
44485
44486 Ok(Some(Expression::Constraint(Box::new(Constraint {
44487 this: Box::new(name.unwrap()),
44488 expressions,
44489 }))))
44490 }
44491
44492 pub fn parse_unnamed_constraints(&mut self) -> Result<Vec<Expression>> {
44495 let mut constraints = Vec::new();
44496
44497 loop {
44498 if let Some(constraint) = self.parse_unnamed_constraint()? {
44499 constraints.push(constraint);
44500 } else {
44501 break;
44502 }
44503 }
44504
44505 Ok(constraints)
44506 }
44507
44508 pub fn parse_unnamed_constraint(&mut self) -> Result<Option<Expression>> {
44511 if self.match_text_seq(&["PRIMARY", "KEY"]) {
44513 if matches!(
44515 self.config.dialect,
44516 Some(crate::dialects::DialectType::ClickHouse)
44517 ) && !self.check(TokenType::LParen)
44518 {
44519 let expr = self.parse_expression()?;
44520 return Ok(Some(Expression::Raw(Raw {
44521 sql: format!("PRIMARY KEY {}", expr),
44522 })));
44523 }
44524 return self.parse_primary_key();
44525 }
44526
44527 if self.match_texts(&["UNIQUE"]) {
44529 return self.parse_unique();
44530 }
44531
44532 if self.match_text_seq(&["FOREIGN", "KEY"]) {
44534 return self.parse_foreign_key();
44535 }
44536
44537 if self.match_texts(&["CHECK"]) {
44539 let expr = self.parse_wrapped()?;
44540 if let Some(check_expr) = expr {
44541 return Ok(Some(Expression::CheckColumnConstraint(Box::new(
44542 CheckColumnConstraint {
44543 this: Box::new(check_expr),
44544 enforced: None,
44545 },
44546 ))));
44547 }
44548 }
44549
44550 if self.match_text_seq(&["NOT", "NULL"]) {
44552 return Ok(Some(Expression::NotNullColumnConstraint(Box::new(
44553 NotNullColumnConstraint {
44554 allow_null: None, },
44556 ))));
44557 }
44558
44559 if self.match_texts(&["NULL"]) {
44561 return Ok(Some(Expression::NotNullColumnConstraint(Box::new(
44562 NotNullColumnConstraint {
44563 allow_null: Some(Box::new(Expression::Boolean(BooleanLiteral {
44564 value: true,
44565 }))),
44566 },
44567 ))));
44568 }
44569
44570 if self.match_token(TokenType::Default) {
44572 let default_value = self.parse_bitwise()?;
44573 if let Some(val) = default_value {
44574 let for_column = if self.match_token(TokenType::For) {
44576 Some(self.expect_identifier_with_quoted()?)
44577 } else {
44578 None
44579 };
44580 return Ok(Some(Expression::DefaultColumnConstraint(Box::new(
44581 DefaultColumnConstraint {
44582 this: Box::new(val),
44583 for_column,
44584 },
44585 ))));
44586 }
44587 }
44588
44589 if self.match_texts(&["REFERENCES"]) {
44591 return self.parse_references();
44592 }
44593
44594 if matches!(
44596 self.config.dialect,
44597 Some(crate::dialects::DialectType::ClickHouse)
44598 ) && self.match_token(TokenType::Index)
44599 {
44600 let name = self.expect_identifier_or_keyword_with_quoted()?;
44601 let expression = self.parse_conjunction()?.ok_or_else(|| {
44603 self.parse_error("Expected expression in ClickHouse INDEX definition")
44604 })?;
44605 let index_type = if self.match_token(TokenType::Type) {
44606 if let Some(func) = self.parse_function()? {
44607 Some(Box::new(func))
44608 } else if !self.is_at_end() {
44609 let type_name = self.advance().text.clone();
44610 if self.check(TokenType::LParen) {
44611 self.skip();
44612 let mut args = Vec::new();
44613 if !self.check(TokenType::RParen) {
44614 args.push(self.parse_expression()?);
44615 while self.match_token(TokenType::Comma) {
44616 args.push(self.parse_expression()?);
44617 }
44618 }
44619 self.expect(TokenType::RParen)?;
44620 Some(Box::new(Expression::Function(Box::new(Function::new(
44621 type_name, args,
44622 )))))
44623 } else {
44624 Some(Box::new(Expression::Identifier(Identifier::new(type_name))))
44625 }
44626 } else {
44627 None
44628 }
44629 } else {
44630 None
44631 };
44632 let _granularity = if self.match_identifier("GRANULARITY") {
44633 let _ = self.parse_expression()?;
44634 true
44635 } else {
44636 false
44637 };
44638 let mut sql = format!("INDEX {} ", name.name);
44640 if let Some(ref idx_type) = index_type {
44641 sql.push_str(&format!("{} TYPE {} ", expression, idx_type));
44642 }
44643 return Ok(Some(Expression::Raw(Raw {
44644 sql: sql.trim().to_string(),
44645 })));
44646 }
44647
44648 if matches!(
44650 self.config.dialect,
44651 Some(crate::dialects::DialectType::ClickHouse)
44652 ) && self.check_identifier("PROJECTION")
44653 {
44654 self.skip(); let name = self.expect_identifier_or_keyword_with_quoted()?;
44656 if self.match_token(TokenType::LParen) {
44658 let mut depth = 1i32;
44659 let start = self.current;
44660 while !self.is_at_end() && depth > 0 {
44661 if self.check(TokenType::LParen) {
44662 depth += 1;
44663 }
44664 if self.check(TokenType::RParen) {
44665 depth -= 1;
44666 if depth == 0 {
44667 break;
44668 }
44669 }
44670 self.skip();
44671 }
44672 let body_sql = self.tokens_to_sql(start, self.current);
44673 self.expect(TokenType::RParen)?;
44674 return Ok(Some(Expression::Raw(Raw {
44675 sql: format!("PROJECTION {} ({})", name.name, body_sql),
44676 })));
44677 }
44678 if self.match_token(TokenType::Index) {
44680 let expr = self.parse_bitwise()?.ok_or_else(|| {
44681 self.parse_error(
44682 "Expected expression in ClickHouse PROJECTION INDEX definition",
44683 )
44684 })?;
44685 let type_str = if self.match_token(TokenType::Type) {
44686 if !self.is_at_end() {
44687 let t = self.advance().text.clone();
44688 format!(" TYPE {}", t)
44689 } else {
44690 String::new()
44691 }
44692 } else {
44693 String::new()
44694 };
44695 return Ok(Some(Expression::Raw(Raw {
44696 sql: format!("PROJECTION {} INDEX {}{}", name.name, expr, type_str),
44697 })));
44698 }
44699 return Ok(Some(Expression::Raw(Raw {
44700 sql: format!("PROJECTION {}", name.name),
44701 })));
44702 }
44703
44704 Ok(None)
44705 }
44706
44707 #[allow(unused_variables, unused_mut)]
44709 pub fn parse_contains_property(&mut self) -> Result<Option<Expression>> {
44710 if self.match_text_seq(&["SQL"]) {
44711 return Ok(None);
44713 }
44714 Ok(None)
44715 }
44716
44717 #[allow(unused_variables, unused_mut)]
44720 pub fn parse_convert(&mut self) -> Result<Option<Expression>> {
44721 let this = match self.parse_bitwise() {
44723 Ok(Some(expr)) => expr,
44724 Ok(None) => return Ok(None),
44725 Err(e) => return Err(e),
44726 };
44727
44728 if self.match_token(TokenType::Using) {
44730 let _ = self.parse_var(); return Ok(Some(Expression::Cast(Box::new(Cast {
44733 this,
44734 to: DataType::Char { length: None },
44735 trailing_comments: Vec::new(),
44736 double_colon_syntax: false,
44737 format: None,
44738 default: None,
44739 inferred_type: None,
44740 }))));
44741 }
44742
44743 if self.match_token(TokenType::Comma) {
44745 let data_type = self.parse_data_type()?;
44746 return Ok(Some(Expression::Cast(Box::new(Cast {
44747 this,
44748 to: data_type,
44749 trailing_comments: Vec::new(),
44750 double_colon_syntax: false,
44751 format: None,
44752 default: None,
44753 inferred_type: None,
44754 }))));
44755 }
44756
44757 Ok(Some(Expression::Cast(Box::new(Cast {
44759 this,
44760 to: DataType::Char { length: None },
44761 trailing_comments: Vec::new(),
44762 double_colon_syntax: false,
44763 format: None,
44764 default: None,
44765 inferred_type: None,
44766 }))))
44767 }
44768
44769 pub fn parse_copy_parameters(&mut self) -> Result<Option<Expression>> {
44773 let mut options = Vec::new();
44774
44775 while !self.is_at_end() && !self.check(TokenType::RParen) {
44776 let option = self.parse_var()?;
44778 if option.is_none() {
44779 break;
44780 }
44781
44782 let option_name = match &option {
44783 Some(Expression::Var(v)) => v.this.to_ascii_uppercase(),
44784 Some(Expression::Identifier(id)) => id.name.to_ascii_uppercase(),
44785 _ => String::new(),
44786 };
44787
44788 self.match_token(TokenType::Eq);
44790 self.match_token(TokenType::Alias);
44791
44792 let (expression, expressions) = if (option_name == "FILE_FORMAT"
44794 || option_name == "FORMAT_OPTIONS")
44795 && self.check(TokenType::LParen)
44796 {
44797 let wrapped = self.parse_wrapped_options()?;
44799 let exprs = match wrapped {
44800 Some(Expression::Tuple(t)) => t.expressions,
44801 Some(e) => vec![e],
44802 None => Vec::new(),
44803 };
44804 (None, exprs)
44805 } else if option_name == "FILE_FORMAT" {
44806 let field = self.parse_field()?;
44808 (field, Vec::new())
44809 } else if option_name == "FORMAT"
44810 && self.previous().token_type == TokenType::Alias
44811 && self.match_texts(&["AVRO", "JSON"])
44812 {
44813 let format_type = self.previous().text.to_ascii_uppercase();
44815 let field = self.parse_field()?;
44816 (
44817 Some(Expression::Var(Box::new(Var {
44818 this: format!("FORMAT AS {}", format_type),
44819 }))),
44820 field.map_or(Vec::new(), |f| vec![f]),
44821 )
44822 } else {
44823 let expr = self
44825 .parse_unquoted_field()?
44826 .or_else(|| self.parse_bracket().ok().flatten());
44827 (expr, Vec::new())
44828 };
44829
44830 options.push(Expression::CopyParameter(Box::new(CopyParameter {
44831 name: option_name,
44832 value: expression,
44833 values: expressions,
44834 eq: true,
44835 })));
44836
44837 self.match_token(TokenType::Comma);
44839 }
44840
44841 if options.is_empty() {
44842 Ok(None)
44843 } else {
44844 Ok(Some(Expression::Tuple(Box::new(Tuple {
44845 expressions: options,
44846 }))))
44847 }
44848 }
44849
44850 #[allow(unused_variables, unused_mut)]
44852 pub fn parse_copy_property(&mut self) -> Result<Option<Expression>> {
44853 if self.match_text_seq(&["GRANTS"]) {
44854 return Ok(None);
44856 }
44857 Ok(None)
44858 }
44859
44860 #[allow(unused_variables, unused_mut)]
44863 pub fn parse_create_like(&mut self) -> Result<Option<Expression>> {
44864 if self.match_texts(&["INCLUDING", "EXCLUDING"]) {
44865 return Ok(None);
44867 }
44868 Ok(None)
44869 }
44870
44871 #[allow(unused_variables, unused_mut)]
44873 pub fn parse_credentials(&mut self) -> Result<Option<Expression>> {
44874 if self.match_text_seq(&["STORAGE_INTEGRATION", "="]) {
44875 return Ok(Some(Expression::Credentials(Box::new(Credentials {
44876 credentials: Vec::new(),
44877 encryption: None,
44878 storage: None,
44879 }))));
44880 }
44881 if self.match_text_seq(&["CREDENTIALS"]) {
44882 return Ok(None);
44884 }
44885 Ok(None)
44886 }
44887
44888 pub fn parse_csv(&mut self) -> Result<Option<Expression>> {
44892 let expressions = self.parse_expression_list()?;
44893 if expressions.is_empty() {
44894 return Ok(None);
44895 }
44896 Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))))
44897 }
44898
44899 #[allow(unused_variables, unused_mut)]
44902 pub fn parse_cte(&mut self) -> Result<Option<Expression>> {
44903 if self.match_text_seq(&["USING", "KEY"]) {
44904 return Ok(Some(Expression::Values(Box::new(Values {
44905 expressions: Vec::new(),
44906 alias: None,
44907 column_aliases: Vec::new(),
44908 }))));
44909 }
44910 if self.match_text_seq(&["NOT", "MATERIALIZED"]) {
44911 return Ok(None);
44913 }
44914 if self.match_text_seq(&["MATERIALIZED"]) {
44915 return Ok(None);
44917 }
44918 Ok(None)
44919 }
44920
44921 #[allow(unused_variables, unused_mut)]
44924 pub fn parse_cube_or_rollup(&mut self) -> Result<Option<Expression>> {
44925 let is_cube = self.match_texts(&["CUBE"]);
44927 let is_rollup = if !is_cube {
44928 self.match_texts(&["ROLLUP"])
44929 } else {
44930 false
44931 };
44932
44933 if !is_cube && !is_rollup {
44934 return Ok(None);
44935 }
44936
44937 self.expect(TokenType::LParen)?;
44939 let mut expressions = Vec::new();
44940 if !self.check(TokenType::RParen) {
44941 loop {
44942 match self.parse_bitwise() {
44943 Ok(Some(expr)) => expressions.push(expr),
44944 Ok(None) => break,
44945 Err(e) => return Err(e),
44946 }
44947 if !self.match_token(TokenType::Comma) {
44948 break;
44949 }
44950 }
44951 }
44952 self.expect(TokenType::RParen)?;
44953
44954 if is_cube {
44955 Ok(Some(Expression::Cube(Box::new(Cube { expressions }))))
44956 } else {
44957 Ok(Some(Expression::Rollup(Box::new(Rollup { expressions }))))
44958 }
44959 }
44960
44961 #[allow(unused_variables, unused_mut)]
44964 pub fn parse_data_deletion_property(&mut self) -> Result<Option<Expression>> {
44965 if self.match_text_seq(&["ON"]) {
44966 return Ok(None);
44968 }
44969 if self.match_text_seq(&["OFF"]) {
44970 return Ok(None);
44972 }
44973 if self.match_text_seq(&["FILTER_COLUMN", "="]) {
44974 return Ok(None);
44976 }
44977 Ok(None)
44978 }
44979
44980 #[allow(unused_variables, unused_mut)]
44983 pub fn parse_datablocksize(&mut self) -> Result<Option<Expression>> {
44984 if self.match_texts(&["BYTES", "KBYTES", "KILOBYTES"]) {
44985 return Ok(None);
44987 }
44988 Ok(None)
44989 }
44990
44991 #[allow(unused_variables, unused_mut)]
44993 pub fn parse_dcolon(&mut self) -> Result<Option<Expression>> {
44994 self.parse_types()
44995 }
44996
44997 #[allow(unused_variables, unused_mut)]
45000 pub fn parse_ddl_select(&mut self) -> Result<Option<Expression>> {
45001 let select = self.parse_select_query()?;
45003
45004 if select.is_none() {
45005 return Ok(None);
45006 }
45007
45008 let with_set_ops = self.parse_set_operations_with_expr(select)?;
45010
45011 Ok(with_set_ops)
45013 }
45014
45015 pub fn parse_for_in(&mut self) -> Result<Expression> {
45020 let this = self
45023 .parse_range()?
45024 .ok_or_else(|| self.parse_error("Expected expression after FOR"))?;
45025
45026 self.match_text_seq(&["DO"]);
45028
45029 let expression = self.parse_statement()?;
45031
45032 Ok(Expression::ForIn(Box::new(ForIn {
45033 this: Box::new(this),
45034 expression: Box::new(expression),
45035 })))
45036 }
45037
45038 pub fn parse_declare(&mut self) -> Result<Option<Expression>> {
45042 let replace = self.match_text_seq(&["OR", "REPLACE"]);
45044
45045 let mut expressions = Vec::new();
45047
45048 let saved = self.current;
45052 let mut multi_names: Vec<Expression> = Vec::new();
45053 if let Some(first_var) = self.parse_id_var()? {
45054 if self.check(TokenType::Comma) && !self.check_identifier("CURSOR") {
45056 multi_names.push(first_var);
45058 while self.match_token(TokenType::Comma) {
45059 if let Some(next_var) = self.parse_id_var()? {
45060 multi_names.push(next_var);
45061 } else {
45062 break;
45063 }
45064 }
45065 if multi_names.len() > 1 && !self.is_at_end() && !self.check(TokenType::Semicolon) {
45068 let data_type = self.parse_data_type()?;
45069 let kind_str = self.data_type_to_sql(&data_type);
45070 let default = if self.match_token(TokenType::Default)
45071 || self.match_token(TokenType::Eq)
45072 {
45073 Some(Box::new(self.parse_expression()?))
45074 } else {
45075 None
45076 };
45077 let first_name = multi_names.remove(0);
45078 expressions.push(Expression::DeclareItem(Box::new(DeclareItem {
45079 this: Box::new(first_name),
45080 kind: Some(kind_str),
45081 default,
45082 has_as: false,
45083 additional_names: multi_names,
45084 })));
45085 return Ok(Some(Expression::Declare(Box::new(Declare {
45086 expressions,
45087 replace,
45088 }))));
45089 }
45090 }
45091 }
45092 self.current = saved;
45094
45095 loop {
45096 if let Some(item) = self.parse_declareitem()? {
45097 expressions.push(item);
45098 } else {
45099 break;
45100 }
45101 if !self.match_token(TokenType::Comma) {
45102 break;
45103 }
45104 }
45105
45106 if !expressions.is_empty() {
45108 return Ok(Some(Expression::Declare(Box::new(Declare {
45109 expressions,
45110 replace,
45111 }))));
45112 }
45113
45114 Ok(None)
45115 }
45116
45117 #[allow(unused_variables, unused_mut)]
45122 pub fn parse_declareitem(&mut self) -> Result<Option<Expression>> {
45123 if self.check_identifier("VAR") || self.check_identifier("VARIABLE") {
45125 self.skip();
45126 }
45127
45128 let var = if let Some(v) = self.parse_id_var()? {
45130 v
45131 } else {
45132 return Ok(None);
45133 };
45134
45135 if self.check_identifier("CURSOR") {
45137 self.skip(); if self.match_token(TokenType::For) {
45141 let start = self.current;
45143 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
45144 self.skip();
45145 }
45146 let query_str = self.tokens_to_sql_uppercased(start, self.current);
45147 let kind_str = format!("CURSOR FOR {}", query_str);
45148 return Ok(Some(Expression::DeclareItem(Box::new(DeclareItem {
45149 this: Box::new(var),
45150 kind: Some(kind_str),
45151 default: None,
45152 has_as: false,
45153 additional_names: Vec::new(),
45154 }))));
45155 } else {
45156 return Ok(Some(Expression::DeclareItem(Box::new(DeclareItem {
45157 this: Box::new(var),
45158 kind: Some("CURSOR".to_string()),
45159 default: None,
45160 has_as: false,
45161 additional_names: Vec::new(),
45162 }))));
45163 }
45164 }
45165
45166 let has_as = self.match_token(TokenType::As);
45168
45169 if self.check(TokenType::Table) {
45171 self.skip(); if self.match_token(TokenType::LParen) {
45173 let start = self.current;
45175 let mut depth = 1;
45176 while depth > 0 && !self.is_at_end() {
45177 if self.check(TokenType::LParen) {
45178 depth += 1;
45179 }
45180 if self.check(TokenType::RParen) {
45181 depth -= 1;
45182 if depth == 0 {
45183 break;
45184 }
45185 }
45186 self.skip();
45187 }
45188 let col_defs_str = self.tokens_to_sql_uppercased(start, self.current);
45189 self.expect(TokenType::RParen)?;
45190 let kind_str = format!("TABLE ({})", col_defs_str);
45191 return Ok(Some(Expression::DeclareItem(Box::new(DeclareItem {
45192 this: Box::new(var),
45193 kind: Some(kind_str),
45194 default: None,
45195 has_as,
45196 additional_names: Vec::new(),
45197 }))));
45198 } else {
45199 return Ok(Some(Expression::DeclareItem(Box::new(DeclareItem {
45200 this: Box::new(var),
45201 kind: Some("TABLE".to_string()),
45202 default: None,
45203 has_as,
45204 additional_names: Vec::new(),
45205 }))));
45206 }
45207 }
45208
45209 let kind_str = if self.check(TokenType::Eq)
45212 || self.check(TokenType::Default)
45213 || self.is_at_end()
45214 || self.check(TokenType::Semicolon)
45215 || self.check(TokenType::Comma)
45216 {
45217 None
45219 } else {
45220 let data_type = self.parse_data_type()?;
45222 Some(self.data_type_to_sql(&data_type))
45223 };
45224
45225 let default = if self.match_token(TokenType::Default) || self.match_token(TokenType::Eq) {
45227 Some(Box::new(self.parse_expression()?))
45228 } else {
45229 None
45230 };
45231
45232 Ok(Some(Expression::DeclareItem(Box::new(DeclareItem {
45233 this: Box::new(var),
45234 kind: kind_str,
45235 default,
45236 has_as,
45237 additional_names: Vec::new(),
45238 }))))
45239 }
45240
45241 fn data_type_to_sql(&self, dt: &DataType) -> String {
45243 match dt {
45244 DataType::Boolean => "BOOLEAN".to_string(),
45245 DataType::TinyInt { length } => {
45246 if let Some(n) = length {
45247 format!("TINYINT({})", n)
45248 } else {
45249 "TINYINT".to_string()
45250 }
45251 }
45252 DataType::SmallInt { length } => {
45253 if let Some(n) = length {
45254 format!("SMALLINT({})", n)
45255 } else {
45256 "SMALLINT".to_string()
45257 }
45258 }
45259 DataType::Int {
45260 length,
45261 integer_spelling,
45262 } => {
45263 if let Some(n) = length {
45264 if *integer_spelling {
45265 format!("INTEGER({})", n)
45266 } else {
45267 format!("INT({})", n)
45268 }
45269 } else if *integer_spelling {
45270 "INTEGER".to_string()
45271 } else {
45272 "INT".to_string()
45273 }
45274 }
45275 DataType::BigInt { length } => {
45276 if let Some(n) = length {
45277 format!("BIGINT({})", n)
45278 } else {
45279 "BIGINT".to_string()
45280 }
45281 }
45282 DataType::Float {
45283 precision, scale, ..
45284 } => match (precision, scale) {
45285 (Some(p), Some(s)) => format!("FLOAT({}, {})", p, s),
45286 (Some(p), None) => format!("FLOAT({})", p),
45287 _ => "FLOAT".to_string(),
45288 },
45289 DataType::Double { precision, scale } => match (precision, scale) {
45290 (Some(p), Some(s)) => format!("DOUBLE({}, {})", p, s),
45291 (Some(p), None) => format!("DOUBLE({})", p),
45292 _ => "DOUBLE".to_string(),
45293 },
45294 DataType::Decimal { precision, scale } => match (precision, scale) {
45295 (Some(p), Some(s)) => format!("DECIMAL({}, {})", p, s),
45296 (Some(p), None) => format!("DECIMAL({})", p),
45297 _ => "DECIMAL".to_string(),
45298 },
45299 DataType::Char { length } => {
45300 if let Some(n) = length {
45301 format!("CHAR({})", n)
45302 } else {
45303 "CHAR".to_string()
45304 }
45305 }
45306 DataType::VarChar { length, .. } => {
45307 if let Some(n) = length {
45308 format!("VARCHAR({})", n)
45309 } else {
45310 "VARCHAR".to_string()
45311 }
45312 }
45313 DataType::Text => "TEXT".to_string(),
45314 DataType::Date => "DATE".to_string(),
45315 DataType::Time { precision, .. } => {
45316 if let Some(p) = precision {
45317 format!("TIME({})", p)
45318 } else {
45319 "TIME".to_string()
45320 }
45321 }
45322 DataType::Timestamp { precision, .. } => {
45323 if let Some(p) = precision {
45324 format!("TIMESTAMP({})", p)
45325 } else {
45326 "TIMESTAMP".to_string()
45327 }
45328 }
45329 DataType::Binary { length } => {
45330 if let Some(n) = length {
45331 format!("BINARY({})", n)
45332 } else {
45333 "BINARY".to_string()
45334 }
45335 }
45336 DataType::VarBinary { length } => {
45337 if let Some(n) = length {
45338 format!("VARBINARY({})", n)
45339 } else {
45340 "VARBINARY".to_string()
45341 }
45342 }
45343 DataType::Blob => "BLOB".to_string(),
45344 DataType::String { length: Some(n) } => format!("STRING({})", n),
45345 DataType::String { length: None } => "STRING".to_string(),
45346 DataType::Json => "JSON".to_string(),
45347 DataType::Uuid => "UUID".to_string(),
45348 DataType::Custom { name } => name.clone(), _ => format!("{:?}", dt), }
45351 }
45352
45353 #[allow(unused_variables, unused_mut)]
45358 pub fn parse_decode(&mut self) -> Result<Option<Expression>> {
45359 let mut args: Vec<Expression> = Vec::new();
45361 loop {
45362 match self.parse_expression() {
45363 Ok(expr) => args.push(expr),
45364 Err(_) => break,
45365 }
45366 if !self.match_token(TokenType::Comma) {
45367 break;
45368 }
45369 }
45370
45371 if args.len() < 3 {
45372 return Ok(Some(Expression::DecodeCase(Box::new(DecodeCase {
45374 expressions: args,
45375 }))));
45376 }
45377
45378 Ok(Some(Expression::DecodeCase(Box::new(DecodeCase {
45381 expressions: args,
45382 }))))
45383 }
45384
45385 #[allow(unused_variables, unused_mut)]
45388 pub fn parse_definer(&mut self) -> Result<Option<Expression>> {
45389 self.match_token(TokenType::Eq);
45391
45392 let user = self.parse_id_var()?;
45394 if user.is_none() {
45395 return Ok(None);
45396 }
45397
45398 if !self.match_token(TokenType::DAt) {
45400 return Ok(None);
45401 }
45402
45403 let host = if let Some(id) = self.parse_id_var()? {
45405 id
45406 } else if self.match_token(TokenType::Mod) {
45407 Expression::Identifier(Identifier::new(self.previous().text.clone()))
45409 } else {
45410 return Ok(None);
45411 };
45412
45413 let user_str = match &user {
45415 Some(Expression::Identifier(id)) => id.name.clone(),
45416 _ => "".to_string(),
45417 };
45418 let host_str = match &host {
45419 Expression::Identifier(id) => id.name.clone(),
45420 _ => "".to_string(),
45421 };
45422
45423 let definer_str = format!("{}@{}", user_str, host_str);
45424
45425 Ok(Some(Expression::DefinerProperty(Box::new(
45426 DefinerProperty {
45427 this: Box::new(Expression::Literal(Box::new(Literal::String(definer_str)))),
45428 },
45429 ))))
45430 }
45431
45432 #[allow(unused_variables, unused_mut)]
45434 pub fn parse_derived_table_values(&mut self) -> Result<Option<Expression>> {
45435 if self.match_text_seq(&["VALUES"]) {
45436 return Ok(Some(Expression::Values(Box::new(Values {
45437 expressions: Vec::new(),
45438 alias: None,
45439 column_aliases: Vec::new(),
45440 }))));
45441 }
45442 if self.match_text_seq(&["FORMAT", "VALUES"]) {
45443 return Ok(None);
45445 }
45446 Ok(None)
45447 }
45448
45449 #[allow(unused_variables, unused_mut)]
45453 pub fn parse_dict_property(&mut self, property_name: &str) -> Result<Option<Expression>> {
45454 if !self.match_token(TokenType::LParen) {
45456 return Ok(None);
45457 }
45458
45459 let kind_str = if self.is_identifier_token() || self.check_keyword() {
45462 self.advance().text.clone()
45463 } else {
45464 String::new()
45465 };
45466 if kind_str.is_empty() {
45467 return Err(self.parse_error("Expected dictionary property kind"));
45468 }
45469
45470 let settings = if self.match_token(TokenType::LParen) {
45472 let mut setting_pairs = Vec::new();
45473 loop {
45474 let key = if let Some(k) = self.parse_id_var()? {
45475 Some(k)
45476 } else if self.is_safe_keyword_as_identifier() || self.check_keyword() {
45477 let name = self.advance().text.clone();
45478 Some(Expression::Identifier(Identifier::new(name)))
45479 } else if !self.check(TokenType::RParen) && !self.check(TokenType::Comma) {
45480 let name = self.advance().text.clone();
45481 Some(Expression::Identifier(Identifier::new(name)))
45482 } else {
45483 None
45484 };
45485 let is_structure = key.as_ref().map_or(false, |k| {
45487 matches!(k, Expression::Identifier(id) if id.name.eq_ignore_ascii_case("STRUCTURE"))
45488 });
45489 let value = if is_structure && self.check(TokenType::LParen) {
45490 let mut raw = String::new();
45491 let mut depth = 0i32;
45492 while !self.is_at_end() {
45493 let tok = self.advance();
45494 match tok.token_type {
45495 TokenType::LParen => {
45496 depth += 1;
45497 raw.push('(');
45498 }
45499 TokenType::RParen => {
45500 depth -= 1;
45501 if depth == 0 {
45502 raw.push(')');
45503 break;
45504 }
45505 raw.push(')');
45506 }
45507 _ => {
45508 if !raw.is_empty() && !raw.ends_with('(') {
45509 raw.push(' ');
45510 }
45511 raw.push_str(&tok.text);
45512 }
45513 }
45514 }
45515 Some(Expression::Var(Box::new(Var { this: raw })))
45516 } else {
45517 self.parse_primary_or_var()?
45518 };
45519 if key.is_none() && value.is_none() {
45520 break;
45521 }
45522 if let (Some(k), Some(v)) = (key, value) {
45523 setting_pairs.push(Expression::Tuple(Box::new(Tuple {
45525 expressions: vec![k, v],
45526 })));
45527 }
45528 self.match_token(TokenType::Comma);
45532 if self.check(TokenType::RParen) {
45534 break;
45535 }
45536 }
45537 self.expect(TokenType::RParen)?;
45538 if !setting_pairs.is_empty() {
45539 Some(Box::new(Expression::Tuple(Box::new(Tuple {
45540 expressions: setting_pairs,
45541 }))))
45542 } else {
45543 None
45544 }
45545 } else {
45546 None
45547 };
45548
45549 self.expect(TokenType::RParen)?;
45550
45551 Ok(Some(Expression::DictProperty(Box::new(DictProperty {
45552 this: Box::new(Expression::Identifier(Identifier::new(
45553 property_name.to_string(),
45554 ))),
45555 kind: kind_str,
45556 settings,
45557 }))))
45558 }
45559
45560 pub fn parse_dict_range(&mut self, property_name: &str) -> Result<Option<Expression>> {
45563 self.expect(TokenType::LParen)?;
45565
45566 let parse_bound = |parser: &mut Parser| -> Result<Option<Expression>> {
45569 if parser.check(TokenType::Dash)
45571 && parser
45572 .peek_nth(1)
45573 .is_some_and(|t| t.token_type == TokenType::Number)
45574 {
45575 parser.advance(); let num = parser.advance().text.clone();
45577 return Ok(Some(Expression::Literal(Box::new(Literal::Number(
45578 format!("-{}", num),
45579 )))));
45580 }
45581 if let Some(id) = parser.parse_id_var()? {
45582 return Ok(Some(id));
45583 }
45584 parser.parse_primary_or_var()
45585 };
45586
45587 let (min_val, max_val) = if self.peek().text.eq_ignore_ascii_case("MIN") {
45588 self.skip(); let min = parse_bound(self)?;
45590 if self.peek().text.eq_ignore_ascii_case("MAX") {
45591 self.skip(); }
45593 let max = parse_bound(self)?;
45594 (min, max)
45595 } else {
45596 let max = parse_bound(self)?;
45597 let min = Some(Expression::Literal(Box::new(Literal::Number(
45598 "0".to_string(),
45599 ))));
45600 (min, max)
45601 };
45602
45603 self.expect(TokenType::RParen)?;
45605
45606 Ok(Some(Expression::DictRange(Box::new(DictRange {
45607 this: Box::new(Expression::Var(Box::new(Var {
45608 this: property_name.to_string(),
45609 }))),
45610 min: min_val.map(Box::new),
45611 max: max_val.map(Box::new),
45612 }))))
45613 }
45614
45615 pub fn parse_disjunction(&mut self) -> Result<Option<Expression>> {
45619 match self.parse_or() {
45620 Ok(expr) => Ok(Some(expr)),
45621 Err(_) => Ok(None),
45622 }
45623 }
45624
45625 #[allow(unused_variables, unused_mut)]
45628 pub fn parse_distkey(&mut self) -> Result<Option<Expression>> {
45629 if !self.match_token(TokenType::LParen) {
45631 return Ok(None);
45632 }
45633
45634 let column = self.parse_id_var()?;
45635 if column.is_none() {
45636 return Ok(None);
45637 }
45638
45639 self.match_token(TokenType::RParen);
45640
45641 Ok(Some(Expression::DistKeyProperty(Box::new(
45642 DistKeyProperty {
45643 this: Box::new(column.unwrap()),
45644 },
45645 ))))
45646 }
45647
45648 #[allow(unused_variables, unused_mut)]
45650 pub fn parse_distributed_property(&mut self) -> Result<Option<Expression>> {
45653 let mut kind = "HASH".to_string();
45654 let mut expressions = Vec::new();
45655
45656 if self.match_text_seq(&["BY", "HASH"]) {
45657 if let Some(wrapped) = self.parse_wrapped_id_vars()? {
45659 if let Expression::Tuple(t) = wrapped {
45660 expressions = t.expressions;
45661 }
45662 }
45663 } else if self.match_text_seq(&["BY", "RANDOM"]) {
45664 kind = "RANDOM".to_string();
45665 } else {
45666 return Ok(None);
45667 }
45668
45669 let buckets = if self.match_text_seq(&["BUCKETS"]) {
45671 if !self.match_text_seq(&["AUTO"]) {
45672 self.parse_number()?
45673 } else {
45674 None
45675 }
45676 } else {
45677 None
45678 };
45679
45680 let order = self.parse_order()?;
45682
45683 Ok(Some(Expression::DistributedByProperty(Box::new(
45684 DistributedByProperty {
45685 expressions,
45686 kind,
45687 buckets: buckets.map(Box::new),
45688 order: order.map(Box::new),
45689 },
45690 ))))
45691 }
45692
45693 pub fn parse_drop_column(&mut self) -> Result<Option<Expression>> {
45696 self.match_token(TokenType::Column);
45698
45699 let _if_exists = self.match_keywords(&[TokenType::If, TokenType::Exists]);
45701
45702 if let Some(column) = self.parse_identifier()? {
45704 let _cascade = self.match_text_seq(&["CASCADE"]);
45706 Ok(Some(column))
45708 } else {
45709 Ok(None)
45710 }
45711 }
45712
45713 pub fn parse_drop_partition(&mut self) -> Result<Option<Expression>> {
45716 self.parse_drop_partition_with_exists(false)
45717 }
45718
45719 pub fn parse_drop_partition_with_exists(&mut self, exists: bool) -> Result<Option<Expression>> {
45721 let mut partitions = Vec::new();
45723
45724 loop {
45725 if self.match_token(TokenType::Partition) {
45727 if self.match_token(TokenType::LParen) {
45728 let mut exprs = Vec::new();
45730 loop {
45731 let expr = self.parse_expression()?;
45732 exprs.push(expr);
45733 if !self.match_token(TokenType::Comma) {
45734 break;
45735 }
45736 }
45737 self.match_token(TokenType::RParen);
45738 partitions.push(Expression::Tuple(Box::new(Tuple { expressions: exprs })));
45739 }
45740 } else {
45741 break;
45742 }
45743
45744 if !self.match_token(TokenType::Comma) {
45745 break;
45746 }
45747 }
45748
45749 if partitions.is_empty() {
45750 Ok(None)
45751 } else {
45752 Ok(Some(Expression::DropPartition(Box::new(DropPartition {
45753 expressions: partitions,
45754 exists,
45755 }))))
45756 }
45757 }
45758
45759 pub fn parse_equality(&mut self) -> Result<Option<Expression>> {
45763 match self.parse_comparison() {
45764 Ok(expr) => Ok(Some(expr)),
45765 Err(_) => Ok(None),
45766 }
45767 }
45768
45769 pub fn parse_escape(&mut self) -> Result<Option<Expression>> {
45773 if !self.match_token(TokenType::Escape) {
45774 return Ok(None);
45775 }
45776
45777 if let Some(escape_char) = self.parse_string()? {
45779 return Ok(Some(escape_char));
45780 }
45781
45782 if let Some(null_expr) = self.parse_null()? {
45784 return Ok(Some(null_expr));
45785 }
45786
45787 Ok(None)
45788 }
45789
45790 #[allow(unused_variables, unused_mut)]
45792 pub fn parse_exists(&mut self) -> Result<Option<Expression>> {
45793 if self.match_text_seq(&["IF"]) {
45794 return Ok(None);
45796 }
45797 Ok(None)
45798 }
45799
45800 pub fn parse_exponent(&mut self) -> Result<Option<Expression>> {
45804 match self.parse_unary() {
45805 Ok(expr) => Ok(Some(expr)),
45806 Err(_) => Ok(None),
45807 }
45808 }
45809
45810 #[allow(unused_variables, unused_mut)]
45813 pub fn parse_expressions(&mut self) -> Result<Option<Expression>> {
45814 let expressions = self.parse_expression_list()?;
45815 if expressions.is_empty() {
45816 return Ok(None);
45817 }
45818 if expressions.len() == 1 {
45819 return Ok(expressions.into_iter().next());
45820 }
45821 Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))))
45822 }
45823
45824 #[allow(unused_variables, unused_mut)]
45827 pub fn parse_extract(&mut self) -> Result<Option<Expression>> {
45828 let field_name = if self.check(TokenType::Identifier) || self.check(TokenType::Var) {
45830 let token = self.advance();
45831 token.text.to_ascii_uppercase()
45832 } else {
45833 return Ok(None);
45834 };
45835
45836 let field = match field_name.as_str() {
45838 "YEAR" => DateTimeField::Year,
45839 "MONTH" => DateTimeField::Month,
45840 "DAY" => DateTimeField::Day,
45841 "HOUR" => DateTimeField::Hour,
45842 "MINUTE" => DateTimeField::Minute,
45843 "SECOND" => DateTimeField::Second,
45844 "MILLISECOND" | "MILLISECONDS" | "MS" => DateTimeField::Millisecond,
45845 "MICROSECOND" | "MICROSECONDS" | "US" => DateTimeField::Microsecond,
45846 "DOW" | "DAYOFWEEK" => DateTimeField::DayOfWeek,
45847 "DOY" | "DAYOFYEAR" => DateTimeField::DayOfYear,
45848 "WEEK" => DateTimeField::Week,
45849 "QUARTER" => DateTimeField::Quarter,
45850 "EPOCH" => DateTimeField::Epoch,
45851 "TIMEZONE" => DateTimeField::Timezone,
45852 "TIMEZONE_HOUR" => DateTimeField::TimezoneHour,
45853 "TIMEZONE_MINUTE" => DateTimeField::TimezoneMinute,
45854 "DATE" => DateTimeField::Date,
45855 "TIME" => DateTimeField::Time,
45856 other => DateTimeField::Custom(other.to_string()),
45857 };
45858
45859 if !self.match_token(TokenType::From) && !self.match_token(TokenType::Comma) {
45861 return Err(self.parse_error("Expected FROM or comma after EXTRACT field"));
45862 }
45863
45864 let expression = self.parse_bitwise()?;
45866 let this = match expression {
45867 Some(expr) => self.try_clickhouse_func_arg_alias(expr),
45868 None => return Err(self.parse_error("Expected expression after FROM in EXTRACT")),
45869 };
45870
45871 Ok(Some(Expression::Extract(Box::new(ExtractFunc {
45872 this,
45873 field,
45874 }))))
45875 }
45876
45877 pub fn parse_factor(&mut self) -> Result<Option<Expression>> {
45881 match self.parse_multiplication() {
45883 Ok(expr) => Ok(Some(expr)),
45884 Err(_) => Ok(None),
45885 }
45886 }
45887
45888 #[allow(unused_variables, unused_mut)]
45890 pub fn parse_fallback(&mut self) -> Result<Option<Expression>> {
45891 if self.match_text_seq(&["PROTECTION"]) {
45892 return Ok(Some(Expression::FallbackProperty(Box::new(
45893 FallbackProperty {
45894 no: None,
45895 protection: None,
45896 },
45897 ))));
45898 }
45899 Ok(None)
45900 }
45901
45902 pub fn parse_field(&mut self) -> Result<Option<Expression>> {
45905 if let Some(expr) = self.parse_string()? {
45907 return Ok(Some(expr));
45908 }
45909 if let Some(expr) = self.parse_number()? {
45910 return Ok(Some(expr));
45911 }
45912 if let Some(expr) = self.parse_boolean()? {
45913 return Ok(Some(expr));
45914 }
45915 if let Some(expr) = self.parse_null()? {
45916 return Ok(Some(expr));
45917 }
45918 if let Some(expr) = self.parse_star()? {
45919 return Ok(Some(expr));
45920 }
45921 if let Some(expr) = self.parse_identifier()? {
45923 return Ok(Some(expr));
45924 }
45925 if let Some(expr) = self.parse_var()? {
45927 return Ok(Some(expr));
45928 }
45929 if self.check_keyword() {
45931 let token = self.advance();
45932 return Ok(Some(Expression::Identifier(Identifier {
45933 name: token.text,
45934 quoted: false,
45935 trailing_comments: Vec::new(),
45936 span: None,
45937 })));
45938 }
45939 Ok(None)
45940 }
45941
45942 #[allow(unused_variables, unused_mut)]
45945 pub fn parse_field_def(&mut self) -> Result<Option<Expression>> {
45946 let field = self.parse_field()?;
45948
45949 if field.is_none() {
45950 return Ok(None);
45951 }
45952
45953 self.parse_column_def_with_field(field)
45955 }
45956
45957 fn parse_column_def_with_field(
45959 &mut self,
45960 field: Option<Expression>,
45961 ) -> Result<Option<Expression>> {
45962 if field.is_none() {
45963 return Ok(None);
45964 }
45965
45966 let this = field.unwrap();
45967
45968 let name_ident = match &this {
45970 Expression::Column(col) => col.name.clone(),
45971 Expression::Identifier(id) => id.clone(),
45972 Expression::Var(v) => Identifier::new(v.this.clone()),
45973 _ => return Ok(None),
45974 };
45975
45976 let data_type = match self.parse_data_type_optional()? {
45978 Some(dt) => dt,
45979 None => DataType::Unknown,
45980 };
45981
45982 let mut col_def = ColumnDef::new(name_ident.name.clone(), data_type);
45984 col_def.name = name_ident;
45985
45986 if self.match_text_seq(&["FOR", "ORDINALITY"]) {
45988 return Ok(Some(Expression::ColumnDef(Box::new(col_def))));
45989 }
45990
45991 loop {
45993 if let Some(constraint) = self.parse_column_constraint()? {
45994 match &constraint {
45996 Expression::NotNullColumnConstraint(_) => {
45997 col_def.nullable = Some(false);
45998 col_def.constraints.push(ColumnConstraint::NotNull);
45999 }
46000 Expression::PrimaryKeyColumnConstraint(_) => {
46001 col_def.primary_key = true;
46002 col_def.constraints.push(ColumnConstraint::PrimaryKey);
46003 }
46004 Expression::UniqueColumnConstraint(_) => {
46005 col_def.unique = true;
46006 col_def.constraints.push(ColumnConstraint::Unique);
46007 }
46008 Expression::DefaultColumnConstraint(dc) => {
46009 col_def.default = Some((*dc.this).clone());
46010 col_def
46011 .constraints
46012 .push(ColumnConstraint::Default((*dc.this).clone()));
46013 }
46014 Expression::AutoIncrementColumnConstraint(_) => {
46015 col_def.auto_increment = true;
46016 }
46017 Expression::CommentColumnConstraint(_) => {
46018 }
46020 Expression::CheckColumnConstraint(cc) => {
46021 col_def
46022 .constraints
46023 .push(ColumnConstraint::Check((*cc.this).clone()));
46024 }
46025 Expression::PathColumnConstraint(pc) => {
46026 col_def
46027 .constraints
46028 .push(ColumnConstraint::Path((*pc.this).clone()));
46029 col_def.constraint_order.push(ConstraintType::Path);
46030 }
46031 _ => {}
46032 }
46033 } else if matches!(
46034 self.config.dialect,
46035 Some(crate::dialects::DialectType::ClickHouse)
46036 ) && self.match_identifier("ALIAS")
46037 {
46038 let expr = self.parse_or()?;
46040 col_def.alias_expr = Some(Box::new(expr));
46041 } else if matches!(
46042 self.config.dialect,
46043 Some(crate::dialects::DialectType::ClickHouse)
46044 ) && self.check(TokenType::Materialized)
46045 && !self.check_next(TokenType::View)
46046 {
46047 self.skip(); let expr = self.parse_or()?;
46050 col_def.materialized_expr = Some(Box::new(expr));
46051 } else if matches!(
46052 self.config.dialect,
46053 Some(crate::dialects::DialectType::ClickHouse)
46054 ) && self.match_identifier("EPHEMERAL")
46055 {
46056 if !self.check(TokenType::Comma)
46058 && !self.check(TokenType::RParen)
46059 && !self.is_at_end()
46060 && !self.check_identifier("CODEC")
46061 && !self.check_identifier("TTL")
46062 && !self.check(TokenType::Comment)
46063 {
46064 let expr = self.parse_bitwise()?.unwrap_or(Expression::Null(Null));
46065 col_def.ephemeral = Some(Some(Box::new(expr)));
46066 } else {
46067 col_def.ephemeral = Some(None);
46068 }
46069 } else if matches!(
46070 self.config.dialect,
46071 Some(crate::dialects::DialectType::ClickHouse)
46072 ) && self.check_identifier("CODEC")
46073 {
46074 self.skip(); self.expect(TokenType::LParen)?;
46077 let start = self.current;
46078 let mut depth = 1;
46079 while !self.is_at_end() && depth > 0 {
46080 if self.check(TokenType::LParen) {
46081 depth += 1;
46082 }
46083 if self.check(TokenType::RParen) {
46084 depth -= 1;
46085 if depth == 0 {
46086 break;
46087 }
46088 }
46089 self.skip();
46090 }
46091 let codec_text = self.tokens_to_sql(start, self.current);
46092 self.expect(TokenType::RParen)?;
46093 col_def.codec = Some(codec_text);
46094 } else if matches!(
46095 self.config.dialect,
46096 Some(crate::dialects::DialectType::ClickHouse)
46097 ) && self.match_identifier("TTL")
46098 {
46099 let expr = self.parse_expression()?;
46101 col_def.ttl_expr = Some(Box::new(expr));
46102 } else {
46103 break;
46104 }
46105 }
46106
46107 Ok(Some(Expression::ColumnDef(Box::new(col_def))))
46108 }
46109
46110 #[allow(unused_variables, unused_mut)]
46113 pub fn parse_foreign_key(&mut self) -> Result<Option<Expression>> {
46114 if self.match_text_seq(&["NO", "ACTION"]) {
46115 return Ok(Some(Expression::ForeignKey(Box::new(ForeignKey {
46116 expressions: Vec::new(),
46117 reference: None,
46118 delete: None,
46119 update: None,
46120 options: Vec::new(),
46121 }))));
46122 }
46123 Ok(None)
46124 }
46125
46126 #[allow(unused_variables, unused_mut)]
46128 pub fn parse_format_json(&mut self) -> Result<Option<Expression>> {
46129 if self.match_text_seq(&["FORMAT", "JSON"]) {
46130 return Ok(None);
46132 }
46133 Ok(None)
46134 }
46135
46136 #[allow(unused_variables, unused_mut)]
46139 pub fn parse_format_name(&mut self) -> Result<Option<Expression>> {
46140 let value = if let Some(s) = self.parse_string()? {
46142 s
46143 } else if let Some(tp) = self.parse_table_parts()? {
46144 tp
46145 } else {
46146 return Ok(None);
46147 };
46148
46149 Ok(Some(Expression::Property(Box::new(Property {
46150 this: Box::new(Expression::Identifier(Identifier::new(
46151 "FORMAT_NAME".to_string(),
46152 ))),
46153 value: Some(Box::new(value)),
46154 }))))
46155 }
46156
46157 #[allow(unused_variables, unused_mut)]
46160 pub fn parse_freespace(&mut self) -> Result<Option<Expression>> {
46161 self.match_token(TokenType::Eq);
46163
46164 let this = self.parse_number()?;
46166 if this.is_none() {
46167 return Ok(None);
46168 }
46169
46170 let percent = if self.match_token(TokenType::Percent) {
46172 Some(Box::new(Expression::Boolean(BooleanLiteral {
46173 value: true,
46174 })))
46175 } else {
46176 None
46177 };
46178
46179 Ok(Some(Expression::FreespaceProperty(Box::new(
46180 FreespaceProperty {
46181 this: Box::new(this.unwrap()),
46182 percent,
46183 },
46184 ))))
46185 }
46186
46187 pub fn parse_function(&mut self) -> Result<Option<Expression>> {
46190 let fn_syntax = if self.check(TokenType::LBrace) {
46192 if let Some(next) = self.tokens.get(self.current + 1) {
46193 if next.text.eq_ignore_ascii_case("FN") {
46194 self.skip(); self.skip(); true
46197 } else {
46198 false
46199 }
46200 } else {
46201 false
46202 }
46203 } else {
46204 false
46205 };
46206
46207 let func = self.parse_function_call()?;
46208
46209 if fn_syntax {
46210 self.match_token(TokenType::RBrace);
46211 }
46212
46213 Ok(func)
46214 }
46215
46216 pub fn parse_function_args_list(&mut self) -> Result<Vec<Expression>> {
46219 let mut args = Vec::new();
46220
46221 if self.check(TokenType::RParen) {
46222 return Ok(args);
46223 }
46224
46225 loop {
46226 if let Some(expr) = self.parse_assignment()? {
46228 if self.match_token(TokenType::As) {
46230 let alias_token = self.advance();
46231 let alias_name = if alias_token.token_type == TokenType::QuotedIdentifier {
46232 let raw = alias_token.text.clone();
46234 let mut ident = Identifier::new(raw);
46235 ident.quoted = true;
46236 ident
46237 } else {
46238 Identifier::new(alias_token.text.clone())
46239 };
46240 args.push(Expression::Alias(Box::new(crate::expressions::Alias {
46241 this: expr,
46242 alias: alias_name,
46243 column_aliases: Vec::new(),
46244 pre_alias_comments: Vec::new(),
46245 trailing_comments: Vec::new(),
46246 inferred_type: None,
46247 })));
46248 } else {
46249 args.push(expr);
46250 }
46251 }
46252
46253 if !self.match_token(TokenType::Comma) {
46254 break;
46255 }
46256 }
46257
46258 Ok(args)
46259 }
46260
46261 pub fn parse_function_call(&mut self) -> Result<Option<Expression>> {
46264 if self.is_at_end() {
46265 return Ok(None);
46266 }
46267
46268 let token = self.peek().clone();
46269 let token_type = token.token_type.clone();
46270 let name = token.text.clone();
46271 let _upper_name = name.to_ascii_uppercase();
46272
46273 if self.is_no_paren_function() {
46275 if !self.check_next(TokenType::LParen) {
46277 self.skip();
46278 return Ok(Some(Expression::Function(Box::new(Function {
46279 name, args: Vec::new(),
46281 distinct: false,
46282 trailing_comments: Vec::new(),
46283 use_bracket_syntax: false,
46284 no_parens: true,
46285 quoted: false,
46286 span: None,
46287 inferred_type: None,
46288 }))));
46289 }
46290 }
46291
46292 if !self.check_next(TokenType::LParen) {
46294 return Ok(None);
46295 }
46296
46297 let is_valid_func_token = matches!(
46299 token_type,
46300 TokenType::Identifier
46301 | TokenType::Var
46302 | TokenType::If
46303 | TokenType::Left
46304 | TokenType::Right
46305 | TokenType::Insert
46306 | TokenType::Replace
46307 | TokenType::Row
46308 | TokenType::Index
46309 );
46310 if !is_valid_func_token {
46311 return Ok(None);
46312 }
46313
46314 self.skip(); self.skip(); let distinct = self.match_token(TokenType::Distinct);
46319
46320 let args = self.parse_function_args_list()?;
46322
46323 self.match_token(TokenType::RParen);
46324
46325 let func_expr = Expression::Function(Box::new(Function {
46327 name, args,
46329 distinct,
46330 trailing_comments: Vec::new(),
46331 use_bracket_syntax: false,
46332 no_parens: false,
46333 quoted: false,
46334 span: None,
46335 inferred_type: None,
46336 }));
46337
46338 if self.match_token(TokenType::Over) {
46340 if self.match_token(TokenType::LParen) {
46342 let spec = self.parse_window_spec_inner()?;
46344 self.expect(TokenType::RParen)?;
46345
46346 if let Some(spec_expr) = spec {
46347 return Ok(Some(spec_expr));
46348 }
46349 }
46350 }
46351
46352 Ok(Some(func_expr))
46353 }
46354
46355 pub fn parse_function_parameter(&mut self) -> Result<Option<Expression>> {
46358 let _mode = if self.match_texts(&["IN"]) {
46360 if self.match_texts(&["OUT"]) {
46361 Some(ParameterMode::InOut)
46362 } else {
46363 Some(ParameterMode::In)
46364 }
46365 } else if self.match_texts(&["OUT"]) {
46366 Some(ParameterMode::Out)
46367 } else if self.match_texts(&["INOUT"]) {
46368 Some(ParameterMode::InOut)
46369 } else {
46370 None
46371 };
46372
46373 let name_expr = self.parse_id_var()?;
46375 let name = name_expr.and_then(|n| match n {
46376 Expression::Identifier(id) => Some(id),
46377 _ => None,
46378 });
46379
46380 let data_type_result = self.parse_data_type();
46383 let _data_type = match data_type_result {
46384 Ok(dt) => dt,
46385 Err(_) => return Ok(None),
46386 };
46387
46388 let _default = if self.match_token(TokenType::Default) || self.match_texts(&["="]) {
46390 self.parse_disjunction()?
46391 } else {
46392 None
46393 };
46394
46395 Ok(Some(Expression::boxed_column(Column {
46397 name: Identifier {
46398 name: name.map(|n| n.name).unwrap_or_default(),
46399 quoted: false,
46400 trailing_comments: Vec::new(),
46401 span: None,
46402 },
46403 table: None,
46404 join_mark: false,
46405 trailing_comments: Vec::new(),
46406 span: None,
46407 inferred_type: None,
46408 })))
46409 }
46410
46411 #[allow(unused_variables, unused_mut)]
46413 pub fn parse_gap_fill(&mut self) -> Result<Option<Expression>> {
46416 self.match_token(TokenType::Table);
46418
46419 let this = self.parse_table()?;
46421 if this.is_none() {
46422 return Ok(None);
46423 }
46424
46425 self.match_token(TokenType::Comma);
46427 let mut args = self.parse_expression_list()?;
46428
46429 let ts_column = args.get(0).cloned().map(Box::new);
46431 let bucket_width = args.get(1).cloned().map(Box::new);
46432 let partitioning_columns = args.get(2).cloned().map(Box::new);
46433 let value_columns = args.get(3).cloned().map(Box::new);
46434
46435 Ok(Some(Expression::GapFill(Box::new(GapFill {
46436 this: Box::new(this.unwrap()),
46437 ts_column,
46438 bucket_width,
46439 partitioning_columns,
46440 value_columns,
46441 origin: None,
46442 ignore_nulls: None,
46443 }))))
46444 }
46445
46446 pub fn parse_semantic_view(&mut self) -> Result<Expression> {
46449 let this = self.parse_primary()?;
46451
46452 let mut metrics = None;
46453 let mut dimensions = None;
46454 let mut facts = None;
46455 let mut where_clause = None;
46456
46457 while !self.check(TokenType::RParen) && !self.is_at_end() {
46459 if self.match_identifier("METRICS") {
46460 let exprs = self.parse_semantic_view_list()?;
46462 metrics = Some(Box::new(Expression::Tuple(Box::new(Tuple {
46463 expressions: exprs,
46464 }))));
46465 } else if self.match_identifier("DIMENSIONS") {
46466 let exprs = self.parse_semantic_view_list()?;
46467 dimensions = Some(Box::new(Expression::Tuple(Box::new(Tuple {
46468 expressions: exprs,
46469 }))));
46470 } else if self.match_identifier("FACTS") {
46471 let exprs = self.parse_semantic_view_list()?;
46472 facts = Some(Box::new(Expression::Tuple(Box::new(Tuple {
46473 expressions: exprs,
46474 }))));
46475 } else if self.match_token(TokenType::Where) {
46476 where_clause = Some(Box::new(self.parse_expression()?));
46478 break;
46480 } else {
46481 break;
46483 }
46484 }
46485
46486 Ok(Expression::SemanticView(Box::new(SemanticView {
46487 this: Box::new(this),
46488 metrics,
46489 dimensions,
46490 facts,
46491 where_: where_clause,
46492 })))
46493 }
46494
46495 fn parse_semantic_view_list(&mut self) -> Result<Vec<Expression>> {
46499 let first = self.parse_semantic_view_element()?;
46500 let mut exprs = vec![first];
46501 while self.match_token(TokenType::Comma) {
46502 if self.check_identifier("METRICS")
46504 || self.check_identifier("DIMENSIONS")
46505 || self.check_identifier("FACTS")
46506 || self.check(TokenType::Where)
46507 || self.check(TokenType::RParen)
46508 {
46509 break;
46510 }
46511 exprs.push(self.parse_semantic_view_element()?);
46512 }
46513 Ok(exprs)
46514 }
46515
46516 fn parse_semantic_view_element(&mut self) -> Result<Expression> {
46518 let expr = self
46519 .parse_disjunction()?
46520 .ok_or_else(|| self.parse_error("Expected expression in SEMANTIC_VIEW clause"))?;
46521 if self.match_token(TokenType::As) {
46523 let alias = self.expect_identifier_or_keyword_with_quoted()?;
46524 Ok(Expression::Alias(Box::new(crate::expressions::Alias {
46525 this: expr,
46526 alias,
46527 column_aliases: Vec::new(),
46528 pre_alias_comments: Vec::new(),
46529 trailing_comments: Vec::new(),
46530 inferred_type: None,
46531 })))
46532 } else {
46533 Ok(expr)
46534 }
46535 }
46536
46537 #[allow(unused_variables, unused_mut)]
46540 pub fn parse_grant_principal(&mut self) -> Result<Option<Expression>> {
46541 if self.match_texts(&["ROLE", "GROUP"]) {
46542 return Ok(None);
46544 }
46545 Ok(None)
46546 }
46547
46548 #[allow(unused_variables, unused_mut)]
46551 pub fn parse_grant_privilege(&mut self) -> Result<Option<Expression>> {
46552 let mut privilege_parts = Vec::new();
46554
46555 while !self.is_at_end() {
46558 if self.check(TokenType::Comma)
46560 || self.check(TokenType::On)
46561 || self.check(TokenType::LParen)
46562 {
46563 break;
46564 }
46565
46566 let text = self.peek().text.to_ascii_uppercase();
46568 privilege_parts.push(text);
46569 self.skip();
46570 }
46571
46572 if privilege_parts.is_empty() {
46573 return Ok(None);
46574 }
46575
46576 let privilege_str = privilege_parts.join(" ");
46577
46578 let expressions = if self.match_token(TokenType::LParen) {
46580 let mut columns = Vec::new();
46581 loop {
46582 if let Some(col) = self.parse_column()? {
46583 columns.push(col);
46584 } else {
46585 break;
46586 }
46587 if !self.match_token(TokenType::Comma) {
46588 break;
46589 }
46590 }
46591 self.match_token(TokenType::RParen);
46592 columns
46593 } else {
46594 Vec::new()
46595 };
46596
46597 Ok(Some(Expression::GrantPrivilege(Box::new(GrantPrivilege {
46598 this: Box::new(Expression::Identifier(Identifier::new(privilege_str))),
46599 expressions,
46600 }))))
46601 }
46602
46603 pub fn parse_grant_revoke_common(&mut self) -> Result<Option<Expression>> {
46607 let mut privileges = Vec::new();
46609 loop {
46610 if let Some(priv_expr) = self.parse_grant_privilege()? {
46611 privileges.push(priv_expr);
46612 }
46613 if !self.match_token(TokenType::Comma) {
46614 break;
46615 }
46616 }
46617
46618 self.match_token(TokenType::On);
46620
46621 let kind = if self.match_texts(&[
46623 "TABLE",
46624 "VIEW",
46625 "SCHEMA",
46626 "DATABASE",
46627 "SEQUENCE",
46628 "FUNCTION",
46629 "PROCEDURE",
46630 "INDEX",
46631 "TYPE",
46632 "TABLESPACE",
46633 "ROLE",
46634 "USER",
46635 ]) {
46636 let kind_text = self.previous().text.to_ascii_uppercase();
46637 Some(Expression::Var(Box::new(Var { this: kind_text })))
46638 } else {
46639 None
46640 };
46641
46642 let securable = self.parse_table_parts()?;
46644
46645 let privileges_expr = Expression::Tuple(Box::new(Tuple {
46647 expressions: privileges,
46648 }));
46649
46650 let mut result_exprs = vec![privileges_expr];
46651
46652 if let Some(k) = kind {
46653 result_exprs.push(k);
46654 } else {
46655 result_exprs.push(Expression::Null(Null));
46656 }
46657
46658 if let Some(s) = securable {
46659 result_exprs.push(s);
46660 } else {
46661 result_exprs.push(Expression::Null(Null));
46662 }
46663
46664 Ok(Some(Expression::Tuple(Box::new(Tuple {
46665 expressions: result_exprs,
46666 }))))
46667 }
46668
46669 pub fn parse_group(&mut self) -> Result<Option<Expression>> {
46672 if !self.match_token(TokenType::Group) {
46674 return Ok(None);
46675 }
46676 self.match_token(TokenType::By);
46678
46679 let all = if self.match_token(TokenType::All) {
46682 Some(true)
46683 } else if self.match_token(TokenType::Distinct) {
46684 Some(false)
46685 } else {
46686 None
46687 };
46688
46689 let mut expressions = Vec::new();
46691 loop {
46692 match self.parse_expression() {
46693 Ok(expr) => expressions.push(expr),
46694 Err(_) => break,
46695 }
46696 if !self.match_token(TokenType::Comma) {
46697 break;
46698 }
46699 }
46700
46701 let totals = if self.match_text_seq(&["WITH", "TOTALS"]) {
46703 Some(Box::new(Expression::Boolean(BooleanLiteral {
46704 value: true,
46705 })))
46706 } else if self.match_text_seq(&["TOTALS"]) {
46707 Some(Box::new(Expression::Boolean(BooleanLiteral {
46708 value: true,
46709 })))
46710 } else {
46711 None
46712 };
46713
46714 Ok(Some(Expression::Group(Box::new(Group {
46715 expressions,
46716 grouping_sets: None,
46717 cube: None,
46718 rollup: None,
46719 totals,
46720 all,
46721 }))))
46722 }
46723
46724 #[allow(unused_variables, unused_mut)]
46726 pub fn parse_group_concat(&mut self) -> Result<Option<Expression>> {
46729 let distinct = self.match_token(TokenType::Distinct);
46731
46732 let expr = self.parse_expression()?;
46734
46735 let order_by = if self.match_keywords(&[TokenType::Order, TokenType::By]) {
46737 let mut orderings = Vec::new();
46738 loop {
46739 let order_expr = self.parse_expression()?;
46740 let desc = if self.match_token(TokenType::Desc) {
46741 true
46742 } else {
46743 self.match_token(TokenType::Asc);
46744 false
46745 };
46746 let nulls_first = if self.match_keywords(&[TokenType::Nulls, TokenType::First]) {
46747 Some(true)
46748 } else if self.match_keywords(&[TokenType::Nulls, TokenType::Last]) {
46749 Some(false)
46750 } else {
46751 None
46752 };
46753 orderings.push(Ordered {
46754 this: order_expr,
46755 desc,
46756 nulls_first,
46757 explicit_asc: !desc,
46758 with_fill: None,
46759 });
46760 if !self.match_token(TokenType::Comma) {
46761 break;
46762 }
46763 }
46764 Some(orderings)
46765 } else {
46766 None
46767 };
46768
46769 let separator = if self.match_token(TokenType::Separator) {
46771 self.parse_string()?
46772 } else {
46773 None
46774 };
46775
46776 Ok(Some(Expression::GroupConcat(Box::new(GroupConcatFunc {
46777 this: expr,
46778 separator,
46779 order_by,
46780 distinct,
46781 filter: None,
46782 inferred_type: None,
46783 }))))
46784 }
46785
46786 #[allow(unused_variables, unused_mut)]
46788 pub fn parse_grouping_set(&mut self) -> Result<Option<Expression>> {
46789 self.parse_grouping_sets()
46790 }
46791
46792 #[allow(unused_variables, unused_mut)]
46795 pub fn parse_grouping_sets(&mut self) -> Result<Option<Expression>> {
46796 if !self.match_text_seq(&["GROUPING", "SETS"]) {
46798 return Ok(None);
46799 }
46800
46801 self.expect(TokenType::LParen)?;
46803 let mut expressions = Vec::new();
46804
46805 if !self.check(TokenType::RParen) {
46806 loop {
46807 if let Some(nested) = self.parse_grouping_sets()? {
46813 expressions.push(nested);
46814 } else if let Some(cube_rollup) = self.parse_cube_or_rollup()? {
46815 expressions.push(cube_rollup);
46816 } else if self.match_token(TokenType::LParen) {
46817 let mut group = Vec::new();
46819 if !self.check(TokenType::RParen) {
46820 loop {
46821 match self.parse_bitwise() {
46822 Ok(Some(expr)) => group.push(expr),
46823 Ok(None) => break,
46824 Err(e) => return Err(e),
46825 }
46826 if !self.match_token(TokenType::Comma) {
46827 break;
46828 }
46829 }
46830 }
46831 self.expect(TokenType::RParen)?;
46832 expressions.push(Expression::Tuple(Box::new(Tuple { expressions: group })));
46833 } else {
46834 match self.parse_bitwise() {
46836 Ok(Some(expr)) => expressions.push(expr),
46837 Ok(None) => break,
46838 Err(e) => return Err(e),
46839 }
46840 }
46841
46842 if !self.match_token(TokenType::Comma) {
46843 break;
46844 }
46845 }
46846 }
46847
46848 self.expect(TokenType::RParen)?;
46849
46850 Ok(Some(Expression::GroupingSets(Box::new(GroupingSets {
46851 expressions,
46852 }))))
46853 }
46854
46855 pub fn parse_having(&mut self) -> Result<Option<Expression>> {
46858 if !self.match_token(TokenType::Having) {
46859 return Ok(None);
46860 }
46861 let condition = self.parse_expression()?;
46863 Ok(Some(Expression::Having(Box::new(Having {
46864 this: condition,
46865 comments: Vec::new(),
46866 }))))
46867 }
46868
46869 #[allow(unused_variables, unused_mut)]
46872 pub fn parse_having_max(&mut self) -> Result<Option<Expression>> {
46873 if self.match_texts(&["MAX", "MIN"]) {
46874 return Ok(None);
46876 }
46877 Ok(None)
46878 }
46879
46880 pub fn parse_heredoc(&mut self) -> Result<Option<Expression>> {
46883 if self.match_token(TokenType::HeredocString) {
46885 let text = self.previous().text.clone();
46886 return Ok(Some(Expression::Heredoc(Box::new(Heredoc {
46887 this: Box::new(Expression::Literal(Box::new(Literal::String(text)))),
46888 tag: None,
46889 }))));
46890 }
46891
46892 if !self.match_text_seq(&["$"]) {
46894 return Ok(None);
46895 }
46896
46897 let mut tags = vec!["$".to_string()];
46899 let mut tag_text: Option<String> = None;
46900
46901 if !self.is_at_end() {
46903 let next_text = self.peek().text.to_ascii_uppercase();
46904 if next_text == "$" {
46905 self.skip();
46907 tags.push("$".to_string());
46908 } else {
46909 self.skip();
46911 tag_text = Some(next_text.clone());
46912 tags.push(next_text);
46913
46914 if self.match_text_seq(&["$"]) {
46916 tags.push("$".to_string());
46917 } else {
46918 return Err(self.parse_error("No closing $ found"));
46919 }
46920 }
46921 }
46922
46923 let mut content_parts = Vec::new();
46925 let closing_tag = tags.join("");
46926
46927 while !self.is_at_end() {
46928 let current_text = self.peek().text.clone();
46930
46931 if current_text == "$" || current_text.eq_ignore_ascii_case(&closing_tag) {
46933 let start_pos = self.current;
46935 let mut matched = true;
46936 for expected in &tags {
46937 if self.is_at_end() || !self.peek().text.eq_ignore_ascii_case(expected) {
46938 matched = false;
46939 break;
46940 }
46941 self.skip();
46942 }
46943 if matched {
46944 let content = content_parts.join(" ");
46946 return Ok(Some(Expression::Heredoc(Box::new(Heredoc {
46947 this: Box::new(Expression::Literal(Box::new(Literal::String(content)))),
46948 tag: tag_text
46949 .map(|t| Box::new(Expression::Literal(Box::new(Literal::String(t))))),
46950 }))));
46951 }
46952 self.current = start_pos;
46954 }
46955
46956 content_parts.push(self.advance().text.clone());
46957 }
46958
46959 Err(self.parse_error(&format!("No closing {} found", closing_tag)))
46960 }
46961
46962 #[allow(unused_variables, unused_mut)]
46964 pub fn parse_hint_body(&mut self) -> Result<Option<Expression>> {
46965 self.parse_hint_fallback_to_string()
46966 }
46967
46968 pub fn parse_hint_fallback_to_string(&mut self) -> Result<Option<Expression>> {
46972 let mut parts = Vec::new();
46974 while !self.is_at_end() {
46975 let token = self.advance();
46976 parts.push(token.text.clone());
46977 }
46978
46979 if parts.is_empty() {
46980 return Ok(None);
46981 }
46982
46983 let hint_text = parts.join(" ");
46984 Ok(Some(Expression::Hint(Box::new(Hint {
46985 expressions: vec![HintExpression::Raw(hint_text)],
46986 }))))
46987 }
46988
46989 #[allow(unused_variables, unused_mut)]
46991 pub fn parse_hint_function_call(&mut self) -> Result<Option<Expression>> {
46992 self.parse_function_call()
46993 }
46994
46995 #[allow(unused_variables, unused_mut)]
46999 pub fn parse_historical_data(&mut self) -> Result<Option<Expression>> {
47000 let start_index = self.current;
47002
47003 let this = if self.match_texts(&["AT", "BEFORE", "END"]) {
47005 self.previous().text.to_ascii_uppercase()
47006 } else {
47007 return Ok(None);
47008 };
47009
47010 if !self.match_token(TokenType::LParen) {
47012 self.current = start_index;
47014 return Ok(None);
47015 }
47016
47017 let kind = if self.match_texts(&["OFFSET", "STATEMENT", "STREAM", "TIMESTAMP", "VERSION"]) {
47018 self.previous().text.to_ascii_uppercase()
47019 } else {
47020 self.current = start_index;
47022 return Ok(None);
47023 };
47024
47025 if !self.match_token(TokenType::FArrow) {
47027 self.current = start_index;
47028 return Ok(None);
47029 }
47030
47031 let expression = self.parse_bitwise()?;
47032 if expression.is_none() {
47033 self.current = start_index;
47034 return Ok(None);
47035 }
47036
47037 self.match_token(TokenType::RParen); Ok(Some(Expression::HistoricalData(Box::new(HistoricalData {
47040 this: Box::new(Expression::Identifier(Identifier::new(this))),
47041 kind,
47042 expression: Box::new(expression.unwrap()),
47043 }))))
47044 }
47045
47046 #[allow(unused_variables, unused_mut)]
47049 pub fn parse_id_var(&mut self) -> Result<Option<Expression>> {
47050 if let Some(ident) = self.parse_identifier()? {
47052 return Ok(Some(ident));
47053 }
47054
47055 if self.match_token(TokenType::Var) {
47057 let text = self.previous().text.clone();
47058 return Ok(Some(Expression::Identifier(Identifier {
47059 name: text,
47060 quoted: false,
47061 trailing_comments: Vec::new(),
47062 span: None,
47063 })));
47064 }
47065
47066 if self.match_token(TokenType::String) {
47068 let text = self.previous().text.clone();
47069 return Ok(Some(Expression::Identifier(Identifier {
47070 name: text,
47071 quoted: true,
47072 trailing_comments: Vec::new(),
47073 span: None,
47074 })));
47075 }
47076
47077 if self.check(TokenType::Select)
47079 || self.check(TokenType::From)
47080 || self.check(TokenType::Where)
47081 || self.check(TokenType::And)
47082 || self.check(TokenType::Or)
47083 || self.check(TokenType::Not)
47084 || self.check(TokenType::True)
47085 || self.check(TokenType::False)
47086 || self.check(TokenType::Null)
47087 {
47088 return Ok(None);
47090 }
47091
47092 Ok(None)
47093 }
47094
47095 pub fn parse_identifier(&mut self) -> Result<Option<Expression>> {
47098 if self.match_token(TokenType::QuotedIdentifier) || self.match_token(TokenType::Identifier)
47100 {
47101 let text = self.previous().text.clone();
47102 let quoted = self.previous().token_type == TokenType::QuotedIdentifier;
47103 return Ok(Some(Expression::Identifier(Identifier {
47104 name: text,
47105 quoted,
47106 trailing_comments: Vec::new(),
47107 span: None,
47108 })));
47109 }
47110 Ok(None)
47111 }
47112
47113 pub fn parse_if(&mut self) -> Result<Option<Expression>> {
47117 if matches!(
47120 self.config.dialect,
47121 Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)
47122 ) && self.check(TokenType::LParen)
47123 {
47124 let cond_start = self.current;
47126 self.skip(); let mut depth = 1;
47128 while depth > 0 && !self.is_at_end() {
47129 if self.check(TokenType::LParen) {
47130 depth += 1;
47131 } else if self.check(TokenType::RParen) {
47132 depth -= 1;
47133 if depth == 0 {
47134 break;
47135 }
47136 }
47137 self.skip();
47138 }
47139 let cond_text = if let Some(ref source) = self.source {
47141 let inner_start = self.tokens[cond_start + 1].span.start;
47142 let inner_end = self.tokens[self.current].span.start;
47143 source[inner_start..inner_end].trim().to_string()
47144 } else {
47145 self.tokens_to_sql(cond_start + 1, self.current)
47146 };
47147 self.skip(); let body_start = self.current;
47151 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
47152 self.skip();
47153 }
47154 let body_text = if let Some(ref source) = self.source {
47155 let start_span = self.tokens[body_start].span.start;
47156 let end_span = if self.current > 0 {
47157 self.tokens[self.current - 1].span.end
47158 } else {
47159 start_span
47160 };
47161 source[start_span..end_span].trim().to_string()
47162 } else {
47163 self.tokens_to_sql(body_start, self.current)
47164 };
47165 let command_text = format!("IF {} {}", cond_text, body_text);
47166 return Ok(Some(Expression::Command(Box::new(
47167 crate::expressions::Command { this: command_text },
47168 ))));
47169 }
47170
47171 if self.match_token(TokenType::LParen) {
47173 if self.check(TokenType::RParen) {
47175 self.skip(); return Ok(Some(Expression::Function(Box::new(Function {
47177 name: "IF".to_string(),
47178 args: vec![],
47179 distinct: false,
47180 trailing_comments: Vec::new(),
47181 use_bracket_syntax: false,
47182 no_parens: false,
47183 quoted: false,
47184 span: None,
47185 inferred_type: None,
47186 }))));
47187 }
47188 let args = self.parse_expression_list()?;
47189 self.expect(TokenType::RParen)?;
47190
47191 if args.len() == 3 {
47192 return Ok(Some(Expression::IfFunc(Box::new(IfFunc {
47193 original_name: None,
47194 condition: args[0].clone(),
47195 true_value: args[1].clone(),
47196 false_value: Some(args[2].clone()),
47197 inferred_type: None,
47198 }))));
47199 } else if args.len() == 2 {
47200 return Ok(Some(Expression::IfFunc(Box::new(IfFunc {
47201 original_name: None,
47202 condition: args[0].clone(),
47203 true_value: args[1].clone(),
47204 false_value: None,
47205 inferred_type: None,
47206 }))));
47207 } else if args.len() == 1 {
47208 return Ok(Some(Expression::Function(Box::new(Function {
47209 name: "IF".to_string(),
47210 args,
47211 distinct: false,
47212 trailing_comments: Vec::new(),
47213 use_bracket_syntax: false,
47214 no_parens: false,
47215 quoted: false,
47216 span: None,
47217 inferred_type: None,
47218 }))));
47219 } else {
47220 return Err(self.parse_error("IF function requires 2 or 3 arguments"));
47221 }
47222 }
47223
47224 if matches!(
47226 self.config.dialect,
47227 Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)
47228 ) {
47229 let saved = self.current;
47230 if self.match_text_seq(&["OBJECT_ID"]) {
47231 let object_id_args_text = if self.match_token(TokenType::LParen) {
47233 let args_start = self.current;
47234 let args = self.parse_expression_list()?;
47235 let args_text = if let Some(ref source) = self.source {
47237 let start_span = self.tokens[args_start].span.start;
47238 let end_span = self.tokens[self.current].span.start;
47239 source[start_span..end_span].trim().to_string()
47240 } else {
47241 args.iter()
47243 .map(|a| format!("{:?}", a))
47244 .collect::<Vec<_>>()
47245 .join(", ")
47246 };
47247 let _ = self.match_token(TokenType::RParen);
47248 Some(args_text)
47249 } else {
47250 None
47251 };
47252 if self.match_text_seq(&["IS", "NOT", "NULL"]) {
47253 let has_begin = self.match_token(TokenType::Begin);
47255 if self.check(TokenType::Drop) {
47256 self.skip(); if self.match_token(TokenType::Table) {
47259 let mut names = Vec::new();
47261 loop {
47262 names.push(self.parse_table_ref()?);
47263 if !self.match_token(TokenType::Comma) {
47264 break;
47265 }
47266 }
47267 if has_begin {
47269 let _ = self.match_token(TokenType::Semicolon);
47270 let _ = self.match_token(TokenType::End);
47271 }
47272 return Ok(Some(Expression::DropTable(Box::new(
47273 crate::expressions::DropTable {
47274 names,
47275 if_exists: true,
47276 cascade: false,
47277 cascade_constraints: false,
47278 purge: false,
47279 leading_comments: Vec::new(),
47280 object_id_args: object_id_args_text,
47281 sync: false,
47282 iceberg: false,
47283 restrict: false,
47284 },
47285 ))));
47286 }
47287 }
47288 }
47289 self.current = saved;
47291 }
47292 }
47293
47294 let condition = match self.parse_disjunction()? {
47298 Some(c) => c,
47299 None => return Ok(None),
47300 };
47301
47302 if !self.match_token(TokenType::Then) {
47303 return Ok(Some(condition));
47305 }
47306
47307 let true_value = match self.parse_disjunction()? {
47309 Some(v) => v,
47310 None => return Err(self.parse_error("Expected expression after THEN")),
47311 };
47312
47313 let false_value = if self.match_token(TokenType::Else) {
47314 match self.parse_disjunction()? {
47315 Some(v) => Some(v),
47316 None => return Err(self.parse_error("Expected expression after ELSE")),
47317 }
47318 } else {
47319 None
47320 };
47321
47322 self.match_token(TokenType::End);
47324
47325 Ok(Some(Expression::IfFunc(Box::new(IfFunc {
47326 original_name: None,
47327 condition,
47328 true_value,
47329 false_value,
47330 inferred_type: None,
47331 }))))
47332 }
47333
47334 #[allow(unused_variables, unused_mut)]
47338 pub fn parse_in(&mut self) -> Result<Option<Expression>> {
47339 if self.match_token(TokenType::In) {
47341 return Err(self.parse_error("Expected expression before IN"));
47342 }
47343
47344 let saved_pos = self.current;
47346
47347 match self.parse_bitwise() {
47349 Ok(Some(left_expr)) => {
47350 let negate = self.match_token(TokenType::Not);
47352
47353 if self.match_token(TokenType::In) {
47355 let in_result = self.parse_in_with_expr(Some(left_expr))?;
47356 return Ok(Some(if negate {
47357 Expression::Not(Box::new(UnaryOp {
47358 this: in_result,
47359 inferred_type: None,
47360 }))
47361 } else {
47362 in_result
47363 }));
47364 }
47365
47366 self.current = saved_pos;
47368 Ok(None)
47369 }
47370 Ok(None) => {
47371 self.current = saved_pos;
47372 Ok(None)
47373 }
47374 Err(_) => {
47375 self.current = saved_pos;
47376 Ok(None)
47377 }
47378 }
47379 }
47380
47381 #[allow(unused_variables, unused_mut)]
47384 pub fn parse_index(&mut self) -> Result<Option<Expression>> {
47385 if self.match_text_seq(&["PRIMARY"]) {
47386 return Ok(Some(Expression::Index(Box::new(Index {
47387 this: None,
47388 table: None,
47389 unique: false,
47390 primary: None,
47391 amp: None,
47392 params: Vec::new(),
47393 }))));
47394 }
47395 if self.match_text_seq(&["AMP"]) {
47396 return Ok(None);
47398 }
47399 Ok(None)
47400 }
47401
47402 #[allow(unused_variables, unused_mut)]
47405 pub fn parse_index_params(&mut self) -> Result<Option<Expression>> {
47406 if self.match_text_seq(&["INCLUDE"]) {
47407 return Ok(Some(Expression::IndexParameters(Box::new(
47408 IndexParameters {
47409 using: None,
47410 include: None,
47411 columns: Vec::new(),
47412 with_storage: None,
47413 partition_by: None,
47414 tablespace: None,
47415 where_: None,
47416 on: None,
47417 },
47418 ))));
47419 }
47420 if self.match_text_seq(&["USING", "INDEX", "TABLESPACE"]) {
47421 return Ok(None);
47423 }
47424 Ok(None)
47425 }
47426
47427 #[allow(unused_variables, unused_mut)]
47429 pub fn parse_initcap(&mut self) -> Result<Option<Expression>> {
47432 let args = self.parse_expression_list()?;
47434
47435 if args.is_empty() {
47436 return Ok(None);
47437 }
47438
47439 Ok(Some(Expression::Initcap(Box::new(UnaryFunc::new(
47441 args.into_iter().next().unwrap(),
47442 )))))
47443 }
47444
47445 #[allow(unused_variables, unused_mut)]
47447 pub fn parse_inline(&mut self) -> Result<Option<Expression>> {
47448 if self.match_text_seq(&["LENGTH"]) {
47449 return Ok(None);
47451 }
47452 Ok(None)
47453 }
47454
47455 #[allow(unused_variables, unused_mut)]
47459 pub fn parse_insert_table(&mut self) -> Result<Option<Expression>> {
47460 self.parse_table()
47462 }
47463
47464 pub fn parse_interpolate(&mut self) -> Result<Option<Expression>> {
47467 if !self.match_text_seq(&["INTERPOLATE"]) {
47468 return Ok(None);
47469 }
47470
47471 if self.match_token(TokenType::LParen) {
47473 let mut expressions = Vec::new();
47474 loop {
47475 if let Some(expr) = self.parse_name_as_expression()? {
47476 expressions.push(expr);
47477 }
47478 if !self.match_token(TokenType::Comma) {
47479 break;
47480 }
47481 }
47482 self.match_token(TokenType::RParen);
47483
47484 if expressions.is_empty() {
47485 return Ok(None);
47486 }
47487
47488 return Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))));
47489 }
47490
47491 Ok(None)
47492 }
47493
47494 #[allow(unused_variables, unused_mut)]
47497 pub fn parse_interval(&mut self) -> Result<Option<Expression>> {
47498 self.try_parse_interval()
47500 }
47501
47502 #[allow(unused_variables, unused_mut)]
47505 pub fn parse_interval_span(&mut self) -> Result<Option<Expression>> {
47506 if self.match_text_seq(&["TO"]) {
47507 return Ok(Some(Expression::Var(Box::new(Var {
47508 this: String::new(),
47509 }))));
47510 }
47511 if self.match_text_seq(&["TO"]) {
47512 return Ok(None);
47514 }
47515 Ok(None)
47516 }
47517
47518 #[allow(unused_variables, unused_mut)]
47522 pub fn parse_into(&mut self) -> Result<Option<Expression>> {
47523 if !self.match_token(TokenType::Into) {
47524 return Ok(None);
47525 }
47526
47527 let _temp = self.match_token(TokenType::Temporary);
47529
47530 let _unlogged = self.match_text_seq(&["UNLOGGED"]);
47532
47533 let _ = self.match_token(TokenType::Table);
47535
47536 self.parse_table_parts()
47538 }
47539
47540 pub fn parse_introducer(&mut self) -> Result<Option<Expression>> {
47544 let token = self.previous().clone();
47546
47547 let literal = self.parse_primary()?;
47550
47551 match &literal {
47553 Expression::Null(_) => {
47554 Ok(Some(Expression::Identifier(Identifier {
47556 name: token.text.clone(),
47557 quoted: false,
47558 trailing_comments: Vec::new(),
47559 span: None,
47560 })))
47561 }
47562 _ => Ok(Some(Expression::Introducer(Box::new(Introducer {
47563 this: Box::new(Expression::Identifier(Identifier {
47564 name: token.text.clone(),
47565 quoted: false,
47566 trailing_comments: Vec::new(),
47567 span: None,
47568 })),
47569 expression: Box::new(literal),
47570 })))),
47571 }
47572 }
47573
47574 #[allow(unused_variables, unused_mut)]
47577 pub fn parse_is(&mut self) -> Result<Option<Expression>> {
47578 if self.match_text_seq(&["DISTINCT", "FROM"]) {
47579 return Ok(Some(Expression::JSON(Box::new(JSON {
47580 this: None,
47581 with_: None,
47582 unique: false,
47583 }))));
47584 }
47585 if self.match_text_seq(&["WITH"]) {
47586 return Ok(None);
47588 }
47589 if self.match_text_seq(&["WITHOUT"]) {
47590 return Ok(None);
47592 }
47593 Ok(None)
47594 }
47595
47596 #[allow(unused_variables, unused_mut)]
47600 pub fn parse_join(&mut self) -> Result<Option<Expression>> {
47601 if self.match_token(TokenType::Comma) {
47603 if let Ok(Some(table)) = self.parse_table() {
47604 return Ok(Some(Expression::Join(Box::new(Join {
47605 this: table,
47606 on: None,
47607 using: Vec::new(),
47608 kind: JoinKind::Implicit,
47609 use_inner_keyword: false,
47610 use_outer_keyword: false,
47611 deferred_condition: false,
47612 join_hint: None,
47613 match_condition: None,
47614 pivots: Vec::new(),
47615 comments: Vec::new(),
47616 nesting_group: 0,
47617 directed: false,
47618 }))));
47619 }
47620 return Ok(None);
47621 }
47622
47623 let saved_pos = self.current;
47625 if let Some((kind, needs_join_keyword, use_inner_keyword, use_outer_keyword, join_hint)) =
47626 self.try_parse_join_kind()
47627 {
47628 let mut join_comments = Vec::new();
47630 for i in saved_pos..self.current {
47631 if i < self.tokens.len() {
47632 join_comments.extend(self.tokens[i].trailing_comments.iter().cloned());
47633 }
47634 }
47635
47636 if needs_join_keyword && !self.match_token(TokenType::Join) {
47638 self.current = saved_pos;
47639 return Ok(None);
47640 }
47641
47642 let table = self.parse_table_expression()?;
47644
47645 let (on, using) = if self.match_token(TokenType::On) {
47647 (Some(self.parse_expression()?), Vec::new())
47648 } else if self.match_token(TokenType::Using) {
47649 let has_parens = self.match_token(TokenType::LParen);
47650 let cols = self.parse_using_column_list()?;
47652 if has_parens {
47653 self.expect(TokenType::RParen)?;
47654 }
47655 (None, cols)
47656 } else {
47657 (None, Vec::new())
47658 };
47659
47660 return Ok(Some(Expression::Join(Box::new(Join {
47661 this: table,
47662 on,
47663 using,
47664 kind,
47665 use_inner_keyword,
47666 use_outer_keyword,
47667 deferred_condition: false,
47668 join_hint,
47669 match_condition: None,
47670 pivots: Vec::new(),
47671 comments: join_comments,
47672 nesting_group: 0,
47673 directed: false,
47674 }))));
47675 }
47676
47677 if self.match_text_seq(&["CROSS", "APPLY"]) || self.match_text_seq(&["OUTER", "APPLY"]) {
47679 let is_outer = self.previous().text.eq_ignore_ascii_case("OUTER");
47680 let table = self.parse_table_expression()?;
47681 return Ok(Some(Expression::Join(Box::new(Join {
47682 this: table,
47683 on: None,
47684 using: Vec::new(),
47685 kind: if is_outer {
47686 JoinKind::Outer
47687 } else {
47688 JoinKind::Cross
47689 },
47690 use_inner_keyword: false,
47691 use_outer_keyword: is_outer,
47692 deferred_condition: false,
47693 join_hint: None,
47694 match_condition: None,
47695 pivots: Vec::new(),
47696 comments: Vec::new(),
47697 nesting_group: 0,
47698 directed: false,
47699 }))));
47700 }
47701
47702 Ok(None)
47703 }
47704
47705 #[allow(unused_variables, unused_mut)]
47709 pub fn parse_join_hint(&mut self, hint_name: &str) -> Result<Option<Expression>> {
47710 let mut tables = Vec::new();
47712 loop {
47713 if let Some(table) = self.parse_table()? {
47714 tables.push(table);
47715 } else {
47716 break;
47717 }
47718 if !self.match_token(TokenType::Comma) {
47719 break;
47720 }
47721 }
47722
47723 Ok(Some(Expression::JoinHint(Box::new(JoinHint {
47724 this: Box::new(Expression::Identifier(Identifier::new(
47725 hint_name.to_ascii_uppercase(),
47726 ))),
47727 expressions: tables,
47728 }))))
47729 }
47730
47731 pub fn parse_join_parts(&mut self) -> (Option<String>, Option<String>, Option<String>) {
47737 let method = if self.match_texts(&["ASOF", "NATURAL", "POSITIONAL"]) {
47739 Some(self.previous().text.to_ascii_uppercase())
47740 } else {
47741 None
47742 };
47743
47744 let side = if self.match_texts(&["LEFT", "RIGHT", "FULL"]) {
47746 Some(self.previous().text.to_ascii_uppercase())
47747 } else {
47748 None
47749 };
47750
47751 let kind = if self.match_texts(&["ANTI", "CROSS", "INNER", "OUTER", "SEMI"]) {
47753 Some(self.previous().text.to_ascii_uppercase())
47754 } else if self.match_token(TokenType::StraightJoin) {
47755 Some("STRAIGHT_JOIN".to_string())
47756 } else {
47757 None
47758 };
47759
47760 (method, side, kind)
47761 }
47762
47763 pub fn parse_journal(&mut self) -> Result<Option<Expression>> {
47767 self.parse_journal_impl(false, false, false, false, false)
47768 }
47769
47770 pub fn parse_journal_impl(
47772 &mut self,
47773 no: bool,
47774 dual: bool,
47775 before: bool,
47776 local: bool,
47777 after: bool,
47778 ) -> Result<Option<Expression>> {
47779 Ok(Some(Expression::JournalProperty(Box::new(
47780 JournalProperty {
47781 no: if no {
47782 Some(Box::new(Expression::Boolean(BooleanLiteral {
47783 value: true,
47784 })))
47785 } else {
47786 None
47787 },
47788 dual: if dual {
47789 Some(Box::new(Expression::Boolean(BooleanLiteral {
47790 value: true,
47791 })))
47792 } else {
47793 None
47794 },
47795 before: if before {
47796 Some(Box::new(Expression::Boolean(BooleanLiteral {
47797 value: true,
47798 })))
47799 } else {
47800 None
47801 },
47802 local: if local {
47803 Some(Box::new(Expression::Boolean(BooleanLiteral {
47804 value: true,
47805 })))
47806 } else {
47807 None
47808 },
47809 after: if after {
47810 Some(Box::new(Expression::Boolean(BooleanLiteral {
47811 value: true,
47812 })))
47813 } else {
47814 None
47815 },
47816 },
47817 ))))
47818 }
47819
47820 #[allow(unused_variables, unused_mut)]
47823 pub fn parse_json_column_def(&mut self) -> Result<Option<Expression>> {
47824 if self.match_text_seq(&["NESTED"]) {
47825 return Ok(Some(Expression::JSONColumnDef(Box::new(JSONColumnDef {
47826 this: None,
47827 kind: None,
47828 path: None,
47829 nested_schema: None,
47830 ordinality: None,
47831 }))));
47832 }
47833 if self.match_text_seq(&["PATH"]) {
47834 return Ok(None);
47836 }
47837 Ok(None)
47838 }
47839
47840 #[allow(unused_variables, unused_mut)]
47842 pub fn parse_json_key_value(&mut self) -> Result<Option<Expression>> {
47846 self.match_text_seq(&["KEY"]);
47848
47849 let key = self.parse_column()?;
47851
47852 let _ = self.match_token(TokenType::Colon)
47854 || self.match_token(TokenType::Comma)
47855 || self.match_text_seq(&["VALUE"]);
47856
47857 self.match_text_seq(&["VALUE"]);
47859
47860 let value = self.parse_bitwise()?;
47862
47863 match (key, value) {
47865 (None, None) => Ok(None),
47866 (Some(k), None) => Ok(Some(Expression::JSONKeyValue(Box::new(JSONKeyValue {
47867 this: Box::new(k),
47868 expression: Box::new(Expression::Null(Null)),
47869 })))),
47870 (None, Some(v)) => Ok(Some(Expression::JSONKeyValue(Box::new(JSONKeyValue {
47871 this: Box::new(Expression::Null(Null)),
47872 expression: Box::new(v),
47873 })))),
47874 (Some(k), Some(v)) => Ok(Some(Expression::JSONKeyValue(Box::new(JSONKeyValue {
47875 this: Box::new(k),
47876 expression: Box::new(v),
47877 })))),
47878 }
47879 }
47880
47881 pub fn parse_json_object(&mut self) -> Result<Option<Expression>> {
47885 self.parse_json_object_impl(false)
47886 }
47887
47888 pub fn parse_json_object_impl(&mut self, agg: bool) -> Result<Option<Expression>> {
47890 let star = self.parse_star()?;
47892
47893 let expressions = if let Some(star_expr) = star {
47895 vec![star_expr]
47896 } else {
47897 let mut exprs = Vec::new();
47899 loop {
47900 if let Some(kv) = self.parse_json_key_value()? {
47901 if self.match_text_seq(&["FORMAT", "JSON"]) {
47903 exprs.push(Expression::JSONFormat(Box::new(JSONFormat {
47904 this: Some(Box::new(kv)),
47905 options: Vec::new(),
47906 is_json: None,
47907 to_json: None,
47908 })));
47909 } else {
47910 exprs.push(kv);
47911 }
47912 } else {
47913 break;
47914 }
47915 if !self.match_token(TokenType::Comma) {
47916 break;
47917 }
47918 }
47919 exprs
47920 };
47921
47922 let null_handling = self.parse_json_on_null_handling()?;
47924
47925 let unique_keys = if self.match_text_seq(&["WITH", "UNIQUE"]) {
47927 self.match_text_seq(&["KEYS"]);
47928 Some(Box::new(Expression::Boolean(BooleanLiteral {
47929 value: true,
47930 })))
47931 } else if self.match_text_seq(&["WITHOUT", "UNIQUE"]) {
47932 self.match_text_seq(&["KEYS"]);
47933 Some(Box::new(Expression::Boolean(BooleanLiteral {
47934 value: false,
47935 })))
47936 } else {
47937 None
47938 };
47939
47940 self.match_text_seq(&["KEYS"]);
47942
47943 let return_type = if self.match_text_seq(&["RETURNING"]) {
47945 let type_expr = self.parse_type()?;
47946 if self.match_text_seq(&["FORMAT", "JSON"]) {
47948 type_expr.map(|t| {
47949 Box::new(Expression::JSONFormat(Box::new(JSONFormat {
47950 this: Some(Box::new(t)),
47951 options: Vec::new(),
47952 is_json: None,
47953 to_json: None,
47954 })))
47955 })
47956 } else {
47957 type_expr.map(Box::new)
47958 }
47959 } else {
47960 None
47961 };
47962
47963 let encoding = if self.match_text_seq(&["ENCODING"]) {
47965 self.parse_var()?.map(Box::new)
47966 } else {
47967 None
47968 };
47969
47970 if agg {
47971 Ok(Some(Expression::JSONObjectAgg(Box::new(JSONObjectAgg {
47972 expressions,
47973 null_handling,
47974 unique_keys,
47975 return_type,
47976 encoding,
47977 }))))
47978 } else {
47979 Ok(Some(Expression::JSONObject(Box::new(JSONObject {
47980 expressions,
47981 null_handling,
47982 unique_keys,
47983 return_type,
47984 encoding,
47985 }))))
47986 }
47987 }
47988
47989 fn parse_json_on_null_handling(&mut self) -> Result<Option<Box<Expression>>> {
47991 if self.match_text_seq(&["NULL", "ON", "NULL"]) {
47992 Ok(Some(Box::new(Expression::Var(Box::new(Var {
47993 this: "NULL ON NULL".to_string(),
47994 })))))
47995 } else if self.match_text_seq(&["ABSENT", "ON", "NULL"]) {
47996 Ok(Some(Box::new(Expression::Var(Box::new(Var {
47997 this: "ABSENT ON NULL".to_string(),
47998 })))))
47999 } else {
48000 Ok(None)
48001 }
48002 }
48003
48004 #[allow(unused_variables, unused_mut)]
48006 pub fn parse_json_schema(&mut self) -> Result<Option<Expression>> {
48007 if self.match_text_seq(&["COLUMNS"]) {
48008 return Ok(Some(Expression::JSONSchema(Box::new(JSONSchema {
48009 expressions: Vec::new(),
48010 }))));
48011 }
48012 Ok(None)
48013 }
48014
48015 pub fn parse_json_table_columns(&mut self) -> Result<Option<Expression>> {
48021 if !self.match_text_seq(&["COLUMNS"]) {
48022 return Ok(None);
48023 }
48024
48025 let has_parens = self.match_token(TokenType::LParen);
48027
48028 let mut columns = Vec::new();
48029
48030 if has_parens {
48032 if !self.check(TokenType::RParen) {
48034 loop {
48035 if let Some(col_def) = self.parse_json_table_column_def()? {
48036 columns.push(col_def);
48037 }
48038 if !self.match_token(TokenType::Comma) {
48039 break;
48040 }
48041 }
48042 }
48043 self.expect(TokenType::RParen)?;
48045 } else {
48046 if let Some(col_def) = self.parse_json_table_column_def()? {
48048 columns.push(col_def);
48049 }
48050 }
48051
48052 Ok(Some(Expression::JSONSchema(Box::new(JSONSchema {
48053 expressions: columns,
48054 }))))
48055 }
48056
48057 pub fn parse_json_table_column_def(&mut self) -> Result<Option<Expression>> {
48062 if self.match_text_seq(&["NESTED"]) {
48064 self.match_text_seq(&["PATH"]); let path = self.parse_string()?;
48067 let nested_schema = self.parse_json_table_columns()?;
48068
48069 return Ok(Some(Expression::JSONColumnDef(Box::new(JSONColumnDef {
48070 this: None,
48071 kind: None,
48072 path: path.map(Box::new),
48073 nested_schema: nested_schema.map(Box::new),
48074 ordinality: None,
48075 }))));
48076 }
48077
48078 let name = self.parse_id_var()?;
48080 if name.is_none() {
48081 return Ok(None);
48082 }
48083
48084 let ordinality = if self.match_text_seq(&["FOR", "ORDINALITY"]) {
48086 Some(Box::new(Expression::Boolean(BooleanLiteral {
48087 value: true,
48088 })))
48089 } else {
48090 None
48091 };
48092
48093 let kind = if ordinality.is_none() {
48095 let data_type = self.parse_data_type_optional()?;
48097 data_type.map(|dt| self.data_type_to_string(&dt))
48098 } else {
48099 None
48100 };
48101
48102 let path = if self.match_text_seq(&["PATH"]) {
48104 self.parse_string()?
48105 } else {
48106 None
48107 };
48108
48109 Ok(Some(Expression::JSONColumnDef(Box::new(JSONColumnDef {
48110 this: name.map(Box::new),
48111 kind,
48112 path: path.map(Box::new),
48113 nested_schema: None,
48114 ordinality,
48115 }))))
48116 }
48117
48118 pub fn parse_json_table(&mut self) -> Result<Option<Expression>> {
48121 let this = self.parse_expression()?;
48123
48124 let path = if self.match_token(TokenType::Comma) {
48126 if let Some(s) = self.parse_string()? {
48127 Some(Box::new(s))
48128 } else {
48129 None
48130 }
48131 } else {
48132 None
48133 };
48134
48135 let error_handling = if self.match_text_seq(&["ON", "ERROR"]) {
48137 if self.match_text_seq(&["NULL"]) {
48138 Some(Box::new(Expression::Var(Box::new(Var {
48139 this: "NULL".to_string(),
48140 }))))
48141 } else if self.match_text_seq(&["ERROR"]) {
48142 Some(Box::new(Expression::Var(Box::new(Var {
48143 this: "ERROR".to_string(),
48144 }))))
48145 } else {
48146 None
48147 }
48148 } else {
48149 None
48150 };
48151
48152 let empty_handling = if self.match_text_seq(&["ON", "EMPTY"]) {
48154 if self.match_text_seq(&["NULL"]) {
48155 Some(Box::new(Expression::Var(Box::new(Var {
48156 this: "NULL".to_string(),
48157 }))))
48158 } else if self.match_text_seq(&["ERROR"]) {
48159 Some(Box::new(Expression::Var(Box::new(Var {
48160 this: "ERROR".to_string(),
48161 }))))
48162 } else {
48163 None
48164 }
48165 } else {
48166 None
48167 };
48168
48169 let schema = self.parse_json_schema()?;
48171
48172 Ok(Some(Expression::JSONTable(Box::new(JSONTable {
48173 this: Box::new(this),
48174 schema: schema.map(Box::new),
48175 path,
48176 error_handling,
48177 empty_handling,
48178 }))))
48179 }
48180
48181 #[allow(unused_variables, unused_mut)]
48183 pub fn parse_json_value(&mut self) -> Result<Option<Expression>> {
48186 let this = self.parse_expression()?;
48188
48189 self.match_token(TokenType::Comma);
48191 let path = self.parse_expression()?;
48192
48193 let returning = if self.match_token(TokenType::Returning) {
48195 Some(Box::new(self.parse_expression()?))
48196 } else {
48197 None
48198 };
48199
48200 let on_condition = if self.check(TokenType::On) {
48202 self.parse_on_condition()?
48203 } else {
48204 None
48205 };
48206
48207 Ok(Some(Expression::JSONValue(Box::new(JSONValue {
48208 this: Box::new(this),
48209 path: Some(Box::new(path)),
48210 returning,
48211 on_condition: on_condition.map(Box::new),
48212 }))))
48213 }
48214
48215 #[allow(unused_variables, unused_mut)]
48217 pub fn parse_key_constraint_options(&mut self) -> Result<Option<Expression>> {
48218 if self.match_text_seq(&["NO", "ACTION"]) {
48219 return Ok(None);
48221 }
48222 if self.match_text_seq(&["CASCADE"]) {
48223 return Ok(None);
48225 }
48226 if self.match_text_seq(&["RESTRICT"]) {
48227 return Ok(None);
48229 }
48230 Ok(None)
48231 }
48232
48233 #[allow(unused_variables, unused_mut)]
48237 pub fn parse_lambda(&mut self) -> Result<Option<Expression>> {
48238 let start_index = self.current;
48239
48240 if !matches!(
48243 self.config.dialect,
48244 Some(crate::dialects::DialectType::ClickHouse)
48245 ) && self.match_token(TokenType::Lambda)
48246 {
48247 let mut params = Vec::new();
48249 loop {
48250 if self.is_identifier_token() {
48252 let token = self.advance();
48253 let quoted = token.token_type == TokenType::QuotedIdentifier;
48254 params.push(Identifier {
48255 name: token.text,
48256 quoted,
48257 trailing_comments: Vec::new(),
48258 span: None,
48259 });
48260 } else {
48261 break;
48262 }
48263 if !self.match_token(TokenType::Comma) {
48264 break;
48265 }
48266 }
48267
48268 if params.is_empty() {
48270 return Err(self.parse_error("LAMBDA requires at least one parameter"));
48271 }
48272
48273 if !self.match_token(TokenType::Colon) {
48275 return Err(self.parse_error("Expected ':' after LAMBDA parameters"));
48276 }
48277
48278 let body = self.parse_expression()?;
48279 return Ok(Some(Expression::Lambda(Box::new(LambdaExpr {
48280 parameters: params,
48281 body,
48282 colon: true,
48283 parameter_types: Vec::new(),
48284 }))));
48285 }
48286
48287 let parameters = if self.match_token(TokenType::LParen) {
48289 let mut params = Vec::new();
48291 if !self.check(TokenType::RParen) {
48292 loop {
48293 if let Some(ident) = self.parse_identifier()? {
48294 if let Expression::Identifier(id) = ident {
48295 params.push(id);
48296 }
48297 }
48298 if !self.match_token(TokenType::Comma) {
48299 break;
48300 }
48301 }
48302 }
48303 if !self.match_token(TokenType::RParen) {
48304 self.current = start_index;
48306 return Ok(None);
48307 }
48308 params
48309 } else {
48310 if let Some(ident) = self.parse_identifier()? {
48312 if let Expression::Identifier(id) = ident {
48313 vec![id]
48314 } else {
48315 self.current = start_index;
48316 return Ok(None);
48317 }
48318 } else {
48319 return Ok(None);
48320 }
48321 };
48322
48323 if self.match_token(TokenType::Arrow) || self.match_token(TokenType::FArrow) {
48325 let body = self.parse_expression()?;
48327 Ok(Some(Expression::Lambda(Box::new(LambdaExpr {
48328 parameters,
48329 body,
48330 colon: false,
48331 parameter_types: Vec::new(),
48332 }))))
48333 } else {
48334 self.current = start_index;
48336 Ok(None)
48337 }
48338 }
48339
48340 #[allow(unused_variables, unused_mut)]
48342 pub fn parse_lambda_arg(&mut self) -> Result<Option<Expression>> {
48343 self.parse_id_var()
48344 }
48345
48346 pub fn parse_lateral(&mut self) -> Result<Option<Expression>> {
48349 if !self.match_token(TokenType::Lateral) {
48353 return Ok(None);
48354 }
48355
48356 let view = self.match_token(TokenType::View);
48358 let outer = if view {
48359 self.match_token(TokenType::Outer)
48360 } else {
48361 false
48362 };
48363
48364 let this = if self.check(TokenType::LParen) {
48366 self.expect(TokenType::LParen)?;
48368 let inner = self.parse_statement()?;
48369 self.expect(TokenType::RParen)?;
48370 inner
48371 } else {
48372 self.parse_primary()?
48374 };
48375
48376 let alias = if self.match_token(TokenType::As) {
48378 Some(self.expect_identifier()?)
48379 } else if self.check(TokenType::Identifier) && !self.check_keyword() {
48380 Some(self.expect_identifier()?)
48381 } else {
48382 None
48383 };
48384
48385 let column_aliases = if alias.is_some() && self.match_token(TokenType::LParen) {
48387 let mut cols = Vec::new();
48388 loop {
48389 if self.check(TokenType::RParen) {
48390 break;
48391 }
48392 let col = self.expect_identifier()?;
48393 cols.push(col);
48394 if !self.match_token(TokenType::Comma) {
48395 break;
48396 }
48397 }
48398 self.expect(TokenType::RParen)?;
48399 cols
48400 } else {
48401 Vec::new()
48402 };
48403
48404 Ok(Some(Expression::Lateral(Box::new(Lateral {
48405 this: Box::new(this),
48406 view: if view {
48407 Some(Box::new(Expression::Boolean(BooleanLiteral {
48408 value: true,
48409 })))
48410 } else {
48411 None
48412 },
48413 outer: if outer {
48414 Some(Box::new(Expression::Boolean(BooleanLiteral {
48415 value: true,
48416 })))
48417 } else {
48418 None
48419 },
48420 alias,
48421 alias_quoted: false,
48422 cross_apply: None,
48423 ordinality: None,
48424 column_aliases,
48425 }))))
48426 }
48427
48428 pub fn parse_limit(&mut self) -> Result<Option<Expression>> {
48431 if !self.match_token(TokenType::Limit) {
48432 return Ok(None);
48433 }
48434 let limit_expr = self.parse_expression()?;
48436 Ok(Some(Expression::Limit(Box::new(Limit {
48437 this: limit_expr,
48438 percent: false,
48439 comments: Vec::new(),
48440 }))))
48441 }
48442
48443 #[allow(unused_variables, unused_mut)]
48445 pub fn parse_limit_by(&mut self) -> Result<Option<Expression>> {
48446 if self.match_text_seq(&["BY"]) {
48447 return Ok(None);
48449 }
48450 Ok(None)
48451 }
48452
48453 #[allow(unused_variables, unused_mut)]
48455 pub fn parse_limit_options(&mut self) -> Result<Option<Expression>> {
48456 if self.match_text_seq(&["ONLY"]) {
48457 return Ok(Some(Expression::LimitOptions(Box::new(LimitOptions {
48458 percent: None,
48459 rows: None,
48460 with_ties: None,
48461 }))));
48462 }
48463 if self.match_text_seq(&["WITH", "TIES"]) {
48464 return Ok(None);
48466 }
48467 Ok(None)
48468 }
48469
48470 #[allow(unused_variables, unused_mut)]
48472 pub fn parse_load(&mut self) -> Result<Option<Expression>> {
48473 if self.match_text_seq(&["DATA"]) {
48474 return Ok(Some(Expression::Command(Box::new(Command {
48475 this: String::new(),
48476 }))));
48477 }
48478 if self.match_text_seq(&["LOCAL"]) {
48479 return Ok(None);
48481 }
48482 Ok(None)
48483 }
48484
48485 #[allow(unused_variables, unused_mut)]
48488 pub fn parse_locking(&mut self) -> Result<Option<Expression>> {
48489 let kind = if self.match_token(TokenType::Table) {
48490 Some("TABLE")
48491 } else if self.match_token(TokenType::View) {
48492 Some("VIEW")
48493 } else if self.match_token(TokenType::Row) {
48494 Some("ROW")
48495 } else if self.match_token(TokenType::Database) || self.match_identifier("DATABASE") {
48496 Some("DATABASE")
48497 } else {
48498 None
48499 };
48500
48501 let kind = match kind {
48502 Some(k) => k.to_string(),
48503 None => return Ok(None),
48504 };
48505
48506 let this = if matches!(kind.as_str(), "DATABASE" | "TABLE" | "VIEW") {
48507 self.parse_table_parts()?
48508 } else {
48509 None
48510 };
48511
48512 let for_or_in = if self.match_token(TokenType::For) {
48513 Some("FOR")
48514 } else if self.match_token(TokenType::In) {
48515 Some("IN")
48516 } else {
48517 None
48518 };
48519
48520 let lock_type = if self.match_identifier("ACCESS") {
48521 Some("ACCESS")
48522 } else if self.match_texts(&["EXCL", "EXCLUSIVE"]) {
48523 Some("EXCLUSIVE")
48524 } else if self.match_identifier("SHARE") {
48525 Some("SHARE")
48526 } else if self.match_identifier("READ") {
48527 Some("READ")
48528 } else if self.match_identifier("WRITE") {
48529 Some("WRITE")
48530 } else if self.match_identifier("CHECKSUM") {
48531 Some("CHECKSUM")
48532 } else {
48533 None
48534 };
48535
48536 let override_ = if self.match_identifier("OVERRIDE") {
48537 Some(Box::new(Expression::Boolean(BooleanLiteral {
48538 value: true,
48539 })))
48540 } else {
48541 None
48542 };
48543
48544 Ok(Some(Expression::LockingProperty(Box::new(
48545 LockingProperty {
48546 this: this.map(Box::new),
48547 kind,
48548 for_or_in: for_or_in.map(|v| {
48549 Box::new(Expression::Var(Box::new(Var {
48550 this: v.to_string(),
48551 })))
48552 }),
48553 lock_type: lock_type.map(|v| {
48554 Box::new(Expression::Var(Box::new(Var {
48555 this: v.to_string(),
48556 })))
48557 }),
48558 override_,
48559 },
48560 ))))
48561 }
48562
48563 fn parse_locking_statement(&mut self) -> Result<Expression> {
48565 self.expect(TokenType::Lock)?;
48566 let locking = self
48567 .parse_locking()?
48568 .ok_or_else(|| self.parse_error("Expected LOCKING clause"))?;
48569 let query = if self.check(TokenType::With) {
48570 self.parse_statement()?
48571 } else {
48572 self.parse_select()?
48573 };
48574 Ok(Expression::LockingStatement(Box::new(LockingStatement {
48575 this: Box::new(locking),
48576 expression: Box::new(query),
48577 })))
48578 }
48579
48580 pub fn parse_log(&mut self) -> Result<Option<Expression>> {
48584 self.parse_log_impl(false)
48585 }
48586
48587 pub fn parse_log_impl(&mut self, no: bool) -> Result<Option<Expression>> {
48589 Ok(Some(Expression::LogProperty(Box::new(LogProperty {
48590 no: if no {
48591 Some(Box::new(Expression::Boolean(BooleanLiteral {
48592 value: true,
48593 })))
48594 } else {
48595 None
48596 },
48597 }))))
48598 }
48599
48600 #[allow(unused_variables, unused_mut)]
48603 pub fn parse_match_against(&mut self) -> Result<Option<Expression>> {
48604 let expressions = if self.match_text_seq(&["TABLE"]) {
48606 if let Some(table) = self.parse_table()? {
48608 vec![table]
48609 } else {
48610 Vec::new()
48611 }
48612 } else {
48613 let mut cols = Vec::new();
48615 loop {
48616 if let Some(col) = self.parse_column()? {
48617 cols.push(col);
48618 }
48619 if !self.match_token(TokenType::Comma) {
48620 break;
48621 }
48622 }
48623 cols
48624 };
48625
48626 self.match_text_seq(&[")", "AGAINST", "("]);
48628
48629 let this = self.parse_string()?;
48631
48632 let modifier = if self.match_text_seq(&["IN", "NATURAL", "LANGUAGE", "MODE"]) {
48634 if self.match_text_seq(&["WITH", "QUERY", "EXPANSION"]) {
48635 Some(Box::new(Expression::Var(Box::new(Var {
48636 this: "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION".to_string(),
48637 }))))
48638 } else {
48639 Some(Box::new(Expression::Var(Box::new(Var {
48640 this: "IN NATURAL LANGUAGE MODE".to_string(),
48641 }))))
48642 }
48643 } else if self.match_text_seq(&["IN", "BOOLEAN", "MODE"]) {
48644 Some(Box::new(Expression::Var(Box::new(Var {
48645 this: "IN BOOLEAN MODE".to_string(),
48646 }))))
48647 } else if self.match_text_seq(&["WITH", "QUERY", "EXPANSION"]) {
48648 Some(Box::new(Expression::Var(Box::new(Var {
48649 this: "WITH QUERY EXPANSION".to_string(),
48650 }))))
48651 } else {
48652 None
48653 };
48654
48655 match this {
48656 Some(t) => Ok(Some(Expression::MatchAgainst(Box::new(MatchAgainst {
48657 this: Box::new(t),
48658 expressions,
48659 modifier,
48660 })))),
48661 None => Ok(None),
48662 }
48663 }
48664
48665 pub fn parse_match_recognize_measure(&mut self) -> Result<Option<Expression>> {
48668 let window_frame = if self.match_texts(&["FINAL", "RUNNING"]) {
48670 let text = self.previous().text.to_ascii_uppercase();
48671 Some(if text == "FINAL" {
48672 MatchRecognizeSemantics::Final
48673 } else {
48674 MatchRecognizeSemantics::Running
48675 })
48676 } else {
48677 None
48678 };
48679
48680 let this = self.parse_expression()?;
48682
48683 Ok(Some(Expression::MatchRecognizeMeasure(Box::new(
48684 MatchRecognizeMeasure { this, window_frame },
48685 ))))
48686 }
48687
48688 #[allow(unused_variables, unused_mut)]
48692 pub fn parse_max_min_by(&mut self, is_max: bool) -> Result<Option<Expression>> {
48693 let mut args = Vec::new();
48694
48695 let distinct = if self.match_token(TokenType::Distinct) {
48697 let lambda_expr = self.parse_lambda()?;
48698 if let Some(expr) = lambda_expr {
48699 args.push(expr);
48700 }
48701 self.match_token(TokenType::Comma);
48702 true
48703 } else {
48704 false
48705 };
48706
48707 loop {
48709 if let Some(arg) = self.parse_lambda()? {
48710 args.push(arg);
48711 } else {
48712 break;
48713 }
48714 if !self.match_token(TokenType::Comma) {
48715 break;
48716 }
48717 }
48718
48719 let this = args
48720 .get(0)
48721 .cloned()
48722 .map(Box::new)
48723 .unwrap_or_else(|| Box::new(Expression::Null(Null)));
48724 let expression = args
48725 .get(1)
48726 .cloned()
48727 .map(Box::new)
48728 .unwrap_or_else(|| Box::new(Expression::Null(Null)));
48729 let count = args.get(2).cloned().map(Box::new);
48730
48731 if is_max {
48732 Ok(Some(Expression::ArgMax(Box::new(ArgMax {
48733 this,
48734 expression,
48735 count,
48736 }))))
48737 } else {
48738 Ok(Some(Expression::ArgMin(Box::new(ArgMin {
48739 this,
48740 expression,
48741 count,
48742 }))))
48743 }
48744 }
48745
48746 pub fn parse_merge(&mut self) -> Result<Option<Expression>> {
48749 self.match_token(TokenType::Into);
48751
48752 let mut target = Expression::Table(Box::new(self.parse_table_ref()?));
48754
48755 if self.check(TokenType::With) && self.check_next(TokenType::LParen) {
48757 if let Expression::Table(ref mut table) = target {
48758 if let Some(hint_expr) = self.parse_table_hints()? {
48759 match hint_expr {
48760 Expression::Tuple(tuple) => {
48761 table.hints = tuple.expressions;
48762 }
48763 other => {
48764 table.hints = vec![other];
48765 }
48766 }
48767 }
48768 }
48769 }
48770
48771 if self.match_token(TokenType::As) {
48775 if let Some(alias_expr) = self.parse_id_var()? {
48776 if let Expression::Identifier(ident) = alias_expr {
48778 target = Expression::Alias(Box::new(Alias {
48779 this: target,
48780 alias: ident,
48781 column_aliases: Vec::new(),
48782 pre_alias_comments: Vec::new(),
48783 trailing_comments: Vec::new(),
48784 inferred_type: None,
48785 }));
48786 }
48787 }
48788 } else if !self.check(TokenType::Using) {
48789 if let Some(alias_expr) = self.parse_id_var()? {
48792 if let Expression::Identifier(ident) = alias_expr {
48793 target = Expression::Alias(Box::new(Alias {
48794 this: target,
48795 alias: ident,
48796 column_aliases: Vec::new(),
48797 pre_alias_comments: Vec::new(),
48798 trailing_comments: Vec::new(),
48799 inferred_type: None,
48800 }));
48801 }
48802 }
48803 }
48804
48805 if !self.match_token(TokenType::Using) {
48807 return Err(self.parse_error("Expected USING in MERGE statement"));
48808 }
48809
48810 let mut using = if self.match_token(TokenType::LParen) {
48812 let query = self.parse_statement()?;
48814 self.expect(TokenType::RParen)?;
48815 let trailing = self.previous_trailing_comments().to_vec();
48816 let mut subq = Subquery {
48817 this: query,
48818 alias: None,
48819 column_aliases: Vec::new(),
48820 order_by: None,
48821 limit: None,
48822 offset: None,
48823 distribute_by: None,
48824 sort_by: None,
48825 cluster_by: None,
48826 lateral: false,
48827 modifiers_inside: false,
48828 trailing_comments: trailing,
48829 inferred_type: None,
48830 };
48831 if self.match_token(TokenType::As) {
48833 let alias_name = self.expect_identifier_or_keyword()?;
48834 subq.alias = Some(Identifier::new(alias_name));
48835 if self.match_token(TokenType::LParen) {
48837 let mut cols = Vec::new();
48838 loop {
48839 let col_name = self.expect_identifier_or_keyword()?;
48840 cols.push(Identifier::new(col_name));
48841 if !self.match_token(TokenType::Comma) {
48842 break;
48843 }
48844 }
48845 self.expect(TokenType::RParen)?;
48846 subq.column_aliases = cols;
48847 }
48848 } else if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
48849 let alias_name = self.expect_identifier_or_keyword()?;
48851 subq.alias = Some(Identifier::new(alias_name));
48852 if self.match_token(TokenType::LParen) {
48854 let mut cols = Vec::new();
48855 loop {
48856 let col_name = self.expect_identifier_or_keyword()?;
48857 cols.push(Identifier::new(col_name));
48858 if !self.match_token(TokenType::Comma) {
48859 break;
48860 }
48861 }
48862 self.expect(TokenType::RParen)?;
48863 subq.column_aliases = cols;
48864 }
48865 }
48866 Expression::Subquery(Box::new(subq))
48867 } else {
48868 Expression::Table(Box::new(self.parse_table_ref()?))
48869 };
48870
48871 if matches!(&using, Expression::Table(_)) {
48873 if self.match_token(TokenType::As) {
48874 if let Some(alias_expr) = self.parse_id_var()? {
48875 if let Expression::Identifier(ident) = alias_expr {
48876 using = Expression::Alias(Box::new(Alias {
48877 this: using,
48878 alias: ident,
48879 column_aliases: Vec::new(),
48880 pre_alias_comments: Vec::new(),
48881 trailing_comments: Vec::new(),
48882 inferred_type: None,
48883 }));
48884 }
48885 }
48886 } else if !self.check(TokenType::On) {
48887 if let Some(alias_expr) = self.parse_id_var()? {
48890 if let Expression::Identifier(ident) = alias_expr {
48891 using = Expression::Alias(Box::new(Alias {
48892 this: using,
48893 alias: ident,
48894 column_aliases: Vec::new(),
48895 pre_alias_comments: Vec::new(),
48896 trailing_comments: Vec::new(),
48897 inferred_type: None,
48898 }));
48899 }
48900 }
48901 }
48902 }
48903
48904 let on = if self.match_token(TokenType::On) {
48906 Some(Box::new(self.parse_expression()?))
48907 } else {
48908 None
48909 };
48910
48911 let using_cond = if self.match_token(TokenType::Using) {
48913 if self.match_token(TokenType::LParen) {
48915 let mut idents = Vec::new();
48916 loop {
48917 if let Some(ident) = self.parse_id_var()? {
48919 idents.push(ident);
48920 } else {
48921 break;
48922 }
48923 if !self.match_token(TokenType::Comma) {
48924 break;
48925 }
48926 }
48927 self.match_token(TokenType::RParen);
48928 if !idents.is_empty() {
48929 Some(Box::new(Expression::Tuple(Box::new(Tuple {
48930 expressions: idents,
48931 }))))
48932 } else {
48933 None
48934 }
48935 } else {
48936 let mut idents = Vec::new();
48938 loop {
48939 if let Some(ident) = self.parse_id_var()? {
48940 idents.push(ident);
48941 } else {
48942 break;
48943 }
48944 if !self.match_token(TokenType::Comma) {
48945 break;
48946 }
48947 }
48948 if !idents.is_empty() {
48949 Some(Box::new(Expression::Tuple(Box::new(Tuple {
48950 expressions: idents,
48951 }))))
48952 } else {
48953 None
48954 }
48955 }
48956 } else {
48957 None
48958 };
48959
48960 let whens = self.parse_when_matched_clauses()?;
48962
48963 let returning = if let Some(ret) = self.parse_returning()? {
48965 Some(ret)
48966 } else if self.match_token(TokenType::Output) {
48967 let output = self.parse_output_clause()?;
48969 Some(Expression::Returning(Box::new(Returning {
48970 expressions: output.columns,
48971 into: output.into_table.map(Box::new),
48972 })))
48973 } else {
48974 None
48975 };
48976
48977 Ok(Some(Expression::Merge(Box::new(Merge {
48978 this: Box::new(target),
48979 using: Box::new(using),
48980 on,
48981 using_cond,
48982 whens: whens.map(Box::new),
48983 with_: None,
48984 returning: returning.map(Box::new),
48985 }))))
48986 }
48987
48988 fn parse_when_matched_clauses(&mut self) -> Result<Option<Expression>> {
48990 let mut whens = Vec::new();
48991
48992 while self.match_token(TokenType::When) {
48993 let matched = !self.match_token(TokenType::Not);
48995 self.match_text_seq(&["MATCHED"]);
48996
48997 let source = if self.match_text_seq(&["BY", "TARGET"]) {
48999 Some(Box::new(Expression::Boolean(BooleanLiteral {
49000 value: false,
49001 })))
49002 } else if self.match_text_seq(&["BY", "SOURCE"]) {
49003 Some(Box::new(Expression::Boolean(BooleanLiteral {
49004 value: true,
49005 })))
49006 } else {
49007 None
49008 };
49009
49010 let condition = if self.match_token(TokenType::And) {
49012 Some(Box::new(self.parse_expression()?))
49013 } else {
49014 None
49015 };
49016
49017 if !self.match_token(TokenType::Then) {
49019 return Err(self.parse_error("Expected THEN in WHEN clause"));
49020 }
49021
49022 let then: Expression = if self.match_token(TokenType::Insert) {
49024 let mut elements = vec![Expression::Var(Box::new(Var {
49026 this: "INSERT".to_string(),
49027 }))];
49028
49029 if self.match_token(TokenType::Star) {
49031 elements.push(Expression::Star(crate::expressions::Star {
49032 table: None,
49033 except: None,
49034 replace: None,
49035 rename: None,
49036 trailing_comments: Vec::new(),
49037 span: None,
49038 }));
49039 } else
49040 if self.match_token(TokenType::LParen) {
49042 let mut columns: Vec<Expression> = Vec::new();
49043 loop {
49044 if let Some(col) = self.parse_id_var()? {
49045 let col = if self.match_token(TokenType::Dot) {
49047 if let Expression::Identifier(table_ident) = col {
49048 if let Some(col_expr) = self.parse_id_var()? {
49049 if let Expression::Identifier(col_ident) = col_expr {
49050 Expression::boxed_column(Column {
49051 name: col_ident,
49052 table: Some(table_ident),
49053 join_mark: false,
49054 trailing_comments: Vec::new(),
49055 span: None,
49056 inferred_type: None,
49057 })
49058 } else {
49059 col_expr
49060 }
49061 } else {
49062 return Err(self.parse_error(
49063 "Expected column name after dot in MERGE INSERT",
49064 ));
49065 }
49066 } else {
49067 col
49068 }
49069 } else {
49070 col
49071 };
49072 columns.push(col);
49073 } else {
49074 break;
49075 }
49076 if !self.match_token(TokenType::Comma) {
49077 break;
49078 }
49079 }
49080 self.match_token(TokenType::RParen);
49081 if !columns.is_empty() {
49082 elements.push(Expression::Tuple(Box::new(Tuple {
49083 expressions: columns,
49084 })));
49085 }
49086 }
49087
49088 if self.match_text_seq(&["VALUES"]) {
49090 if let Some(values) = self.parse_value()? {
49091 elements.push(values);
49092 }
49093 } else if self.match_text_seq(&["ROW"]) {
49094 elements.push(Expression::Var(Box::new(Var {
49095 this: "ROW".to_string(),
49096 })));
49097 }
49098
49099 if elements.len() == 1 {
49100 elements[0].clone()
49101 } else {
49102 Expression::Tuple(Box::new(Tuple {
49103 expressions: elements,
49104 }))
49105 }
49106 } else if self.match_token(TokenType::Update) {
49107 let mut elements = vec![Expression::Var(Box::new(Var {
49109 this: "UPDATE".to_string(),
49110 }))];
49111
49112 if self.match_token(TokenType::Star) {
49114 elements.push(Expression::Star(crate::expressions::Star {
49115 table: None,
49116 except: None,
49117 replace: None,
49118 rename: None,
49119 trailing_comments: Vec::new(),
49120 span: None,
49121 }));
49122 } else if self.match_token(TokenType::Set) {
49123 let mut assignments: Vec<Expression> = Vec::new();
49125 loop {
49126 if let Some(col) = self.parse_id_var()? {
49128 let col = if self.match_token(TokenType::Dot) {
49130 if let Expression::Identifier(table_ident) = col {
49132 if let Some(col_expr) = self.parse_id_var()? {
49134 if let Expression::Identifier(col_ident) = col_expr {
49135 Expression::boxed_column(Column {
49136 name: col_ident,
49137 table: Some(table_ident),
49138 join_mark: false,
49139 trailing_comments: Vec::new(),
49140 span: None,
49141 inferred_type: None,
49142 })
49143 } else {
49144 col_expr
49145 }
49146 } else {
49147 return Err(
49148 self.parse_error("Expected column name after dot")
49149 );
49150 }
49151 } else {
49152 col
49153 }
49154 } else {
49155 col
49156 };
49157 if self.match_token(TokenType::Eq) {
49158 let value = self.parse_expression()?;
49159 let assignment = Expression::Eq(Box::new(BinaryOp {
49161 left: col,
49162 right: value,
49163 left_comments: Vec::new(),
49164 operator_comments: Vec::new(),
49165 trailing_comments: Vec::new(),
49166 inferred_type: None,
49167 }));
49168 assignments.push(assignment);
49169 }
49170 }
49171 if !self.match_token(TokenType::Comma) {
49172 break;
49173 }
49174 }
49175 if !assignments.is_empty() {
49176 elements.push(Expression::Tuple(Box::new(Tuple {
49177 expressions: assignments,
49178 })));
49179 }
49180 }
49181
49182 if elements.len() == 1 {
49183 elements[0].clone()
49184 } else {
49185 Expression::Tuple(Box::new(Tuple {
49186 expressions: elements,
49187 }))
49188 }
49189 } else if self.match_token(TokenType::Delete) {
49190 Expression::Var(Box::new(Var {
49192 this: "DELETE".to_string(),
49193 }))
49194 } else if self.match_identifier("DO") {
49195 if self.match_identifier("NOTHING") {
49197 Expression::Var(Box::new(Var {
49198 this: "DO NOTHING".to_string(),
49199 }))
49200 } else {
49201 return Err(self.parse_error("Expected NOTHING after DO"));
49202 }
49203 } else {
49204 if let Some(var) = self.parse_var()? {
49206 var
49207 } else {
49208 return Err(
49209 self.parse_error("Expected INSERT, UPDATE, DELETE, or action keyword")
49210 );
49211 }
49212 };
49213
49214 whens.push(Expression::When(Box::new(When {
49215 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
49216 value: matched,
49217 }))),
49218 source,
49219 condition,
49220 then: Box::new(then),
49221 })));
49222 }
49223
49224 if whens.is_empty() {
49225 Ok(None)
49226 } else {
49227 Ok(Some(Expression::Whens(Box::new(Whens {
49228 expressions: whens,
49229 }))))
49230 }
49231 }
49232
49233 pub fn parse_mergeblockratio(&mut self) -> Result<Option<Expression>> {
49237 self.parse_mergeblockratio_impl(false, false)
49238 }
49239
49240 pub fn parse_mergeblockratio_impl(
49242 &mut self,
49243 no: bool,
49244 default: bool,
49245 ) -> Result<Option<Expression>> {
49246 if self.match_token(TokenType::Eq) {
49248 let this = self.parse_number()?;
49249 let percent = self.match_token(TokenType::Percent);
49250
49251 Ok(Some(Expression::MergeBlockRatioProperty(Box::new(
49252 MergeBlockRatioProperty {
49253 this: this.map(Box::new),
49254 no: None,
49255 default: None,
49256 percent: if percent {
49257 Some(Box::new(Expression::Boolean(BooleanLiteral {
49258 value: true,
49259 })))
49260 } else {
49261 None
49262 },
49263 },
49264 ))))
49265 } else {
49266 Ok(Some(Expression::MergeBlockRatioProperty(Box::new(
49268 MergeBlockRatioProperty {
49269 this: None,
49270 no: if no {
49271 Some(Box::new(Expression::Boolean(BooleanLiteral {
49272 value: true,
49273 })))
49274 } else {
49275 None
49276 },
49277 default: if default {
49278 Some(Box::new(Expression::Boolean(BooleanLiteral {
49279 value: true,
49280 })))
49281 } else {
49282 None
49283 },
49284 percent: None,
49285 },
49286 ))))
49287 }
49288 }
49289
49290 #[allow(unused_variables, unused_mut)]
49292 pub fn parse_modifies_property(&mut self) -> Result<Option<Expression>> {
49293 if self.match_text_seq(&["SQL", "DATA"]) {
49294 return Ok(None);
49296 }
49297 Ok(None)
49298 }
49299
49300 pub fn parse_multitable_inserts(
49304 &mut self,
49305 leading_comments: Vec<String>,
49306 ) -> Result<Option<Expression>> {
49307 let kind = self.previous().text.to_ascii_uppercase();
49309
49310 let mut expressions = Vec::new();
49311
49312 loop {
49315 let condition = if self.match_token(TokenType::When) {
49317 let cond = self.parse_or()?;
49318 self.match_token(TokenType::Then);
49319 Some(cond)
49320 } else {
49321 None
49322 };
49323
49324 let is_else = self.match_token(TokenType::Else);
49326
49327 if !self.match_token(TokenType::Into) {
49329 break;
49330 }
49331
49332 let table_expr = self.parse_table_parts()?;
49334
49335 let table_ref = if let Some(Expression::Table(t)) = table_expr {
49337 *t
49338 } else {
49339 TableRef::new("")
49341 };
49342
49343 let columns = if self.match_token(TokenType::LParen) {
49345 let cols = self.parse_identifier_list()?;
49346 self.expect(TokenType::RParen)?;
49347 cols
49348 } else {
49349 Vec::new()
49350 };
49351
49352 let values = if self.match_token(TokenType::Values) {
49354 self.expect(TokenType::LParen)?;
49355 let row = self.parse_expression_list()?;
49356 self.expect(TokenType::RParen)?;
49357 vec![row]
49358 } else {
49359 Vec::new()
49360 };
49361
49362 let insert_expr = Expression::Insert(Box::new(Insert {
49364 table: table_ref,
49365 columns,
49366 values,
49367 query: None,
49368 overwrite: false,
49369 partition: Vec::new(),
49370 directory: None,
49371 returning: Vec::new(),
49372 output: None,
49373 on_conflict: None,
49374 leading_comments: Vec::new(),
49375 if_exists: false,
49376 with: None,
49377 ignore: false,
49378 source_alias: None,
49379 alias: None,
49380 alias_explicit_as: false,
49381 default_values: false,
49382 by_name: false,
49383 conflict_action: None,
49384 is_replace: false,
49385 replace_where: None,
49386 source: None,
49387 hint: None,
49388 function_target: None,
49389 partition_by: None,
49390 settings: Vec::new(),
49391 }));
49392
49393 let conditional_insert = Expression::ConditionalInsert(Box::new(ConditionalInsert {
49395 this: Box::new(insert_expr),
49396 expression: condition.map(Box::new),
49397 else_: if is_else {
49398 Some(Box::new(Expression::Boolean(BooleanLiteral {
49399 value: true,
49400 })))
49401 } else {
49402 None
49403 },
49404 }));
49405
49406 expressions.push(conditional_insert);
49407 }
49408
49409 let source = self.parse_statement()?;
49411
49412 Ok(Some(Expression::MultitableInserts(Box::new(
49413 MultitableInserts {
49414 kind,
49415 expressions,
49416 source: Some(Box::new(source)),
49417 leading_comments,
49418 },
49419 ))))
49420 }
49421
49422 #[allow(unused_variables, unused_mut)]
49425 pub fn parse_name_as_expression(&mut self) -> Result<Option<Expression>> {
49426 let this = self.parse_id_var()?;
49428 if this.is_none() {
49429 return Ok(None);
49430 }
49431
49432 if self.match_token(TokenType::Alias) {
49434 let expression = self.parse_disjunction()?;
49435 if expression.is_none() {
49436 return Ok(this);
49437 }
49438
49439 let alias_ident =
49441 match this.ok_or_else(|| self.parse_error("Expected identifier for alias"))? {
49442 Expression::Identifier(id) => id,
49443 _ => Identifier::new(String::new()),
49444 };
49445
49446 return Ok(Some(Expression::Alias(Box::new(Alias {
49447 this: expression.ok_or_else(|| self.parse_error("Expected expression after AS"))?,
49448 alias: alias_ident,
49449 column_aliases: Vec::new(),
49450 pre_alias_comments: Vec::new(),
49451 trailing_comments: Vec::new(),
49452 inferred_type: None,
49453 }))));
49454 }
49455
49456 Ok(this)
49457 }
49458
49459 #[allow(unused_variables, unused_mut)]
49462 pub fn parse_named_window(&mut self) -> Result<Option<Expression>> {
49463 let name = self.parse_id_var()?;
49465 if name.is_none() {
49466 return Ok(None);
49467 }
49468
49469 if !self.match_token(TokenType::As) {
49471 return Ok(name); }
49473
49474 self.expect(TokenType::LParen)?;
49476 let spec = self.parse_window_spec_inner()?;
49477 self.expect(TokenType::RParen)?;
49478
49479 if let (Some(name_expr), Some(spec_expr)) = (name, spec) {
49480 let alias_ident = if let Expression::Identifier(id) = name_expr {
49482 id
49483 } else {
49484 Identifier::new("window")
49485 };
49486 Ok(Some(Expression::Alias(Box::new(Alias {
49487 this: spec_expr,
49488 alias: alias_ident,
49489 column_aliases: Vec::new(),
49490 pre_alias_comments: Vec::new(),
49491 trailing_comments: Vec::new(),
49492 inferred_type: None,
49493 }))))
49494 } else {
49495 Ok(None)
49496 }
49497 }
49498
49499 #[allow(unused_variables, unused_mut)]
49502 pub fn parse_next_value_for(&mut self) -> Result<Option<Expression>> {
49503 if !self.match_text_seq(&["VALUE", "FOR"]) {
49504 if self.current > 0 {
49506 self.current -= 1;
49507 }
49508 return Ok(None);
49509 }
49510
49511 let first = self
49514 .parse_id_var()?
49515 .ok_or_else(|| self.parse_error("Expected sequence name after NEXT VALUE FOR"))?;
49516 let first_id = match first {
49517 Expression::Identifier(id) => id,
49518 Expression::Var(v) => Identifier {
49519 name: v.this,
49520 quoted: false,
49521 trailing_comments: Vec::new(),
49522 span: None,
49523 },
49524 _ => Identifier {
49525 name: String::new(),
49526 quoted: false,
49527 trailing_comments: Vec::new(),
49528 span: None,
49529 },
49530 };
49531
49532 let mut parts = vec![first_id];
49534 while self.match_token(TokenType::Dot) {
49535 if self.is_identifier_or_keyword_token() {
49536 let token = self.advance();
49537 parts.push(Identifier {
49538 name: token.text,
49539 quoted: token.token_type == TokenType::QuotedIdentifier,
49540 trailing_comments: Vec::new(),
49541 span: None,
49542 });
49543 } else {
49544 break;
49545 }
49546 }
49547
49548 let this = if parts.len() == 1 {
49550 Expression::boxed_column(Column {
49551 name: parts.remove(0),
49552 table: None,
49553 join_mark: false,
49554 trailing_comments: Vec::new(),
49555 span: None,
49556 inferred_type: None,
49557 })
49558 } else if parts.len() == 2 {
49559 Expression::boxed_column(Column {
49560 name: parts.remove(1),
49561 table: Some(parts.remove(0)),
49562 join_mark: false,
49563 trailing_comments: Vec::new(),
49564 span: None,
49565 inferred_type: None,
49566 })
49567 } else {
49568 let mut expr = Expression::Identifier(parts.remove(0));
49570 for part in parts.drain(..) {
49571 expr = Expression::Dot(Box::new(DotAccess {
49572 this: expr,
49573 field: part,
49574 }));
49575 }
49576 expr
49577 };
49578
49579 let order = if self.match_token(TokenType::Over) {
49581 if self.match_token(TokenType::LParen) {
49582 let ord = self.parse_order()?;
49583 self.expect(TokenType::RParen)?;
49584 ord.map(Box::new)
49585 } else {
49586 None
49587 }
49588 } else {
49589 None
49590 };
49591
49592 Ok(Some(Expression::NextValueFor(Box::new(NextValueFor {
49593 this: Box::new(this),
49594 order,
49595 }))))
49596 }
49597
49598 #[allow(unused_variables, unused_mut)]
49600 pub fn parse_no_property(&mut self) -> Result<Option<Expression>> {
49601 if self.match_text_seq(&["PRIMARY", "INDEX"]) {
49602 return Ok(None);
49604 }
49605 if self.match_text_seq(&["SQL"]) {
49606 return Ok(None);
49608 }
49609 Ok(None)
49610 }
49611
49612 #[allow(unused_variables, unused_mut)]
49614 pub fn parse_normalize(&mut self) -> Result<Option<Expression>> {
49617 let this = self.parse_expression()?;
49619
49620 let form = if self.match_token(TokenType::Comma) {
49622 self.parse_var()?.map(Box::new)
49623 } else {
49624 None
49625 };
49626
49627 Ok(Some(Expression::Normalize(Box::new(Normalize {
49628 this: Box::new(this),
49629 form,
49630 is_casefold: None,
49631 }))))
49632 }
49633
49634 pub fn parse_not_constraint(&mut self) -> Result<Option<Expression>> {
49637 if self.match_text_seq(&["NULL"]) {
49639 return Ok(Some(Expression::NotNullColumnConstraint(Box::new(
49640 NotNullColumnConstraint { allow_null: None },
49641 ))));
49642 }
49643 if self.match_text_seq(&["CASESPECIFIC"]) {
49645 return Ok(Some(Expression::CaseSpecificColumnConstraint(Box::new(
49646 CaseSpecificColumnConstraint {
49647 not_: Some(Box::new(Expression::Boolean(BooleanLiteral {
49648 value: true,
49649 }))),
49650 },
49651 ))));
49652 }
49653 if self.match_token(TokenType::For) && self.match_identifier("REPLICATION") {
49655 return Ok(Some(Expression::Property(Box::new(
49656 crate::expressions::Property {
49657 this: Box::new(Expression::Identifier(Identifier::new(
49658 "NOT FOR REPLICATION".to_string(),
49659 ))),
49660 value: None,
49661 },
49662 ))));
49663 }
49664 Ok(None)
49665 }
49666
49667 pub fn parse_null(&mut self) -> Result<Option<Expression>> {
49670 if self.match_token(TokenType::Null) {
49671 return Ok(Some(Expression::Null(Null)));
49672 }
49673 if self.match_token(TokenType::Unknown) {
49675 return Ok(Some(Expression::Null(Null)));
49676 }
49677 Ok(None)
49678 }
49679
49680 pub fn parse_number(&mut self) -> Result<Option<Expression>> {
49684 if self.match_token(TokenType::Number) {
49685 let text = self.previous().text.clone();
49686 if let Some(sep_pos) = text.find("::") {
49688 let num_part = &text[..sep_pos];
49689 let type_name = &text[sep_pos + 2..];
49690 let num_expr = Expression::Literal(Box::new(Literal::Number(num_part.to_string())));
49692 let data_type = match type_name {
49693 "BIGINT" => crate::expressions::DataType::BigInt { length: None },
49694 "SMALLINT" => crate::expressions::DataType::SmallInt { length: None },
49695 "TINYINT" => crate::expressions::DataType::TinyInt { length: None },
49696 "DOUBLE" => crate::expressions::DataType::Double {
49697 precision: None,
49698 scale: None,
49699 },
49700 "FLOAT" => crate::expressions::DataType::Float {
49701 precision: None,
49702 scale: None,
49703 real_spelling: false,
49704 },
49705 "DECIMAL" => crate::expressions::DataType::Decimal {
49706 precision: None,
49707 scale: None,
49708 },
49709 _ => crate::expressions::DataType::Custom {
49710 name: type_name.to_string(),
49711 },
49712 };
49713 return Ok(Some(Expression::TryCast(Box::new(
49714 crate::expressions::Cast {
49715 this: num_expr,
49716 to: data_type,
49717 trailing_comments: Vec::new(),
49718 double_colon_syntax: false,
49719 format: None,
49720 default: None,
49721 inferred_type: None,
49722 },
49723 ))));
49724 }
49725 return Ok(Some(Expression::Literal(Box::new(Literal::Number(text)))));
49726 }
49727 Ok(None)
49728 }
49729
49730 #[allow(unused_variables, unused_mut)]
49732 pub fn parse_odbc_datetime_literal(&mut self) -> Result<Option<Expression>> {
49735 if !self.match_token(TokenType::Var) {
49737 return Ok(None);
49738 }
49739 let type_indicator = self.previous().text.to_lowercase();
49740
49741 let value = self.parse_string()?;
49743 if value.is_none() {
49744 return Ok(None);
49745 }
49746
49747 self.expect(TokenType::RBrace)?;
49749
49750 let value = value
49752 .ok_or_else(|| self.parse_error("Expected string value in ODBC datetime literal"))?;
49753 match type_indicator.as_str() {
49754 "d" => Ok(Some(Expression::Date(Box::new(UnaryFunc::new(value))))),
49755 "t" => Ok(Some(Expression::Time(Box::new(UnaryFunc::new(value))))),
49756 "ts" => Ok(Some(Expression::Timestamp(Box::new(TimestampFunc {
49757 this: Some(Box::new(value)),
49758 zone: None,
49759 with_tz: None,
49760 safe: None,
49761 })))),
49762 _ => Ok(Some(value)),
49763 }
49764 }
49765
49766 pub fn parse_offset(&mut self) -> Result<Option<Expression>> {
49769 if !self.match_token(TokenType::Offset) {
49770 return Ok(None);
49771 }
49772 let offset_expr = self.parse_expression()?;
49774 Ok(Some(Expression::Offset(Box::new(Offset {
49775 this: offset_expr,
49776 rows: None,
49777 }))))
49778 }
49779
49780 #[allow(unused_variables, unused_mut)]
49782 pub fn parse_on_condition(&mut self) -> Result<Option<Expression>> {
49785 let empty = if self.match_text_seq(&["NULL", "ON", "EMPTY"]) {
49787 Some(Box::new(Expression::Identifier(Identifier::new(
49788 "NULL".to_string(),
49789 ))))
49790 } else if self.match_text_seq(&["ERROR", "ON", "EMPTY"]) {
49791 Some(Box::new(Expression::Identifier(Identifier::new(
49792 "ERROR".to_string(),
49793 ))))
49794 } else if self.match_text_seq(&["DEFAULT"]) {
49795 let default_val = self.parse_expression()?;
49796 if self.match_text_seq(&["ON", "EMPTY"]) {
49797 Some(Box::new(default_val))
49798 } else {
49799 None
49800 }
49801 } else {
49802 None
49803 };
49804
49805 let error = if self.match_text_seq(&["NULL", "ON", "ERROR"]) {
49807 Some(Box::new(Expression::Identifier(Identifier::new(
49808 "NULL".to_string(),
49809 ))))
49810 } else if self.match_text_seq(&["ERROR", "ON", "ERROR"]) {
49811 Some(Box::new(Expression::Identifier(Identifier::new(
49812 "ERROR".to_string(),
49813 ))))
49814 } else if self.match_text_seq(&["DEFAULT"]) {
49815 let default_val = self.parse_expression()?;
49816 if self.match_text_seq(&["ON", "ERROR"]) {
49817 Some(Box::new(default_val))
49818 } else {
49819 None
49820 }
49821 } else {
49822 None
49823 };
49824
49825 let null = if self.match_text_seq(&["NULL", "ON", "NULL"]) {
49827 Some(Box::new(Expression::Identifier(Identifier::new(
49828 "NULL".to_string(),
49829 ))))
49830 } else {
49831 None
49832 };
49833
49834 if empty.is_none() && error.is_none() && null.is_none() {
49835 return Ok(None);
49836 }
49837
49838 Ok(Some(Expression::OnCondition(Box::new(OnCondition {
49839 empty,
49840 error,
49841 null,
49842 }))))
49843 }
49844
49845 #[allow(unused_variables, unused_mut)]
49848 pub fn parse_on_handling(&mut self) -> Result<Option<Expression>> {
49849 if self.match_text_seq(&["ON"]) {
49850 return Ok(None);
49852 }
49853 if self.match_text_seq(&["ON"]) {
49854 return Ok(None);
49856 }
49857 Ok(None)
49858 }
49859
49860 #[allow(unused_variables, unused_mut)]
49862 pub fn parse_on_property(&mut self) -> Result<Option<Expression>> {
49863 if self.match_text_seq(&["COMMIT", "PRESERVE", "ROWS"]) {
49864 return Ok(Some(Expression::OnCommitProperty(Box::new(
49865 OnCommitProperty { delete: None },
49866 ))));
49867 }
49868 if self.match_text_seq(&["COMMIT", "DELETE", "ROWS"]) {
49869 return Ok(None);
49871 }
49872 Ok(None)
49873 }
49874
49875 #[allow(unused_variables, unused_mut)]
49877 pub fn parse_opclass(&mut self) -> Result<Option<Expression>> {
49880 let this = self.parse_expression()?;
49882
49883 if self.check(TokenType::Asc)
49886 || self.check(TokenType::Desc)
49887 || self.check(TokenType::Nulls)
49888 || self.check(TokenType::Comma)
49889 || self.check(TokenType::RParen)
49890 {
49891 return Ok(Some(this));
49892 }
49893
49894 if let Some(opclass_name) = self.parse_table()? {
49896 return Ok(Some(Expression::Opclass(Box::new(Opclass {
49897 this: Box::new(this),
49898 expression: Box::new(opclass_name),
49899 }))));
49900 }
49901
49902 Ok(Some(this))
49903 }
49904
49905 pub fn parse_open_json(&mut self) -> Result<Option<Expression>> {
49908 let this = self.parse_expression()?;
49910
49911 let path = if self.match_token(TokenType::Comma) {
49913 self.parse_string()?.map(Box::new)
49914 } else {
49915 None
49916 };
49917
49918 let expressions = if self.match_token(TokenType::RParen)
49920 && self.match_token(TokenType::With)
49921 {
49922 self.expect(TokenType::LParen)?;
49923 let mut cols = Vec::new();
49924 loop {
49925 let col_name = self.parse_field()?;
49927 if col_name.is_none() {
49928 break;
49929 }
49930 let col_type = self.parse_data_type()?;
49931 let col_path = self.parse_string()?.map(Box::new);
49932 let as_json = if self.match_token(TokenType::As) && self.match_identifier("JSON") {
49933 Some(Box::new(Expression::Boolean(BooleanLiteral {
49934 value: true,
49935 })))
49936 } else {
49937 None
49938 };
49939 cols.push(Expression::OpenJSONColumnDef(Box::new(OpenJSONColumnDef {
49940 this: Box::new(col_name.ok_or_else(|| {
49941 self.parse_error("Expected column name in OPENJSON WITH clause")
49942 })?),
49943 kind: String::new(), path: col_path,
49945 as_json,
49946 data_type: Some(col_type),
49947 })));
49948 if !self.match_token(TokenType::Comma) {
49949 break;
49950 }
49951 }
49952 self.expect(TokenType::RParen)?;
49953 cols
49954 } else {
49955 Vec::new()
49956 };
49957
49958 Ok(Some(Expression::OpenJSON(Box::new(OpenJSON {
49959 this: Box::new(this),
49960 path,
49961 expressions,
49962 }))))
49963 }
49964
49965 #[allow(unused_variables, unused_mut)]
49967 pub fn parse_operator(&mut self, this: Option<Expression>) -> Result<Option<Expression>> {
49970 let mut result = this;
49971
49972 while self.match_token(TokenType::LParen) {
49974 let mut op_text = String::new();
49976 while !self.check(TokenType::RParen) && !self.is_at_end() {
49977 op_text.push_str(&self.peek().text);
49978 self.skip();
49979 }
49980 self.expect(TokenType::RParen)?;
49981
49982 let rhs = self.parse_expression()?;
49984
49985 result = Some(Expression::Operator(Box::new(Operator {
49986 this: Box::new(result.unwrap_or_else(|| Expression::Null(Null))),
49987 operator: Some(Box::new(Expression::Identifier(Identifier::new(op_text)))),
49988 expression: Box::new(rhs),
49989 comments: Vec::new(),
49990 })));
49991
49992 if !self.match_token(TokenType::Operator) {
49994 break;
49995 }
49996 }
49997
49998 Ok(result)
49999 }
50000
50001 pub fn parse_order(&mut self) -> Result<Option<Expression>> {
50004 if !self.match_token(TokenType::Order) {
50005 return Ok(None);
50006 }
50007 self.match_token(TokenType::By);
50009
50010 let mut expressions = Vec::new();
50012 loop {
50013 if let Some(ordered) = self.parse_ordered_item()? {
50014 expressions.push(ordered);
50015 } else {
50016 break;
50017 }
50018 if !self.match_token(TokenType::Comma) {
50019 break;
50020 }
50021 }
50022
50023 Ok(Some(Expression::OrderBy(Box::new(OrderBy {
50024 expressions,
50025 siblings: false,
50026 comments: Vec::new(),
50027 }))))
50028 }
50029
50030 fn parse_ordered_item(&mut self) -> Result<Option<Ordered>> {
50032 let expr = match self.parse_expression() {
50034 Ok(e) => e,
50035 Err(_) => return Ok(None),
50036 };
50037
50038 let mut desc = false;
50040 let mut explicit_asc = false;
50041 if self.match_token(TokenType::Asc) {
50042 explicit_asc = true;
50043 } else if self.match_token(TokenType::Desc) {
50044 desc = true;
50045 }
50046
50047 let nulls_first = if self.match_text_seq(&["NULLS", "FIRST"]) {
50049 Some(true)
50050 } else if self.match_text_seq(&["NULLS", "LAST"]) {
50051 Some(false)
50052 } else {
50053 None
50054 };
50055
50056 let with_fill = if self.match_text_seq(&["WITH", "FILL"]) {
50058 let from_ = if self.match_token(TokenType::From) {
50059 Some(Box::new(self.parse_or()?))
50060 } else {
50061 None
50062 };
50063 let to = if self.match_text_seq(&["TO"]) {
50064 Some(Box::new(self.parse_or()?))
50065 } else {
50066 None
50067 };
50068 let step = if self.match_text_seq(&["STEP"]) {
50069 Some(Box::new(self.parse_or()?))
50070 } else {
50071 None
50072 };
50073 let staleness = if self.match_text_seq(&["STALENESS"]) {
50074 Some(Box::new(self.parse_or()?))
50075 } else {
50076 None
50077 };
50078 let interpolate = if self.match_text_seq(&["INTERPOLATE"]) {
50079 if self.match_token(TokenType::LParen) {
50080 let exprs = self.parse_expression_list()?;
50081 self.expect(TokenType::RParen)?;
50082 if exprs.len() == 1 {
50083 Some(Box::new(exprs.into_iter().next().unwrap()))
50084 } else {
50085 Some(Box::new(Expression::Tuple(Box::new(
50086 crate::expressions::Tuple { expressions: exprs },
50087 ))))
50088 }
50089 } else {
50090 None
50091 }
50092 } else {
50093 None
50094 };
50095 Some(Box::new(WithFill {
50096 from_,
50097 to,
50098 step,
50099 staleness,
50100 interpolate,
50101 }))
50102 } else {
50103 None
50104 };
50105
50106 Ok(Some(Ordered {
50107 this: expr,
50108 desc,
50109 nulls_first,
50110 explicit_asc,
50111 with_fill,
50112 }))
50113 }
50114
50115 #[allow(unused_variables, unused_mut)]
50117 pub fn parse_ordered(&mut self) -> Result<Option<Expression>> {
50118 if let Some(ordered) = self.parse_ordered_item()? {
50119 return Ok(Some(Expression::Ordered(Box::new(ordered))));
50120 }
50121 if self.match_text_seq(&["NULLS", "FIRST"]) {
50122 return Ok(Some(Expression::WithFill(Box::new(WithFill {
50123 from_: None,
50124 to: None,
50125 step: None,
50126 staleness: None,
50127 interpolate: None,
50128 }))));
50129 }
50130 if self.match_text_seq(&["NULLS", "LAST"]) {
50131 return Ok(None);
50133 }
50134 if self.match_text_seq(&["WITH", "FILL"]) {
50135 return Ok(None);
50137 }
50138 Ok(None)
50139 }
50140
50141 #[allow(unused_variables, unused_mut)]
50144 pub fn parse_overlay(&mut self) -> Result<Option<Expression>> {
50145 let this = match self.parse_bitwise() {
50147 Ok(Some(expr)) => expr,
50148 Ok(None) => return Ok(None),
50149 Err(e) => return Err(e),
50150 };
50151
50152 let replacement = if self.match_text_seq(&["PLACING"]) || self.match_token(TokenType::Comma)
50154 {
50155 match self.parse_bitwise() {
50156 Ok(Some(expr)) => expr,
50157 Ok(None) => {
50158 return Err(self.parse_error("Expected replacement expression in OVERLAY"))
50159 }
50160 Err(e) => return Err(e),
50161 }
50162 } else {
50163 return Err(self.parse_error("Expected PLACING in OVERLAY function"));
50164 };
50165
50166 let from = if self.match_token(TokenType::From) || self.match_token(TokenType::Comma) {
50168 match self.parse_bitwise() {
50169 Ok(Some(expr)) => expr,
50170 Ok(None) => return Err(self.parse_error("Expected position expression in OVERLAY")),
50171 Err(e) => return Err(e),
50172 }
50173 } else {
50174 return Err(self.parse_error("Expected FROM in OVERLAY function"));
50175 };
50176
50177 let length = if self.match_token(TokenType::For) || self.match_token(TokenType::Comma) {
50179 match self.parse_bitwise() {
50180 Ok(Some(expr)) => Some(expr),
50181 Ok(None) => None,
50182 Err(_) => None,
50183 }
50184 } else {
50185 None
50186 };
50187
50188 Ok(Some(Expression::Overlay(Box::new(OverlayFunc {
50189 this,
50190 replacement,
50191 from,
50192 length,
50193 }))))
50194 }
50195
50196 pub fn parse_parameter(&mut self) -> Result<Option<Expression>> {
50199 if self.match_token(TokenType::Parameter) {
50201 let text = self.previous().text.clone();
50202 return Ok(Some(Expression::Parameter(Box::new(Parameter {
50203 name: Some(text),
50204 index: None,
50205 style: ParameterStyle::Colon,
50206 quoted: false,
50207 string_quoted: false,
50208 expression: None,
50209 }))));
50210 }
50211
50212 if self.match_token(TokenType::SessionParameter) {
50214 let text = self.previous().text.clone();
50215 return Ok(Some(Expression::SessionParameter(Box::new(
50216 SessionParameter {
50217 this: Box::new(Expression::Identifier(Identifier::new(text))),
50218 kind: None,
50219 },
50220 ))));
50221 }
50222
50223 Ok(None)
50224 }
50225
50226 #[allow(unused_variables, unused_mut)]
50229 pub fn parse_paren(&mut self) -> Result<Option<Expression>> {
50230 if !self.match_token(TokenType::LParen) {
50231 return Ok(None);
50232 }
50233
50234 if self.match_token(TokenType::RParen) {
50236 return Ok(Some(Expression::Tuple(Box::new(Tuple {
50237 expressions: Vec::new(),
50238 }))));
50239 }
50240
50241 if self.check(TokenType::Select)
50244 || self.check(TokenType::With)
50245 || (matches!(
50246 self.config.dialect,
50247 Some(crate::dialects::DialectType::ClickHouse)
50248 ) && self.check(TokenType::Var)
50249 && self.peek().text.eq_ignore_ascii_case("EXPLAIN"))
50250 {
50251 let query = self.parse_statement()?;
50252 self.expect(TokenType::RParen)?;
50253 return Ok(Some(Expression::Subquery(Box::new(Subquery {
50254 this: query,
50255 alias: None,
50256 column_aliases: Vec::new(),
50257 order_by: None,
50258 limit: None,
50259 offset: None,
50260 lateral: false,
50261 modifiers_inside: true,
50262 trailing_comments: Vec::new(),
50263 distribute_by: None,
50264 sort_by: None,
50265 cluster_by: None,
50266 inferred_type: None,
50267 }))));
50268 }
50269
50270 let mut expressions = Vec::new();
50272 let mut trailing_comma = false;
50273 loop {
50274 match self.parse_expression() {
50275 Ok(expr) => expressions.push(expr),
50276 Err(_) => break,
50277 }
50278 if !self.match_token(TokenType::Comma) {
50279 break;
50280 }
50281 if self.check(TokenType::RParen) {
50283 trailing_comma = true;
50284 break;
50285 }
50286 }
50287
50288 self.expect(TokenType::RParen)?;
50289
50290 if trailing_comma && expressions.len() == 1 {
50292 return Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))));
50293 }
50294
50295 if expressions.len() == 1 {
50297 return Ok(Some(Expression::Paren(Box::new(Paren {
50298 this: expressions.remove(0),
50299 trailing_comments: Vec::new(),
50300 }))));
50301 }
50302
50303 Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))))
50305 }
50306
50307 pub fn parse_partition(&mut self) -> Result<Option<Expression>> {
50310 if !self.match_texts(&["PARTITION", "SUBPARTITION"]) {
50312 return Ok(None);
50313 }
50314
50315 let subpartition = self.previous().text.eq_ignore_ascii_case("SUBPARTITION");
50316
50317 if !self.match_token(TokenType::LParen) {
50319 return Ok(Some(Expression::Partition(Box::new(Partition {
50321 expressions: Vec::new(),
50322 subpartition,
50323 }))));
50324 }
50325
50326 let mut expressions = Vec::new();
50327 loop {
50328 if let Some(expr) = self.parse_disjunction()? {
50329 expressions.push(expr);
50330 } else {
50331 break;
50332 }
50333
50334 if !self.match_token(TokenType::Comma) {
50335 break;
50336 }
50337 }
50338
50339 self.match_token(TokenType::RParen);
50340
50341 Ok(Some(Expression::Partition(Box::new(Partition {
50342 expressions,
50343 subpartition,
50344 }))))
50345 }
50346
50347 #[allow(unused_variables, unused_mut)]
50349 pub fn parse_partition_and_order(&mut self) -> Result<Option<Expression>> {
50350 self.parse_partition_by()
50351 }
50352
50353 #[allow(unused_variables, unused_mut)]
50356 pub fn parse_partition_bound_spec_legacy(&mut self) -> Result<Option<Expression>> {
50357 if self.match_text_seq(&["MINVALUE"]) {
50358 return Ok(Some(Expression::PartitionBoundSpec(Box::new(
50359 PartitionBoundSpec {
50360 this: None,
50361 expression: None,
50362 from_expressions: None,
50363 to_expressions: None,
50364 },
50365 ))));
50366 }
50367 if self.match_text_seq(&["MAXVALUE"]) {
50368 return Ok(None);
50370 }
50371 if self.match_text_seq(&["TO"]) {
50372 return Ok(None);
50374 }
50375 Ok(None)
50376 }
50377
50378 #[allow(unused_variables, unused_mut)]
50381 pub fn parse_partition_by(&mut self) -> Result<Option<Expression>> {
50382 if !self.match_keywords(&[TokenType::Partition, TokenType::By]) {
50383 return Ok(None);
50384 }
50385 let expressions = self.parse_expression_list()?;
50386 Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))))
50387 }
50388
50389 pub fn parse_partitioned_by(&mut self) -> Result<Option<Expression>> {
50392 self.match_token(TokenType::Eq);
50394
50395 if let Some(schema) = self.parse_schema()? {
50397 return Ok(Some(Expression::PartitionedByProperty(Box::new(
50398 PartitionedByProperty {
50399 this: Box::new(schema),
50400 },
50401 ))));
50402 }
50403
50404 if let Some(bracket) = self.parse_bracket()? {
50406 return Ok(Some(Expression::PartitionedByProperty(Box::new(
50407 PartitionedByProperty {
50408 this: Box::new(bracket),
50409 },
50410 ))));
50411 }
50412
50413 if let Some(field) = self.parse_field()? {
50415 return Ok(Some(Expression::PartitionedByProperty(Box::new(
50416 PartitionedByProperty {
50417 this: Box::new(field),
50418 },
50419 ))));
50420 }
50421
50422 Ok(None)
50423 }
50424
50425 pub fn parse_partitioned_by_bucket_or_truncate(&mut self) -> Result<Option<Expression>> {
50430 if !self.check(TokenType::LParen) {
50432 if self.current > 0 {
50434 self.current -= 1;
50435 }
50436 return Ok(None);
50437 }
50438
50439 let is_bucket = self.previous().text.eq_ignore_ascii_case("BUCKET");
50441
50442 self.expect(TokenType::LParen)?;
50444 let mut args = Vec::new();
50445
50446 if !self.check(TokenType::RParen) {
50447 loop {
50448 if let Some(expr) = self.parse_primary_or_var()? {
50450 args.push(expr);
50451 } else if let Some(col) = self.parse_column()? {
50452 args.push(col);
50453 }
50454
50455 if !self.match_token(TokenType::Comma) {
50456 break;
50457 }
50458 }
50459 }
50460 self.match_token(TokenType::RParen);
50461
50462 let (mut this, mut expr) = (args.get(0).cloned(), args.get(1).cloned());
50464
50465 if let Some(Expression::Literal(_)) = &this {
50468 std::mem::swap(&mut this, &mut expr);
50469 }
50470
50471 let this_expr = this.unwrap_or(Expression::Null(Null));
50473 let expr_expr = expr.unwrap_or(Expression::Null(Null));
50474
50475 if is_bucket {
50476 Ok(Some(Expression::PartitionedByBucket(Box::new(
50477 PartitionedByBucket {
50478 this: Box::new(this_expr),
50479 expression: Box::new(expr_expr),
50480 },
50481 ))))
50482 } else {
50483 Ok(Some(Expression::PartitionByTruncate(Box::new(
50484 PartitionByTruncate {
50485 this: Box::new(this_expr),
50486 expression: Box::new(expr_expr),
50487 },
50488 ))))
50489 }
50490 }
50491
50492 fn parse_doris_partition_by_range_or_list(&mut self, kind: &str) -> Result<Expression> {
50499 let partition_expressions = self.parse_wrapped_csv()?;
50502
50503 let create_expressions = if self.check(TokenType::LParen) {
50505 self.skip(); if kind == "LIST" {
50508 let partitions = self.parse_doris_list_partition_definitions()?;
50510 self.expect(TokenType::RParen)?;
50511 Some(Box::new(Expression::Tuple(Box::new(Tuple {
50512 expressions: partitions,
50513 }))))
50514 } else {
50515 if self.check(TokenType::From) {
50517 let dynamic_expr = self.parse_doris_dynamic_partition()?;
50519 self.expect(TokenType::RParen)?;
50520 Some(Box::new(dynamic_expr))
50521 } else if self.check(TokenType::Start) {
50522 let mut dynamics = Vec::new();
50524 loop {
50525 if !self.check(TokenType::Start) {
50526 break;
50527 }
50528 let dynamic_expr = self.parse_starrocks_start_end_every()?;
50529 dynamics.push(dynamic_expr);
50530 if !self.match_token(TokenType::Comma) {
50531 break;
50532 }
50533 }
50534 self.expect(TokenType::RParen)?;
50535 Some(Box::new(Expression::Tuple(Box::new(Tuple {
50536 expressions: dynamics,
50537 }))))
50538 } else if self.check(TokenType::Partition) {
50539 let partitions = self.parse_doris_range_partition_definitions()?;
50541 self.expect(TokenType::RParen)?;
50542 Some(Box::new(Expression::Tuple(Box::new(Tuple {
50543 expressions: partitions,
50544 }))))
50545 } else {
50546 self.expect(TokenType::RParen)?;
50547 None
50548 }
50549 }
50550 } else {
50551 None
50552 };
50553
50554 if kind == "LIST" {
50555 Ok(Expression::PartitionByListProperty(Box::new(
50556 PartitionByListProperty {
50557 partition_expressions: partition_expressions.map(Box::new),
50558 create_expressions,
50559 },
50560 )))
50561 } else {
50562 Ok(Expression::PartitionByRangeProperty(Box::new(
50563 PartitionByRangeProperty {
50564 partition_expressions: partition_expressions.map(Box::new),
50565 create_expressions,
50566 },
50567 )))
50568 }
50569 }
50570
50571 fn parse_doris_list_partition_definitions(&mut self) -> Result<Vec<Expression>> {
50573 let mut partitions = Vec::new();
50574 loop {
50575 if !self.match_token(TokenType::Partition) {
50576 break;
50577 }
50578 let name = self.parse_id_var()?.unwrap_or(Expression::Null(Null));
50579 self.match_text_seq(&["VALUES", "IN"]);
50580 let values = self.parse_wrapped_csv_expressions()?;
50581
50582 let part_list = Expression::PartitionList(Box::new(PartitionList {
50583 this: Box::new(name),
50584 expressions: values,
50585 }));
50586 partitions.push(Expression::Partition(Box::new(Partition {
50587 expressions: vec![part_list],
50588 subpartition: false,
50589 })));
50590
50591 if !self.match_token(TokenType::Comma) {
50592 break;
50593 }
50594 }
50595 Ok(partitions)
50596 }
50597
50598 fn parse_doris_range_partition_definitions(&mut self) -> Result<Vec<Expression>> {
50600 let mut partitions = Vec::new();
50601 loop {
50602 if !self.match_token(TokenType::Partition) {
50603 break;
50604 }
50605 let name = self.parse_id_var()?.unwrap_or(Expression::Null(Null));
50606 self.match_text_seq(&["VALUES"]);
50607
50608 let part_range = if self.match_text_seq(&["LESS", "THAN"]) {
50609 if self.match_token(TokenType::Maxvalue) {
50610 Expression::PartitionRange(Box::new(PartitionRange {
50612 this: Box::new(name),
50613 expression: None,
50614 expressions: vec![Expression::Identifier(Identifier::new("MAXVALUE"))],
50615 }))
50616 } else {
50617 let values = self.parse_wrapped_csv_expressions()?;
50619 Expression::PartitionRange(Box::new(PartitionRange {
50620 this: Box::new(name),
50621 expression: None,
50622 expressions: values,
50623 }))
50624 }
50625 } else if self.check(TokenType::LBracket) {
50626 self.skip(); let mut value_tuples = Vec::new();
50629 loop {
50630 let vals = self.parse_wrapped_csv_expressions()?;
50631 value_tuples.push(Expression::Tuple(Box::new(Tuple { expressions: vals })));
50633 if !self.match_token(TokenType::Comma) {
50634 break;
50635 }
50636 }
50637 self.expect(TokenType::RParen)?;
50639 Expression::PartitionRange(Box::new(PartitionRange {
50640 this: Box::new(name),
50641 expression: None,
50642 expressions: value_tuples,
50643 }))
50644 } else {
50645 Expression::PartitionRange(Box::new(PartitionRange {
50647 this: Box::new(name),
50648 expression: None,
50649 expressions: Vec::new(),
50650 }))
50651 };
50652
50653 partitions.push(Expression::Partition(Box::new(Partition {
50654 expressions: vec![part_range],
50655 subpartition: false,
50656 })));
50657
50658 if !self.match_token(TokenType::Comma) {
50659 break;
50660 }
50661 }
50662 Ok(partitions)
50663 }
50664
50665 fn parse_doris_dynamic_partition(&mut self) -> Result<Expression> {
50667 self.expect(TokenType::From)?;
50668 let start = self.parse_wrapped_expression()?;
50669 self.expect(TokenType::To)?;
50670 let end = self.parse_wrapped_expression()?;
50671
50672 let every = if self.match_token(TokenType::Interval) {
50674 let number = self.parse_expression()?;
50675 let unit = if self.is_identifier_token() || self.is_safe_keyword_as_identifier() {
50676 let unit_text = self.advance().text.to_ascii_uppercase();
50677 let interval_unit = match unit_text.as_str() {
50679 "YEAR" | "YEARS" => crate::expressions::IntervalUnit::Year,
50680 "MONTH" | "MONTHS" => crate::expressions::IntervalUnit::Month,
50681 "DAY" | "DAYS" => crate::expressions::IntervalUnit::Day,
50682 "HOUR" | "HOURS" => crate::expressions::IntervalUnit::Hour,
50683 "MINUTE" | "MINUTES" => crate::expressions::IntervalUnit::Minute,
50684 "SECOND" | "SECONDS" => crate::expressions::IntervalUnit::Second,
50685 _ => crate::expressions::IntervalUnit::Day, };
50687 Some(crate::expressions::IntervalUnitSpec::Simple {
50688 unit: interval_unit,
50689 use_plural: unit_text.ends_with('S'),
50690 })
50691 } else {
50692 None
50693 };
50694 Some(Box::new(Expression::Interval(Box::new(Interval {
50695 this: Some(number),
50696 unit,
50697 }))))
50698 } else {
50699 None
50700 };
50701
50702 Ok(Expression::PartitionByRangePropertyDynamic(Box::new(
50703 PartitionByRangePropertyDynamic {
50704 this: None,
50705 start: Some(Box::new(start)),
50706 end: Some(Box::new(end)),
50707 every,
50708 use_start_end: false,
50709 },
50710 )))
50711 }
50712
50713 fn parse_starrocks_start_end_every(&mut self) -> Result<Expression> {
50715 self.expect(TokenType::Start)?;
50716 let start = self.parse_wrapped_expression()?;
50717 self.expect(TokenType::End)?;
50718 let end = self.parse_wrapped_expression()?;
50719
50720 let every = if self.match_identifier("EVERY") {
50722 self.expect(TokenType::LParen)?;
50723 let expr = self.parse_expression()?;
50724 self.expect(TokenType::RParen)?;
50725 Some(Box::new(expr))
50726 } else {
50727 None
50728 };
50729
50730 Ok(Expression::PartitionByRangePropertyDynamic(Box::new(
50731 PartitionByRangePropertyDynamic {
50732 this: None,
50733 start: Some(Box::new(start)),
50734 end: Some(Box::new(end)),
50735 every,
50736 use_start_end: true,
50737 },
50738 )))
50739 }
50740
50741 fn parse_wrapped_csv_expressions(&mut self) -> Result<Vec<Expression>> {
50743 self.expect(TokenType::LParen)?;
50744 let mut exprs = Vec::new();
50745 if !self.check(TokenType::RParen) {
50746 loop {
50747 if self.match_token(TokenType::Maxvalue) {
50749 exprs.push(Expression::Var(Box::new(Var {
50750 this: "MAXVALUE".to_string(),
50751 })));
50752 } else {
50753 exprs.push(self.parse_expression()?);
50754 }
50755 if !self.match_token(TokenType::Comma) {
50756 break;
50757 }
50758 }
50759 }
50760 self.expect(TokenType::RParen)?;
50761 Ok(exprs)
50762 }
50763
50764 fn parse_wrapped_expression(&mut self) -> Result<Expression> {
50766 self.expect(TokenType::LParen)?;
50767 let expr = self.parse_expression()?;
50768 self.expect(TokenType::RParen)?;
50769 Ok(expr)
50770 }
50771
50772 #[allow(unused_variables, unused_mut)]
50774 pub fn parse_partitioned_of(&mut self) -> Result<Option<Expression>> {
50775 if self.match_text_seq(&["OF"]) {
50776 return Ok(Some(Expression::PartitionBoundSpec(Box::new(
50777 PartitionBoundSpec {
50778 this: None,
50779 expression: None,
50780 from_expressions: None,
50781 to_expressions: None,
50782 },
50783 ))));
50784 }
50785 if self.match_text_seq(&["FOR", "VALUES"]) {
50786 return Ok(None);
50788 }
50789 Ok(None)
50790 }
50791
50792 pub fn parse_period_for_system_time(&mut self) -> Result<Option<Expression>> {
50796 if !self.match_token(TokenType::TimestampSnapshot) {
50798 if self.current > 0 {
50800 self.current -= 1;
50801 }
50802 return Ok(None);
50803 }
50804
50805 let id_vars = self.parse_wrapped_id_vars()?;
50807
50808 let (this, expression) = if let Some(Expression::Tuple(tuple)) = id_vars {
50810 let exprs = &tuple.expressions;
50811 (
50812 exprs.get(0).cloned().unwrap_or(Expression::Null(Null)),
50813 exprs.get(1).cloned().unwrap_or(Expression::Null(Null)),
50814 )
50815 } else {
50816 return Ok(None);
50817 };
50818
50819 Ok(Some(Expression::PeriodForSystemTimeConstraint(Box::new(
50820 PeriodForSystemTimeConstraint {
50821 this: Box::new(this),
50822 expression: Box::new(expression),
50823 },
50824 ))))
50825 }
50826
50827 #[allow(unused_variables, unused_mut)]
50829 pub fn parse_pipe_syntax_aggregate(&mut self) -> Result<Option<Expression>> {
50830 if self.match_text_seq(&["AGGREGATE"]) {
50831 return Ok(Some(Expression::Select(Box::new(Select {
50832 expressions: Vec::new(),
50833 from: None,
50834 joins: Vec::new(),
50835 lateral_views: Vec::new(),
50836 prewhere: None,
50837 where_clause: None,
50838 group_by: None,
50839 having: None,
50840 qualify: None,
50841 order_by: None,
50842 distribute_by: None,
50843 cluster_by: None,
50844 sort_by: None,
50845 limit: None,
50846 offset: None,
50847 limit_by: None,
50848 fetch: None,
50849 distinct: false,
50850 distinct_on: None,
50851 top: None,
50852 with: None,
50853 sample: None,
50854 settings: None,
50855 format: None,
50856 windows: None,
50857 hint: None,
50858 connect: None,
50859 into: None,
50860 locks: Vec::new(),
50861 for_xml: Vec::new(),
50862 leading_comments: Vec::new(),
50863 post_select_comments: Vec::new(),
50864 kind: None,
50865 operation_modifiers: Vec::new(),
50866 qualify_after_window: false,
50867 option: None,
50868 exclude: None,
50869 }))));
50870 }
50871 if self.match_text_seq(&["GROUP", "AND"]) {
50872 return Ok(None);
50874 }
50875 Ok(None)
50876 }
50877
50878 #[allow(unused_variables, unused_mut)]
50881 pub fn parse_pipe_syntax_aggregate_fields(&mut self) -> Result<Option<Expression>> {
50882 if self.match_text_seq(&["GROUP", "AND"]) {
50883 return Ok(None);
50885 }
50886 Ok(None)
50887 }
50888
50889 pub fn parse_pipe_syntax_aggregate_group_order_by(&mut self) -> Result<Option<Expression>> {
50894 let mut aggregates_or_groups = Vec::new();
50896 let mut orders = Vec::new();
50897
50898 loop {
50899 if let Some(element) = self.parse_pipe_syntax_aggregate_fields()? {
50900 match &element {
50902 Expression::Ordered(ordered) => {
50903 let this = match &ordered.this {
50905 Expression::Alias(alias) => {
50906 Expression::Identifier(alias.alias.clone())
50908 }
50909 other => other.clone(),
50910 };
50911 orders.push(Expression::Ordered(Box::new(Ordered {
50913 this: this.clone(),
50914 desc: ordered.desc,
50915 nulls_first: ordered.nulls_first,
50916 explicit_asc: ordered.explicit_asc,
50917 with_fill: ordered.with_fill.clone(),
50918 })));
50919 aggregates_or_groups.push(this);
50920 }
50921 _ => {
50922 aggregates_or_groups.push(element);
50923 }
50924 }
50925 }
50926
50927 if !self.match_token(TokenType::Comma) {
50928 break;
50929 }
50930 }
50931
50932 if aggregates_or_groups.is_empty() && orders.is_empty() {
50933 return Ok(None);
50934 }
50935
50936 Ok(Some(Expression::Tuple(Box::new(Tuple {
50938 expressions: vec![
50939 Expression::Tuple(Box::new(Tuple {
50940 expressions: aggregates_or_groups,
50941 })),
50942 Expression::Tuple(Box::new(Tuple {
50943 expressions: orders,
50944 })),
50945 ],
50946 }))))
50947 }
50948
50949 #[allow(unused_variables, unused_mut)]
50951 pub fn parse_pipe_syntax_extend(&mut self) -> Result<Option<Expression>> {
50952 if self.match_text_seq(&["EXTEND"]) {
50953 return Ok(Some(Expression::Select(Box::new(Select {
50954 expressions: Vec::new(),
50955 from: None,
50956 joins: Vec::new(),
50957 lateral_views: Vec::new(),
50958 prewhere: None,
50959 where_clause: None,
50960 group_by: None,
50961 having: None,
50962 qualify: None,
50963 order_by: None,
50964 distribute_by: None,
50965 cluster_by: None,
50966 sort_by: None,
50967 limit: None,
50968 offset: None,
50969 limit_by: None,
50970 fetch: None,
50971 distinct: false,
50972 distinct_on: None,
50973 top: None,
50974 with: None,
50975 sample: None,
50976 settings: None,
50977 format: None,
50978 windows: None,
50979 hint: None,
50980 connect: None,
50981 into: None,
50982 locks: Vec::new(),
50983 for_xml: Vec::new(),
50984 leading_comments: Vec::new(),
50985 post_select_comments: Vec::new(),
50986 kind: None,
50987 operation_modifiers: Vec::new(),
50988 qualify_after_window: false,
50989 option: None,
50990 exclude: None,
50991 }))));
50992 }
50993 Ok(None)
50994 }
50995
50996 pub fn parse_pipe_syntax_join(&mut self) -> Result<Option<Expression>> {
51000 self.parse_join()
51002 }
51003
51004 pub fn parse_pipe_syntax_limit(&mut self) -> Result<Option<Expression>> {
51008 let limit = self.parse_limit()?;
51010
51011 let offset = self.parse_offset()?;
51013
51014 match (limit, offset) {
51016 (Some(l), Some(o)) => Ok(Some(Expression::Tuple(Box::new(Tuple {
51017 expressions: vec![l, o],
51018 })))),
51019 (Some(l), None) => Ok(Some(l)),
51020 (None, Some(o)) => Ok(Some(o)),
51021 (None, None) => Ok(None),
51022 }
51023 }
51024
51025 pub fn parse_pipe_syntax_pivot(&mut self) -> Result<Option<Expression>> {
51029 self.parse_pivot_aggregation()
51032 }
51033
51034 pub fn parse_pipe_syntax_query(&mut self) -> Result<Option<Expression>> {
51038 let mut query = self.parse_select_query()?;
51040
51041 if query.is_none() {
51042 return Ok(None);
51043 }
51044
51045 while self.match_token(TokenType::PipeGt) {
51047 let start_pos = self.current;
51048 let operator_text = self.peek().text.to_ascii_uppercase();
51049
51050 let transform_result = match operator_text.as_str() {
51052 "WHERE" => {
51053 self.skip();
51054 self.parse_where()?
51055 }
51056 "SELECT" => {
51057 self.skip();
51058 self.parse_pipe_syntax_select()?
51059 }
51060 "AGGREGATE" => {
51061 self.skip();
51062 self.parse_pipe_syntax_aggregate()?
51063 }
51064 "EXTEND" => {
51065 self.skip();
51066 self.parse_pipe_syntax_extend()?
51067 }
51068 "LIMIT" => {
51069 self.skip();
51070 self.parse_pipe_syntax_limit()?
51071 }
51072 "JOIN" | "LEFT" | "RIGHT" | "INNER" | "OUTER" | "CROSS" | "FULL" => {
51073 self.parse_pipe_syntax_join()?
51074 }
51075 "UNION" | "INTERSECT" | "EXCEPT" => self.parse_pipe_syntax_set_operator()?,
51076 "PIVOT" => {
51077 self.skip();
51078 self.parse_pipe_syntax_pivot()?
51079 }
51080 "TABLESAMPLE" => {
51081 self.skip();
51082 self.parse_pipe_syntax_tablesample()?
51083 }
51084 _ => {
51085 let set_op = self.parse_pipe_syntax_set_operator()?;
51087 if set_op.is_some() {
51088 set_op
51089 } else {
51090 let join_op = self.parse_pipe_syntax_join()?;
51091 if join_op.is_some() {
51092 join_op
51093 } else {
51094 self.current = start_pos;
51096 break;
51097 }
51098 }
51099 }
51100 };
51101
51102 if let Some(transform) = transform_result {
51104 let current_query = query.ok_or_else(|| {
51106 self.parse_error("Expected base query before pipe syntax transform")
51107 })?;
51108 query = Some(Expression::PipeOperator(Box::new(PipeOperator {
51109 this: current_query,
51110 expression: transform,
51111 })));
51112 }
51113 }
51114
51115 Ok(query)
51116 }
51117
51118 pub fn parse_pipe_syntax_select(&mut self) -> Result<Option<Expression>> {
51122 let expressions = self.parse_expressions()?;
51124
51125 match expressions {
51126 Some(expr) => Ok(Some(expr)),
51127 None => Ok(Some(Expression::Star(Star {
51128 table: None,
51129 except: None,
51130 replace: None,
51131 rename: None,
51132 trailing_comments: Vec::new(),
51133 span: None,
51134 }))),
51135 }
51136 }
51137
51138 pub fn parse_pipe_syntax_set_operator(&mut self) -> Result<Option<Expression>> {
51142 if let Some(set_op) = self.parse_set_operations()? {
51144 Ok(Some(set_op))
51145 } else {
51146 Ok(None)
51147 }
51148 }
51149
51150 pub fn parse_pipe_syntax_tablesample(&mut self) -> Result<Option<Expression>> {
51154 self.parse_table_sample()
51156 }
51157
51158 #[allow(unused_variables, unused_mut)]
51161 pub fn parse_pivot_aggregation(&mut self) -> Result<Option<Expression>> {
51162 let func = self.parse_function()?;
51164
51165 if func.is_none() {
51166 if self.previous().token_type == TokenType::Comma {
51168 return Ok(None);
51169 }
51170 return Ok(None);
51172 }
51173
51174 self.parse_alias_with_expr(func)
51176 }
51177
51178 pub fn parse_pivot_in(&mut self) -> Result<Option<Expression>> {
51182 let value = self.parse_column()?;
51184 let value_expr = value.unwrap_or(Expression::Null(Null));
51185
51186 if !self.match_token(TokenType::In) {
51188 return Err(self.parse_error("Expecting IN"));
51189 }
51190
51191 if self.match_token(TokenType::LParen) {
51193 let expressions = if self.match_text_seq(&["ANY"]) {
51195 let order = self.parse_order()?;
51197 vec![Expression::PivotAny(Box::new(PivotAny {
51198 this: order.map(Box::new),
51199 }))]
51200 } else {
51201 let mut exprs = Vec::new();
51203 loop {
51204 if let Some(expr) = self.parse_select_or_expression()? {
51205 let final_expr = if self.match_token(TokenType::Alias) {
51207 if let Some(alias) = self.parse_bitwise()? {
51208 Expression::PivotAlias(Box::new(PivotAlias { this: expr, alias }))
51210 } else {
51211 expr
51212 }
51213 } else {
51214 expr
51215 };
51216 exprs.push(final_expr);
51217 } else {
51218 break;
51219 }
51220 if !self.match_token(TokenType::Comma) {
51221 break;
51222 }
51223 }
51224 exprs
51225 };
51226
51227 self.expect(TokenType::RParen)?;
51228
51229 Ok(Some(Expression::In(Box::new(In {
51230 this: value_expr,
51231 expressions,
51232 query: None,
51233 not: false,
51234 global: false,
51235 unnest: None,
51236 is_field: false,
51237 }))))
51238 } else {
51239 let field = self.parse_id_var()?;
51241 let expressions = if let Some(f) = field {
51243 vec![f]
51244 } else {
51245 Vec::new()
51246 };
51247 Ok(Some(Expression::In(Box::new(In {
51248 this: value_expr,
51249 expressions,
51250 query: None,
51251 not: false,
51252 global: false,
51253 unnest: None,
51254 is_field: true,
51255 }))))
51256 }
51257 }
51258
51259 pub fn parse_pivots_for_source(&mut self, source: Expression) -> Result<Option<Expression>> {
51263 let mut result = source;
51264
51265 loop {
51266 if self.match_token(TokenType::Pivot) {
51267 result = self.parse_pivot(result)?;
51268 } else if self.match_texts(&["UNPIVOT"]) {
51269 result = self.parse_unpivot(result)?;
51270 } else {
51271 break;
51272 }
51273 }
51274
51275 if matches!(result, Expression::Null(_)) {
51277 Ok(None)
51278 } else {
51279 Ok(Some(result))
51280 }
51281 }
51282
51283 pub fn parse_placeholder(&mut self) -> Result<Option<Expression>> {
51286 if self.match_token(TokenType::Placeholder) {
51288 return Ok(Some(Expression::Placeholder(Placeholder { index: None })));
51289 }
51290 if self.match_token(TokenType::Parameter) {
51292 let text = self.previous().text.clone();
51293 return Ok(Some(Expression::Parameter(Box::new(Parameter {
51294 name: Some(text),
51295 index: None,
51296 style: ParameterStyle::Colon,
51297 quoted: false,
51298 string_quoted: false,
51299 expression: None,
51300 }))));
51301 }
51302 Ok(None)
51303 }
51304
51305 fn parse_clickhouse_braced_parameter(&mut self) -> Result<Option<Expression>> {
51307 if !matches!(
51308 self.config.dialect,
51309 Some(crate::dialects::DialectType::ClickHouse)
51310 ) {
51311 return Ok(None);
51312 }
51313 if !self.check(TokenType::LBrace) {
51314 return Ok(None);
51315 }
51316
51317 let start = self.current;
51318 self.skip(); if !(self.is_identifier_token() || self.is_safe_keyword_as_identifier()) {
51321 self.current = start;
51322 return Ok(None);
51323 }
51324 let name = self.advance().text.clone();
51325
51326 if !self.match_token(TokenType::Colon) {
51327 self.current = start;
51328 return Ok(None);
51329 }
51330
51331 let kind_start = self.current;
51332 let mut paren_depth = 0usize;
51333 let mut bracket_depth = 0usize;
51334
51335 while !self.is_at_end() {
51336 let token_type = self.peek().token_type;
51337 match token_type {
51338 TokenType::LParen => {
51339 paren_depth += 1;
51340 self.skip();
51341 }
51342 TokenType::RParen => {
51343 if paren_depth == 0 {
51344 break;
51345 }
51346 paren_depth -= 1;
51347 self.skip();
51348 }
51349 TokenType::LBracket => {
51350 bracket_depth += 1;
51351 self.skip();
51352 }
51353 TokenType::RBracket => {
51354 if bracket_depth == 0 {
51355 break;
51356 }
51357 bracket_depth -= 1;
51358 self.skip();
51359 }
51360 TokenType::RBrace => {
51361 if paren_depth == 0 && bracket_depth == 0 {
51362 break;
51363 }
51364 self.skip();
51365 }
51366 _ => {
51367 self.skip();
51368 }
51369 }
51370 }
51371
51372 if self.current <= kind_start || !self.match_token(TokenType::RBrace) {
51373 return Err(self.parse_error("Expected } in ClickHouse query parameter"));
51374 }
51375
51376 let kind = self
51377 .tokens_to_sql(kind_start, self.current - 1)
51378 .trim()
51379 .to_string();
51380 if kind.is_empty() {
51381 return Err(self.parse_error("Expected parameter kind in ClickHouse query parameter"));
51382 }
51383
51384 Ok(Some(Expression::Parameter(Box::new(Parameter {
51385 name: Some(name),
51386 index: None,
51387 style: ParameterStyle::Brace,
51388 quoted: false,
51389 string_quoted: false,
51390 expression: Some(kind),
51391 }))))
51392 }
51393
51394 #[allow(unused_variables, unused_mut)]
51397 pub fn parse_position(&mut self) -> Result<Option<Expression>> {
51398 let mut args: Vec<Expression> = Vec::new();
51400
51401 match self.parse_bitwise() {
51402 Ok(Some(expr)) => {
51403 let expr = self.maybe_clickhouse_alias(expr);
51404 let expr = self.try_clickhouse_func_arg_alias(expr);
51405 args.push(expr);
51406 }
51407 Ok(None) => return Ok(None),
51408 Err(e) => return Err(e),
51409 }
51410
51411 if self.match_token(TokenType::In) {
51413 match self.parse_bitwise() {
51414 Ok(Some(haystack)) => {
51415 let haystack = self.maybe_clickhouse_alias(haystack);
51416 let haystack = self.try_clickhouse_func_arg_alias(haystack);
51417 return Ok(Some(Expression::StrPosition(Box::new(StrPosition {
51418 this: Box::new(haystack),
51419 substr: Some(Box::new(args.remove(0))),
51420 position: None,
51421 occurrence: None,
51422 }))));
51423 }
51424 Ok(None) => {
51425 return Err(self.parse_error("Expected expression after IN in POSITION"))
51426 }
51427 Err(e) => return Err(e),
51428 }
51429 }
51430
51431 while self.match_token(TokenType::Comma) {
51433 match self.parse_bitwise() {
51434 Ok(Some(expr)) => {
51435 let expr = self.maybe_clickhouse_alias(expr);
51436 let expr = self.try_clickhouse_func_arg_alias(expr);
51437 args.push(expr);
51438 }
51439 Ok(None) => break,
51440 Err(e) => return Err(e),
51441 }
51442 }
51443
51444 let position = args.get(2).cloned();
51446 let (haystack, needle) = if matches!(
51447 self.config.dialect,
51448 Some(crate::dialects::DialectType::ClickHouse)
51449 ) {
51450 (args.get(0).cloned(), args.get(1).cloned())
51451 } else {
51452 (args.get(1).cloned(), args.get(0).cloned())
51453 };
51454
51455 Ok(Some(Expression::StrPosition(Box::new(StrPosition {
51456 this: Box::new(
51457 haystack.unwrap_or_else(|| {
51458 Expression::Literal(Box::new(Literal::String("".to_string())))
51459 }),
51460 ),
51461 substr: needle.map(Box::new),
51462 position: position.map(Box::new),
51463 occurrence: None,
51464 }))))
51465 }
51466
51467 #[allow(unused_variables, unused_mut)]
51470 pub fn parse_prewhere(&mut self) -> Result<Option<Expression>> {
51471 if !self.match_token(TokenType::Prewhere) {
51472 return Ok(None);
51473 }
51474 let condition = self.parse_expression()?;
51476 Ok(Some(Expression::PreWhere(Box::new(PreWhere {
51477 this: condition,
51478 }))))
51479 }
51480
51481 pub fn parse_primary_key(&mut self) -> Result<Option<Expression>> {
51485 self.parse_primary_key_impl(false, false)
51486 }
51487
51488 pub fn parse_primary_key_impl(
51490 &mut self,
51491 wrapped_optional: bool,
51492 in_props: bool,
51493 ) -> Result<Option<Expression>> {
51494 let desc = if self.match_token(TokenType::Asc) {
51496 false
51497 } else if self.match_token(TokenType::Desc) {
51498 true
51499 } else {
51500 false
51501 };
51502
51503 let this = if (self.check(TokenType::Identifier) || self.check(TokenType::Var))
51505 && self.check_next(TokenType::LParen)
51506 {
51507 self.parse_id_var()?
51508 } else {
51509 None
51510 };
51511
51512 if !in_props && !self.check(TokenType::LParen) {
51514 let options = self.parse_key_constraint_options_list()?;
51515 return Ok(Some(Expression::PrimaryKeyColumnConstraint(Box::new(
51516 PrimaryKeyColumnConstraint {
51517 desc: if desc {
51518 Some(Box::new(Expression::Boolean(BooleanLiteral {
51519 value: true,
51520 })))
51521 } else {
51522 None
51523 },
51524 options,
51525 },
51526 ))));
51527 }
51528
51529 let expressions = if self.match_token(TokenType::LParen) {
51531 let mut exprs = Vec::new();
51532 loop {
51533 if let Some(part) = self.parse_primary_key_part()? {
51534 exprs.push(part);
51535 }
51536 if !self.match_token(TokenType::Comma) {
51537 break;
51538 }
51539 }
51540 self.expect(TokenType::RParen)?;
51541 exprs
51542 } else if wrapped_optional {
51543 Vec::new()
51544 } else {
51545 return Err(self.parse_error("Expected '(' for PRIMARY KEY column list"));
51546 };
51547
51548 let include = self.parse_index_params()?;
51550
51551 let options = self.parse_key_constraint_options_list()?;
51553
51554 Ok(Some(Expression::PrimaryKey(Box::new(PrimaryKey {
51555 this: this.map(Box::new),
51556 expressions,
51557 options,
51558 include: include.map(Box::new),
51559 }))))
51560 }
51561
51562 fn parse_key_constraint_options_list(&mut self) -> Result<Vec<Expression>> {
51564 let mut options = Vec::new();
51565
51566 loop {
51567 if self.is_at_end() {
51568 break;
51569 }
51570
51571 if self.match_token(TokenType::On) {
51572 let on_what = if !self.is_at_end() {
51574 let token = self.advance();
51575 token.text.clone()
51576 } else {
51577 break;
51578 };
51579
51580 let action = if self.match_text_seq(&["NO", "ACTION"]) {
51581 "NO ACTION"
51582 } else if self.match_text_seq(&["CASCADE"]) {
51583 "CASCADE"
51584 } else if self.match_text_seq(&["RESTRICT"]) {
51585 "RESTRICT"
51586 } else if self.match_token(TokenType::Set) && self.match_token(TokenType::Null) {
51587 "SET NULL"
51588 } else if self.match_token(TokenType::Set) && self.match_token(TokenType::Default) {
51589 "SET DEFAULT"
51590 } else {
51591 break;
51592 };
51593
51594 options.push(Expression::Var(Box::new(Var {
51595 this: format!("ON {} {}", on_what, action),
51596 })));
51597 } else if self.match_text_seq(&["NOT", "ENFORCED"]) {
51598 options.push(Expression::Var(Box::new(Var {
51599 this: "NOT ENFORCED".to_string(),
51600 })));
51601 } else if self.match_text_seq(&["DEFERRABLE"]) {
51602 options.push(Expression::Var(Box::new(Var {
51603 this: "DEFERRABLE".to_string(),
51604 })));
51605 } else if self.match_text_seq(&["INITIALLY", "DEFERRED"]) {
51606 options.push(Expression::Var(Box::new(Var {
51607 this: "INITIALLY DEFERRED".to_string(),
51608 })));
51609 } else if self.match_text_seq(&["NORELY"]) {
51610 options.push(Expression::Var(Box::new(Var {
51611 this: "NORELY".to_string(),
51612 })));
51613 } else if self.match_text_seq(&["RELY"]) {
51614 options.push(Expression::Var(Box::new(Var {
51615 this: "RELY".to_string(),
51616 })));
51617 } else {
51618 break;
51619 }
51620 }
51621
51622 Ok(options)
51623 }
51624
51625 #[allow(unused_variables, unused_mut)]
51627 pub fn parse_primary_key_part(&mut self) -> Result<Option<Expression>> {
51628 if matches!(
51630 self.config.dialect,
51631 Some(crate::dialects::DialectType::ClickHouse)
51632 ) {
51633 return self.parse_expression().map(Some);
51634 }
51635 if (self.is_identifier_token() || self.is_safe_keyword_as_identifier())
51636 && self.check_next(TokenType::LParen)
51637 {
51638 return self.parse_expression().map(Some);
51639 }
51640 if let Some(field) = self.parse_field()? {
51641 Ok(Some(field))
51642 } else {
51643 self.parse_expression().map(Some)
51644 }
51645 }
51646
51647 pub fn parse_primary_or_var(&mut self) -> Result<Option<Expression>> {
51651 let saved_pos = self.current;
51653 match self.parse_primary() {
51654 Ok(expr) => return Ok(Some(expr)),
51655 Err(_) => {
51656 self.current = saved_pos;
51658 }
51659 }
51660
51661 self.parse_var()
51663 }
51664
51665 #[allow(unused_variables, unused_mut)]
51667 pub fn parse_procedure_option(&mut self) -> Result<Option<Expression>> {
51668 if self.match_text_seq(&["EXECUTE", "AS"]) {
51669 return Ok(None);
51671 }
51672 Ok(None)
51673 }
51674
51675 #[allow(unused_variables, unused_mut)]
51677 pub fn parse_projections(&mut self) -> Result<Option<Expression>> {
51678 self.parse_expressions()
51679 }
51680
51681 pub fn parse_properties(&mut self) -> Result<Option<Expression>> {
51685 self.parse_properties_impl(None)
51686 }
51687
51688 pub fn parse_properties_impl(&mut self, before: Option<bool>) -> Result<Option<Expression>> {
51690 let mut properties = Vec::new();
51691
51692 loop {
51693 let prop = if before == Some(true) {
51694 self.parse_property_before()?
51695 } else {
51696 self.parse_property()?
51697 };
51698
51699 if let Some(p) = prop {
51700 properties.push(p);
51701 } else {
51702 break;
51703 }
51704 }
51705
51706 if properties.is_empty() {
51707 Ok(None)
51708 } else {
51709 Ok(Some(Expression::Properties(Box::new(Properties {
51710 expressions: properties,
51711 }))))
51712 }
51713 }
51714
51715 #[allow(unused_variables, unused_mut)]
51718 pub fn parse_property(&mut self) -> Result<Option<Expression>> {
51719 if self.match_text_seq(&["COMPOUND", "SORTKEY"]) {
51720 return Ok(Some(Expression::Identifier(Identifier {
51721 name: String::new(),
51722 quoted: false,
51723 trailing_comments: Vec::new(),
51724 span: None,
51725 })));
51726 }
51727 if self.match_text_seq(&["SQL", "SECURITY"]) {
51728 return Ok(None);
51730 }
51731 if self.match_texts(&["DEFINER", "INVOKER"]) {
51732 return Ok(None);
51734 }
51735 Ok(None)
51736 }
51737
51738 fn parse_on_cluster_clause(&mut self) -> Result<Option<OnCluster>> {
51740 if !matches!(
51741 self.config.dialect,
51742 Some(crate::dialects::DialectType::ClickHouse)
51743 ) {
51744 return Ok(None);
51745 }
51746
51747 let start = self.current;
51748 if !self.match_token(TokenType::On) {
51749 return Ok(None);
51750 }
51751
51752 if !self.match_token(TokenType::Cluster) {
51753 self.current = start;
51754 return Ok(None);
51755 }
51756
51757 let this = if self.check(TokenType::String) {
51758 let value = self.expect_string()?;
51759 Expression::Literal(Box::new(Literal::String(value)))
51760 } else if let Some(id_expr) = self.parse_id_var()? {
51761 id_expr
51762 } else if self.is_safe_keyword_as_identifier() {
51763 let name = self.advance().text;
51764 Expression::Identifier(Identifier {
51765 name,
51766 quoted: false,
51767 trailing_comments: Vec::new(),
51768 span: None,
51769 })
51770 } else {
51771 return Err(self.parse_error("Expected cluster name after ON CLUSTER"));
51772 };
51773
51774 Ok(Some(OnCluster {
51775 this: Box::new(this),
51776 }))
51777 }
51778
51779 fn parse_clickhouse_table_properties(
51781 &mut self,
51782 properties: &mut Vec<Expression>,
51783 ) -> Result<()> {
51784 loop {
51785 if self.match_identifier("ENGINE") {
51786 self.match_token(TokenType::Eq);
51787 let engine = self.parse_clickhouse_engine_expression()?;
51788 properties.push(Expression::EngineProperty(Box::new(EngineProperty {
51789 this: Box::new(engine),
51790 })));
51791 continue;
51792 }
51793
51794 if self.match_token(TokenType::Order) {
51795 self.expect(TokenType::By)?;
51796 let order_by = if matches!(
51797 self.config.dialect,
51798 Some(crate::dialects::DialectType::ClickHouse)
51799 ) && self.match_token(TokenType::LParen)
51800 {
51801 if self.check(TokenType::RParen) {
51804 self.skip();
51805 OrderBy {
51806 expressions: vec![Ordered::asc(Expression::Tuple(Box::new(Tuple {
51807 expressions: Vec::new(),
51808 })))],
51809 siblings: false,
51810 comments: Vec::new(),
51811 }
51812 } else {
51813 let mut inner_exprs = Vec::new();
51815 loop {
51816 let expr = self.parse_expression()?;
51817 inner_exprs.push(expr);
51818 if !self.match_token(TokenType::Comma) {
51819 break;
51820 }
51821 }
51822 self.expect(TokenType::RParen)?;
51823 let wrapper = if inner_exprs.len() == 1 {
51825 Expression::Paren(Box::new(Paren {
51826 this: inner_exprs.into_iter().next().unwrap(),
51827 trailing_comments: Vec::new(),
51828 }))
51829 } else {
51830 Expression::Tuple(Box::new(Tuple {
51831 expressions: inner_exprs,
51832 }))
51833 };
51834 OrderBy {
51835 expressions: vec![Ordered::asc(wrapper)],
51836 siblings: false,
51837 comments: Vec::new(),
51838 }
51839 }
51840 } else {
51841 self.parse_order_by()?
51842 };
51843 properties.push(Expression::OrderBy(Box::new(order_by)));
51844 continue;
51845 }
51846
51847 if self.match_token(TokenType::Partition) {
51848 self.expect(TokenType::By)?;
51849 if self.check(TokenType::Order) && self.check_next(TokenType::By) {
51850 return Err(self.parse_error("Expected expression after PARTITION BY"));
51851 }
51852 let expr = self
51853 .parse_assignment()?
51854 .ok_or_else(|| self.parse_error("Expected expression after PARTITION BY"))?;
51855 properties.push(Expression::PartitionedByProperty(Box::new(
51856 PartitionedByProperty {
51857 this: Box::new(expr),
51858 },
51859 )));
51860 continue;
51861 }
51862
51863 if self.match_token(TokenType::PrimaryKey) {
51864 let _ = self.match_token(TokenType::Key);
51866 if self.check(TokenType::LParen) {
51867 if let Some(pk) = self.parse_primary_key_impl(false, true)? {
51868 properties.push(pk);
51869 }
51870 } else if let Some(expr) = self.parse_conjunction()? {
51871 let mut exprs = vec![expr];
51873 while self.match_token(TokenType::Comma) {
51874 if let Some(next_expr) = self.parse_field()? {
51875 exprs.push(next_expr);
51876 } else {
51877 break;
51878 }
51879 }
51880 properties.push(Expression::PrimaryKey(Box::new(PrimaryKey {
51881 this: None,
51882 expressions: exprs,
51883 options: Vec::new(),
51884 include: None,
51885 })));
51886 } else {
51887 return Err(self.parse_error("Expected expression after PRIMARY KEY"));
51888 }
51889 continue;
51890 }
51891
51892 if self.match_token(TokenType::Sample) {
51893 let _ = self.match_token(TokenType::By);
51894 let expr = self.parse_expression()?;
51895 properties.push(Expression::SampleProperty(Box::new(SampleProperty {
51896 this: Box::new(expr),
51897 })));
51898 continue;
51899 }
51900
51901 if self.match_token(TokenType::Settings) {
51902 let mut settings = Vec::new();
51903 loop {
51904 settings.push(self.parse_expression()?);
51905 if !self.match_token(TokenType::Comma) {
51906 break;
51907 }
51908 }
51909 properties.push(Expression::SettingsProperty(Box::new(SettingsProperty {
51910 expressions: settings,
51911 })));
51912 continue;
51913 }
51914
51915 if self.match_token(TokenType::Comment) {
51916 let comment_expr = if self.check(TokenType::String) {
51917 Expression::Literal(Box::new(Literal::String(self.expect_string()?)))
51918 } else {
51919 self.parse_expression()?
51920 };
51921 properties.push(Expression::SchemaCommentProperty(Box::new(
51922 SchemaCommentProperty {
51923 this: Box::new(comment_expr),
51924 },
51925 )));
51926 continue;
51927 }
51928
51929 if self.match_identifier("TTL") {
51931 if let Some(ttl_expr) = self.parse_ttl()? {
51932 properties.push(ttl_expr);
51933 }
51934 continue;
51935 }
51936
51937 if self.match_identifier("SOURCE") {
51938 if let Some(prop) = self.parse_dict_property("SOURCE")? {
51939 properties.push(prop);
51940 }
51941 continue;
51942 }
51943
51944 if self.match_identifier("LAYOUT") {
51945 if let Some(prop) = self.parse_dict_property("LAYOUT")? {
51946 properties.push(prop);
51947 }
51948 continue;
51949 }
51950
51951 if self.match_identifier("LIFETIME") {
51952 if let Some(range) = self.parse_dict_range("LIFETIME")? {
51953 properties.push(range);
51954 }
51955 continue;
51956 }
51957
51958 if self.match_identifier("RANGE") || self.match_token(TokenType::Range) {
51959 if let Some(range) = self.parse_dict_range("RANGE")? {
51960 properties.push(range);
51961 }
51962 continue;
51963 }
51964
51965 break;
51966 }
51967
51968 Ok(())
51969 }
51970
51971 fn try_clickhouse_implicit_alias(&mut self, expr: Expression) -> Expression {
51974 if !matches!(
51975 self.config.dialect,
51976 Some(crate::dialects::DialectType::ClickHouse)
51977 ) {
51978 return expr;
51979 }
51980 if self.check(TokenType::Var) || self.check(TokenType::Identifier) {
51981 let next_after = self.peek_nth(1).map(|t| t.token_type);
51982 let is_delimiter = matches!(
51983 next_after,
51984 Some(TokenType::Comma)
51985 | Some(TokenType::RParen)
51986 | Some(TokenType::From)
51987 | Some(TokenType::For)
51988 | Some(TokenType::As)
51989 );
51990 if is_delimiter {
51991 let alias_token = self.advance();
51992 let alias_name = alias_token.text.clone();
51993 return Expression::Alias(Box::new(crate::expressions::Alias::new(
51994 expr,
51995 Identifier::new(alias_name),
51996 )));
51997 }
51998 }
51999 expr
52000 }
52001
52002 fn normalize_tsql_date_part(&self, expr: Expression) -> Expression {
52007 let name = match &expr {
52008 Expression::Var(v) => Some(v.this.to_ascii_uppercase()),
52009 Expression::Column(c) if c.table.is_none() => Some(c.name.name.to_ascii_uppercase()),
52010 Expression::Identifier(id) => Some(id.name.to_ascii_uppercase()),
52011 _ => None,
52012 };
52013 if let Some(name) = name {
52014 let mapped = match name.as_str() {
52015 "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => "YEAR",
52016 "MM" | "MON" | "MONS" | "MONTHS" | "M" => "MONTH",
52017 "D" | "DD" | "DAYS" | "DAYOFMONTH" => "DAY",
52018 "DOW" | "DW" | "WEEKDAY" => "DAYOFWEEK",
52019 "DOY" | "DY" | "Y" => "DAYOFYEAR",
52020 "W" | "WK" | "WEEKOFYEAR" | "WOY" | "WY" | "WW" => "WEEK",
52021 "Q" | "QTR" | "QTRS" | "QUARTERS" | "QQ" => "QUARTER",
52022 "H" | "HH" | "HR" | "HOURS" | "HRS" => "HOUR",
52023 "MI" | "MIN" | "MINUTES" | "MINS" | "N" => "MINUTE",
52024 "S" | "SEC" | "SECONDS" | "SECS" | "SS" => "SECOND",
52025 "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC" | "MILLISECS"
52026 | "MILLISECON" | "MILLISECONDS" => "MILLISECOND",
52027 "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND" | "USECONDS"
52028 | "MICROSECONDS" | "MCS" => "MICROSECOND",
52029 "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS" | "NANOSECS" => "NANOSECOND",
52030 "TZH" => "TIMEZONE_HOUR",
52031 "TZM" | "TZOFFSET" | "TZ" => "TIMEZONE_MINUTE",
52032 "DEC" | "DECS" | "DECADES" => "DECADE",
52033 "MIL" | "MILS" | "MILLENIA" => "MILLENNIUM",
52034 "C" | "CENT" | "CENTS" | "CENTURIES" => "CENTURY",
52035 "ISOWK" | "ISOWW" | "ISO_WEEK" | "WEEKOFYEARISO" | "WEEKOFYEAR_ISO"
52036 | "WEEK_ISO" => "WEEKISO",
52037 _ => return expr, };
52039 return Expression::Var(Box::new(Var {
52040 this: mapped.to_string(),
52041 }));
52042 }
52043 expr
52044 }
52045
52046 fn try_parse_date_part_unit_expr(&self, expr: &Expression) -> Option<IntervalUnit> {
52047 let upper = self.date_part_expr_name(expr)?.to_ascii_uppercase();
52048 let canonical = match upper.as_str() {
52049 "Y" | "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => "YEAR",
52051 "Q" | "QTR" | "QTRS" | "QUARTERS" | "QQ" => "QUARTER",
52053 "MM" | "MON" | "MONS" | "MONTHS" | "M" => "MONTH",
52055 "W" | "WK" | "WEEKOFYEAR" | "WOY" | "WY" | "WW" | "WEEKS" => "WEEK",
52057 "D" | "DD" | "DAYS" | "DAYOFMONTH" => "DAY",
52059 "H" | "HH" | "HR" | "HOURS" | "HRS" => "HOUR",
52061 "MI" | "MIN" | "MINUTES" | "MINS" | "N" => "MINUTE",
52063 "S" | "SEC" | "SECONDS" | "SECS" | "SS" => "SECOND",
52065 "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC" | "MILLISECS"
52067 | "MILLISECON" | "MILLISECONDS" => "MILLISECOND",
52068 "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND" | "USECONDS"
52070 | "MICROSECONDS" | "MCS" => "MICROSECOND",
52071 "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS" | "NANOSECS" => "NANOSECOND",
52073 _ => upper.as_str(),
52074 };
52075
52076 Self::parse_interval_unit_from_string(canonical)
52077 }
52078
52079 fn try_parse_date_part_unit_identifier_expr(&self, expr: &Expression) -> Option<IntervalUnit> {
52080 let upper = self
52081 .date_part_identifier_expr_name(expr)?
52082 .to_ascii_uppercase();
52083 let canonical = match upper.as_str() {
52084 "Y" | "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => "YEAR",
52085 "Q" | "QTR" | "QTRS" | "QUARTERS" | "QQ" => "QUARTER",
52086 "MM" | "MON" | "MONS" | "MONTHS" | "M" => "MONTH",
52087 "W" | "WK" | "WEEKOFYEAR" | "WOY" | "WY" | "WW" | "WEEKS" => "WEEK",
52088 "D" | "DD" | "DAYS" | "DAYOFMONTH" => "DAY",
52089 "H" | "HH" | "HR" | "HOURS" | "HRS" => "HOUR",
52090 "MI" | "MIN" | "MINUTES" | "MINS" | "N" => "MINUTE",
52091 "S" | "SEC" | "SECONDS" | "SECS" | "SS" => "SECOND",
52092 "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC" | "MILLISECS"
52093 | "MILLISECON" | "MILLISECONDS" => "MILLISECOND",
52094 "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND" | "USECONDS"
52095 | "MICROSECONDS" | "MCS" => "MICROSECOND",
52096 "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS" | "NANOSECS" => "NANOSECOND",
52097 _ => upper.as_str(),
52098 };
52099
52100 Self::parse_interval_unit_from_string(canonical)
52101 }
52102
52103 fn try_parse_date_part_field_identifier_expr(
52104 &self,
52105 expr: &Expression,
52106 ) -> Option<DateTimeField> {
52107 let upper = self
52108 .date_part_identifier_expr_name(expr)?
52109 .to_ascii_uppercase();
52110 Some(match upper.as_str() {
52111 "YEAR" | "Y" | "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => DateTimeField::Year,
52112 "MONTH" | "MM" | "MON" | "MONS" | "MONTHS" => DateTimeField::Month,
52113 "DAY" | "D" | "DD" | "DAYS" | "DAYOFMONTH" => DateTimeField::Day,
52114 "HOUR" | "H" | "HH" | "HR" | "HOURS" | "HRS" => DateTimeField::Hour,
52115 "MINUTE" | "MI" | "MIN" | "MINUTES" | "MINS" => DateTimeField::Minute,
52116 "SECOND" | "S" | "SEC" | "SECONDS" | "SECS" => DateTimeField::Second,
52117 "MILLISECOND" | "MS" | "MSEC" | "MILLISECONDS" => DateTimeField::Millisecond,
52118 "MICROSECOND" | "US" | "USEC" | "MICROSECONDS" => DateTimeField::Microsecond,
52119 "DOW" | "DAYOFWEEK" | "DW" => DateTimeField::DayOfWeek,
52120 "DOY" | "DAYOFYEAR" | "DY" => DateTimeField::DayOfYear,
52121 "WEEK" | "W" | "WK" | "WEEKOFYEAR" | "WOY" | "WW" => DateTimeField::Week,
52122 "QUARTER" | "Q" | "QTR" | "QTRS" | "QUARTERS" => DateTimeField::Quarter,
52123 "EPOCH" | "EPOCH_SECOND" | "EPOCH_SECONDS" => DateTimeField::Epoch,
52124 "TIMEZONE" => DateTimeField::Timezone,
52125 "TIMEZONE_HOUR" | "TZH" => DateTimeField::TimezoneHour,
52126 "TIMEZONE_MINUTE" | "TZM" => DateTimeField::TimezoneMinute,
52127 "DATE" => DateTimeField::Date,
52128 "TIME" => DateTimeField::Time,
52129 other => DateTimeField::Custom(other.to_string()),
52130 })
52131 }
52132
52133 fn convert_date_part_identifier_expr_to_var(&self, expr: Expression) -> Expression {
52134 match expr {
52135 Expression::Var(_) => expr,
52136 Expression::Column(c) if c.table.is_none() => {
52137 Expression::Var(Box::new(Var { this: c.name.name }))
52138 }
52139 Expression::Identifier(id) => Expression::Var(Box::new(Var { this: id.name })),
52140 _ => expr,
52141 }
52142 }
52143
52144 fn date_part_identifier_expr_name<'a>(&self, expr: &'a Expression) -> Option<&'a str> {
52145 match expr {
52146 Expression::Var(v) => Some(v.this.as_str()),
52147 Expression::Column(c) if c.table.is_none() => Some(c.name.name.as_str()),
52148 Expression::Identifier(id) => Some(id.name.as_str()),
52149 _ => None,
52150 }
52151 }
52152
52153 fn date_part_expr_name<'a>(&self, expr: &'a Expression) -> Option<&'a str> {
52154 self.date_part_identifier_expr_name(expr).or(match expr {
52155 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
52156 let Literal::String(s) = lit.as_ref() else {
52157 unreachable!()
52158 };
52159 Some(s.as_str())
52160 }
52161 _ => None,
52162 })
52163 }
52164
52165 fn try_clickhouse_func_arg_alias(&mut self, expr: Expression) -> Expression {
52166 if !matches!(
52167 self.config.dialect,
52168 Some(crate::dialects::DialectType::ClickHouse)
52169 ) {
52170 return expr;
52171 }
52172 if self.check(TokenType::Var) || self.check(TokenType::Identifier) {
52174 let next_after = self.peek_nth(1).map(|t| t.token_type);
52175 let is_delimiter = matches!(
52176 next_after,
52177 Some(TokenType::Comma)
52178 | Some(TokenType::RParen)
52179 | Some(TokenType::From)
52180 | Some(TokenType::For)
52181 | Some(TokenType::As)
52182 );
52183 if is_delimiter {
52184 let alias_token = self.advance();
52185 let alias_name = alias_token.text.clone();
52186 return Expression::Alias(Box::new(crate::expressions::Alias::new(
52187 expr,
52188 Identifier::new(alias_name),
52189 )));
52190 }
52191 }
52192 if self.check(TokenType::As) {
52194 let next_idx = self.current + 1;
52195 let after_alias_idx = self.current + 2;
52196 let is_alias_token = next_idx < self.tokens.len()
52197 && matches!(
52198 self.tokens[next_idx].token_type,
52199 TokenType::Identifier | TokenType::Var | TokenType::QuotedIdentifier
52200 );
52201 let is_delimiter = is_alias_token
52202 && after_alias_idx < self.tokens.len()
52203 && matches!(
52204 self.tokens[after_alias_idx].token_type,
52205 TokenType::Comma
52206 | TokenType::RParen
52207 | TokenType::From
52208 | TokenType::For
52209 | TokenType::As
52210 );
52211 if is_delimiter {
52212 self.skip(); let alias_token = self.advance();
52214 let alias_name = if alias_token.token_type == TokenType::QuotedIdentifier {
52215 let mut ident = Identifier::new(alias_token.text.clone());
52216 ident.quoted = true;
52217 ident
52218 } else {
52219 Identifier::new(alias_token.text.clone())
52220 };
52221 return Expression::Alias(Box::new(crate::expressions::Alias::new(
52222 expr, alias_name,
52223 )));
52224 }
52225 }
52226 expr
52227 }
52228
52229 fn parse_clickhouse_engine_expression(&mut self) -> Result<Expression> {
52231 if self.is_at_end() {
52232 return Err(self.parse_error("Expected engine name after ENGINE"));
52233 }
52234
52235 let token = self.advance();
52236 let quoted = matches!(token.token_type, TokenType::QuotedIdentifier);
52237 let name = token.text.clone();
52238
52239 let ident = Expression::Identifier(Identifier {
52240 name,
52241 quoted,
52242 trailing_comments: Vec::new(),
52243 span: None,
52244 });
52245
52246 if self.match_token(TokenType::LParen) {
52247 let args = if self.check(TokenType::RParen) {
52248 Vec::new()
52249 } else {
52250 self.parse_expression_list()?
52251 };
52252 self.expect(TokenType::RParen)?;
52253 Ok(Expression::Anonymous(Box::new(Anonymous {
52254 this: Box::new(ident),
52255 expressions: args,
52256 })))
52257 } else {
52258 Ok(ident)
52259 }
52260 }
52261
52262 #[allow(unused_variables, unused_mut)]
52265 pub fn parse_property_assignment(&mut self) -> Result<Option<Expression>> {
52266 let _ = self.match_token(TokenType::Eq);
52268 let _ = self.match_token(TokenType::Alias);
52269
52270 let value = self.parse_unquoted_field()?;
52272
52273 Ok(value)
52274 }
52275
52276 #[allow(unused_variables, unused_mut)]
52278 pub fn parse_property_before(&mut self) -> Result<Option<Expression>> {
52279 if self.match_text_seq(&["NO"]) {
52280 return Ok(None);
52282 }
52283 if self.match_text_seq(&["DUAL"]) {
52284 return Ok(None);
52286 }
52287 if self.match_text_seq(&["BEFORE"]) {
52288 return Ok(None);
52290 }
52291 if self.match_texts(&["MIN", "MINIMUM"]) {
52292 return Ok(None);
52294 }
52295 if self.match_texts(&["MAX", "MAXIMUM"]) {
52296 return Ok(None);
52298 }
52299 Ok(None)
52300 }
52301
52302 pub fn parse_qualify(&mut self) -> Result<Option<Expression>> {
52305 if !self.match_token(TokenType::Qualify) {
52306 return Ok(None);
52307 }
52308 let condition = self.parse_expression()?;
52309 Ok(Some(Expression::Qualify(Box::new(Qualify {
52310 this: condition,
52311 }))))
52312 }
52313
52314 pub fn parse_range(&mut self) -> Result<Option<Expression>> {
52317 let mut this = self.parse_bitwise()?;
52319 if this.is_none() {
52320 return Ok(None);
52321 }
52322
52323 let negate = self.match_token(TokenType::Not);
52325
52326 if self.match_token(TokenType::Between) {
52328 let between = self.parse_between_with_expr(this.clone(), negate)?;
52329 this = Some(between);
52330 return Ok(this);
52331 }
52332
52333 if self.match_token(TokenType::Like) {
52335 let left = this.clone().expect("left expression checked above");
52336 let right = self
52337 .parse_bitwise()?
52338 .ok_or_else(|| self.parse_error("Expected expression after LIKE"))?;
52339 let escape = self.parse_escape()?;
52340 let like = Expression::Like(Box::new(LikeOp {
52341 left,
52342 right,
52343 escape,
52344 quantifier: None,
52345 inferred_type: None,
52346 }));
52347 this = if negate {
52348 Some(Expression::Not(Box::new(UnaryOp {
52349 this: like,
52350 inferred_type: None,
52351 })))
52352 } else {
52353 Some(like)
52354 };
52355 return Ok(this);
52356 }
52357
52358 if self.match_token(TokenType::ILike) {
52360 let left = this.clone().expect("left expression checked above");
52361 let right = self
52362 .parse_bitwise()?
52363 .ok_or_else(|| self.parse_error("Expected expression after ILIKE"))?;
52364 let escape = self.parse_escape()?;
52365 let ilike = Expression::ILike(Box::new(LikeOp {
52366 left,
52367 right,
52368 escape,
52369 quantifier: None,
52370 inferred_type: None,
52371 }));
52372 this = if negate {
52373 Some(Expression::Not(Box::new(UnaryOp {
52374 this: ilike,
52375 inferred_type: None,
52376 })))
52377 } else {
52378 Some(ilike)
52379 };
52380 return Ok(this);
52381 }
52382
52383 if self.match_token(TokenType::In) {
52385 let in_expr = self.parse_in_with_expr(this.clone())?;
52386 this = if negate {
52387 Some(Expression::Not(Box::new(UnaryOp {
52388 this: in_expr,
52389 inferred_type: None,
52390 })))
52391 } else {
52392 Some(in_expr)
52393 };
52394 return Ok(this);
52395 }
52396
52397 if self.match_token(TokenType::Is) {
52399 let is_expr = self.parse_is_with_expr(this.clone())?;
52400 this = Some(is_expr);
52401 return Ok(this);
52402 }
52403
52404 if negate && self.match_token(TokenType::Null) {
52406 if let Some(left) = this {
52407 let is_null = Expression::Is(Box::new(BinaryOp {
52408 left,
52409 right: Expression::Null(Null),
52410 left_comments: Vec::new(),
52411 operator_comments: Vec::new(),
52412 trailing_comments: Vec::new(),
52413 inferred_type: None,
52414 }));
52415 return Ok(Some(Expression::Not(Box::new(UnaryOp {
52416 this: is_null,
52417 inferred_type: None,
52418 }))));
52419 }
52420 }
52421
52422 Ok(this)
52423 }
52424
52425 fn parse_between_with_expr(
52427 &mut self,
52428 this: Option<Expression>,
52429 negate: bool,
52430 ) -> Result<Expression> {
52431 let this_expr = match this {
52432 Some(e) => e,
52433 None => return Err(self.parse_error("Expected expression before BETWEEN")),
52434 };
52435
52436 let symmetric = if self.match_texts(&["SYMMETRIC"]) {
52438 Some(true)
52439 } else if self.match_texts(&["ASYMMETRIC"]) {
52440 Some(false)
52441 } else {
52442 None
52443 };
52444
52445 let low = self
52446 .parse_bitwise()?
52447 .ok_or_else(|| self.parse_error("Expected low expression after BETWEEN"))?;
52448
52449 if !self.match_token(TokenType::And) {
52450 return Err(self.parse_error("Expected AND in BETWEEN expression"));
52451 }
52452
52453 let high = self
52454 .parse_bitwise()?
52455 .ok_or_else(|| self.parse_error("Expected high expression after AND in BETWEEN"))?;
52456
52457 Ok(Expression::Between(Box::new(Between {
52458 this: this_expr,
52459 low,
52460 high,
52461 not: negate,
52462 symmetric,
52463 })))
52464 }
52465
52466 fn parse_in_with_expr(&mut self, this: Option<Expression>) -> Result<Expression> {
52468 let this_expr = match this {
52469 Some(e) => e,
52470 None => return Err(self.parse_error("Expected expression before IN")),
52471 };
52472
52473 if self.check_identifier("UNNEST") {
52475 self.skip(); self.expect(TokenType::LParen)?;
52477 let unnest_expr = self.parse_expression()?;
52478 self.expect(TokenType::RParen)?;
52479 return Ok(Expression::In(Box::new(In {
52480 this: this_expr,
52481 expressions: Vec::new(),
52482 query: None,
52483 not: false,
52484 global: false,
52485 unnest: Some(Box::new(unnest_expr)),
52486 is_field: false,
52487 })));
52488 }
52489
52490 if !self.match_token(TokenType::LParen) {
52492 if let Ok(expr) = self.parse_primary() {
52495 return Ok(Expression::In(Box::new(In {
52496 this: this_expr,
52497 expressions: vec![expr],
52498 query: None,
52499 not: false,
52500 global: false,
52501 unnest: None,
52502 is_field: true,
52503 })));
52504 }
52505 return Err(self.parse_error("Expected expression or parenthesized list after IN"));
52506 }
52507
52508 if self.check(TokenType::Select) {
52510 let subquery = self.parse_select()?;
52511 self.expect(TokenType::RParen)?;
52512 return Ok(Expression::In(Box::new(In {
52513 this: this_expr,
52514 expressions: Vec::new(),
52515 query: Some(subquery),
52516 not: false,
52517 global: false,
52518 unnest: None,
52519 is_field: false,
52520 })));
52521 }
52522
52523 let capacity_hint = self.estimate_expression_list_capacity_until_rparen();
52525 let expressions = self.parse_expression_list_with_capacity(capacity_hint)?;
52526 self.expect(TokenType::RParen)?;
52527
52528 if expressions.is_empty() {
52529 return Err(self.parse_error("Expected expression list after IN"));
52530 }
52531
52532 Ok(Expression::In(Box::new(In {
52533 this: this_expr,
52534 expressions,
52535 query: None,
52536 not: false,
52537 global: false,
52538 unnest: None,
52539 is_field: false,
52540 })))
52541 }
52542
52543 fn parse_is_with_expr(&mut self, this: Option<Expression>) -> Result<Expression> {
52545 let this_expr = match this {
52546 Some(e) => e,
52547 None => return Err(self.parse_error("Expected expression before IS")),
52548 };
52549
52550 let negate = self.match_token(TokenType::Not);
52551
52552 if self.match_token(TokenType::Null) {
52554 let is_null = Expression::Is(Box::new(BinaryOp {
52555 left: this_expr,
52556 right: Expression::Null(Null),
52557 left_comments: Vec::new(),
52558 operator_comments: Vec::new(),
52559 trailing_comments: Vec::new(),
52560 inferred_type: None,
52561 }));
52562 return if negate {
52563 Ok(Expression::Not(Box::new(UnaryOp {
52564 this: is_null,
52565 inferred_type: None,
52566 })))
52567 } else {
52568 Ok(is_null)
52569 };
52570 }
52571
52572 if self.match_texts(&["TRUE"]) {
52574 let is_true = Expression::Is(Box::new(BinaryOp {
52575 left: this_expr,
52576 right: Expression::Boolean(BooleanLiteral { value: true }),
52577 left_comments: Vec::new(),
52578 operator_comments: Vec::new(),
52579 trailing_comments: Vec::new(),
52580 inferred_type: None,
52581 }));
52582 return if negate {
52583 Ok(Expression::Not(Box::new(UnaryOp {
52584 this: is_true,
52585 inferred_type: None,
52586 })))
52587 } else {
52588 Ok(is_true)
52589 };
52590 }
52591
52592 if self.match_texts(&["FALSE"]) {
52594 let is_false = Expression::Is(Box::new(BinaryOp {
52595 left: this_expr,
52596 right: Expression::Boolean(BooleanLiteral { value: false }),
52597 left_comments: Vec::new(),
52598 operator_comments: Vec::new(),
52599 trailing_comments: Vec::new(),
52600 inferred_type: None,
52601 }));
52602 return if negate {
52603 Ok(Expression::Not(Box::new(UnaryOp {
52604 this: is_false,
52605 inferred_type: None,
52606 })))
52607 } else {
52608 Ok(is_false)
52609 };
52610 }
52611
52612 if self.match_texts(&["JSON"]) {
52614 let json_type = if self.match_texts(&["VALUE"]) {
52616 Some("VALUE".to_string())
52617 } else if self.match_texts(&["SCALAR"]) {
52618 Some("SCALAR".to_string())
52619 } else if self.match_texts(&["OBJECT"]) {
52620 Some("OBJECT".to_string())
52621 } else if self.match_texts(&["ARRAY"]) {
52622 Some("ARRAY".to_string())
52623 } else {
52624 None
52625 };
52626
52627 let unique_keys = if self.match_text_seq(&["WITH", "UNIQUE", "KEYS"]) {
52629 Some(JsonUniqueKeys::With)
52630 } else if self.match_text_seq(&["WITHOUT", "UNIQUE", "KEYS"]) {
52631 Some(JsonUniqueKeys::Without)
52632 } else if self.match_text_seq(&["UNIQUE", "KEYS"]) {
52633 Some(JsonUniqueKeys::Shorthand)
52635 } else {
52636 None
52637 };
52638
52639 return Ok(Expression::IsJson(Box::new(IsJson {
52640 this: this_expr,
52641 json_type,
52642 unique_keys,
52643 negated: negate,
52644 })));
52645 }
52646
52647 if self.match_text_seq(&["DISTINCT", "FROM"]) {
52649 let right = self.parse_bitwise()?;
52650 if let Some(right_expr) = right {
52651 let expr = if negate {
52655 Expression::NullSafeEq(Box::new(BinaryOp {
52656 left: this_expr,
52657 right: right_expr,
52658 left_comments: Vec::new(),
52659 operator_comments: Vec::new(),
52660 trailing_comments: Vec::new(),
52661 inferred_type: None,
52662 }))
52663 } else {
52664 Expression::NullSafeNeq(Box::new(BinaryOp {
52665 left: this_expr,
52666 right: right_expr,
52667 left_comments: Vec::new(),
52668 operator_comments: Vec::new(),
52669 trailing_comments: Vec::new(),
52670 inferred_type: None,
52671 }))
52672 };
52673 return Ok(expr);
52674 }
52675 return Err(self.parse_error("Expected expression after IS DISTINCT FROM"));
52676 }
52677
52678 Err(self.parse_error("Expected NULL, TRUE, FALSE, JSON, or DISTINCT FROM after IS"))
52679 }
52680
52681 #[allow(unused_variables, unused_mut)]
52683 pub fn parse_reads_property(&mut self) -> Result<Option<Expression>> {
52684 if self.match_text_seq(&["SQL", "DATA"]) {
52685 return Ok(None);
52687 }
52688 Ok(None)
52689 }
52690
52691 #[allow(unused_variables, unused_mut)]
52695 pub fn parse_recursive_with_search(&mut self) -> Result<Option<Box<Expression>>> {
52696 let kind = if self.match_text_seq(&["SEARCH"]) {
52698 let search_kind = if self.match_text_seq(&["BREADTH"]) {
52700 "BREADTH"
52701 } else if self.match_text_seq(&["DEPTH"]) {
52702 "DEPTH"
52703 } else {
52704 return Ok(None);
52705 };
52706 self.match_text_seq(&["FIRST"]);
52708 self.match_text_seq(&["BY"]);
52709 search_kind.to_string()
52710 } else if self.match_token(TokenType::Cycle) {
52711 "CYCLE".to_string()
52712 } else {
52713 return Ok(None);
52714 };
52715
52716 let this = self.expect_identifier()?;
52718 let this_expr = Expression::Identifier(Identifier::new(this));
52719
52720 let expression = if self.match_text_seq(&["SET"]) {
52722 let set_col = self.expect_identifier()?;
52723 Expression::Identifier(Identifier::new(set_col))
52724 } else {
52725 return Err(self.parse_error("Expected SET in CYCLE/SEARCH clause"));
52726 };
52727
52728 let using = if self.match_token(TokenType::Using) {
52730 let using_col = self.expect_identifier()?;
52731 Some(Box::new(Expression::Identifier(Identifier::new(using_col))))
52732 } else {
52733 None
52734 };
52735
52736 Ok(Some(Box::new(Expression::RecursiveWithSearch(Box::new(
52737 RecursiveWithSearch {
52738 kind,
52739 this: Box::new(this_expr),
52740 expression: Box::new(expression),
52741 using,
52742 },
52743 )))))
52744 }
52745
52746 #[allow(unused_variables, unused_mut)]
52749 pub fn parse_references(&mut self) -> Result<Option<Expression>> {
52750 if !self.match_token(TokenType::References) {
52751 return Ok(None);
52752 }
52753
52754 let this = self.parse_table()?;
52756 if this.is_none() {
52757 return Err(self.parse_error("Expected table name after REFERENCES"));
52758 }
52759
52760 let expressions = if self.match_token(TokenType::LParen) {
52762 let cols = self.parse_identifier_list()?;
52763 self.expect(TokenType::RParen)?;
52764 cols.into_iter()
52765 .map(|id| Expression::Identifier(id))
52766 .collect()
52767 } else {
52768 Vec::new()
52769 };
52770
52771 let options = self.parse_fk_constraint_options()?;
52773
52774 Ok(Some(Expression::Reference(Box::new(Reference {
52775 this: Box::new(this.unwrap()),
52776 expressions,
52777 options,
52778 }))))
52779 }
52780
52781 fn parse_fk_constraint_options(&mut self) -> Result<Vec<Expression>> {
52783 let mut options = Vec::new();
52784
52785 while self.match_token(TokenType::On) {
52786 let kind = if self.match_token(TokenType::Delete) {
52787 "DELETE"
52788 } else if self.match_token(TokenType::Update) {
52789 "UPDATE"
52790 } else {
52791 break;
52792 };
52793
52794 let action = if self.match_text_seq(&["NO", "ACTION"]) {
52795 "NO ACTION"
52796 } else if self.match_text_seq(&["SET", "NULL"]) {
52797 "SET NULL"
52798 } else if self.match_text_seq(&["SET", "DEFAULT"]) {
52799 "SET DEFAULT"
52800 } else if self.match_token(TokenType::Cascade) {
52801 "CASCADE"
52802 } else if self.match_token(TokenType::Restrict) {
52803 "RESTRICT"
52804 } else {
52805 continue;
52806 };
52807
52808 options.push(Expression::Identifier(Identifier {
52810 name: format!("ON {} {}", kind, action),
52811 quoted: false,
52812 trailing_comments: Vec::new(),
52813 span: None,
52814 }));
52815 }
52816
52817 if self.match_token(TokenType::Match) {
52819 let match_type = if self.match_identifier("FULL") {
52820 "FULL"
52821 } else if self.match_identifier("PARTIAL") {
52822 "PARTIAL"
52823 } else if self.match_identifier("SIMPLE") {
52824 "SIMPLE"
52825 } else {
52826 ""
52827 };
52828 if !match_type.is_empty() {
52829 options.push(Expression::Identifier(Identifier {
52830 name: format!("MATCH {}", match_type),
52831 quoted: false,
52832 trailing_comments: Vec::new(),
52833 span: None,
52834 }));
52835 }
52836 }
52837
52838 Ok(options)
52839 }
52840
52841 #[allow(unused_variables, unused_mut)]
52843 pub fn parse_refresh(&mut self) -> Result<Option<Expression>> {
52846 let kind = if self.match_token(TokenType::Table) {
52847 "TABLE".to_string()
52848 } else if self.match_text_seq(&["MATERIALIZED", "VIEW"]) {
52849 "MATERIALIZED VIEW".to_string()
52850 } else {
52851 String::new()
52852 };
52853
52854 if let Some(s) = self.parse_string()? {
52857 return Ok(Some(Expression::Refresh(Box::new(Refresh {
52858 this: Box::new(s),
52859 kind,
52860 }))));
52861 }
52862
52863 let table_ref = self.parse_table_ref()?;
52865 let table_expr = Expression::Table(Box::new(table_ref));
52866
52867 Ok(Some(Expression::Refresh(Box::new(Refresh {
52868 this: Box::new(table_expr),
52869 kind,
52870 }))))
52871 }
52872
52873 pub fn parse_refresh_trigger_property(&mut self) -> Result<RefreshTriggerProperty> {
52880 let method = self.expect_identifier_or_keyword()?.to_ascii_uppercase();
52882
52883 self.expect(TokenType::On)?;
52885
52886 let kind_text = self.expect_identifier_or_keyword()?.to_ascii_uppercase();
52888 let kind = Some(kind_text.clone());
52889
52890 let (every, unit, starts) = if kind_text == "SCHEDULE" {
52892 let every = if self.match_identifier("EVERY") {
52894 self.parse_number()?.map(Box::new)
52896 } else {
52897 None
52898 };
52899
52900 let unit = if every.is_some() {
52902 Some(self.expect_identifier_or_keyword()?.to_ascii_uppercase())
52903 } else {
52904 None
52905 };
52906
52907 let starts = if self.match_identifier("STARTS") {
52909 let s = self.expect_string()?;
52910 Some(Box::new(Expression::Literal(Box::new(Literal::String(s)))))
52911 } else {
52912 None
52913 };
52914
52915 (every, unit, starts)
52916 } else {
52917 (None, None, None)
52918 };
52919
52920 Ok(RefreshTriggerProperty {
52921 method,
52922 kind,
52923 every,
52924 unit,
52925 starts,
52926 })
52927 }
52928
52929 #[allow(unused_variables, unused_mut)]
52931 pub fn parse_remote_with_connection(&mut self) -> Result<Option<Expression>> {
52932 if self.match_text_seq(&["WITH", "CONNECTION"]) {
52933 return Ok(None);
52935 }
52936 Ok(None)
52937 }
52938
52939 #[allow(unused_variables, unused_mut)]
52941 pub fn parse_respect_or_ignore_nulls(&mut self) -> Result<Option<Expression>> {
52942 if self.match_text_seq(&["IGNORE", "NULLS"]) {
52943 return Ok(None);
52945 }
52946 if self.match_text_seq(&["RESPECT", "NULLS"]) {
52947 return Ok(None);
52949 }
52950 Ok(None)
52951 }
52952
52953 pub fn parse_retention_period(&mut self) -> Result<Option<Expression>> {
52957 let number = self.parse_number()?;
52959 let number_str = number
52960 .map(|n| match n {
52961 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
52962 let Literal::Number(s) = lit.as_ref() else {
52963 unreachable!()
52964 };
52965 format!("{} ", s)
52966 }
52967 _ => String::new(),
52968 })
52969 .unwrap_or_default();
52970
52971 let unit = self.parse_var_any_token()?;
52973 let unit_str = unit
52974 .map(|u| match u {
52975 Expression::Var(v) => v.this.clone(),
52976 _ => String::new(),
52977 })
52978 .unwrap_or_default();
52979
52980 let result = format!("{}{}", number_str, unit_str);
52981 Ok(Some(Expression::Var(Box::new(Var { this: result }))))
52982 }
52983
52984 fn parse_var_any_token(&mut self) -> Result<Option<Expression>> {
52986 if !self.is_at_end() {
52987 let token = self.advance();
52988 Ok(Some(Expression::Var(Box::new(Var {
52989 this: token.text.clone(),
52990 }))))
52991 } else {
52992 Ok(None)
52993 }
52994 }
52995
52996 #[allow(unused_variables, unused_mut)]
52999 pub fn parse_returning(&mut self) -> Result<Option<Expression>> {
53000 if !self.match_token(TokenType::Returning) {
53001 return Ok(None);
53002 }
53003
53004 let expressions = self.parse_expression_list()?;
53006
53007 let into = if self.match_token(TokenType::Into) {
53009 self.parse_table()?.map(Box::new)
53010 } else {
53011 None
53012 };
53013
53014 Ok(Some(Expression::Returning(Box::new(Returning {
53015 expressions,
53016 into,
53017 }))))
53018 }
53019
53020 pub fn parse_output_clause(&mut self) -> Result<OutputClause> {
53024 let mut columns = Vec::new();
53026 loop {
53027 let expr = self.parse_expression()?;
53028 let expr = if self.match_token(TokenType::As) {
53030 let alias = self.expect_identifier_or_keyword_with_quoted()?;
53031 Expression::Alias(Box::new(Alias {
53032 this: expr,
53033 alias,
53034 column_aliases: Vec::new(),
53035 pre_alias_comments: Vec::new(),
53036 trailing_comments: Vec::new(),
53037 inferred_type: None,
53038 }))
53039 } else {
53040 expr
53041 };
53042 columns.push(expr);
53043 if !self.match_token(TokenType::Comma) {
53044 break;
53045 }
53046 }
53047
53048 let into_table = if self.match_token(TokenType::Into) {
53050 Some(self.parse_expression()?)
53051 } else {
53052 None
53053 };
53054
53055 Ok(OutputClause {
53056 columns,
53057 into_table,
53058 })
53059 }
53060
53061 #[allow(unused_variables, unused_mut)]
53064 pub fn parse_returns(&mut self) -> Result<Option<Expression>> {
53065 if self.match_text_seq(&["NULL", "ON", "NULL", "INPUT"]) {
53066 return Ok(Some(Expression::Schema(Box::new(Schema {
53067 this: None,
53068 expressions: Vec::new(),
53069 }))));
53070 }
53071 Ok(None)
53072 }
53073
53074 pub fn parse_row(&mut self) -> Result<Option<Expression>> {
53077 if !self.match_token(TokenType::Format) {
53079 return Ok(None);
53080 }
53081 self.parse_row_format()
53082 }
53083
53084 pub fn parse_row_format(&mut self) -> Result<Option<Expression>> {
53087 if self.match_text_seq(&["SERDE"]) {
53089 let this = self.parse_string()?;
53090 let serde_properties = self.parse_serde_properties(false)?;
53091
53092 return Ok(Some(Expression::RowFormatSerdeProperty(Box::new(
53093 RowFormatSerdeProperty {
53094 this: Box::new(this.unwrap_or(Expression::Null(Null))),
53095 serde_properties: serde_properties.map(Box::new),
53096 },
53097 ))));
53098 }
53099
53100 self.match_text_seq(&["DELIMITED"]);
53102
53103 let mut fields = None;
53104 let mut escaped = None;
53105 let mut collection_items = None;
53106 let mut map_keys = None;
53107 let mut lines = None;
53108 let mut null = None;
53109
53110 if self.match_text_seq(&["FIELDS", "TERMINATED", "BY"]) {
53112 fields = self.parse_string()?.map(Box::new);
53113 if self.match_text_seq(&["ESCAPED", "BY"]) {
53115 escaped = self.parse_string()?.map(Box::new);
53116 }
53117 }
53118
53119 if self.match_text_seq(&["COLLECTION", "ITEMS", "TERMINATED", "BY"]) {
53121 collection_items = self.parse_string()?.map(Box::new);
53122 }
53123
53124 if self.match_text_seq(&["MAP", "KEYS", "TERMINATED", "BY"]) {
53126 map_keys = self.parse_string()?.map(Box::new);
53127 }
53128
53129 if self.match_text_seq(&["LINES", "TERMINATED", "BY"]) {
53131 lines = self.parse_string()?.map(Box::new);
53132 }
53133
53134 if self.match_text_seq(&["NULL", "DEFINED", "AS"]) {
53136 null = self.parse_string()?.map(Box::new);
53137 }
53138
53139 let serde = self.parse_serde_properties(false)?.map(Box::new);
53141
53142 Ok(Some(Expression::RowFormatDelimitedProperty(Box::new(
53143 RowFormatDelimitedProperty {
53144 fields,
53145 escaped,
53146 collection_items,
53147 map_keys,
53148 lines,
53149 null,
53150 serde,
53151 },
53152 ))))
53153 }
53154
53155 #[allow(unused_variables, unused_mut)]
53159 pub fn parse_schema(&mut self) -> Result<Option<Expression>> {
53160 self.parse_schema_with_this(None)
53161 }
53162
53163 fn parse_schema_with_this(&mut self, this: Option<Expression>) -> Result<Option<Expression>> {
53165 if !self.match_token(TokenType::LParen) {
53167 return Ok(this.map(|e| e));
53168 }
53169
53170 if self.check(TokenType::Select) || self.check(TokenType::With) {
53172 self.current -= 1;
53174 return Ok(this.map(|e| e));
53175 }
53176
53177 let mut expressions = Vec::new();
53179 if !self.check(TokenType::RParen) {
53180 loop {
53181 if let Some(constraint) = self.parse_constraint()? {
53183 expressions.push(constraint);
53184 } else if let Some(field_def) = self.parse_field_def()? {
53185 expressions.push(field_def);
53186 } else {
53187 break;
53188 }
53189
53190 if !self.match_token(TokenType::Comma) {
53191 break;
53192 }
53193 }
53194 }
53195
53196 self.expect(TokenType::RParen)?;
53197
53198 Ok(Some(Expression::Schema(Box::new(Schema {
53199 this: this.map(Box::new),
53200 expressions,
53201 }))))
53202 }
53203
53204 fn parse_schema_identifier(&mut self) -> Result<Expression> {
53207 let name = self.expect_identifier_with_quoted()?;
53209 let name_expr = Expression::Identifier(name);
53210
53211 if self.match_token(TokenType::LParen) {
53213 let mut columns = Vec::new();
53214 loop {
53215 let col = self.expect_identifier_with_quoted()?;
53216 columns.push(Expression::Identifier(col));
53217 if !self.match_token(TokenType::Comma) {
53218 break;
53219 }
53220 }
53221 self.expect(TokenType::RParen)?;
53222 Ok(Expression::Schema(Box::new(Schema {
53223 this: Some(Box::new(name_expr)),
53224 expressions: columns,
53225 })))
53226 } else {
53227 Ok(name_expr)
53229 }
53230 }
53231
53232 #[allow(unused_variables, unused_mut)]
53234 pub fn parse_security(&mut self) -> Result<Option<Expression>> {
53235 if self.match_texts(&["NONE", "DEFINER", "INVOKER"]) {
53236 return Ok(None);
53238 }
53239 Ok(None)
53240 }
53241
53242 pub fn parse_select_or_expression(&mut self) -> Result<Option<Expression>> {
53245 let start_pos = self.current;
53247
53248 if self.check(TokenType::Select) {
53250 return Ok(Some(self.parse_select()?));
53251 }
53252
53253 if let Some(expr) = self.parse_disjunction()? {
53255 return Ok(Some(expr));
53256 }
53257
53258 self.current = start_pos;
53260
53261 Ok(None)
53262 }
53263
53264 #[allow(unused_variables, unused_mut)]
53267 pub fn parse_select_query(&mut self) -> Result<Option<Expression>> {
53268 if self.match_texts(&["STRUCT", "VALUE"]) {
53269 return Ok(None);
53271 }
53272 Ok(None)
53273 }
53274
53275 #[allow(unused_variables, unused_mut)]
53278 pub fn parse_sequence_properties(&mut self) -> Result<Option<Expression>> {
53279 if self.match_text_seq(&["INCREMENT"]) {
53280 return Ok(Some(Expression::SequenceProperties(Box::new(
53281 SequenceProperties {
53282 increment: None,
53283 minvalue: None,
53284 maxvalue: None,
53285 cache: None,
53286 start: None,
53287 owned: None,
53288 options: Vec::new(),
53289 },
53290 ))));
53291 }
53292 if self.match_text_seq(&["BY"]) {
53293 return Ok(None);
53295 }
53296 if self.match_text_seq(&["="]) {
53297 return Ok(None);
53299 }
53300 Ok(None)
53301 }
53302
53303 pub fn parse_serde_properties(&mut self, with_: bool) -> Result<Option<Expression>> {
53306 let start_index = self.current;
53307 let has_with = with_ || self.match_text_seq(&["WITH"]);
53308
53309 if !self.match_token(TokenType::SerdeProperties) {
53311 self.current = start_index;
53312 return Ok(None);
53313 }
53314
53315 let mut expressions = Vec::new();
53317 if self.match_token(TokenType::LParen) {
53318 loop {
53319 if self.check(TokenType::RParen) {
53320 break;
53321 }
53322 let key = self.parse_primary()?;
53324 if self.match_token(TokenType::Eq) {
53325 let value = self.parse_primary()?;
53326 expressions.push(Expression::Eq(Box::new(BinaryOp::new(key, value))));
53327 } else {
53328 expressions.push(key);
53329 }
53330 if !self.match_token(TokenType::Comma) {
53331 break;
53332 }
53333 }
53334 self.expect(TokenType::RParen)?;
53335 }
53336
53337 Ok(Some(Expression::SerdeProperties(Box::new(
53338 SerdeProperties {
53339 expressions,
53340 with_: if has_with {
53341 Some(Box::new(Expression::Boolean(BooleanLiteral {
53342 value: true,
53343 })))
53344 } else {
53345 None
53346 },
53347 },
53348 ))))
53349 }
53350
53351 #[allow(unused_variables, unused_mut)]
53353 pub fn parse_session_parameter(&mut self) -> Result<Option<Expression>> {
53356 let first = if let Some(id) = self.parse_id_var()? {
53358 id
53359 } else if let Some(primary) = self.parse_primary_or_var()? {
53360 primary
53361 } else {
53362 return Ok(None);
53363 };
53364
53365 let (kind, this) = if self.match_token(TokenType::Dot) {
53367 let kind_name = match &first {
53369 Expression::Identifier(id) => Some(id.name.clone()),
53370 _ => None,
53371 };
53372 let second = self
53373 .parse_var()?
53374 .or_else(|| self.parse_primary_or_var().ok().flatten());
53375 (kind_name, second.unwrap_or(first))
53376 } else {
53377 (None, first)
53378 };
53379
53380 Ok(Some(Expression::SessionParameter(Box::new(
53381 SessionParameter {
53382 this: Box::new(this),
53383 kind,
53384 },
53385 ))))
53386 }
53387
53388 #[allow(unused_variables, unused_mut)]
53391 pub fn parse_set_item(&mut self) -> Result<Option<Expression>> {
53392 let kind = if self.match_text_seq(&["GLOBAL"]) {
53394 Some("GLOBAL".to_string())
53395 } else if self.match_text_seq(&["LOCAL"]) {
53396 Some("LOCAL".to_string())
53397 } else if self.match_text_seq(&["SESSION"]) {
53398 Some("SESSION".to_string())
53399 } else {
53400 None
53401 };
53402
53403 self.parse_set_item_assignment()
53405 }
53406
53407 pub fn parse_set_item_assignment(&mut self) -> Result<Option<Expression>> {
53410 let start_index = self.current;
53411
53412 if self.match_text_seq(&["TRANSACTION"]) {
53414 return Ok(Some(Expression::SetItem(Box::new(SetItem {
53416 name: Expression::Var(Box::new(Var {
53417 this: "TRANSACTION".to_string(),
53418 })),
53419 value: Expression::Null(Null),
53420 kind: None,
53421 no_equals: false,
53422 }))));
53423 }
53424
53425 let left = self
53427 .parse_primary_or_var()?
53428 .or_else(|| self.parse_column().ok().flatten());
53429
53430 if left.is_none() {
53431 self.current = start_index;
53432 return Ok(None);
53433 }
53434
53435 if !self.match_texts(&["=", "TO", ":="]) {
53437 self.current = start_index;
53438 return Ok(None);
53439 }
53440
53441 let right_val = if self.check(TokenType::String) {
53444 let text = self.advance().text.clone();
53445 Expression::Literal(Box::new(Literal::String(text)))
53446 } else if self.check(TokenType::False) {
53447 self.skip();
53448 Expression::Boolean(BooleanLiteral { value: false })
53449 } else if self.check(TokenType::True) {
53450 self.skip();
53451 Expression::Boolean(BooleanLiteral { value: true })
53452 } else {
53453 let right = self
53454 .parse_id_var()?
53455 .or_else(|| self.parse_primary_or_var().ok().flatten());
53456 match right {
53458 Some(Expression::Column(col)) => Expression::Var(Box::new(Var {
53459 this: col.name.name.clone(),
53460 })),
53461 Some(Expression::Identifier(id)) => Expression::Var(Box::new(Var {
53462 this: id.name.clone(),
53463 })),
53464 Some(other) => other,
53465 None => Expression::Null(Null),
53466 }
53467 };
53468
53469 Ok(Some(Expression::SetItem(Box::new(SetItem {
53470 name: left
53471 .ok_or_else(|| self.parse_error("Expected variable name in SET statement"))?,
53472 value: right_val,
53473 kind: None,
53474 no_equals: false,
53475 }))))
53476 }
53477
53478 pub fn parse_set_operations(&mut self) -> Result<Option<Expression>> {
53482 let left = if self.check(TokenType::Select) {
53484 Some(self.parse_select()?)
53485 } else if self.match_token(TokenType::LParen) {
53486 let inner = self.parse_select()?;
53487 self.match_token(TokenType::RParen);
53488 Some(inner)
53489 } else {
53490 None
53491 };
53492
53493 if left.is_none() {
53494 return Ok(None);
53495 }
53496
53497 self.parse_set_operations_with_expr(left)
53498 }
53499
53500 pub fn parse_set_operations_with_expr(
53502 &mut self,
53503 this: Option<Expression>,
53504 ) -> Result<Option<Expression>> {
53505 let mut result = this;
53506
53507 while result.is_some() {
53508 if let Some(setop) = self.parse_set_operation_with_expr(result.clone())? {
53509 result = Some(setop);
53510 } else {
53511 break;
53512 }
53513 }
53514
53515 Ok(result)
53516 }
53517
53518 fn parse_set_operation_with_expr(
53520 &mut self,
53521 left: Option<Expression>,
53522 ) -> Result<Option<Expression>> {
53523 let left_expr = match left {
53524 Some(e) => e,
53525 None => return Ok(None),
53526 };
53527
53528 let op_type = if self.match_token(TokenType::Union) {
53530 "UNION"
53531 } else if self.match_token(TokenType::Intersect) {
53532 "INTERSECT"
53533 } else if self.match_token(TokenType::Except) {
53534 "EXCEPT"
53535 } else {
53536 return Ok(Some(left_expr));
53537 };
53538
53539 let (all, distinct) = if self.match_token(TokenType::All) {
53541 (true, false)
53542 } else {
53543 let d = self.match_token(TokenType::Distinct);
53544 (false, d)
53545 };
53546
53547 let by_name = self.match_token(TokenType::By) && self.match_identifier("NAME");
53549
53550 let right = if self.check(TokenType::Select) {
53552 self.parse_select()?
53553 } else if self.match_token(TokenType::LParen) {
53554 let inner = self.parse_select()?;
53555 self.match_token(TokenType::RParen);
53556 inner
53557 } else {
53558 return Ok(Some(left_expr));
53559 };
53560
53561 match op_type {
53563 "UNION" => Ok(Some(Expression::Union(Box::new(Union {
53564 left: left_expr,
53565 right,
53566 all,
53567 distinct,
53568 with: None,
53569 order_by: None,
53570 limit: None,
53571 offset: None,
53572 distribute_by: None,
53573 sort_by: None,
53574 cluster_by: None,
53575 by_name,
53576 side: None,
53577 kind: None,
53578 corresponding: false,
53579 strict: false,
53580 on_columns: Vec::new(),
53581 })))),
53582 "INTERSECT" => Ok(Some(Expression::Intersect(Box::new(Intersect {
53583 left: left_expr,
53584 right,
53585 all,
53586 distinct,
53587 with: None,
53588 order_by: None,
53589 limit: None,
53590 offset: None,
53591 distribute_by: None,
53592 sort_by: None,
53593 cluster_by: None,
53594 by_name,
53595 side: None,
53596 kind: None,
53597 corresponding: false,
53598 strict: false,
53599 on_columns: Vec::new(),
53600 })))),
53601 "EXCEPT" => Ok(Some(Expression::Except(Box::new(Except {
53602 left: left_expr,
53603 right,
53604 all,
53605 distinct,
53606 with: None,
53607 order_by: None,
53608 limit: None,
53609 offset: None,
53610 distribute_by: None,
53611 sort_by: None,
53612 cluster_by: None,
53613 by_name,
53614 side: None,
53615 kind: None,
53616 corresponding: false,
53617 strict: false,
53618 on_columns: Vec::new(),
53619 })))),
53620 _ => Ok(Some(left_expr)),
53621 }
53622 }
53623
53624 #[allow(unused_variables, unused_mut)]
53626 pub fn parse_set_transaction(&mut self) -> Result<Option<Expression>> {
53627 if self.match_text_seq(&["TRANSACTION"]) {
53628 return Ok(None);
53630 }
53631 Ok(None)
53632 }
53633
53634 fn parse_clickhouse_settings_clause(&mut self) -> Result<()> {
53637 if self.match_token(TokenType::Settings) {
53638 let _ = self.parse_settings_property()?;
53639 }
53640 Ok(())
53641 }
53642
53643 pub fn parse_settings_property(&mut self) -> Result<Option<Expression>> {
53647 let mut expressions = Vec::new();
53649 loop {
53650 if let Some(assignment) = self.parse_assignment()? {
53651 expressions.push(assignment);
53652 } else {
53653 break;
53654 }
53655 if !self.match_token(TokenType::Comma) {
53656 break;
53657 }
53658 }
53659
53660 Ok(Some(Expression::SettingsProperty(Box::new(
53661 SettingsProperty { expressions },
53662 ))))
53663 }
53664
53665 #[allow(unused_variables, unused_mut)]
53670 pub fn parse_simplified_pivot(&mut self, is_unpivot: bool) -> Result<Option<Expression>> {
53671 let this = if self.check(TokenType::LParen) {
53673 self.skip(); if self.check(TokenType::Select) || self.check(TokenType::With) {
53676 let inner = self.parse_statement()?;
53677 self.expect(TokenType::RParen)?;
53678 Some(Expression::Subquery(Box::new(Subquery {
53679 this: inner,
53680 alias: None,
53681 column_aliases: Vec::new(),
53682 order_by: None,
53683 limit: None,
53684 offset: None,
53685 lateral: false,
53686 modifiers_inside: false,
53687 trailing_comments: Vec::new(),
53688 distribute_by: None,
53689 sort_by: None,
53690 cluster_by: None,
53691 inferred_type: None,
53692 })))
53693 } else {
53694 self.current -= 1; Some(self.parse_primary()?)
53697 }
53698 } else {
53699 Some(self.parse_primary()?)
53701 };
53702
53703 let expressions = if self.match_text_seq(&["ON"]) {
53705 let mut on_exprs = Vec::new();
53706 loop {
53707 let on_expr = self.parse_bitwise()?;
53709 if on_expr.is_none() {
53710 break;
53711 }
53712 let mut expr = on_expr.unwrap();
53713
53714 if self.match_token(TokenType::In) {
53716 if self.match_token(TokenType::LParen) {
53717 let mut in_exprs = Vec::new();
53718 loop {
53719 if self.check(TokenType::RParen) {
53720 break;
53721 }
53722 if let Some(val) = self.parse_select_or_expression()? {
53723 in_exprs.push(val);
53724 }
53725 if !self.match_token(TokenType::Comma) {
53726 break;
53727 }
53728 }
53729 self.expect(TokenType::RParen)?;
53730 expr = Expression::In(Box::new(In {
53731 this: expr,
53732 expressions: in_exprs,
53733 query: None,
53734 not: false,
53735 global: false,
53736 unnest: None,
53737 is_field: false,
53738 }));
53739 }
53740 }
53741 else if self.match_token(TokenType::As) {
53743 let alias_name = self.expect_identifier()?;
53744 expr =
53745 Expression::Alias(Box::new(Alias::new(expr, Identifier::new(alias_name))));
53746 }
53747
53748 on_exprs.push(expr);
53749
53750 if !self.match_token(TokenType::Comma) {
53752 break;
53753 }
53754 }
53755 on_exprs
53756 } else {
53757 Vec::new()
53758 };
53759
53760 let into = self.parse_unpivot_columns()?;
53762
53763 let using = if self.match_text_seq(&["USING"]) {
53767 let mut using_exprs = Vec::new();
53768 loop {
53769 if self.is_at_end() || self.check(TokenType::Group) || self.check(TokenType::RParen)
53771 {
53772 break;
53773 }
53774 let func = self.parse_primary()?;
53776 let expr = if self.match_token(TokenType::DColon) {
53778 let data_type = self.parse_data_type()?;
53779 Expression::Cast(Box::new(Cast {
53780 this: func,
53781 to: data_type,
53782 trailing_comments: Vec::new(),
53783 double_colon_syntax: true,
53784 format: None,
53785 default: None,
53786 inferred_type: None,
53787 }))
53788 } else {
53789 func
53790 };
53791 if self.match_token(TokenType::As) {
53793 let alias_name = self.expect_identifier()?;
53794 using_exprs.push(Expression::Alias(Box::new(Alias::new(
53795 expr,
53796 Identifier::new(alias_name),
53797 ))));
53798 } else {
53799 using_exprs.push(expr);
53800 }
53801 if !self.match_token(TokenType::Comma) {
53802 break;
53803 }
53804 }
53805 using_exprs
53806 } else {
53807 Vec::new()
53808 };
53809
53810 let group = self.parse_group()?;
53812
53813 let source = this.unwrap();
53814
53815 Ok(Some(Expression::Pivot(Box::new(Pivot {
53816 this: source,
53817 expressions,
53818 fields: Vec::new(),
53819 using,
53820 group: group.map(Box::new),
53821 unpivot: is_unpivot,
53822 into: into.map(Box::new),
53823 alias: None,
53824 include_nulls: None,
53825 default_on_null: None,
53826 with: None,
53827 }))))
53828 }
53829
53830 pub fn parse_slice(&mut self) -> Result<Option<Expression>> {
53834 self.parse_slice_with_this(None)
53835 }
53836
53837 pub fn parse_slice_with_this(
53839 &mut self,
53840 this: Option<Expression>,
53841 ) -> Result<Option<Expression>> {
53842 if !self.match_token(TokenType::Colon) {
53844 return Ok(this);
53845 }
53846
53847 let end = if self.check(TokenType::Dash) && self.check_next(TokenType::Colon) {
53850 self.skip(); Some(Expression::Neg(Box::new(UnaryOp::new(
53853 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
53854 ))))
53855 } else if self.check(TokenType::Colon) || self.check(TokenType::RBracket) {
53856 None
53858 } else {
53859 Some(self.parse_unary()?)
53860 };
53861
53862 let step = if self.match_token(TokenType::Colon) {
53864 if self.check(TokenType::RBracket) {
53865 None
53866 } else {
53867 Some(self.parse_unary()?)
53868 }
53869 } else {
53870 None
53871 };
53872
53873 Ok(Some(Expression::Slice(Box::new(Slice {
53874 this: this.map(Box::new),
53875 expression: end.map(Box::new),
53876 step: step.map(Box::new),
53877 }))))
53878 }
53879
53880 fn parse_slice_element(&mut self) -> Result<Option<Expression>> {
53884 if self.check(TokenType::Colon) || self.check(TokenType::RBracket) {
53886 return Ok(None);
53887 }
53888 if self.check(TokenType::Dash) && self.check_next(TokenType::Colon) {
53891 self.skip(); return Ok(Some(Expression::Neg(Box::new(UnaryOp::new(
53894 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
53895 )))));
53896 }
53897 let expr = self.parse_disjunction()?;
53899 Ok(expr)
53900 }
53901
53902 #[allow(unused_variables, unused_mut)]
53905 pub fn parse_sort(&mut self) -> Result<Option<Expression>> {
53906 if !self.match_keywords(&[TokenType::Sort, TokenType::By]) {
53908 return Ok(None);
53909 }
53910
53911 let mut expressions = Vec::new();
53913 loop {
53914 if let Some(ordered) = self.parse_ordered_item()? {
53915 expressions.push(ordered);
53916 } else {
53917 break;
53918 }
53919 if !self.match_token(TokenType::Comma) {
53920 break;
53921 }
53922 }
53923
53924 Ok(Some(Expression::SortBy(Box::new(SortBy { expressions }))))
53925 }
53926
53927 #[allow(unused_variables, unused_mut)]
53929 pub fn parse_cluster_by_clause(&mut self) -> Result<Option<Expression>> {
53930 if !self.match_keywords(&[TokenType::Cluster, TokenType::By]) {
53931 return Ok(None);
53932 }
53933
53934 let mut expressions: Vec<Ordered> = Vec::new();
53936 loop {
53937 if let Some(ordered) = self.parse_ordered_item()? {
53938 expressions.push(ordered);
53939 } else {
53940 break;
53941 }
53942 if !self.match_token(TokenType::Comma) {
53943 break;
53944 }
53945 }
53946 Ok(Some(Expression::ClusterBy(Box::new(ClusterBy {
53947 expressions,
53948 }))))
53949 }
53950
53951 #[allow(unused_variables, unused_mut)]
53953 pub fn parse_distribute_by_clause(&mut self) -> Result<Option<Expression>> {
53954 if !self.match_keywords(&[TokenType::Distribute, TokenType::By]) {
53955 return Ok(None);
53956 }
53957
53958 let expressions = self.parse_expression_list()?;
53959 Ok(Some(Expression::DistributeBy(Box::new(DistributeBy {
53960 expressions,
53961 }))))
53962 }
53963
53964 #[allow(unused_variables, unused_mut)]
53967 pub fn parse_sortkey(&mut self) -> Result<Option<Expression>> {
53968 let this = if self.match_token(TokenType::LParen) {
53970 let mut columns = Vec::new();
53971 loop {
53972 if let Some(id) = self.parse_id_var()? {
53973 columns.push(id);
53974 } else {
53975 break;
53976 }
53977 if !self.match_token(TokenType::Comma) {
53978 break;
53979 }
53980 }
53981 self.match_token(TokenType::RParen);
53982
53983 if columns.is_empty() {
53984 return Ok(None);
53985 }
53986
53987 if columns.len() == 1 {
53988 columns.into_iter().next().unwrap()
53989 } else {
53990 Expression::Tuple(Box::new(Tuple {
53991 expressions: columns,
53992 }))
53993 }
53994 } else {
53995 if let Some(id) = self.parse_id_var()? {
53997 id
53998 } else {
53999 return Ok(None);
54000 }
54001 };
54002
54003 Ok(Some(Expression::SortKeyProperty(Box::new(
54004 SortKeyProperty {
54005 this: Box::new(this),
54006 compound: None, },
54008 ))))
54009 }
54010
54011 pub fn parse_star(&mut self) -> Result<Option<Expression>> {
54014 if !self.match_token(TokenType::Star) {
54015 return Ok(None);
54016 }
54017
54018 let except = self.parse_star_except()?;
54020
54021 let replace = self.parse_star_replace()?;
54023
54024 let rename = self.parse_star_rename()?;
54026
54027 Ok(Some(Expression::Star(Star {
54028 table: None,
54029 except,
54030 replace,
54031 rename,
54032 trailing_comments: Vec::new(),
54033 span: None,
54034 })))
54035 }
54036
54037 fn try_parse_identifier(&mut self) -> Option<Identifier> {
54039 if self.is_identifier_token() {
54040 let token = self.advance();
54041 let quoted = token.token_type == TokenType::QuotedIdentifier;
54042 Some(Identifier {
54043 name: token.text,
54044 quoted,
54045 trailing_comments: Vec::new(),
54046 span: None,
54047 })
54048 } else {
54049 None
54050 }
54051 }
54052
54053 fn parse_star_except(&mut self) -> Result<Option<Vec<Identifier>>> {
54056 if !self.match_texts(&["EXCEPT", "EXCLUDE"]) {
54057 return Ok(None);
54058 }
54059
54060 if self.match_token(TokenType::LParen) {
54062 let mut columns = Vec::new();
54063 loop {
54064 if let Some(id) = self.try_parse_identifier() {
54065 columns.push(id);
54066 } else if self.is_safe_keyword_as_identifier() {
54067 let token = self.advance();
54069 columns.push(Identifier {
54070 name: token.text,
54071 quoted: false,
54072 trailing_comments: Vec::new(),
54073 span: None,
54074 });
54075 } else {
54076 break;
54077 }
54078 if !self.match_token(TokenType::Comma) {
54079 break;
54080 }
54081 }
54082 self.match_token(TokenType::RParen);
54083 return Ok(Some(columns));
54084 }
54085
54086 if let Some(id) = self.try_parse_identifier() {
54088 return Ok(Some(vec![id]));
54089 }
54090
54091 Ok(None)
54092 }
54093
54094 fn parse_star_replace(&mut self) -> Result<Option<Vec<Alias>>> {
54097 if !self.match_texts(&["REPLACE"]) {
54098 return Ok(None);
54099 }
54100
54101 if self.match_token(TokenType::LParen) {
54102 let mut aliases = Vec::new();
54103 loop {
54104 if let Some(expr) = self.parse_disjunction()? {
54106 let alias_name = if self.match_token(TokenType::As) {
54107 self.try_parse_identifier()
54108 } else {
54109 None
54110 };
54111
54112 aliases.push(Alias {
54113 this: expr,
54114 alias: alias_name.unwrap_or_else(|| Identifier::new("")),
54115 column_aliases: Vec::new(),
54116 pre_alias_comments: Vec::new(),
54117 trailing_comments: Vec::new(),
54118 inferred_type: None,
54119 });
54120 } else {
54121 break;
54122 }
54123 if !self.match_token(TokenType::Comma) {
54124 break;
54125 }
54126 }
54127 self.match_token(TokenType::RParen);
54128 return Ok(Some(aliases));
54129 }
54130
54131 Ok(None)
54132 }
54133
54134 fn parse_star_rename(&mut self) -> Result<Option<Vec<(Identifier, Identifier)>>> {
54137 if !self.match_texts(&["RENAME"]) {
54138 return Ok(None);
54139 }
54140
54141 if self.match_token(TokenType::LParen) {
54142 let mut renames = Vec::new();
54143 loop {
54144 if let Some(old_name) = self.try_parse_identifier() {
54146 if self.match_token(TokenType::As) {
54147 if let Some(new_name) = self.try_parse_identifier() {
54148 renames.push((old_name, new_name));
54149 }
54150 }
54151 } else {
54152 break;
54153 }
54154 if !self.match_token(TokenType::Comma) {
54155 break;
54156 }
54157 }
54158 self.match_token(TokenType::RParen);
54159 return Ok(Some(renames));
54160 }
54161
54162 Ok(None)
54163 }
54164
54165 pub fn parse_star_op(&mut self, keywords: &[&str]) -> Result<Option<Vec<Expression>>> {
54168 if !self.match_texts(keywords) {
54169 return Ok(None);
54170 }
54171
54172 if self.match_token(TokenType::LParen) {
54174 let expressions = self.parse_expression_list()?;
54175 self.match_token(TokenType::RParen);
54176 return Ok(Some(expressions));
54177 }
54178
54179 if let Some(expr) = self.parse_disjunction()? {
54181 let result = if self.match_token(TokenType::As) {
54183 if let Some(alias_name) = self.try_parse_identifier() {
54184 Expression::Alias(Box::new(Alias {
54185 this: expr,
54186 alias: alias_name,
54187 column_aliases: Vec::new(),
54188 pre_alias_comments: Vec::new(),
54189 trailing_comments: Vec::new(),
54190 inferred_type: None,
54191 }))
54192 } else {
54193 expr
54194 }
54195 } else {
54196 expr
54197 };
54198 return Ok(Some(vec![result]));
54199 }
54200
54201 Ok(None)
54202 }
54203
54204 pub fn parse_star_ops(&mut self) -> Result<Option<Expression>> {
54208 if self.match_text_seq(&["COLUMNS"]) && self.check(TokenType::LParen) {
54211 self.expect(TokenType::LParen)?;
54213 let this = self.parse_expression()?;
54214 self.expect(TokenType::RParen)?;
54215
54216 return Ok(Some(Expression::Columns(Box::new(Columns {
54218 this: Box::new(this),
54219 unpack: Some(Box::new(Expression::Boolean(BooleanLiteral {
54220 value: true,
54221 }))),
54222 }))));
54223 }
54224
54225 let except_exprs = self.parse_star_op(&["EXCEPT", "EXCLUDE"])?;
54227 let except = except_exprs.map(|exprs| {
54228 exprs
54229 .into_iter()
54230 .filter_map(|e| match e {
54231 Expression::Identifier(id) => Some(id),
54232 Expression::Column(col) => Some(col.name),
54233 _ => None,
54234 })
54235 .collect()
54236 });
54237
54238 let replace_exprs = self.parse_star_op(&["REPLACE"])?;
54240 let replace = replace_exprs.map(|exprs| {
54241 exprs
54242 .into_iter()
54243 .filter_map(|e| match e {
54244 Expression::Alias(a) => Some(*a),
54245 _ => None,
54246 })
54247 .collect()
54248 });
54249
54250 let _rename_exprs = self.parse_star_op(&["RENAME"])?;
54252 let rename: Option<Vec<(Identifier, Identifier)>> = None; Ok(Some(Expression::Star(Star {
54255 table: None,
54256 except,
54257 replace,
54258 rename,
54259 trailing_comments: Vec::new(),
54260 span: None,
54261 })))
54262 }
54263
54264 #[allow(unused_variables, unused_mut)]
54266 pub fn parse_stored(&mut self) -> Result<Option<Expression>> {
54267 if self.match_text_seq(&["BY"]) {
54268 return Ok(Some(Expression::InputOutputFormat(Box::new(
54269 InputOutputFormat {
54270 input_format: None,
54271 output_format: None,
54272 },
54273 ))));
54274 }
54275 if self.match_text_seq(&["INPUTFORMAT"]) {
54276 return Ok(None);
54278 }
54279 Ok(None)
54280 }
54281
54282 #[allow(unused_variables, unused_mut)]
54284 pub fn parse_stream(&mut self) -> Result<Option<Expression>> {
54285 if self.match_text_seq(&["STREAM"]) {
54286 return Ok(None);
54288 }
54289 Ok(None)
54290 }
54291
54292 pub fn parse_string(&mut self) -> Result<Option<Expression>> {
54295 if self.match_token(TokenType::String) {
54297 let text = self.previous().text.clone();
54298 return Ok(Some(Expression::Literal(Box::new(Literal::String(text)))));
54299 }
54300 if self.match_token(TokenType::NationalString) {
54302 let text = self.previous().text.clone();
54303 return Ok(Some(Expression::Literal(Box::new(
54304 Literal::NationalString(text),
54305 ))));
54306 }
54307 if self.match_token(TokenType::RawString) {
54309 let text = self.previous().text.clone();
54310 return Ok(Some(Expression::Literal(Box::new(Literal::RawString(
54311 text,
54312 )))));
54313 }
54314 if self.match_token(TokenType::HeredocString) {
54316 let text = self.previous().text.clone();
54317 return Ok(Some(Expression::Literal(Box::new(Literal::String(text)))));
54318 }
54319 if self.match_token(TokenType::HexString) {
54321 let text = self.previous().text.clone();
54322 return Ok(Some(Expression::Literal(Box::new(Literal::HexString(
54323 text,
54324 )))));
54325 }
54326 if self.match_token(TokenType::BitString) {
54328 let text = self.previous().text.clone();
54329 return Ok(Some(Expression::Literal(Box::new(Literal::BitString(
54330 text,
54331 )))));
54332 }
54333 if self.match_token(TokenType::ByteString) {
54335 let text = self.previous().text.clone();
54336 return Ok(Some(Expression::Literal(Box::new(Literal::ByteString(
54337 text,
54338 )))));
54339 }
54340 Ok(None)
54341 }
54342
54343 #[allow(unused_variables, unused_mut)]
54347 pub fn parse_string_agg(&mut self) -> Result<Option<Expression>> {
54348 let distinct = self.match_token(TokenType::Distinct);
54350
54351 let this = self.parse_disjunction()?;
54353 if this.is_none() {
54354 return Ok(None);
54355 }
54356
54357 let separator = if self.match_token(TokenType::Comma) {
54359 self.parse_disjunction()?
54360 } else {
54361 None
54362 };
54363
54364 let on_overflow = if self.match_text_seq(&["ON", "OVERFLOW"]) {
54366 if self.match_text_seq(&["ERROR"]) {
54367 Some(Box::new(Expression::Var(Box::new(Var {
54368 this: "ERROR".to_string(),
54369 }))))
54370 } else {
54371 self.match_text_seq(&["TRUNCATE"]);
54372 let truncate_str = self.parse_string()?;
54373 let with_count = if self.match_text_seq(&["WITH", "COUNT"]) {
54374 Some(true)
54375 } else if self.match_text_seq(&["WITHOUT", "COUNT"]) {
54376 Some(false)
54377 } else {
54378 None
54379 };
54380 Some(Box::new(Expression::OverflowTruncateBehavior(Box::new(
54381 OverflowTruncateBehavior {
54382 this: truncate_str.map(Box::new),
54383 with_count: with_count
54384 .map(|c| Box::new(Expression::Boolean(BooleanLiteral { value: c }))),
54385 },
54386 ))))
54387 }
54388 } else {
54389 None
54390 };
54391
54392 let order_by = if self.match_token(TokenType::OrderBy) {
54394 Some(self.parse_expression_list()?)
54395 } else if self.match_text_seq(&["WITHIN", "GROUP"]) {
54396 self.match_token(TokenType::LParen);
54397 let order = self.parse_order()?;
54398 self.match_token(TokenType::RParen);
54399 order.map(|o| vec![o])
54400 } else {
54401 None
54402 };
54403
54404 Ok(Some(Expression::GroupConcat(Box::new(GroupConcatFunc {
54406 this: this.unwrap(),
54407 separator: separator,
54408 order_by: None,
54409 distinct,
54410 filter: None,
54411 inferred_type: None,
54412 }))))
54413 }
54414
54415 pub fn parse_string_as_identifier(&mut self) -> Result<Option<Expression>> {
54419 if self.match_token(TokenType::String) {
54420 let text = self.previous().text.clone();
54421 let name = if text.starts_with('\'') && text.ends_with('\'') && text.len() >= 2 {
54423 text[1..text.len() - 1].to_string()
54424 } else if text.starts_with('"') && text.ends_with('"') && text.len() >= 2 {
54425 text[1..text.len() - 1].to_string()
54426 } else {
54427 text
54428 };
54429
54430 Ok(Some(Expression::Identifier(Identifier {
54431 name,
54432 quoted: true,
54433 trailing_comments: Vec::new(),
54434 span: None,
54435 })))
54436 } else {
54437 Ok(None)
54438 }
54439 }
54440
54441 #[allow(unused_variables, unused_mut)]
54443 pub fn parse_struct_types(&mut self) -> Result<Option<Expression>> {
54444 self.parse_types()
54445 }
54446
54447 #[allow(unused_variables, unused_mut)]
54450 pub fn parse_subquery(&mut self) -> Result<Option<Expression>> {
54451 if !self.match_token(TokenType::LParen) {
54453 return Ok(None);
54454 }
54455
54456 if !self.check(TokenType::Select) && !self.check(TokenType::With) {
54458 self.current -= 1;
54460 return Ok(None);
54461 }
54462
54463 let query = self.parse_statement()?;
54465 self.expect(TokenType::RParen)?;
54466
54467 let alias = self.parse_table_alias_if_present()?;
54469
54470 Ok(Some(Expression::Subquery(Box::new(Subquery {
54471 this: query,
54472 alias,
54473 column_aliases: Vec::new(),
54474 order_by: None,
54475 limit: None,
54476 offset: None,
54477 lateral: false,
54478 modifiers_inside: false,
54479 trailing_comments: Vec::new(),
54480 distribute_by: None,
54481 sort_by: None,
54482 cluster_by: None,
54483 inferred_type: None,
54484 }))))
54485 }
54486
54487 fn parse_table_alias_if_present(&mut self) -> Result<Option<Identifier>> {
54489 let explicit_as = self.match_token(TokenType::As);
54491
54492 let is_keyword_alias = explicit_as
54494 && matches!(
54495 self.config.dialect,
54496 Some(crate::dialects::DialectType::ClickHouse)
54497 )
54498 && self.peek().token_type.is_keyword();
54499
54500 if self.check(TokenType::Identifier)
54502 || self.check(TokenType::QuotedIdentifier)
54503 || is_keyword_alias
54504 {
54505 if is_keyword_alias
54506 && !self.check(TokenType::Identifier)
54507 && !self.check(TokenType::QuotedIdentifier)
54508 {
54509 let token = self.advance();
54510 return Ok(Some(Identifier::new(token.text)));
54511 }
54512 if let Some(Expression::Identifier(id)) = self.parse_identifier()? {
54513 return Ok(Some(id));
54514 }
54515 } else if explicit_as {
54516 return Err(self.parse_error("Expected identifier after AS"));
54518 }
54519
54520 Ok(None)
54521 }
54522
54523 #[allow(unused_variables, unused_mut)]
54528 pub fn parse_substring(&mut self) -> Result<Option<Expression>> {
54529 let mut args: Vec<Expression> = Vec::new();
54531
54532 match self.parse_bitwise() {
54534 Ok(Some(expr)) => {
54535 let expr = self.try_clickhouse_func_arg_alias(expr);
54536 args.push(expr);
54537 }
54538 Ok(None) => return Ok(None),
54539 Err(e) => return Err(e),
54540 }
54541
54542 while self.match_token(TokenType::Comma) {
54544 match self.parse_bitwise() {
54545 Ok(Some(expr)) => {
54546 let expr = self.try_clickhouse_func_arg_alias(expr);
54547 args.push(expr);
54548 }
54549 Ok(None) => break,
54550 Err(e) => return Err(e),
54551 }
54552 }
54553
54554 let mut start: Option<Expression> = None;
54556 let mut length: Option<Expression> = None;
54557 let mut from_for_syntax = false;
54558
54559 loop {
54560 if self.match_token(TokenType::From) {
54561 from_for_syntax = true;
54562 match self.parse_bitwise() {
54563 Ok(Some(expr)) => {
54564 let expr = self.try_clickhouse_func_arg_alias(expr);
54565 start = Some(expr);
54566 }
54567 Ok(None) => {}
54568 Err(e) => return Err(e),
54569 }
54570 } else if self.match_token(TokenType::For) {
54571 from_for_syntax = true;
54572 if start.is_none() {
54574 start = Some(Expression::Literal(Box::new(Literal::Number(
54575 "1".to_string(),
54576 ))));
54577 }
54578 match self.parse_bitwise() {
54579 Ok(Some(expr)) => {
54580 let expr = self.try_clickhouse_func_arg_alias(expr);
54581 length = Some(expr);
54582 }
54583 Ok(None) => {}
54584 Err(e) => return Err(e),
54585 }
54586 } else {
54587 break;
54588 }
54589 }
54590
54591 if args.is_empty() {
54593 return Ok(None);
54594 }
54595
54596 let this = args.remove(0);
54597
54598 let final_start = if let Some(s) = start {
54600 s
54601 } else if !args.is_empty() {
54602 args.remove(0)
54603 } else {
54604 Expression::Literal(Box::new(Literal::Number("1".to_string())))
54605 };
54606
54607 let final_length = if length.is_some() {
54608 length
54609 } else if !args.is_empty() {
54610 Some(args.remove(0))
54611 } else {
54612 None
54613 };
54614
54615 Ok(Some(Expression::Substring(Box::new(SubstringFunc {
54616 this,
54617 start: final_start,
54618 length: final_length,
54619 from_for_syntax,
54620 }))))
54621 }
54622
54623 #[allow(unused_variables, unused_mut)]
54626 pub fn parse_system_versioning_property(&mut self) -> Result<Option<Expression>> {
54627 if self.match_text_seq(&["OFF"]) {
54628 return Ok(Some(Expression::WithSystemVersioningProperty(Box::new(
54629 WithSystemVersioningProperty {
54630 on: None,
54631 this: None,
54632 data_consistency: None,
54633 retention_period: None,
54634 with_: None,
54635 },
54636 ))));
54637 }
54638 if self.match_text_seq(&["HISTORY_TABLE", "="]) {
54639 return Ok(None);
54641 }
54642 if self.match_text_seq(&["DATA_CONSISTENCY_CHECK", "="]) {
54643 return Ok(None);
54645 }
54646 Ok(None)
54647 }
54648
54649 fn parse_rows_from(&mut self) -> Result<Expression> {
54652 self.expect(TokenType::LParen)?;
54654
54655 let mut expressions = Vec::new();
54656
54657 loop {
54658 let func_expr = self.parse_rows_from_function()?;
54661 expressions.push(func_expr);
54662
54663 if !self.match_token(TokenType::Comma) {
54664 break;
54665 }
54666 }
54667
54668 self.expect(TokenType::RParen)?;
54669
54670 let ordinality =
54672 if self.match_token(TokenType::With) && self.match_token(TokenType::Ordinality) {
54673 true
54674 } else {
54675 false
54676 };
54677
54678 let alias = if self.match_token(TokenType::As) {
54680 Some(Box::new(self.parse_rows_from_alias()?))
54681 } else {
54682 None
54683 };
54684
54685 Ok(Expression::RowsFrom(Box::new(RowsFrom {
54686 expressions,
54687 ordinality,
54688 alias,
54689 })))
54690 }
54691
54692 fn parse_rows_from_function(&mut self) -> Result<Expression> {
54694 let func_name = self.expect_identifier_or_keyword()?;
54696
54697 self.expect(TokenType::LParen)?;
54699 let args = if self.check(TokenType::RParen) {
54700 Vec::new()
54701 } else {
54702 self.parse_function_arguments()?
54703 };
54704 self.expect(TokenType::RParen)?;
54705
54706 let func_expr = Expression::Function(Box::new(Function {
54707 name: func_name,
54708 args,
54709 distinct: false,
54710 trailing_comments: Vec::new(),
54711 use_bracket_syntax: false,
54712 no_parens: false,
54713 quoted: false,
54714 span: None,
54715 inferred_type: None,
54716 }));
54717
54718 if self.match_token(TokenType::As) {
54721 let alias_expr = self.parse_rows_from_alias()?;
54722 Ok(Expression::Tuple(Box::new(Tuple {
54723 expressions: vec![func_expr, alias_expr],
54724 })))
54725 } else {
54726 Ok(func_expr)
54727 }
54728 }
54729
54730 fn parse_rows_from_alias(&mut self) -> Result<Expression> {
54732 let alias_name = self.expect_identifier_or_keyword_with_quoted()?;
54733
54734 let columns = if self.match_token(TokenType::LParen) {
54736 let mut cols = Vec::new();
54737 loop {
54738 if self.check(TokenType::RParen) {
54739 break;
54740 }
54741 let col_name = self.expect_identifier_or_keyword_with_quoted()?;
54743 let col_type = self.parse_data_type()?;
54745 let mut col_def = ColumnDef::new(col_name.name.clone(), col_type);
54747 col_def.name = col_name; cols.push(Expression::ColumnDef(Box::new(col_def)));
54749
54750 if !self.match_token(TokenType::Comma) {
54751 break;
54752 }
54753 }
54754 self.expect(TokenType::RParen)?;
54755 cols
54756 } else {
54757 Vec::new()
54758 };
54759
54760 Ok(Expression::TableAlias(Box::new(TableAlias {
54761 this: Some(Box::new(Expression::Identifier(alias_name))),
54762 columns,
54763 })))
54764 }
54765
54766 #[allow(unused_variables, unused_mut)]
54769 pub fn parse_table(&mut self) -> Result<Option<Expression>> {
54770 if self.match_text_seq(&["ROWS", "FROM"]) {
54771 return Ok(None);
54773 }
54774 if self.match_text_seq(&["*"]) {
54775 return Ok(None);
54777 }
54778 if self.match_text_seq(&["NOT", "INDEXED"]) {
54779 return Ok(None);
54781 }
54782 Ok(None)
54783 }
54784
54785 #[allow(unused_variables, unused_mut)]
54788 pub fn parse_table_alias(&mut self) -> Result<Option<Expression>> {
54789 let has_as = self.match_token(TokenType::As);
54791
54792 if has_as && self.check(TokenType::LParen) {
54794 self.skip(); let mut cols = Vec::new();
54797 loop {
54798 if self.check(TokenType::RParen) {
54799 break;
54800 }
54801 if let Ok(Some(col)) = self.parse_id_var() {
54802 cols.push(col);
54803 }
54804 if !self.match_token(TokenType::Comma) {
54805 break;
54806 }
54807 }
54808 self.expect(TokenType::RParen)?;
54809 return Ok(Some(Expression::TableAlias(Box::new(TableAlias {
54810 this: None,
54811 columns: cols,
54812 }))));
54813 }
54814
54815 let is_keyword_alias = has_as
54818 && matches!(
54819 self.config.dialect,
54820 Some(crate::dialects::DialectType::ClickHouse)
54821 )
54822 && self.peek().token_type.is_keyword();
54823 if !self.check(TokenType::Identifier)
54824 && !self.check(TokenType::QuotedIdentifier)
54825 && !self.check(TokenType::Var)
54826 && !is_keyword_alias
54827 {
54828 if has_as {
54829 return Err(self.parse_error("Expected identifier after AS"));
54830 }
54831 return Ok(None);
54832 }
54833
54834 let alias_token = self.advance();
54835 let is_quoted = alias_token.token_type == TokenType::QuotedIdentifier;
54836 let mut alias_ident = Identifier::new(alias_token.text.clone());
54837 if is_quoted {
54838 alias_ident.quoted = true;
54839 }
54840 let alias = Expression::Identifier(alias_ident);
54841
54842 let columns = if self.match_token(TokenType::LParen) {
54844 let mut cols = Vec::new();
54845 loop {
54846 if self.check(TokenType::RParen) {
54847 break;
54848 }
54849 if let Ok(Some(col)) = self.parse_id_var() {
54850 cols.push(col);
54851 }
54852 if !self.match_token(TokenType::Comma) {
54853 break;
54854 }
54855 }
54856 self.expect(TokenType::RParen)?;
54857 cols
54858 } else {
54859 Vec::new()
54860 };
54861
54862 Ok(Some(Expression::TableAlias(Box::new(TableAlias {
54863 this: Some(Box::new(alias)),
54864 columns,
54865 }))))
54866 }
54867
54868 #[allow(unused_variables, unused_mut)]
54871 pub fn parse_table_hints(&mut self) -> Result<Option<Expression>> {
54872 let mut hints = Vec::new();
54873
54874 if self.match_text_seq(&["WITH"]) && self.match_token(TokenType::LParen) {
54876 let mut expressions = Vec::new();
54877 loop {
54878 if let Some(func) = self.parse_function()? {
54880 expressions.push(func);
54881 } else if let Some(var) = self.parse_var()? {
54882 expressions.push(var);
54883 } else {
54884 break;
54885 }
54886 if !self.match_token(TokenType::Comma) {
54887 break;
54888 }
54889 }
54890 self.match_token(TokenType::RParen);
54891
54892 if !expressions.is_empty() {
54893 hints.push(Expression::WithTableHint(Box::new(WithTableHint {
54894 expressions,
54895 })));
54896 }
54897 } else {
54898 while self.match_texts(&["USE", "IGNORE", "FORCE"]) {
54900 let hint_type = self.previous().text.to_ascii_uppercase();
54901
54902 let _ = self.match_texts(&["INDEX", "KEY"]);
54904
54905 let target = if self.match_text_seq(&["FOR"]) {
54907 let target_token = self.advance();
54908 let target_text = target_token.text.to_ascii_uppercase();
54909 let full_target = if (target_text == "ORDER" || target_text == "GROUP")
54911 && self.check(TokenType::By)
54912 {
54913 self.skip(); format!("{} BY", target_text)
54915 } else {
54916 target_text
54917 };
54918 Some(Box::new(Expression::Identifier(Identifier {
54919 name: full_target,
54920 quoted: false,
54921 trailing_comments: Vec::new(),
54922 span: None,
54923 })))
54924 } else {
54925 None
54926 };
54927
54928 let expressions = if self.match_token(TokenType::LParen) {
54930 let mut ids = Vec::new();
54931 loop {
54932 if self.check(TokenType::RParen) {
54933 break;
54934 }
54935 if let Some(id) = self.parse_id_var()? {
54936 ids.push(id);
54937 } else if self.is_safe_keyword_as_identifier()
54938 || self.check(TokenType::PrimaryKey)
54939 {
54940 let name = self.advance().text.clone();
54942 ids.push(Expression::Identifier(Identifier::new(name)));
54943 } else {
54944 break;
54945 }
54946 if !self.match_token(TokenType::Comma) {
54947 break;
54948 }
54949 }
54950 self.match_token(TokenType::RParen);
54951 ids
54952 } else {
54953 Vec::new()
54954 };
54955
54956 hints.push(Expression::IndexTableHint(Box::new(IndexTableHint {
54957 this: Box::new(Expression::Identifier(Identifier {
54958 name: hint_type,
54959 quoted: false,
54960 trailing_comments: Vec::new(),
54961 span: None,
54962 })),
54963 expressions,
54964 target,
54965 })));
54966 }
54967 }
54968
54969 if hints.is_empty() {
54970 return Ok(None);
54971 }
54972
54973 Ok(Some(Expression::Tuple(Box::new(Tuple {
54975 expressions: hints,
54976 }))))
54977 }
54978
54979 pub fn parse_truncate_table_hints(&mut self) -> Result<Option<Expression>> {
54982 if !self.match_text_seq(&["WITH"]) || !self.match_token(TokenType::LParen) {
54983 return Ok(None);
54984 }
54985
54986 let mut hints = Vec::new();
54987
54988 if self.check_identifier("PARTITIONS") {
54990 self.skip(); self.expect(TokenType::LParen)?;
54992
54993 let mut parts = Vec::new();
54995 loop {
54996 if self.check(TokenType::RParen) {
54997 break;
54998 }
54999 let low = self.parse_primary()?;
55000 if self.match_text_seq(&["TO"]) {
55001 let high = self.parse_primary()?;
55002 parts.push(Expression::PartitionRange(Box::new(PartitionRange {
55003 this: Box::new(low),
55004 expression: Some(Box::new(high)),
55005 expressions: Vec::new(),
55006 })));
55007 } else {
55008 parts.push(low);
55009 }
55010 if !self.match_token(TokenType::Comma) {
55011 break;
55012 }
55013 }
55014 self.expect(TokenType::RParen)?; hints.push(Expression::Anonymous(Box::new(Anonymous {
55018 this: Box::new(Expression::Identifier(Identifier {
55019 name: "PARTITIONS".to_string(),
55020 quoted: false,
55021 trailing_comments: Vec::new(),
55022 span: None,
55023 })),
55024 expressions: parts,
55025 })));
55026 } else {
55027 loop {
55029 if let Some(func) = self.parse_function()? {
55030 hints.push(func);
55031 } else if let Some(var) = self.parse_var()? {
55032 hints.push(var);
55033 } else {
55034 break;
55035 }
55036 if !self.match_token(TokenType::Comma) {
55037 break;
55038 }
55039 }
55040 }
55041
55042 self.expect(TokenType::RParen)?; if hints.is_empty() {
55045 return Ok(None);
55046 }
55047
55048 let hint = Expression::WithTableHint(Box::new(WithTableHint { expressions: hints }));
55050
55051 Ok(Some(Expression::Tuple(Box::new(Tuple {
55052 expressions: vec![hint],
55053 }))))
55054 }
55055
55056 #[allow(unused_variables, unused_mut)]
55059 pub fn parse_table_part(&mut self) -> Result<Option<Expression>> {
55060 if let Some(id) = self.parse_id_var()? {
55062 return Ok(Some(id));
55063 }
55064
55065 if let Some(str_id) = self.parse_string_as_identifier()? {
55067 return Ok(Some(str_id));
55068 }
55069
55070 if let Some(placeholder) = self.parse_placeholder()? {
55072 return Ok(Some(placeholder));
55073 }
55074
55075 if self.check_keyword_as_identifier() {
55078 let text = self.peek().text.clone();
55079 self.skip();
55080 return Ok(Some(Expression::Identifier(Identifier {
55081 name: text,
55082 quoted: false,
55083 trailing_comments: Vec::new(),
55084 span: None,
55085 })));
55086 }
55087
55088 Ok(None)
55089 }
55090
55091 fn check_keyword_as_identifier(&self) -> bool {
55094 if self.is_at_end() {
55095 return false;
55096 }
55097 let token_type = self.peek().token_type;
55098 matches!(
55100 token_type,
55101 TokenType::Cluster
55102 | TokenType::Table
55103 | TokenType::Index
55104 | TokenType::View
55105 | TokenType::Database
55106 | TokenType::Schema
55107 | TokenType::Column
55108 | TokenType::Function
55109 | TokenType::Procedure
55110 | TokenType::Constraint
55111 | TokenType::Sequence
55112 | TokenType::Type
55113 | TokenType::Partition
55114 | TokenType::Comment
55115 | TokenType::Cache
55116 | TokenType::Commit
55117 | TokenType::Begin
55118 | TokenType::End
55119 | TokenType::Set
55120 | TokenType::Show
55121 | TokenType::Describe
55122 | TokenType::Use
55123 | TokenType::Execute
55124 | TokenType::Delete
55125 | TokenType::Update
55126 | TokenType::Merge
55127 | TokenType::Load
55128 | TokenType::Copy
55129 | TokenType::Truncate
55130 | TokenType::Replace
55131 | TokenType::Refresh
55132 | TokenType::Rename
55133 | TokenType::Filter
55134 | TokenType::Format
55135 | TokenType::First
55136 | TokenType::Next
55137 | TokenType::Last
55138 | TokenType::Keep
55139 | TokenType::Match
55140 | TokenType::Over
55141 | TokenType::Range
55142 | TokenType::Rows
55143 | TokenType::Row
55144 | TokenType::Offset
55145 | TokenType::Limit
55146 | TokenType::Top
55147 | TokenType::Cube
55148 | TokenType::Rollup
55149 | TokenType::Pivot
55150 | TokenType::Unpivot
55151 | TokenType::Window
55152 | TokenType::Recursive
55153 | TokenType::Unique
55154 | TokenType::Temporary
55155 | TokenType::Volatile
55156 | TokenType::References
55157 | TokenType::Natural
55158 | TokenType::Left
55159 | TokenType::Right
55160 | TokenType::Full
55161 | TokenType::Semi
55162 | TokenType::Anti
55163 | TokenType::Apply
55164 | TokenType::All
55165 | TokenType::Asc
55166 | TokenType::Desc
55167 | TokenType::Analyze
55168 )
55169 }
55170
55171 #[allow(unused_variables, unused_mut)]
55174 pub fn parse_table_parts(&mut self) -> Result<Option<Expression>> {
55175 let first = self.parse_table_part()?;
55177 if first.is_none() {
55178 return Ok(None);
55179 }
55180
55181 let mut parts = vec![first.unwrap()];
55182
55183 while self.match_token(TokenType::Dot) {
55185 if let Some(part) = self.parse_table_part()? {
55186 parts.push(part);
55187 } else {
55188 break;
55189 }
55190 }
55191
55192 let (catalog, schema, name) = match parts.len() {
55195 1 => (None, None, parts.pop().unwrap()),
55196 2 => {
55197 let table = parts.pop().unwrap();
55198 let schema = parts.pop().unwrap();
55199 (None, Some(schema), table)
55200 }
55201 _ => {
55202 let table = parts.pop().unwrap();
55203 let schema = parts.pop().unwrap();
55204 let catalog = parts.pop();
55205 (catalog, Some(schema), table)
55206 }
55207 };
55208
55209 let name_ident = match name {
55211 Expression::Identifier(id) => id,
55212 _ => Identifier::new(String::new()),
55213 };
55214 let schema_ident = schema.map(|s| match s {
55215 Expression::Identifier(id) => id,
55216 _ => Identifier::new(String::new()),
55217 });
55218 let catalog_ident = catalog.map(|c| match c {
55219 Expression::Identifier(id) => id,
55220 _ => Identifier::new(String::new()),
55221 });
55222
55223 Ok(Some(Expression::boxed_table(TableRef {
55224 name: name_ident,
55225 schema: schema_ident,
55226 catalog: catalog_ident,
55227 alias: None,
55228 alias_explicit_as: false,
55229 column_aliases: Vec::new(),
55230 leading_comments: Vec::new(),
55231 trailing_comments: Vec::new(),
55232 when: None,
55233 only: false,
55234 final_: false,
55235 table_sample: None,
55236 hints: Vec::new(),
55237 system_time: None,
55238 partitions: Vec::new(),
55239 identifier_func: None,
55240 changes: None,
55241 version: None,
55242 span: None,
55243 })))
55244 }
55245
55246 #[allow(unused_variables, unused_mut)]
55249 pub fn parse_table_sample(&mut self) -> Result<Option<Expression>> {
55250 if self.match_text_seq(&["USING", "SAMPLE"]) {
55251 return Ok(Some(Expression::TableSample(Box::new(TableSample {
55252 this: None,
55253 sample: None,
55254 expressions: Vec::new(),
55255 method: None,
55256 bucket_numerator: None,
55257 bucket_denominator: None,
55258 bucket_field: None,
55259 percent: None,
55260 rows: None,
55261 size: None,
55262 seed: None,
55263 }))));
55264 }
55265 if self.match_text_seq(&["BUCKET"]) {
55266 return Ok(None);
55268 }
55269 if self.match_text_seq(&["OUT", "OF"]) {
55270 return Ok(None);
55272 }
55273 if self.match_texts(&["SEED", "REPEATABLE"]) {
55274 return Ok(None);
55276 }
55277 Ok(None)
55278 }
55279
55280 pub fn parse_term(&mut self) -> Result<Option<Expression>> {
55284 match self.parse_addition() {
55286 Ok(expr) => Ok(Some(expr)),
55287 Err(_) => Ok(None),
55288 }
55289 }
55290
55291 #[allow(unused_variables, unused_mut)]
55294 pub fn parse_to_table(&mut self) -> Result<Option<Expression>> {
55295 let table = self.parse_table_parts()?;
55297 if table.is_none() {
55298 return Ok(None);
55299 }
55300
55301 Ok(Some(Expression::ToTableProperty(Box::new(
55302 ToTableProperty {
55303 this: Box::new(table.unwrap()),
55304 },
55305 ))))
55306 }
55307
55308 #[allow(unused_variables, unused_mut)]
55310 pub fn parse_tokens(&mut self) -> Result<Option<Expression>> {
55311 Ok(None)
55313 }
55314
55315 #[allow(unused_variables, unused_mut)]
55318 pub fn parse_trim(&mut self) -> Result<Option<Expression>> {
55319 let (position, position_explicit) = if self.match_texts(&["BOTH"]) {
55321 (TrimPosition::Both, true)
55322 } else if self.match_texts(&["LEADING"]) {
55323 (TrimPosition::Leading, true)
55324 } else if self.match_texts(&["TRAILING"]) {
55325 (TrimPosition::Trailing, true)
55326 } else {
55327 (TrimPosition::Both, false)
55328 };
55329
55330 let first = match self.parse_bitwise() {
55332 Ok(Some(expr)) => self.try_clickhouse_func_arg_alias(expr),
55333 Ok(None) => return Ok(None),
55334 Err(e) => return Err(e),
55335 };
55336
55337 let (this, characters, sql_standard_syntax) = if self.match_token(TokenType::From) {
55339 let second = match self.parse_bitwise() {
55341 Ok(Some(expr)) => self.try_clickhouse_func_arg_alias(expr),
55342 Ok(None) => return Err(self.parse_error("Expected expression after FROM in TRIM")),
55343 Err(e) => return Err(e),
55344 };
55345 (second, Some(first), true)
55347 } else if self.match_token(TokenType::Comma) {
55348 let second = match self.parse_bitwise() {
55350 Ok(Some(expr)) => Some(expr),
55351 Ok(None) => None,
55352 Err(e) => return Err(e),
55353 };
55354 let trim_pattern_first = matches!(
55357 self.config.dialect,
55358 Some(crate::dialects::DialectType::Spark)
55359 );
55360 if trim_pattern_first && second.is_some() {
55361 (second.unwrap(), Some(first), false)
55363 } else {
55364 (first, second, false)
55365 }
55366 } else {
55367 (first, None, false)
55369 };
55370
55371 Ok(Some(Expression::Trim(Box::new(TrimFunc {
55372 this,
55373 characters,
55374 position,
55375 sql_standard_syntax,
55376 position_explicit,
55377 }))))
55378 }
55379
55380 #[allow(unused_variables, unused_mut)]
55383 pub fn parse_truncate_table(&mut self) -> Result<Option<Expression>> {
55384 if self.match_text_seq(&["RESTART", "IDENTITY"]) {
55385 return Ok(Some(Expression::TruncateTable(Box::new(TruncateTable {
55386 expressions: Vec::new(),
55387 is_database: None,
55388 exists: false,
55389 only: None,
55390 cluster: None,
55391 identity: None,
55392 option: None,
55393 partition: None,
55394 }))));
55395 }
55396 if self.match_text_seq(&["CONTINUE", "IDENTITY"]) {
55397 return Ok(None);
55399 }
55400 if self.match_text_seq(&["CASCADE"]) {
55401 return Ok(None);
55403 }
55404 Ok(None)
55405 }
55406
55407 pub fn parse_ttl(&mut self) -> Result<Option<Expression>> {
55410 let mut expressions = Vec::new();
55412
55413 loop {
55414 let base_start = self.current;
55416 let this = match self.parse_bitwise() {
55417 Ok(Some(expr)) => expr,
55418 _ => {
55419 self.current = base_start;
55420 let mut paren_depth = 0usize;
55421 while !self.is_at_end() {
55422 if paren_depth == 0
55423 && (self.check(TokenType::Comma)
55424 || self.peek().text.eq_ignore_ascii_case("DELETE")
55425 || self.peek().text.eq_ignore_ascii_case("RECOMPRESS")
55426 || self.peek().text.eq_ignore_ascii_case("TO")
55427 || self.peek().text.eq_ignore_ascii_case("WHERE")
55428 || self.peek().text.eq_ignore_ascii_case("GROUP")
55429 || self.peek().text.eq_ignore_ascii_case("SET"))
55430 {
55431 break;
55432 }
55433 if self.check(TokenType::LParen) {
55434 paren_depth += 1;
55435 } else if self.check(TokenType::RParen) {
55436 if paren_depth == 0 {
55437 break;
55438 }
55439 paren_depth -= 1;
55440 }
55441 self.skip();
55442 }
55443 if self.current == base_start {
55444 break;
55445 }
55446 let raw = self
55447 .tokens_to_sql(base_start, self.current)
55448 .trim()
55449 .to_string();
55450 Expression::Var(Box::new(Var { this: raw }))
55451 }
55452 };
55453
55454 let action = if self.match_text_seq(&["DELETE"]) {
55456 Expression::MergeTreeTTLAction(Box::new(MergeTreeTTLAction {
55457 this: Box::new(this),
55458 delete: Some(Box::new(Expression::Boolean(BooleanLiteral {
55459 value: true,
55460 }))),
55461 recompress: None,
55462 to_disk: None,
55463 to_volume: None,
55464 }))
55465 } else if self.match_text_seq(&["RECOMPRESS"]) {
55466 let recompress = if self.match_identifier("CODEC") {
55467 self.expect(TokenType::LParen)?;
55468 let mut args = Vec::new();
55469 if !self.check(TokenType::RParen) {
55470 args.push(self.parse_expression()?);
55471 while self.match_token(TokenType::Comma) {
55472 args.push(self.parse_expression()?);
55473 }
55474 }
55475 self.expect(TokenType::RParen)?;
55476 Some(Box::new(Expression::Function(Box::new(Function::new(
55477 "CODEC".to_string(),
55478 args,
55479 )))))
55480 } else {
55481 self.parse_bitwise()?.map(Box::new)
55482 };
55483 Expression::MergeTreeTTLAction(Box::new(MergeTreeTTLAction {
55484 this: Box::new(this),
55485 delete: None,
55486 recompress,
55487 to_disk: None,
55488 to_volume: None,
55489 }))
55490 } else if self.match_text_seq(&["TO", "DISK"]) {
55491 let to_disk = self.parse_string()?.map(Box::new);
55492 Expression::MergeTreeTTLAction(Box::new(MergeTreeTTLAction {
55493 this: Box::new(this),
55494 delete: None,
55495 recompress: None,
55496 to_disk,
55497 to_volume: None,
55498 }))
55499 } else if self.match_text_seq(&["TO", "VOLUME"]) {
55500 let to_volume = self.parse_string()?.map(Box::new);
55501 Expression::MergeTreeTTLAction(Box::new(MergeTreeTTLAction {
55502 this: Box::new(this),
55503 delete: None,
55504 recompress: None,
55505 to_disk: None,
55506 to_volume,
55507 }))
55508 } else {
55509 this
55510 };
55511
55512 expressions.push(action);
55513
55514 if !self.match_token(TokenType::Comma) {
55515 break;
55516 }
55517 }
55518
55519 let where_ = self.parse_where()?.map(Box::new);
55521
55522 let group = if self.match_token(TokenType::Group) {
55524 self.expect(TokenType::By)?;
55525 let mut exprs = Vec::new();
55526 exprs.push(self.parse_expression()?);
55527 while self.match_token(TokenType::Comma) {
55528 exprs.push(self.parse_expression()?);
55529 }
55530 Some(Box::new(Expression::Group(Box::new(Group {
55531 expressions: exprs,
55532 grouping_sets: None,
55533 cube: None,
55534 rollup: None,
55535 totals: None,
55536 all: None,
55537 }))))
55538 } else {
55539 None
55540 };
55541
55542 let aggregates = if group.is_some() && self.match_token(TokenType::Set) {
55544 let mut aggs = Vec::new();
55545 loop {
55546 aggs.push(self.parse_expression()?);
55547 if !self.match_token(TokenType::Comma) {
55548 break;
55549 }
55550 }
55551 if aggs.is_empty() {
55552 None
55553 } else {
55554 Some(Box::new(Expression::Tuple(Box::new(Tuple {
55555 expressions: aggs,
55556 }))))
55557 }
55558 } else {
55559 None
55560 };
55561
55562 Ok(Some(Expression::MergeTreeTTL(Box::new(MergeTreeTTL {
55563 expressions,
55564 where_,
55565 group,
55566 aggregates,
55567 }))))
55568 }
55569
55570 pub fn parse_type(&mut self) -> Result<Option<Expression>> {
55573 if let Some(interval) = self.parse_interval()? {
55575 return self.parse_column_ops_with_expr(Some(interval));
55576 }
55577
55578 let data_type = self.parse_types()?;
55580
55581 if let Some(dt) = data_type {
55582 if matches!(dt, Expression::Cast(_)) {
55584 return self.parse_column_ops_with_expr(Some(dt));
55585 }
55586
55587 let start_pos = self.current;
55589 if let Some(primary) = self.parse_primary_or_var()? {
55590 if let Expression::Literal(_) = &primary {
55592 let result = self.parse_column_ops_with_expr(Some(primary))?;
55593 if let Some(value) = result {
55594 if let Expression::DataType(data_type_struct) = dt {
55596 return Ok(Some(Expression::Cast(Box::new(Cast {
55597 this: value,
55598 to: data_type_struct,
55599 trailing_comments: Vec::new(),
55600 double_colon_syntax: false,
55601 format: None,
55602 default: None,
55603 inferred_type: None,
55604 }))));
55605 }
55606 }
55607 }
55608 self.current = start_pos;
55610 }
55611
55612 return Ok(Some(dt));
55613 }
55614
55615 Ok(None)
55616 }
55617
55618 #[allow(unused_variables, unused_mut)]
55621 pub fn parse_type_size(&mut self) -> Result<Option<Expression>> {
55622 let this = self.parse_type()?;
55624
55625 if this.is_none() {
55626 return Ok(None);
55627 }
55628
55629 let mut result = this.unwrap();
55630
55631 if let Expression::Column(ref col) = result {
55634 if col.table.is_none() {
55635 result = Expression::Identifier(col.name.clone());
55636 }
55637 }
55638
55639 if let Some(var_token) = self.parse_var()? {
55642 }
55646
55647 Ok(Some(result))
55648 }
55649
55650 #[allow(unused_variables, unused_mut)]
55653 pub fn parse_types(&mut self) -> Result<Option<Expression>> {
55654 if self.match_text_seq(&["SYSUDTLIB", "."]) {
55655 return Ok(Some(Expression::Identifier(Identifier {
55656 name: String::new(),
55657 quoted: false,
55658 trailing_comments: Vec::new(),
55659 span: None,
55660 })));
55661 }
55662 if self.match_text_seq(&["WITH", "TIME", "ZONE"]) {
55663 return Ok(None);
55665 }
55666 if self.match_text_seq(&["WITH", "LOCAL", "TIME", "ZONE"]) {
55667 return Ok(None);
55669 }
55670 Ok(None)
55671 }
55672
55673 #[allow(unused_variables, unused_mut)]
55676 pub fn parse_unique(&mut self) -> Result<Option<Expression>> {
55677 let _ = self.match_texts(&["KEY", "INDEX"]);
55679
55680 let nulls = if self.match_text_seq(&["NULLS", "NOT", "DISTINCT"]) {
55682 Some(Box::new(Expression::Boolean(BooleanLiteral {
55683 value: true,
55684 })))
55685 } else {
55686 None
55687 };
55688
55689 let unique_key = self.parse_unique_key()?;
55691 let this = self.parse_schema_with_this(unique_key)?;
55692
55693 let index_type = if self.match_token(TokenType::Using) {
55695 self.skip();
55696 Some(Box::new(Expression::Var(Box::new(Var {
55697 this: self.previous().text.clone(),
55698 }))))
55699 } else {
55700 None
55701 };
55702
55703 Ok(Some(Expression::UniqueColumnConstraint(Box::new(
55704 UniqueColumnConstraint {
55705 this: this.map(Box::new),
55706 index_type,
55707 on_conflict: None,
55708 nulls,
55709 options: Vec::new(),
55710 },
55711 ))))
55712 }
55713
55714 #[allow(unused_variables, unused_mut)]
55717 pub fn parse_unique_key(&mut self) -> Result<Option<Expression>> {
55718 self.parse_id_var()
55719 }
55720
55721 #[allow(unused_variables, unused_mut)]
55724 pub fn parse_unnest(&mut self) -> Result<Option<Expression>> {
55725 if !self.match_texts(&["UNNEST"]) {
55727 return Ok(None);
55728 }
55729
55730 if !self.match_token(TokenType::LParen) {
55732 return Ok(None);
55733 }
55734
55735 let this = match self.parse_expression() {
55737 Ok(expr) => expr,
55738 Err(e) => return Err(e),
55739 };
55740
55741 let mut extra_expressions = Vec::new();
55742 while self.match_token(TokenType::Comma) {
55743 let expr = self.parse_expression()?;
55744 extra_expressions.push(expr);
55745 }
55746
55747 self.expect(TokenType::RParen)?;
55749
55750 let mut with_ordinality = self.match_text_seq(&["WITH", "ORDINALITY"]);
55752 let mut offset_alias = None;
55753 if !with_ordinality && self.match_text_seq(&["WITH", "OFFSET"]) {
55754 with_ordinality = true;
55755 if matches!(
55757 self.config.dialect,
55758 Some(crate::dialects::DialectType::BigQuery)
55759 ) {
55760 let has_as = self.match_token(TokenType::As);
55761 if has_as || self.check(TokenType::Identifier) || self.check(TokenType::Var) {
55762 let alias_name = self.advance().text;
55763 offset_alias = Some(crate::expressions::Identifier {
55764 name: alias_name,
55765 quoted: false,
55766 trailing_comments: Vec::new(),
55767 span: None,
55768 });
55769 }
55770 }
55771 }
55772
55773 let alias = if self.match_token(TokenType::As)
55775 || self.check(TokenType::Identifier)
55776 || self.check(TokenType::QuotedIdentifier)
55777 {
55778 if self.check(TokenType::Identifier) || self.check(TokenType::QuotedIdentifier) {
55779 let is_quoted = self.check(TokenType::QuotedIdentifier);
55780 let token = self.advance();
55781 let mut ident = Identifier::new(token.text.clone());
55782 if is_quoted {
55783 ident.quoted = true;
55784 }
55785 Some(ident)
55786 } else {
55787 None
55788 }
55789 } else {
55790 None
55791 };
55792
55793 Ok(Some(Expression::Unnest(Box::new(UnnestFunc {
55794 this,
55795 expressions: extra_expressions,
55796 with_ordinality,
55797 alias,
55798 offset_alias,
55799 }))))
55800 }
55801
55802 #[allow(unused_variables, unused_mut)]
55806 pub fn parse_unpivot_columns(&mut self) -> Result<Option<Expression>> {
55807 if !self.match_token(TokenType::Into) {
55809 return Ok(None);
55810 }
55811
55812 let this = if self.match_text_seq(&["NAME"]) {
55814 self.parse_column()?
55815 } else {
55816 None
55817 };
55818
55819 let expressions = if self.match_text_seq(&["VALUE"]) {
55821 let mut cols = Vec::new();
55822 loop {
55823 if let Some(col) = self.parse_column()? {
55824 cols.push(col);
55825 }
55826 if !self.match_token(TokenType::Comma) {
55827 break;
55828 }
55829 }
55830 cols
55831 } else {
55832 Vec::new()
55833 };
55834
55835 if this.is_some() || !expressions.is_empty() {
55837 Ok(Some(Expression::UnpivotColumns(Box::new(UnpivotColumns {
55838 this: Box::new(this.unwrap_or(Expression::Null(Null))),
55839 expressions,
55840 }))))
55841 } else {
55842 Ok(None)
55843 }
55844 }
55845
55846 pub fn parse_unquoted_field(&mut self) -> Result<Option<Expression>> {
55849 let field = self.parse_field()?;
55850
55851 match field {
55853 Some(Expression::Identifier(id)) if !id.quoted => {
55854 Ok(Some(Expression::Var(Box::new(Var { this: id.name }))))
55855 }
55856 other => Ok(other),
55857 }
55858 }
55859
55860 pub fn parse_user_defined_function(&mut self) -> Result<Option<Expression>> {
55864 let this = self.parse_table_parts()?;
55866 if this.is_none() {
55867 return Ok(None);
55868 }
55869
55870 if !self.match_token(TokenType::LParen) {
55872 return Ok(this);
55873 }
55874
55875 let mut expressions = Vec::new();
55877 if !self.check(TokenType::RParen) {
55878 loop {
55879 if let Some(param) = self.parse_function_parameter()? {
55880 expressions.push(param);
55881 }
55882 if !self.match_token(TokenType::Comma) {
55883 break;
55884 }
55885 }
55886 }
55887
55888 self.match_token(TokenType::RParen);
55889
55890 Ok(Some(Expression::UserDefinedFunction(Box::new(
55891 UserDefinedFunction {
55892 this: Box::new(this.unwrap()),
55893 expressions,
55894 wrapped: Some(Box::new(Expression::Boolean(BooleanLiteral {
55895 value: true,
55896 }))),
55897 },
55898 ))))
55899 }
55900
55901 #[allow(unused_variables, unused_mut)]
55903 pub fn parse_user_defined_function_expression(&mut self) -> Result<Option<Expression>> {
55904 match self.parse_statement() {
55906 Ok(stmt) => Ok(Some(stmt)),
55907 Err(_) => Ok(None),
55908 }
55909 }
55910
55911 pub fn parse_user_defined_type(
55915 &mut self,
55916 identifier: Identifier,
55917 ) -> Result<Option<Expression>> {
55918 let mut type_name = identifier.name.clone();
55919
55920 while self.match_token(TokenType::Dot) {
55922 if !self.is_at_end() {
55923 let token = self.advance();
55924 type_name = format!("{}.{}", type_name, token.text);
55925 } else {
55926 break;
55927 }
55928 }
55929
55930 Ok(Some(Expression::DataType(DataType::Custom {
55932 name: type_name,
55933 })))
55934 }
55935
55936 #[allow(unused_variables, unused_mut)]
55939 pub fn parse_using_identifiers(&mut self) -> Result<Option<Expression>> {
55940 let has_paren = self.match_token(TokenType::LParen);
55942
55943 let mut identifiers = Vec::new();
55944 loop {
55945 if let Some(expr) = self.parse_identifier()? {
55947 identifiers.push(expr);
55948 } else {
55949 break;
55950 }
55951 if !self.match_token(TokenType::Comma) {
55952 break;
55953 }
55954 }
55955
55956 if has_paren {
55958 self.expect(TokenType::RParen)?;
55959 }
55960
55961 if identifiers.is_empty() {
55962 Ok(None)
55963 } else {
55964 Ok(Some(Expression::Tuple(Box::new(Tuple {
55965 expressions: identifiers,
55966 }))))
55967 }
55968 }
55969
55970 pub fn parse_value(&mut self) -> Result<Option<Expression>> {
55974 if self.match_token(TokenType::LParen) {
55976 let mut expressions = Vec::new();
55977
55978 if !self.check(TokenType::RParen) {
55979 loop {
55980 if self.match_texts(&["DEFAULT"]) {
55982 let text = self.previous().text.to_ascii_uppercase();
55983 expressions.push(Expression::Var(Box::new(Var { this: text })));
55984 } else {
55985 let saved_pos = self.current;
55987 match self.parse_expression() {
55988 Ok(expr) => expressions.push(expr),
55989 Err(_) => {
55990 self.current = saved_pos;
55991 }
55992 }
55993 }
55994
55995 if !self.match_token(TokenType::Comma) {
55996 break;
55997 }
55998 }
55999 }
56000
56001 self.match_token(TokenType::RParen);
56002 return Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))));
56003 }
56004
56005 let saved_pos = self.current;
56007 match self.parse_expression() {
56008 Ok(expr) => {
56009 return Ok(Some(Expression::Tuple(Box::new(Tuple {
56010 expressions: vec![expr],
56011 }))));
56012 }
56013 Err(_) => {
56014 self.current = saved_pos;
56015 }
56016 }
56017
56018 Ok(None)
56019 }
56020
56021 pub fn parse_var(&mut self) -> Result<Option<Expression>> {
56024 if self.match_token(TokenType::Var) {
56025 let text = self.previous().text.clone();
56026 return Ok(Some(Expression::Var(Box::new(Var { this: text }))));
56027 }
56028 self.parse_placeholder()
56030 }
56031
56032 #[allow(unused_variables, unused_mut)]
56035 pub fn parse_var_from_options(&mut self) -> Result<Option<Expression>> {
56036 if self.is_at_end() {
56038 return Ok(None);
56039 }
56040
56041 let token = self.peek().clone();
56043 if token.token_type == TokenType::Identifier || token.token_type == TokenType::Var {
56044 self.skip();
56045 return Ok(Some(Expression::Var(Box::new(Var {
56046 this: token.text.to_ascii_uppercase(),
56047 }))));
56048 }
56049
56050 Ok(None)
56051 }
56052
56053 #[allow(unused_variables, unused_mut)]
56055 pub fn parse_var_or_string(&mut self) -> Result<Option<Expression>> {
56058 if let Some(s) = self.parse_string()? {
56060 return Ok(Some(s));
56061 }
56062 self.parse_var_any_token()
56063 }
56064
56065 pub fn parse_vector_expressions(&mut self) -> Result<Option<Expression>> {
56072 let mut expressions = Vec::new();
56073
56074 if let Some(type_expr) = self.parse_type()? {
56076 expressions.push(type_expr);
56077 } else {
56078 return Ok(None);
56079 }
56080
56081 while self.match_token(TokenType::Comma) {
56083 if let Some(expr) = self.parse_primary_or_var()? {
56084 expressions.push(expr);
56085 }
56086 }
56087
56088 if expressions.is_empty() {
56089 return Ok(None);
56090 }
56091
56092 Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))))
56093 }
56094
56095 #[allow(unused_variables, unused_mut)]
56099 pub fn parse_version(&mut self) -> Result<Option<Expression>> {
56100 let this = if self.match_token(TokenType::TimestampSnapshot) {
56102 "TIMESTAMP".to_string()
56103 } else if self.match_token(TokenType::VersionSnapshot) {
56104 "VERSION".to_string()
56105 } else {
56106 return Ok(None);
56107 };
56108
56109 let (kind, expression) = if self.match_texts(&["FROM", "BETWEEN"]) {
56111 let kind_str = self.previous().text.to_ascii_uppercase();
56113 let start = self.parse_bitwise()?;
56114 self.match_texts(&["TO", "AND"]);
56115 let end = self.parse_bitwise()?;
56116 let tuple = Expression::Tuple(Box::new(Tuple {
56117 expressions: vec![
56118 start.unwrap_or(Expression::Null(Null)),
56119 end.unwrap_or(Expression::Null(Null)),
56120 ],
56121 }));
56122 (kind_str, Some(Box::new(tuple)))
56123 } else if self.match_text_seq(&["CONTAINED", "IN"]) {
56124 let expressions = if self.match_token(TokenType::LParen) {
56126 let exprs = self.parse_expression_list()?;
56127 self.expect(TokenType::RParen)?;
56128 exprs
56129 } else {
56130 Vec::new()
56131 };
56132 (
56133 "CONTAINED IN".to_string(),
56134 Some(Box::new(Expression::Tuple(Box::new(Tuple { expressions })))),
56135 )
56136 } else if self.match_token(TokenType::All) {
56137 ("ALL".to_string(), None)
56139 } else {
56140 self.match_text_seq(&["AS", "OF"]);
56142 let type_expr = self.parse_type()?;
56143 ("AS OF".to_string(), type_expr.map(Box::new))
56144 };
56145
56146 Ok(Some(Expression::Version(Box::new(Version {
56147 this: Box::new(Expression::Var(Box::new(Var { this }))),
56148 kind,
56149 expression,
56150 }))))
56151 }
56152
56153 pub fn parse_volatile_property(&mut self) -> Result<Option<Expression>> {
56157 let is_table_context = if self.current >= 2 {
56165 let pre_token = &self.tokens[self.current - 2];
56166 matches!(
56167 pre_token.token_type,
56168 TokenType::Create | TokenType::Global | TokenType::Temporary | TokenType::Replace
56169 )
56170 } else {
56171 false
56172 };
56173
56174 if is_table_context {
56175 Ok(Some(Expression::VolatileProperty(Box::new(
56176 VolatileProperty { this: None },
56177 ))))
56178 } else {
56179 Ok(Some(Expression::StabilityProperty(Box::new(
56181 StabilityProperty {
56182 this: Box::new(Expression::Literal(Box::new(Literal::String(
56183 "VOLATILE".to_string(),
56184 )))),
56185 },
56186 ))))
56187 }
56188 }
56189
56190 #[allow(unused_variables, unused_mut)]
56193 pub fn parse_when_matched(&mut self) -> Result<Option<Expression>> {
56196 self.parse_when_matched_clauses()
56197 }
56198
56199 pub fn parse_where(&mut self) -> Result<Option<Expression>> {
56202 if !self.match_token(TokenType::Where) {
56203 return Ok(None);
56204 }
56205 let condition = self.parse_expression()?;
56207 Ok(Some(Expression::Where(Box::new(Where { this: condition }))))
56208 }
56209
56210 #[allow(unused_variables, unused_mut)]
56213 pub fn parse_window(&mut self) -> Result<Option<Expression>> {
56214 if self.match_text_seq(&["WITHIN", "GROUP"]) {
56215 return Ok(Some(Expression::WindowSpec(Box::new(WindowSpec {
56216 partition_by: Vec::new(),
56217 order_by: Vec::new(),
56218 frame: None,
56219 }))));
56220 }
56221 if self.match_text_seq(&["LAST"]) {
56222 return Ok(None);
56224 }
56225 if self.match_text_seq(&["EXCLUDE"]) {
56226 return Ok(None);
56228 }
56229 Ok(None)
56230 }
56231
56232 #[allow(unused_variables, unused_mut)]
56235 pub fn parse_window_clause(&mut self) -> Result<Option<Expression>> {
56236 if !self.match_token(TokenType::Window) {
56237 return Ok(None);
56238 }
56239
56240 let mut windows = Vec::new();
56242 loop {
56243 let name = self.parse_identifier()?;
56245 if name.is_none() {
56246 break;
56247 }
56248
56249 self.expect(TokenType::As)?;
56251
56252 self.expect(TokenType::LParen)?;
56254 let spec = self.parse_window_spec_inner()?;
56255 self.expect(TokenType::RParen)?;
56256
56257 if let (Some(name_expr), Some(spec_expr)) = (name, spec) {
56258 let alias_ident = if let Expression::Identifier(id) = name_expr {
56260 id
56261 } else {
56262 Identifier::new("window")
56263 };
56264 windows.push(Expression::Alias(Box::new(Alias {
56265 this: spec_expr,
56266 alias: alias_ident,
56267 column_aliases: Vec::new(),
56268 pre_alias_comments: Vec::new(),
56269 trailing_comments: Vec::new(),
56270 inferred_type: None,
56271 })));
56272 }
56273
56274 if !self.match_token(TokenType::Comma) {
56275 break;
56276 }
56277 }
56278
56279 if windows.is_empty() {
56280 Ok(None)
56281 } else {
56282 Ok(Some(Expression::Tuple(Box::new(Tuple {
56283 expressions: windows,
56284 }))))
56285 }
56286 }
56287
56288 fn parse_window_spec_inner(&mut self) -> Result<Option<Expression>> {
56290 let _base = if (self.check(TokenType::Identifier)
56292 || self.check(TokenType::QuotedIdentifier))
56293 && !self.check(TokenType::Partition)
56294 && !self.check(TokenType::Order)
56295 && !self.check(TokenType::Distribute)
56296 && !self.check(TokenType::Sort)
56297 {
56298 self.parse_identifier()?
56299 } else {
56300 None
56301 };
56302
56303 let partition_by = if self.match_keywords(&[TokenType::Partition, TokenType::By]) {
56305 self.parse_expression_list()?
56306 } else if self.match_keywords(&[TokenType::Distribute, TokenType::By]) {
56307 self.parse_expression_list()?
56309 } else {
56310 Vec::new()
56311 };
56312
56313 let order_by = if self.match_token(TokenType::Order) {
56315 self.match_token(TokenType::By);
56316 let mut orders = Vec::new();
56317 loop {
56318 if let Some(ordered) = self.parse_ordered_item()? {
56319 orders.push(ordered);
56320 } else {
56321 break;
56322 }
56323 if !self.match_token(TokenType::Comma) {
56324 break;
56325 }
56326 }
56327 orders
56328 } else if self.match_token(TokenType::Sort) {
56329 self.match_token(TokenType::By);
56331 let mut orders = Vec::new();
56332 loop {
56333 if let Some(ordered) = self.parse_ordered_item()? {
56334 orders.push(ordered);
56335 } else {
56336 break;
56337 }
56338 if !self.match_token(TokenType::Comma) {
56339 break;
56340 }
56341 }
56342 orders
56343 } else {
56344 Vec::new()
56345 };
56346
56347 let frame = self.parse_window_frame()?;
56349
56350 Ok(Some(Expression::WindowSpec(Box::new(WindowSpec {
56351 partition_by,
56352 order_by,
56353 frame,
56354 }))))
56355 }
56356
56357 #[allow(unused_variables, unused_mut)]
56359 pub fn parse_window_spec(&mut self) -> Result<Option<Expression>> {
56360 if self.match_text_seq(&["UNBOUNDED"]) {
56361 return Ok(None);
56363 }
56364 if self.match_text_seq(&["CURRENT", "ROW"]) {
56365 return Ok(None);
56367 }
56368 Ok(None)
56369 }
56370
56371 #[allow(unused_variables, unused_mut)]
56374 pub fn parse_with_operator(&mut self) -> Result<Option<Expression>> {
56375 let this = if let Some(opclass) = self.parse_opclass()? {
56377 opclass
56378 } else if let Some(ordered) = self.parse_ordered()? {
56379 ordered
56380 } else {
56381 return Ok(None);
56382 };
56383
56384 if !self.match_token(TokenType::With) {
56386 return Ok(Some(this));
56387 }
56388
56389 let op = self.parse_var()?;
56391 let op_str = match op {
56392 Some(Expression::Identifier(id)) => id.name,
56393 Some(Expression::Var(v)) => v.this.clone(),
56394 _ => String::new(),
56395 };
56396
56397 Ok(Some(Expression::WithOperator(Box::new(WithOperator {
56398 this: Box::new(this),
56399 op: op_str,
56400 }))))
56401 }
56402
56403 #[allow(unused_variables, unused_mut)]
56406 pub fn parse_with_property(&mut self) -> Result<Option<Expression>> {
56407 if self.match_text_seq(&["(", "SYSTEM_VERSIONING"]) {
56408 return Ok(Some(Expression::WithProcedureOptions(Box::new(
56409 WithProcedureOptions {
56410 expressions: Vec::new(),
56411 },
56412 ))));
56413 }
56414 if self.match_text_seq(&["JOURNAL"]) {
56415 return Ok(None);
56417 }
56418 if self.match_text_seq(&["DATA"]) {
56419 return Ok(None);
56421 }
56422 Ok(None)
56423 }
56424
56425 #[allow(unused_variables, unused_mut)]
56427 pub fn parse_withdata(&mut self) -> Result<Option<Expression>> {
56428 if self.match_text_seq(&["AND", "STATISTICS"]) {
56429 return Ok(Some(Expression::WithDataProperty(Box::new(
56430 WithDataProperty {
56431 no: None,
56432 statistics: None,
56433 },
56434 ))));
56435 }
56436 if self.match_text_seq(&["AND", "NO", "STATISTICS"]) {
56437 return Ok(None);
56439 }
56440 Ok(None)
56441 }
56442
56443 #[allow(unused_variables, unused_mut)]
56445 pub fn parse_withisolatedloading(&mut self) -> Result<Option<Expression>> {
56446 if self.match_text_seq(&["NO"]) {
56447 return Ok(Some(Expression::IsolatedLoadingProperty(Box::new(
56448 IsolatedLoadingProperty {
56449 no: None,
56450 concurrent: None,
56451 target: None,
56452 },
56453 ))));
56454 }
56455 if self.match_text_seq(&["CONCURRENT"]) {
56456 return Ok(None);
56458 }
56459 Ok(None)
56460 }
56461
56462 #[allow(unused_variables, unused_mut)]
56465 pub fn parse_withjournaltable(&mut self) -> Result<Option<Expression>> {
56466 self.match_token(TokenType::Table);
56468
56469 self.match_token(TokenType::Eq);
56471
56472 let table = self.parse_table_parts()?;
56474 if table.is_none() {
56475 return Ok(None);
56476 }
56477
56478 Ok(Some(Expression::WithJournalTableProperty(Box::new(
56479 WithJournalTableProperty {
56480 this: Box::new(table.unwrap()),
56481 },
56482 ))))
56483 }
56484
56485 pub fn parse_wrapped(&mut self) -> Result<Option<Expression>> {
56489 if !self.match_token(TokenType::LParen) {
56490 return Ok(None);
56491 }
56492
56493 let result = self.parse_disjunction()?;
56494 self.match_token(TokenType::RParen);
56495
56496 Ok(result)
56497 }
56498
56499 pub fn parse_wrapped_csv(&mut self) -> Result<Option<Expression>> {
56502 if !self.match_token(TokenType::LParen) {
56503 return Ok(None);
56504 }
56505
56506 let expressions = self.parse_expression_list()?;
56507 self.match_token(TokenType::RParen);
56508
56509 if expressions.is_empty() {
56510 return Ok(None);
56511 }
56512
56513 Ok(Some(Expression::Tuple(Box::new(Tuple { expressions }))))
56514 }
56515
56516 pub fn parse_wrapped_id_vars(&mut self) -> Result<Option<Expression>> {
56519 if !self.match_token(TokenType::LParen) {
56520 return Ok(None);
56521 }
56522
56523 let mut identifiers = Vec::new();
56524 loop {
56525 if let Some(id) = self.parse_id_var()? {
56526 identifiers.push(id);
56527 } else {
56528 break;
56529 }
56530 if !self.match_token(TokenType::Comma) {
56531 break;
56532 }
56533 }
56534
56535 self.match_token(TokenType::RParen);
56536
56537 if identifiers.is_empty() {
56538 return Ok(None);
56539 }
56540
56541 Ok(Some(Expression::Tuple(Box::new(Tuple {
56542 expressions: identifiers,
56543 }))))
56544 }
56545
56546 pub fn parse_wrapped_options(&mut self) -> Result<Option<Expression>> {
56550 self.match_token(TokenType::Eq);
56552
56553 if !self.match_token(TokenType::LParen) {
56555 return Ok(None);
56556 }
56557
56558 let mut properties = Vec::new();
56560 while !self.check(TokenType::RParen) && !self.is_at_end() {
56561 if let Some(prop) = self.parse_option_property()? {
56563 properties.push(prop);
56564 } else {
56565 break;
56566 }
56567 }
56568
56569 self.match_token(TokenType::RParen);
56571
56572 if properties.is_empty() {
56573 Ok(None)
56574 } else {
56575 Ok(Some(Expression::Tuple(Box::new(Tuple {
56576 expressions: properties,
56577 }))))
56578 }
56579 }
56580
56581 fn parse_option_property(&mut self) -> Result<Option<Expression>> {
56584 let index = self.current;
56586
56587 let key = if self.check(TokenType::Identifier)
56590 || self.check(TokenType::Var)
56591 || self
56592 .peek()
56593 .text
56594 .chars()
56595 .all(|c| c.is_ascii_alphanumeric() || c == '_')
56596 {
56597 let name = self.peek().text.clone();
56598 self.skip();
56599 Some(Expression::Var(Box::new(Var { this: name })))
56600 } else {
56601 None
56602 };
56603
56604 let key = match key {
56605 Some(k) => k,
56606 None => {
56607 self.current = index;
56608 return Ok(None);
56609 }
56610 };
56611
56612 if !self.match_token(TokenType::Eq) {
56614 self.current = index;
56615 return Ok(None);
56616 }
56617
56618 let value = if self.check(TokenType::LParen) {
56624 self.skip(); let mut inner_exprs = Vec::new();
56627 while !self.check(TokenType::RParen) && !self.is_at_end() {
56628 if let Some(expr) = self.parse_primary_for_option()? {
56629 inner_exprs.push(expr);
56630 }
56631 self.match_token(TokenType::Comma);
56633 }
56634 self.match_token(TokenType::RParen);
56635 Expression::Tuple(Box::new(Tuple {
56636 expressions: inner_exprs,
56637 }))
56638 } else if let Some(primary) = self.parse_primary_for_option()? {
56639 primary
56640 } else {
56641 let text = self.peek().text.clone();
56643 self.skip();
56644 Expression::Var(Box::new(Var { this: text }))
56645 };
56646
56647 Ok(Some(Expression::Property(Box::new(Property {
56649 this: Box::new(key),
56650 value: Some(Box::new(value)),
56651 }))))
56652 }
56653
56654 fn parse_primary_for_option(&mut self) -> Result<Option<Expression>> {
56657 if self.check(TokenType::String) {
56659 let text = self.peek().text.clone();
56660 self.skip();
56661 return Ok(Some(Expression::Literal(Box::new(Literal::String(text)))));
56662 }
56663
56664 if self.check(TokenType::Number) {
56666 let text = self.peek().text.clone();
56667 self.skip();
56668 return Ok(Some(Expression::Literal(Box::new(Literal::Number(text)))));
56669 }
56670
56671 if self.check(TokenType::True) {
56673 self.skip();
56674 return Ok(Some(Expression::Boolean(BooleanLiteral { value: true })));
56675 }
56676 if self.check(TokenType::False) {
56677 self.skip();
56678 return Ok(Some(Expression::Boolean(BooleanLiteral { value: false })));
56679 }
56680
56681 if self.check(TokenType::Identifier)
56683 || self.check(TokenType::Var)
56684 || (!self.check(TokenType::RParen)
56685 && !self.check(TokenType::Comma)
56686 && !self.check(TokenType::Eq)
56687 && !self.is_at_end())
56688 {
56689 let text = self.peek().text.clone();
56690 if self.check(TokenType::RParen) {
56692 return Ok(None);
56693 }
56694 if self.check_next(TokenType::Eq) {
56696 return Ok(None);
56697 }
56698 self.skip();
56699 return Ok(Some(Expression::Var(Box::new(Var { this: text }))));
56700 }
56701
56702 Ok(None)
56703 }
56704
56705 pub fn parse_options_list(&mut self) -> Result<Vec<Expression>> {
56708 if !self.match_token(TokenType::LParen) {
56710 return Ok(Vec::new());
56711 }
56712
56713 let mut options = Vec::new();
56715 loop {
56716 if self.check(TokenType::RParen) {
56718 break;
56719 }
56720
56721 if let Some(opt) = self.parse_assignment()? {
56723 options.push(opt);
56724 } else {
56725 break;
56726 }
56727
56728 if !self.match_token(TokenType::Comma) {
56729 break;
56730 }
56731 }
56732
56733 self.expect(TokenType::RParen)?;
56735
56736 Ok(options)
56737 }
56738
56739 fn parse_bigquery_partition_by_property(&mut self) -> Result<Option<Expression>> {
56741 let start = self.current;
56742 let matched_partition = if self.match_token(TokenType::PartitionBy) {
56743 true
56744 } else if self.match_token(TokenType::Partition) {
56745 self.match_token(TokenType::By)
56746 } else {
56747 false
56748 };
56749
56750 if !matched_partition {
56751 self.current = start;
56752 return Ok(None);
56753 }
56754
56755 let mut expressions = Vec::new();
56756 while !self.is_at_end()
56757 && !self.check(TokenType::Cluster)
56758 && !self.check(TokenType::As)
56759 && !self.check(TokenType::Semicolon)
56760 && !self.check(TokenType::RParen)
56761 && !self.check_identifier("OPTIONS")
56762 {
56763 match self.parse_expression() {
56764 Ok(expr) => expressions.push(expr),
56765 Err(_) => {
56766 self.current = start;
56768 return Ok(None);
56769 }
56770 }
56771
56772 if !self.match_token(TokenType::Comma) {
56773 break;
56774 }
56775 }
56776
56777 if expressions.is_empty() {
56778 self.current = start;
56779 return Ok(None);
56780 }
56781
56782 Ok(Some(Expression::PartitionByProperty(Box::new(
56783 PartitionByProperty { expressions },
56784 ))))
56785 }
56786
56787 fn parse_bigquery_cluster_by_property(&mut self) -> Result<Option<Expression>> {
56789 let start = self.current;
56790 if !self.match_keywords(&[TokenType::Cluster, TokenType::By]) {
56791 self.current = start;
56792 return Ok(None);
56793 }
56794
56795 let mut columns = Vec::new();
56796 loop {
56797 if let Some(Expression::Identifier(id)) = self.parse_identifier()? {
56798 columns.push(id);
56799 } else if self.is_identifier_or_keyword_token() {
56800 let name = self.advance().text;
56801 columns.push(Identifier {
56802 name,
56803 quoted: false,
56804 trailing_comments: Vec::new(),
56805 span: None,
56806 });
56807 } else {
56808 self.current = start;
56810 return Ok(None);
56811 }
56812
56813 if !self.match_token(TokenType::Comma) {
56814 break;
56815 }
56816 }
56817
56818 if columns.is_empty() {
56819 self.current = start;
56820 return Ok(None);
56821 }
56822
56823 Ok(Some(Expression::ClusterByColumnsProperty(Box::new(
56824 ClusterByColumnsProperty { columns },
56825 ))))
56826 }
56827
56828 fn parse_bigquery_options_property(&mut self) -> Result<Option<Expression>> {
56831 let start = self.current;
56832 if !self.match_identifier("OPTIONS") {
56833 self.current = start;
56834 return Ok(None);
56835 }
56836
56837 let options = self.parse_options_list()?;
56838 if options.is_empty() {
56839 return Ok(Some(Expression::OptionsProperty(Box::new(
56840 OptionsProperty {
56841 entries: Vec::new(),
56842 },
56843 ))));
56844 }
56845
56846 let mut entries = Vec::new();
56847 for option_expr in &options {
56848 let Some(entry) = Self::option_entry_from_expression(option_expr) else {
56849 return Ok(Some(Expression::Properties(Box::new(Properties {
56850 expressions: options,
56851 }))));
56852 };
56853 entries.push(entry);
56854 }
56855
56856 Ok(Some(Expression::OptionsProperty(Box::new(
56857 OptionsProperty { entries },
56858 ))))
56859 }
56860
56861 fn option_entry_from_expression(expr: &Expression) -> Option<OptionEntry> {
56862 let Expression::Eq(eq) = expr else {
56863 return None;
56864 };
56865
56866 let key = match &eq.left {
56867 Expression::Column(col) if col.table.is_none() => col.name.clone(),
56868 Expression::Identifier(id) => id.clone(),
56869 Expression::Var(var) => Identifier {
56870 name: var.this.clone(),
56871 quoted: false,
56872 trailing_comments: Vec::new(),
56873 span: None,
56874 },
56875 _ => return None,
56876 };
56877
56878 Some(OptionEntry {
56879 key,
56880 value: eq.right.clone(),
56881 })
56882 }
56883
56884 pub fn parse_environment_list(&mut self) -> Result<Vec<Expression>> {
56887 if !self.match_token(TokenType::LParen) {
56889 return Ok(Vec::new());
56890 }
56891
56892 let mut env_items = Vec::new();
56894 loop {
56895 if self.check(TokenType::RParen) {
56897 break;
56898 }
56899
56900 if let Some(opt) = self.parse_assignment()? {
56902 env_items.push(opt);
56903 } else {
56904 break;
56905 }
56906
56907 if !self.match_token(TokenType::Comma) {
56908 break;
56909 }
56910 }
56911
56912 self.expect(TokenType::RParen)?;
56914
56915 Ok(env_items)
56916 }
56917
56918 #[allow(unused_variables, unused_mut)]
56921 pub fn parse_wrapped_properties(&mut self) -> Result<Option<Expression>> {
56922 if !self.match_token(TokenType::LParen) {
56924 return Ok(None);
56925 }
56926
56927 let mut props = Vec::new();
56928 loop {
56929 if let Some(prop) = self.parse_property()? {
56930 props.push(prop);
56931 }
56932 if !self.match_token(TokenType::Comma) {
56933 break;
56934 }
56935 }
56936
56937 self.match_token(TokenType::RParen);
56938
56939 if props.is_empty() {
56940 return Ok(None);
56941 }
56942
56943 Ok(Some(Expression::Properties(Box::new(Properties {
56945 expressions: props,
56946 }))))
56947 }
56948
56949 #[allow(unused_variables, unused_mut)]
56952 pub fn parse_wrapped_select(&mut self, table: bool) -> Result<Option<Expression>> {
56953 let is_unpivot = self.check(TokenType::Unpivot);
56955 if self.match_token(TokenType::Pivot) || self.match_token(TokenType::Unpivot) {
56956 return self.parse_simplified_pivot(is_unpivot);
56958 }
56959
56960 if self.match_token(TokenType::From) {
56962 let from_expr = self.parse_table()?;
56964
56965 let select = self.parse_select_query()?;
56967
56968 if let Some(sel) = select {
56969 let with_ops = self.parse_set_operations_with_expr(Some(sel))?;
56971 return Ok(with_ops);
56972 } else if let Some(from_table) = from_expr {
56973 let mut select_struct = Select::new();
56975 select_struct.expressions = vec![Expression::Star(Star {
56976 table: None,
56977 except: None,
56978 replace: None,
56979 rename: None,
56980 trailing_comments: Vec::new(),
56981 span: None,
56982 })];
56983 select_struct.from = Some(From {
56984 expressions: vec![from_table],
56985 });
56986 let select_all = Expression::Select(Box::new(select_struct));
56987 let with_ops = self.parse_set_operations_with_expr(Some(select_all))?;
56988 return Ok(with_ops);
56989 }
56990 return Ok(None);
56991 }
56992
56993 let this = if table {
56995 self.parse_table()?
56996 } else {
56997 self.parse_select_query()?
56999 };
57000
57001 if this.is_none() {
57002 return Ok(None);
57003 }
57004
57005 let with_ops = self.parse_set_operations_with_expr(this)?;
57007 Ok(with_ops)
57008 }
57009
57010 pub fn parse_wrapped_select_default(&mut self) -> Result<Option<Expression>> {
57012 self.parse_wrapped_select(false)
57013 }
57014
57015 #[allow(unused_variables, unused_mut)]
57019 pub fn parse_xml_element(&mut self) -> Result<Option<Expression>> {
57020 let (this, evalname) = if self.match_text_seq(&["EVALNAME"]) {
57021 let expr = self.parse_bitwise()?;
57023 (
57024 expr,
57025 Some(Box::new(Expression::Boolean(BooleanLiteral {
57026 value: true,
57027 }))),
57028 )
57029 } else {
57030 self.match_text_seq(&["NAME"]);
57032 let id = self.parse_id_var()?;
57033 (id, None)
57034 };
57035
57036 let expressions = if self.match_token(TokenType::Comma) {
57038 self.parse_expression_list()?
57039 } else {
57040 Vec::new()
57041 };
57042
57043 match this {
57044 Some(t) => Ok(Some(Expression::XMLElement(Box::new(XMLElement {
57045 this: Box::new(t),
57046 expressions,
57047 evalname,
57048 })))),
57049 None => Ok(None),
57050 }
57051 }
57052
57053 #[allow(unused_variables, unused_mut)]
57056 pub fn parse_xml_namespace(&mut self) -> Result<Option<Expression>> {
57057 let mut namespaces = Vec::new();
57058
57059 loop {
57060 let is_default = self.match_text_seq(&["DEFAULT"]);
57062
57063 let uri = if is_default {
57065 self.parse_string()?
57066 } else {
57067 let uri_expr = self.parse_string()?;
57069 if let Some(u) = uri_expr {
57070 self.parse_alias_with_expr(Some(u))?
57071 } else {
57072 None
57073 }
57074 };
57075
57076 if let Some(u) = uri {
57077 namespaces.push(u);
57078 }
57079
57080 if !self.match_token(TokenType::Comma) {
57082 break;
57083 }
57084 }
57085
57086 if namespaces.is_empty() {
57087 return Ok(None);
57088 }
57089
57090 Ok(Some(Expression::Tuple(Box::new(Tuple {
57092 expressions: namespaces,
57093 }))))
57094 }
57095
57096 #[allow(unused_variables, unused_mut)]
57100 pub fn parse_xml_table(&mut self) -> Result<Option<Expression>> {
57101 let namespaces = if self.match_text_seq(&["XMLNAMESPACES", "("]) {
57103 let ns = self.parse_xml_namespace()?;
57104 self.match_text_seq(&[")", ","]);
57105 ns.map(Box::new)
57106 } else {
57107 None
57108 };
57109
57110 let this = self.parse_string()?;
57112 if this.is_none() {
57113 return Ok(None);
57114 }
57115
57116 let passing = if self.match_text_seq(&["PASSING"]) {
57118 self.match_text_seq(&["BY", "VALUE"]);
57120 let mut cols = Vec::new();
57125 loop {
57126 if !self.is_at_end() {
57128 let next_text = self.peek().text.to_ascii_uppercase();
57129 if next_text == "COLUMNS" || next_text == "RETURNING" {
57130 break;
57131 }
57132 if self.check(TokenType::RParen) {
57133 break;
57134 }
57135 }
57136 if let Some(col) = self.parse_assignment()? {
57137 cols.push(col);
57138 } else {
57139 break;
57140 }
57141 if !self.match_token(TokenType::Comma) {
57142 break;
57143 }
57144 }
57145 if cols.is_empty() {
57146 None
57147 } else {
57148 Some(Box::new(Expression::Tuple(Box::new(Tuple {
57149 expressions: cols,
57150 }))))
57151 }
57152 } else {
57153 None
57154 };
57155
57156 let by_ref = if self.match_text_seq(&["RETURNING", "SEQUENCE", "BY", "REF"]) {
57158 Some(Box::new(Expression::Boolean(BooleanLiteral {
57159 value: true,
57160 })))
57161 } else {
57162 None
57163 };
57164
57165 let columns = if self.match_text_seq(&["COLUMNS"]) {
57167 let mut cols = Vec::new();
57168 loop {
57169 if self.check(TokenType::RParen) {
57171 break;
57172 }
57173 if self.match_token(TokenType::Comma) {
57175 continue;
57176 }
57177 if let Some(col_def) = self.parse_field_def()? {
57178 cols.push(col_def);
57179 } else {
57180 break;
57181 }
57182 if !self.match_token(TokenType::Comma) {
57183 break;
57184 }
57185 }
57186 cols
57187 } else {
57188 Vec::new()
57189 };
57190
57191 Ok(Some(Expression::XMLTable(Box::new(XMLTable {
57192 this: Box::new(this.unwrap()),
57193 namespaces,
57194 passing,
57195 columns,
57196 by_ref,
57197 }))))
57198 }
57199
57200 fn parse_unload(&mut self) -> Result<Expression> {
57203 let mut parts = Vec::new();
57205 parts.push(self.advance().text.clone()); parts.push(" ".to_string()); while !self.is_at_end() && !self.check(TokenType::Semicolon) {
57209 let token_type = self.peek().token_type;
57210 let token_text = self.peek().text.clone();
57211
57212 if token_type == TokenType::String {
57214 parts.push(format!("'{}'", token_text.replace('\'', "''")));
57215 self.skip();
57216 if !self.is_at_end() {
57218 let next_type = self.peek().token_type;
57219 if !matches!(
57220 next_type,
57221 TokenType::Comma | TokenType::RParen | TokenType::Semicolon
57222 ) {
57223 parts.push(" ".to_string());
57224 }
57225 }
57226 continue;
57227 }
57228
57229 if token_text.eq_ignore_ascii_case("ARRAY")
57231 && self
57232 .peek_nth(1)
57233 .is_some_and(|t| t.token_type == TokenType::LBracket)
57234 {
57235 parts.push(token_text);
57236 self.skip();
57237 parts.push("[".to_string());
57239 self.skip();
57240 while !self.is_at_end() && !self.check(TokenType::RBracket) {
57242 let inner_type = self.peek().token_type;
57243 let inner_text = self.peek().text.clone();
57244 if inner_type == TokenType::String {
57245 parts.push(format!("'{}'", inner_text.replace('\'', "''")));
57246 } else {
57247 parts.push(inner_text);
57248 }
57249 self.skip();
57250 if self.check(TokenType::Comma) {
57251 parts.push(", ".to_string());
57252 self.skip();
57253 }
57254 }
57255 if self.check(TokenType::RBracket) {
57256 parts.push("]".to_string());
57257 self.skip();
57258 }
57259 continue;
57260 }
57261
57262 parts.push(token_text);
57263 self.skip();
57264
57265 if !self.is_at_end() {
57267 let next_type = self.peek().token_type;
57268 let no_space_before = matches!(
57269 next_type,
57270 TokenType::Comma
57271 | TokenType::RParen
57272 | TokenType::RBracket
57273 | TokenType::Semicolon
57274 | TokenType::LBracket
57275 );
57276 let no_space_after = matches!(token_type, TokenType::LParen | TokenType::LBracket);
57277 if !no_space_before && !no_space_after {
57278 parts.push(" ".to_string());
57279 }
57280 }
57281 }
57282
57283 Ok(Expression::Command(Box::new(Command {
57284 this: parts.join(""),
57285 })))
57286 }
57287
57288 fn parse_using_external_function(&mut self) -> Result<Expression> {
57291 let start_pos = self.peek().span.start;
57293
57294 while !self.is_at_end() && !self.check(TokenType::Semicolon) {
57296 self.skip();
57297 }
57298
57299 let end_pos = if self.current > 0 {
57301 self.tokens[self.current - 1].span.end
57302 } else {
57303 start_pos
57304 };
57305
57306 let command_text = if let Some(ref source) = self.source {
57308 source[start_pos..end_pos].to_string()
57309 } else {
57310 let mut parts = Vec::new();
57312 for i in 0..self.current {
57313 if self.tokens[i].span.start >= start_pos && self.tokens[i].span.end <= end_pos {
57314 if self.tokens[i].token_type == TokenType::String {
57315 parts.push(format!("'{}'", self.tokens[i].text.replace('\'', "''")));
57316 } else {
57317 parts.push(self.tokens[i].text.clone());
57318 }
57319 if i + 1 < self.current {
57320 parts.push(" ".to_string());
57321 }
57322 }
57323 }
57324 parts.join("")
57325 };
57326
57327 Ok(Expression::Command(Box::new(Command {
57328 this: command_text,
57329 })))
57330 }
57331}
57332
57333#[cfg(test)]
57334mod tests {
57335 use super::*;
57336 use crate::traversal::ExpressionWalk;
57337
57338 #[test]
57339 fn test_comment_before_limit() {
57340 let sql = "SELECT a FROM b WHERE foo AND bla\n-- comment 3\nLIMIT 10";
57341 let result = Parser::parse_sql(sql).unwrap();
57342 let output = crate::Generator::sql(&result[0]).unwrap();
57343 assert_eq!(
57344 output,
57345 "SELECT a FROM b WHERE foo AND bla LIMIT 10 /* comment 3 */"
57346 );
57347 }
57348
57349 #[test]
57350 fn test_variadic_array_postgres() {
57351 use crate::dialects::DialectType;
57352 use crate::transpile;
57353
57354 let sql = "SELECT ARRAY[10, -1, 5, 4.4]";
57356 let result = transpile(sql, DialectType::PostgreSQL, DialectType::PostgreSQL).unwrap();
57357 eprintln!("Array test: {} -> {}", sql, result[0]);
57358
57359 let sql2 = "SELECT MLEAST(VARIADIC ARRAY[10, -1, 5, 4.4])";
57361 let result2 = transpile(sql2, DialectType::PostgreSQL, DialectType::PostgreSQL).unwrap();
57362 eprintln!("VARIADIC test: {} -> {}", sql2, result2[0]);
57363 assert_eq!(result2[0], sql2);
57364 }
57365
57366 #[test]
57367 fn test_parse_simple_select() {
57368 let result = Parser::parse_sql("SELECT 1").unwrap();
57369 assert_eq!(result.len(), 1);
57370 assert!(result[0].is_select());
57371 }
57372
57373 #[test]
57374 fn test_parse_select_from() {
57375 let result = Parser::parse_sql("SELECT a, b FROM t").unwrap();
57376 assert_eq!(result.len(), 1);
57377
57378 let select = result[0].as_select().unwrap();
57379 assert_eq!(select.expressions.len(), 2);
57380 assert!(select.from.is_some());
57381 }
57382
57383 #[test]
57384 fn test_parse_select_where() {
57385 let result = Parser::parse_sql("SELECT * FROM t WHERE x = 1").unwrap();
57386 let select = result[0].as_select().unwrap();
57387 assert!(select.where_clause.is_some());
57388 }
57389
57390 #[test]
57391 fn test_parse_balances_large_and_chain_depth() {
57392 let mut sql = String::from("SELECT 1 WHERE c0 = 0");
57393 for i in 1..4096 {
57394 sql.push_str(&format!(" AND c{i} = {i}"));
57395 }
57396
57397 let result = Parser::parse_sql(&sql).unwrap();
57398 let select = result[0].as_select().unwrap();
57399 let where_clause = select.where_clause.as_ref().expect("WHERE clause missing");
57400 let depth = where_clause.this.tree_depth();
57401 assert!(
57402 depth < 128,
57403 "Expected balanced boolean tree depth, got {}",
57404 depth
57405 );
57406 }
57407
57408 #[test]
57409 fn test_parse_balances_large_or_chain_depth() {
57410 let mut sql = String::from("SELECT 1 WHERE c0 = 0");
57411 for i in 1..4096 {
57412 sql.push_str(&format!(" OR c{i} = {i}"));
57413 }
57414
57415 let result = Parser::parse_sql(&sql).unwrap();
57416 let select = result[0].as_select().unwrap();
57417 let where_clause = select.where_clause.as_ref().expect("WHERE clause missing");
57418 let depth = where_clause.this.tree_depth();
57419 assert!(
57420 depth < 128,
57421 "Expected balanced boolean tree depth, got {}",
57422 depth
57423 );
57424 }
57425
57426 #[test]
57427 fn test_parse_select_join() {
57428 let result = Parser::parse_sql("SELECT * FROM a JOIN b ON a.id = b.id").unwrap();
57429 let select = result[0].as_select().unwrap();
57430 assert_eq!(select.joins.len(), 1);
57431 assert_eq!(select.joins[0].kind, JoinKind::Inner);
57432 }
57433
57434 #[test]
57435 fn test_parse_expression_precedence() {
57436 let result = Parser::parse_sql("SELECT 1 + 2 * 3").unwrap();
57437 let select = result[0].as_select().unwrap();
57438 assert!(matches!(select.expressions[0], Expression::Add(_)));
57440 }
57441
57442 #[test]
57443 fn test_parse_function() {
57444 let result = Parser::parse_sql("SELECT COUNT(*)").unwrap();
57446 let select = result[0].as_select().unwrap();
57447 assert!(matches!(select.expressions[0], Expression::Count(_)));
57448
57449 let result = Parser::parse_sql("SELECT MY_CUSTOM_FUNC(name)").unwrap();
57451 let select = result[0].as_select().unwrap();
57452 assert!(matches!(select.expressions[0], Expression::Function(_)));
57453
57454 let result = Parser::parse_sql("SELECT SUM(amount)").unwrap();
57456 let select = result[0].as_select().unwrap();
57457 assert!(matches!(select.expressions[0], Expression::Sum(_)));
57458 }
57459
57460 #[test]
57461 fn test_parse_window_function() {
57462 let result =
57463 Parser::parse_sql("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)")
57464 .unwrap();
57465 let select = result[0].as_select().unwrap();
57466 assert!(matches!(
57467 select.expressions[0],
57468 Expression::WindowFunction(_)
57469 ));
57470 }
57471
57472 #[test]
57473 fn test_parse_window_function_with_frame() {
57474 let result = Parser::parse_sql("SELECT SUM(amount) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)").unwrap();
57475 let select = result[0].as_select().unwrap();
57476 assert!(matches!(
57477 select.expressions[0],
57478 Expression::WindowFunction(_)
57479 ));
57480 }
57481
57482 #[test]
57483 fn test_parse_subscript() {
57484 let result = Parser::parse_sql("SELECT arr[0]").unwrap();
57486 let select = result[0].as_select().unwrap();
57487 assert!(matches!(select.expressions[0], Expression::Subscript(_)));
57488
57489 let result = Parser::parse_sql("SELECT SPLIT(name, ',')[0]").unwrap();
57491 let select = result[0].as_select().unwrap();
57492 assert!(matches!(select.expressions[0], Expression::Subscript(_)));
57493 }
57494
57495 #[test]
57496 fn test_parse_case() {
57497 let result = Parser::parse_sql("SELECT CASE WHEN x = 1 THEN 'a' ELSE 'b' END").unwrap();
57498 let select = result[0].as_select().unwrap();
57499 assert!(matches!(select.expressions[0], Expression::Case(_)));
57500 }
57501
57502 #[test]
57503 fn test_parse_insert() {
57504 let result = Parser::parse_sql("INSERT INTO t (a, b) VALUES (1, 2)").unwrap();
57505 assert!(matches!(result[0], Expression::Insert(_)));
57506 }
57507
57508 #[test]
57509 fn test_parse_template_variable() {
57510 let result = Parser::parse_sql("SELECT ${x} FROM ${y} WHERE ${z} > 1").unwrap();
57512 let select = result[0].as_select().unwrap();
57513 assert!(
57515 matches!(&select.expressions[0], Expression::Parameter(p) if p.name == Some("x".to_string()))
57516 );
57517 if let Expression::Parameter(p) = &select.expressions[0] {
57519 assert_eq!(p.style, ParameterStyle::DollarBrace);
57520 }
57521 }
57522
57523 #[test]
57524 fn test_parse_update() {
57525 let result = Parser::parse_sql("UPDATE t SET a = 1 WHERE b = 2").unwrap();
57526 assert!(matches!(result[0], Expression::Update(_)));
57527 }
57528
57529 #[test]
57530 fn test_parse_delete() {
57531 let result = Parser::parse_sql("DELETE FROM t WHERE a = 1").unwrap();
57532 assert!(matches!(result[0], Expression::Delete(_)));
57533 }
57534
57535 #[test]
57537 fn test_parse_create_table() {
57538 let result = Parser::parse_sql(
57539 "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100) NOT NULL)",
57540 )
57541 .unwrap();
57542 assert!(matches!(result[0], Expression::CreateTable(_)));
57543
57544 if let Expression::CreateTable(ct) = &result[0] {
57545 assert_eq!(ct.name.name.name, "users");
57546 assert_eq!(ct.columns.len(), 2);
57547 assert!(ct.columns[0].primary_key);
57548 assert_eq!(ct.columns[1].nullable, Some(false));
57549 }
57550 }
57551
57552 #[test]
57553 fn test_parse_create_table_if_not_exists() {
57554 let result = Parser::parse_sql("CREATE TABLE IF NOT EXISTS t (id INT)").unwrap();
57555 if let Expression::CreateTable(ct) = &result[0] {
57556 assert!(ct.if_not_exists);
57557 }
57558 }
57559
57560 #[test]
57561 fn test_parse_create_temporary_table() {
57562 let result = Parser::parse_sql("CREATE TEMPORARY TABLE t (id INT)").unwrap();
57563 if let Expression::CreateTable(ct) = &result[0] {
57564 assert!(ct.temporary);
57565 }
57566 }
57567
57568 #[test]
57569 fn test_bigquery_create_table_properties_are_typed() {
57570 use crate::DialectType;
57571
57572 let sql = "CREATE OR REPLACE TABLE `p1`.`d1`.`t1` PARTITION BY DATE_TRUNC(day, month) CLUSTER BY some_cluster_column OPTIONS(description='', labels=[('l1', 'v1'), ('l2', 'v2')]) AS SELECT CURRENT_DATE AS day, DATE_TRUNC(CURRENT_DATE(), month) AS month, 'c' AS some_cluster_column";
57573 let parsed = crate::parse(sql, DialectType::BigQuery).unwrap();
57574
57575 let create = match &parsed[0] {
57576 Expression::CreateTable(ct) => ct,
57577 other => panic!(
57578 "Expected CreateTable, got {:?}",
57579 std::mem::discriminant(other)
57580 ),
57581 };
57582
57583 assert!(
57584 create
57585 .properties
57586 .iter()
57587 .any(|p| matches!(p, Expression::PartitionByProperty(_))),
57588 "Expected typed PARTITION BY property"
57589 );
57590 assert!(
57591 create
57592 .properties
57593 .iter()
57594 .any(|p| matches!(p, Expression::ClusterByColumnsProperty(_))),
57595 "Expected typed CLUSTER BY property"
57596 );
57597 assert!(
57598 create
57599 .properties
57600 .iter()
57601 .any(|p| matches!(p, Expression::OptionsProperty(_))),
57602 "Expected typed OPTIONS property"
57603 );
57604 assert!(
57605 !create
57606 .properties
57607 .iter()
57608 .any(|p| matches!(p, Expression::Raw(_))),
57609 "BigQuery table properties should not fall back to Raw"
57610 );
57611
57612 let options = create
57613 .properties
57614 .iter()
57615 .find_map(|p| match p {
57616 Expression::OptionsProperty(o) => Some(o),
57617 _ => None,
57618 })
57619 .expect("Expected OptionsProperty");
57620 assert_eq!(options.entries.len(), 2);
57621 assert_eq!(options.entries[0].key.name, "description");
57622 assert_eq!(options.entries[1].key.name, "labels");
57623 }
57624
57625 #[test]
57626 fn test_bigquery_create_table_properties_roundtrip() {
57627 use crate::DialectType;
57628
57629 let sql = "CREATE TABLE t1 PARTITION BY DATE_TRUNC(day, month) CLUSTER BY some_cluster_column OPTIONS(description='', labels=[('l1', 'v1')]) AS SELECT 1 AS day, 1 AS month, 'c' AS some_cluster_column";
57630 let expected = "CREATE TABLE t1 PARTITION BY DATE_TRUNC(day, month) CLUSTER BY some_cluster_column OPTIONS (description='', labels=[('l1', 'v1')]) AS SELECT 1 AS day, 1 AS month, 'c' AS some_cluster_column";
57631 let parsed = crate::parse(sql, DialectType::BigQuery).unwrap();
57632 let generated = crate::generate(&parsed[0], DialectType::BigQuery).unwrap();
57633 assert_eq!(generated, expected);
57634 }
57635
57636 #[test]
57637 fn test_parse_drop_table() {
57638 let result = Parser::parse_sql("DROP TABLE IF EXISTS users CASCADE").unwrap();
57639 assert!(matches!(result[0], Expression::DropTable(_)));
57640
57641 if let Expression::DropTable(dt) = &result[0] {
57642 assert!(dt.if_exists);
57643 assert!(dt.cascade);
57644 assert_eq!(dt.names.len(), 1);
57645 }
57646 }
57647
57648 #[test]
57649 fn test_parse_alter_table_add_column() {
57650 let result = Parser::parse_sql("ALTER TABLE users ADD COLUMN email VARCHAR(255)").unwrap();
57651 assert!(matches!(result[0], Expression::AlterTable(_)));
57652
57653 if let Expression::AlterTable(at) = &result[0] {
57654 assert_eq!(at.actions.len(), 1);
57655 assert!(matches!(at.actions[0], AlterTableAction::AddColumn { .. }));
57656 }
57657 }
57658
57659 #[test]
57660 fn test_parse_alter_table_drop_column() {
57661 let result = Parser::parse_sql("ALTER TABLE users DROP COLUMN email").unwrap();
57662 if let Expression::AlterTable(at) = &result[0] {
57663 assert!(matches!(at.actions[0], AlterTableAction::DropColumn { .. }));
57664 }
57665 }
57666
57667 #[test]
57668 fn test_tsql_alter_table_set_options() {
57669 use crate::{transpile, DialectType};
57670 let tests = vec![
57671 "ALTER TABLE tbl SET (SYSTEM_VERSIONING=OFF)",
57672 "ALTER TABLE tbl SET (FILESTREAM_ON = 'test')",
57673 "ALTER TABLE tbl SET (DATA_DELETION=ON)",
57674 "ALTER TABLE tbl SET (DATA_DELETION=OFF)",
57675 "ALTER TABLE tbl SET (SYSTEM_VERSIONING=ON(HISTORY_TABLE=db.tbl, DATA_CONSISTENCY_CHECK=OFF, HISTORY_RETENTION_PERIOD=5 DAYS))",
57676 "ALTER TABLE tbl SET (SYSTEM_VERSIONING=ON(HISTORY_TABLE=db.tbl, HISTORY_RETENTION_PERIOD=INFINITE))",
57677 "ALTER TABLE tbl SET (DATA_DELETION=ON(FILTER_COLUMN=col, RETENTION_PERIOD=5 MONTHS))",
57678 ];
57679 for sql in tests {
57680 let result = transpile(sql, DialectType::TSQL, DialectType::TSQL);
57681 match result {
57682 Ok(output) => {
57683 assert_eq!(output[0].trim(), sql, "Identity failed for: {}", sql);
57684 }
57685 Err(e) => {
57686 panic!("Parse/generate failed for: {} -- {:?}", sql, e);
57687 }
57688 }
57689 }
57690 }
57691
57692 #[test]
57693 fn test_parse_create_index() {
57694 let result = Parser::parse_sql("CREATE UNIQUE INDEX idx_email ON users (email)").unwrap();
57695 assert!(matches!(result[0], Expression::CreateIndex(_)));
57696
57697 if let Expression::CreateIndex(ci) = &result[0] {
57698 assert!(ci.unique);
57699 assert_eq!(ci.name.name, "idx_email");
57700 assert_eq!(ci.table.name.name, "users");
57701 assert_eq!(ci.columns.len(), 1);
57702 }
57703 }
57704
57705 #[test]
57706 fn test_parse_drop_index() {
57707 let result = Parser::parse_sql("DROP INDEX IF EXISTS idx_email ON users").unwrap();
57708 assert!(matches!(result[0], Expression::DropIndex(_)));
57709
57710 if let Expression::DropIndex(di) = &result[0] {
57711 assert!(di.if_exists);
57712 assert!(di.table.is_some());
57713 }
57714 }
57715
57716 #[test]
57717 fn test_parse_create_view() {
57718 let result =
57719 Parser::parse_sql("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1")
57720 .unwrap();
57721 assert!(matches!(result[0], Expression::CreateView(_)));
57722 }
57723
57724 #[test]
57725 fn test_parse_create_materialized_view() {
57726 let result =
57727 Parser::parse_sql("CREATE MATERIALIZED VIEW stats AS SELECT COUNT(*) FROM users")
57728 .unwrap();
57729 if let Expression::CreateView(cv) = &result[0] {
57730 assert!(cv.materialized);
57731 }
57732 }
57733
57734 #[test]
57735 fn test_hive_stored_by() {
57736 use crate::{transpile, DialectType};
57737 let sql = "CREATE EXTERNAL TABLE X (y INT) STORED BY 'x'";
57738 let result = transpile(sql, DialectType::Hive, DialectType::Hive);
57739 match result {
57740 Ok(output) => {
57741 assert_eq!(output[0].trim(), sql, "Identity failed for: {}", sql);
57742 }
57743 Err(e) => {
57744 panic!("Parse/generate failed for: {} -- {:?}", sql, e);
57745 }
57746 }
57747 }
57748
57749 #[test]
57750 fn test_hive_row_format_serde() {
57751 use crate::{transpile, DialectType};
57752
57753 let test_cases = vec![
57755 (
57756 "CREATE TABLE my_table (a7 ARRAY<DATE>)",
57757 "CREATE TABLE my_table (a7 ARRAY<DATE>)",
57758 ),
57759 (
57760 "CREATE EXTERNAL TABLE my_table (x INT) ROW FORMAT SERDE 'a'",
57761 "CREATE EXTERNAL TABLE my_table (x INT) ROW FORMAT SERDE 'a'",
57762 ),
57763 (
57764 "CREATE EXTERNAL TABLE my_table (x INT) STORED AS INPUTFORMAT 'b' OUTPUTFORMAT 'c'",
57765 "CREATE EXTERNAL TABLE my_table (x INT) STORED AS INPUTFORMAT 'b' OUTPUTFORMAT 'c'",
57766 ),
57767 (
57768 "CREATE EXTERNAL TABLE my_table (x INT) LOCATION 'd'",
57769 "CREATE EXTERNAL TABLE my_table (x INT) LOCATION 'd'",
57770 ),
57771 (
57772 "CREATE EXTERNAL TABLE my_table (x INT) TBLPROPERTIES ('e'='f')",
57773 "CREATE EXTERNAL TABLE my_table (x INT) TBLPROPERTIES ('e'='f')",
57774 ),
57775 (
57776 "CREATE EXTERNAL TABLE X (y INT) STORED BY 'x'",
57777 "CREATE EXTERNAL TABLE X (y INT) STORED BY 'x'",
57778 ),
57779 ];
57780
57781 for (sql, expected) in &test_cases {
57782 let result = transpile(sql, DialectType::Hive, DialectType::Hive);
57783 match result {
57784 Ok(output) => {
57785 assert_eq!(output[0].trim(), *expected, "Identity failed for: {}", sql);
57786 }
57787 Err(e) => {
57788 panic!("Parse/generate failed for: {} -- {:?}", sql, e);
57789 }
57790 }
57791 }
57792
57793 let sql = "CREATE EXTERNAL TABLE `my_table` (`a7` ARRAY<DATE>) ROW FORMAT SERDE 'a' STORED AS INPUTFORMAT 'b' OUTPUTFORMAT 'c' LOCATION 'd' TBLPROPERTIES ('e'='f')";
57795 let result = transpile(sql, DialectType::Hive, DialectType::Hive);
57796 match result {
57797 Ok(output) => {
57798 assert_eq!(output[0].trim(), sql, "Identity failed for: {}", sql);
57799 }
57800 Err(e) => {
57801 panic!("Parse/generate failed for: {} -- {:?}", sql, e);
57802 }
57803 }
57804 }
57805
57806 #[test]
57807 fn test_parse_drop_view() {
57808 let result = Parser::parse_sql("DROP VIEW IF EXISTS active_users").unwrap();
57809 assert!(matches!(result[0], Expression::DropView(_)));
57810 }
57811
57812 #[test]
57813 fn test_parse_truncate() {
57814 let result = Parser::parse_sql("TRUNCATE TABLE users CASCADE").unwrap();
57815 assert!(matches!(result[0], Expression::Truncate(_)));
57816
57817 if let Expression::Truncate(tr) = &result[0] {
57818 assert!(tr.cascade);
57819 }
57820 }
57821
57822 #[test]
57824 fn test_parse_typed_aggregates() {
57825 let result = Parser::parse_sql("SELECT COUNT(DISTINCT user_id)").unwrap();
57827 let select = result[0].as_select().unwrap();
57828 if let Expression::Count(c) = &select.expressions[0] {
57829 assert!(c.distinct);
57830 assert!(!c.star);
57831 } else {
57832 panic!("Expected Count expression");
57833 }
57834
57835 let result = Parser::parse_sql("SELECT AVG(price)").unwrap();
57837 let select = result[0].as_select().unwrap();
57838 assert!(matches!(select.expressions[0], Expression::Avg(_)));
57839
57840 let result = Parser::parse_sql("SELECT MIN(a), MAX(b)").unwrap();
57842 let select = result[0].as_select().unwrap();
57843 assert!(matches!(select.expressions[0], Expression::Min(_)));
57844 assert!(matches!(select.expressions[1], Expression::Max(_)));
57845
57846 let result = Parser::parse_sql("SELECT STDDEV(x), VARIANCE(y)").unwrap();
57848 let select = result[0].as_select().unwrap();
57849 assert!(matches!(select.expressions[0], Expression::Stddev(_)));
57850 assert!(matches!(select.expressions[1], Expression::Variance(_)));
57851 }
57852
57853 #[test]
57854 fn test_parse_typed_window_functions() {
57855 let result = Parser::parse_sql("SELECT ROW_NUMBER() OVER (ORDER BY id)").unwrap();
57857 let select = result[0].as_select().unwrap();
57858 if let Expression::WindowFunction(wf) = &select.expressions[0] {
57859 assert!(matches!(wf.this, Expression::RowNumber(_)));
57860 } else {
57861 panic!("Expected WindowFunction");
57862 }
57863
57864 let result = Parser::parse_sql("SELECT RANK() OVER (), DENSE_RANK() OVER ()").unwrap();
57866 let select = result[0].as_select().unwrap();
57867 if let Expression::WindowFunction(wf) = &select.expressions[0] {
57868 assert!(matches!(wf.this, Expression::Rank(_)));
57869 }
57870 if let Expression::WindowFunction(wf) = &select.expressions[1] {
57871 assert!(matches!(wf.this, Expression::DenseRank(_)));
57872 }
57873
57874 let result = Parser::parse_sql("SELECT LEAD(val, 1, 0) OVER (ORDER BY id)").unwrap();
57876 let select = result[0].as_select().unwrap();
57877 if let Expression::WindowFunction(wf) = &select.expressions[0] {
57878 if let Expression::Lead(f) = &wf.this {
57879 assert!(f.offset.is_some());
57880 assert!(f.default.is_some());
57881 } else {
57882 panic!("Expected Lead");
57883 }
57884 }
57885
57886 let result = Parser::parse_sql("SELECT NTILE(4) OVER (ORDER BY score)").unwrap();
57888 let select = result[0].as_select().unwrap();
57889 if let Expression::WindowFunction(wf) = &select.expressions[0] {
57890 assert!(matches!(wf.this, Expression::NTile(_)));
57891 }
57892 }
57893
57894 #[test]
57895 fn test_parse_string_functions() {
57896 let result = Parser::parse_sql("SELECT CONTAINS(name, 'test')").unwrap();
57898 let select = result[0].as_select().unwrap();
57899 assert!(matches!(select.expressions[0], Expression::Contains(_)));
57900
57901 let result = Parser::parse_sql("SELECT STARTS_WITH(name, 'A')").unwrap();
57902 let select = result[0].as_select().unwrap();
57903 assert!(matches!(select.expressions[0], Expression::StartsWith(_)));
57904
57905 let result = Parser::parse_sql("SELECT ENDS_WITH(name, 'z')").unwrap();
57906 let select = result[0].as_select().unwrap();
57907 assert!(matches!(select.expressions[0], Expression::EndsWith(_)));
57908 }
57909
57910 #[test]
57911 fn test_parse_math_functions() {
57912 let result = Parser::parse_sql("SELECT MOD(10, 3)").unwrap();
57914 let select = result[0].as_select().unwrap();
57915 assert!(matches!(select.expressions[0], Expression::ModFunc(_)));
57916
57917 let result = Parser::parse_sql("SELECT RANDOM()").unwrap();
57919 let select = result[0].as_select().unwrap();
57920 assert!(matches!(select.expressions[0], Expression::Random(_)));
57921
57922 let result = Parser::parse_sql("SELECT RAND(42)").unwrap();
57923 let select = result[0].as_select().unwrap();
57924 assert!(matches!(select.expressions[0], Expression::Rand(_)));
57925
57926 let result = Parser::parse_sql("SELECT SIN(x), COS(x), TAN(x)").unwrap();
57928 let select = result[0].as_select().unwrap();
57929 assert!(matches!(select.expressions[0], Expression::Sin(_)));
57930 assert!(matches!(select.expressions[1], Expression::Cos(_)));
57931 assert!(matches!(select.expressions[2], Expression::Tan(_)));
57932 }
57933
57934 #[test]
57935 fn test_parse_date_functions() {
57936 let result =
57938 Parser::parse_sql("SELECT YEAR(date_col), MONTH(date_col), DAY(date_col)").unwrap();
57939 let select = result[0].as_select().unwrap();
57940 assert!(matches!(select.expressions[0], Expression::Year(_)));
57941 assert!(matches!(select.expressions[1], Expression::Month(_)));
57942 assert!(matches!(select.expressions[2], Expression::Day(_)));
57943
57944 let result = Parser::parse_sql("SELECT EPOCH(ts), EPOCH_MS(ts)").unwrap();
57946 let select = result[0].as_select().unwrap();
57947 assert!(matches!(select.expressions[0], Expression::Epoch(_)));
57948 assert!(matches!(select.expressions[1], Expression::EpochMs(_)));
57949 }
57950
57951 #[test]
57952 fn test_parse_array_functions() {
57953 let result = Parser::parse_sql("SELECT ARRAY_LENGTH(arr)").unwrap();
57955 let select = result[0].as_select().unwrap();
57956 assert!(matches!(select.expressions[0], Expression::ArrayLength(_)));
57957
57958 let result = Parser::parse_sql("SELECT ARRAY_CONTAINS(arr, 1)").unwrap();
57960 let select = result[0].as_select().unwrap();
57961 assert!(matches!(
57962 select.expressions[0],
57963 Expression::ArrayContains(_)
57964 ));
57965
57966 let result = Parser::parse_sql("SELECT EXPLODE(arr)").unwrap();
57968 let select = result[0].as_select().unwrap();
57969 assert!(matches!(select.expressions[0], Expression::Explode(_)));
57970 }
57971
57972 #[test]
57973 fn test_parse_json_functions() {
57974 let result = Parser::parse_sql("SELECT JSON_EXTRACT(data, '$.name')").unwrap();
57976 let select = result[0].as_select().unwrap();
57977 assert!(matches!(select.expressions[0], Expression::JsonExtract(_)));
57978
57979 let result = Parser::parse_sql("SELECT JSON_ARRAY_LENGTH(arr)").unwrap();
57981 let select = result[0].as_select().unwrap();
57982 assert!(matches!(
57983 select.expressions[0],
57984 Expression::JsonArrayLength(_)
57985 ));
57986
57987 let result = Parser::parse_sql("SELECT TO_JSON(obj), PARSE_JSON(str)").unwrap();
57989 let select = result[0].as_select().unwrap();
57990 assert!(matches!(select.expressions[0], Expression::ToJson(_)));
57991 assert!(matches!(select.expressions[1], Expression::ParseJson(_)));
57992
57993 let result = Parser::parse_sql("SELECT JSON '\"foo\"'").unwrap();
57995 let select = result[0].as_select().unwrap();
57996 assert!(
57997 matches!(select.expressions[0], Expression::ParseJson(_)),
57998 "Expected ParseJson, got: {:?}",
57999 select.expressions[0]
58000 );
58001 }
58002
58003 #[test]
58004 fn test_parse_map_functions() {
58005 let result = Parser::parse_sql("SELECT MAP_KEYS(m), MAP_VALUES(m)").unwrap();
58007 let select = result[0].as_select().unwrap();
58008 assert!(matches!(select.expressions[0], Expression::MapKeys(_)));
58009 assert!(matches!(select.expressions[1], Expression::MapValues(_)));
58010
58011 let result = Parser::parse_sql("SELECT ELEMENT_AT(m, 'key')").unwrap();
58013 let select = result[0].as_select().unwrap();
58014 assert!(matches!(select.expressions[0], Expression::ElementAt(_)));
58015 }
58016
58017 #[test]
58018 fn test_parse_date_literals() {
58019 let result = Parser::parse_sql("SELECT DATE '2024-01-15'").unwrap();
58021 let select = result[0].as_select().unwrap();
58022 match &select.expressions[0] {
58023 Expression::Cast(cast) => {
58024 match &cast.this {
58025 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
58026 let Literal::String(s) = lit.as_ref() else {
58027 unreachable!()
58028 };
58029 assert_eq!(s, "2024-01-15")
58030 }
58031 other => panic!("Expected String literal in Cast, got {:?}", other),
58032 }
58033 assert!(matches!(cast.to, DataType::Date));
58034 }
58035 other => panic!("Expected Cast expression, got {:?}", other),
58036 }
58037
58038 let result = Parser::parse_sql("SELECT TIME '10:30:00'").unwrap();
58040 let select = result[0].as_select().unwrap();
58041 match &select.expressions[0] {
58042 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Time(_)) => {
58043 let Literal::Time(t) = lit.as_ref() else {
58044 unreachable!()
58045 };
58046 assert_eq!(t, "10:30:00");
58047 }
58048 _ => panic!("Expected Time literal"),
58049 }
58050
58051 let result = Parser::parse_sql("SELECT TIMESTAMP '2024-01-15 10:30:00'").unwrap();
58053 let select = result[0].as_select().unwrap();
58054 match &select.expressions[0] {
58055 Expression::Cast(cast) => {
58056 match &cast.this {
58057 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
58058 let Literal::String(s) = lit.as_ref() else {
58059 unreachable!()
58060 };
58061 assert_eq!(s, "2024-01-15 10:30:00")
58062 }
58063 other => panic!("Expected String literal inside Cast, got {:?}", other),
58064 }
58065 assert!(matches!(
58066 &cast.to,
58067 DataType::Timestamp {
58068 precision: None,
58069 timezone: false
58070 }
58071 ));
58072 }
58073 _ => panic!("Expected Cast expression for TIMESTAMP literal"),
58074 }
58075 }
58076
58077 #[test]
58078 fn test_parse_star_exclude() {
58079 let result = Parser::parse_sql("SELECT * EXCLUDE (col1, col2) FROM t").unwrap();
58081 let select = result[0].as_select().unwrap();
58082 if let Expression::Star(star) = &select.expressions[0] {
58083 assert!(star.except.is_some());
58084 let except = star.except.as_ref().unwrap();
58085 assert_eq!(except.len(), 2);
58086 assert_eq!(except[0].name, "col1");
58087 assert_eq!(except[1].name, "col2");
58088 } else {
58089 panic!("Expected Star expression");
58090 }
58091
58092 let result = Parser::parse_sql("SELECT * EXCEPT (id, created_at) FROM t").unwrap();
58094 let select = result[0].as_select().unwrap();
58095 if let Expression::Star(star) = &select.expressions[0] {
58096 assert!(star.except.is_some());
58097 } else {
58098 panic!("Expected Star expression");
58099 }
58100
58101 let result = Parser::parse_sql("SELECT t.* EXCLUDE (col1) FROM t").unwrap();
58103 let select = result[0].as_select().unwrap();
58104 if let Expression::Star(star) = &select.expressions[0] {
58105 assert!(star.table.is_some());
58106 assert_eq!(star.table.as_ref().unwrap().name, "t");
58107 assert!(star.except.is_some());
58108 } else {
58109 panic!("Expected Star expression");
58110 }
58111 }
58112
58113 #[test]
58114 fn test_parse_star_replace() {
58115 let result = Parser::parse_sql("SELECT * REPLACE (UPPER(name) AS name) FROM t").unwrap();
58117 let select = result[0].as_select().unwrap();
58118 if let Expression::Star(star) = &select.expressions[0] {
58119 assert!(star.replace.is_some());
58120 let replace = star.replace.as_ref().unwrap();
58121 assert_eq!(replace.len(), 1);
58122 assert_eq!(replace[0].alias.name, "name");
58123 } else {
58124 panic!("Expected Star expression");
58125 }
58126
58127 let result = Parser::parse_sql("SELECT * REPLACE (a + 1 AS a, b * 2 AS b) FROM t").unwrap();
58129 let select = result[0].as_select().unwrap();
58130 if let Expression::Star(star) = &select.expressions[0] {
58131 let replace = star.replace.as_ref().unwrap();
58132 assert_eq!(replace.len(), 2);
58133 } else {
58134 panic!("Expected Star expression");
58135 }
58136 }
58137
58138 #[test]
58139 fn test_parse_star_rename() {
58140 let result =
58142 Parser::parse_sql("SELECT * RENAME (old_col AS new_col, x AS y) FROM t").unwrap();
58143 let select = result[0].as_select().unwrap();
58144 if let Expression::Star(star) = &select.expressions[0] {
58145 assert!(star.rename.is_some());
58146 let rename = star.rename.as_ref().unwrap();
58147 assert_eq!(rename.len(), 2);
58148 assert_eq!(rename[0].0.name, "old_col");
58149 assert_eq!(rename[0].1.name, "new_col");
58150 } else {
58151 panic!("Expected Star expression");
58152 }
58153 }
58154
58155 #[test]
58156 fn test_parse_star_combined() {
58157 let result =
58159 Parser::parse_sql("SELECT * EXCLUDE (id) REPLACE (name || '!' AS name) FROM t")
58160 .unwrap();
58161 let select = result[0].as_select().unwrap();
58162 if let Expression::Star(star) = &select.expressions[0] {
58163 assert!(star.except.is_some());
58164 assert!(star.replace.is_some());
58165 } else {
58166 panic!("Expected Star expression");
58167 }
58168 }
58169
58170 #[test]
58171 fn test_parse_spatial_types() {
58172 let result = Parser::parse_sql("CREATE TABLE t (geom GEOMETRY(Point, 4326))").unwrap();
58174 if let Expression::CreateTable(ct) = &result[0] {
58175 assert_eq!(ct.columns.len(), 1);
58176 match &ct.columns[0].data_type {
58177 DataType::Geometry { subtype, srid } => {
58178 assert_eq!(subtype.as_deref(), Some("POINT"));
58179 assert_eq!(*srid, Some(4326));
58180 }
58181 _ => panic!("Expected Geometry type"),
58182 }
58183 }
58184
58185 let result = Parser::parse_sql("CREATE TABLE t (loc GEOGRAPHY)").unwrap();
58187 if let Expression::CreateTable(ct) = &result[0] {
58188 match &ct.columns[0].data_type {
58189 DataType::Geography { subtype, srid } => {
58190 assert!(subtype.is_none());
58191 assert!(srid.is_none());
58192 }
58193 _ => panic!("Expected Geography type"),
58194 }
58195 }
58196
58197 let result = Parser::parse_sql("CREATE TABLE t (geom GEOMETRY(LineString))").unwrap();
58199 if let Expression::CreateTable(ct) = &result[0] {
58200 match &ct.columns[0].data_type {
58201 DataType::Geometry { subtype, srid } => {
58202 assert_eq!(subtype.as_deref(), Some("LINESTRING"));
58203 assert!(srid.is_none());
58204 }
58205 _ => panic!("Expected Geometry type"),
58206 }
58207 }
58208
58209 let result = Parser::parse_sql("CREATE TABLE t (pt POINT)").unwrap();
58211 if let Expression::CreateTable(ct) = &result[0] {
58212 match &ct.columns[0].data_type {
58213 DataType::Geometry { subtype, srid } => {
58214 assert_eq!(subtype.as_deref(), Some("POINT"));
58215 assert!(srid.is_none());
58216 }
58217 _ => panic!("Expected Geometry type"),
58218 }
58219 }
58220 }
58221
58222 #[test]
58223 fn test_parse_duckdb_pivot_simple() {
58224 let sql = "PIVOT Cities ON Year USING SUM(Population)";
58225 let result = Parser::parse_sql(sql);
58226 assert!(
58227 result.is_ok(),
58228 "Failed to parse: {} - {:?}",
58229 sql,
58230 result.err()
58231 );
58232 let stmts = result.unwrap();
58233 assert_eq!(
58234 stmts.len(),
58235 1,
58236 "Expected 1 statement, got {}: {:?}",
58237 stmts.len(),
58238 stmts
58239 );
58240 match &stmts[0] {
58241 Expression::Pivot(p) => {
58242 assert!(!p.unpivot);
58243 assert!(!p.expressions.is_empty(), "Should have ON expressions");
58244 assert!(!p.using.is_empty(), "Should have USING expressions");
58245 }
58246 other => panic!("Expected Pivot, got {:?}", other),
58247 }
58248 }
58249
58250 #[test]
58251 fn test_parse_duckdb_pivot_with_group_by() {
58252 let sql = "PIVOT Cities ON Year USING SUM(Population) GROUP BY Country";
58253 let result = Parser::parse_sql(sql);
58254 assert!(
58255 result.is_ok(),
58256 "Failed to parse: {} - {:?}",
58257 sql,
58258 result.err()
58259 );
58260 }
58261
58262 #[test]
58263 fn test_parse_duckdb_unpivot() {
58264 let sql = "UNPIVOT monthly_sales ON jan, feb, mar INTO NAME month VALUE sales";
58265 let result = Parser::parse_sql(sql);
58266 assert!(
58267 result.is_ok(),
58268 "Failed to parse: {} - {:?}",
58269 sql,
58270 result.err()
58271 );
58272 }
58273
58274 #[test]
58275 fn test_parse_standard_pivot_in_from() {
58276 let sql = "SELECT * FROM cities PIVOT(SUM(population) FOR year IN (2000, 2010, 2020))";
58277 let result = Parser::parse_sql(sql);
58278 assert!(
58279 result.is_ok(),
58280 "Failed to parse: {} - {:?}",
58281 sql,
58282 result.err()
58283 );
58284 }
58285
58286 fn assert_pivot_roundtrip(sql: &str) {
58287 let parsed = crate::parse(sql, crate::DialectType::DuckDB);
58288 assert!(
58289 parsed.is_ok(),
58290 "Failed to parse: {} - {:?}",
58291 sql,
58292 parsed.err()
58293 );
58294 let stmts = parsed.unwrap();
58295 assert_eq!(stmts.len(), 1, "Expected 1 statement for: {}", sql);
58296 let generated = crate::generate(&stmts[0], crate::DialectType::DuckDB);
58297 assert!(
58298 generated.is_ok(),
58299 "Failed to generate: {} - {:?}",
58300 sql,
58301 generated.err()
58302 );
58303 let result = generated.unwrap();
58304 assert_eq!(result.trim(), sql, "Round-trip mismatch for: {}", sql);
58305 }
58306
58307 fn assert_pivot_roundtrip_bq(sql: &str) {
58308 let parsed = crate::parse(sql, crate::DialectType::BigQuery);
58309 assert!(
58310 parsed.is_ok(),
58311 "Failed to parse: {} - {:?}",
58312 sql,
58313 parsed.err()
58314 );
58315 let stmts = parsed.unwrap();
58316 assert_eq!(stmts.len(), 1, "Expected 1 statement for: {}", sql);
58317 let generated = crate::generate(&stmts[0], crate::DialectType::BigQuery);
58318 assert!(
58319 generated.is_ok(),
58320 "Failed to generate: {} - {:?}",
58321 sql,
58322 generated.err()
58323 );
58324 let result = generated.unwrap();
58325 assert_eq!(result.trim(), sql, "Round-trip mismatch for: {}", sql);
58326 }
58327
58328 #[test]
58329 fn test_pivot_roundtrip_duckdb_simple() {
58330 assert_pivot_roundtrip("PIVOT Cities ON Year USING SUM(Population)");
58331 }
58332
58333 #[test]
58334 fn test_pivot_roundtrip_duckdb_group_by() {
58335 assert_pivot_roundtrip("PIVOT Cities ON Year USING SUM(Population) GROUP BY Country");
58336 }
58337
58338 #[test]
58339 fn test_pivot_roundtrip_duckdb_in_clause() {
58340 assert_pivot_roundtrip(
58341 "PIVOT Cities ON Year IN (2000, 2010) USING SUM(Population) GROUP BY Country",
58342 );
58343 }
58344
58345 #[test]
58346 fn test_pivot_roundtrip_duckdb_multiple_using() {
58347 assert_pivot_roundtrip("PIVOT Cities ON Year USING SUM(Population) AS total, MAX(Population) AS max GROUP BY Country");
58348 }
58349
58350 #[test]
58351 fn test_pivot_roundtrip_duckdb_multiple_on() {
58352 assert_pivot_roundtrip("PIVOT Cities ON Country, Name USING SUM(Population)");
58353 }
58354
58355 #[test]
58356 fn test_pivot_roundtrip_duckdb_concat_on() {
58357 assert_pivot_roundtrip("PIVOT Cities ON Country || '_' || Name USING SUM(Population)");
58358 }
58359
58360 #[test]
58361 fn test_pivot_roundtrip_duckdb_multiple_group_by() {
58362 assert_pivot_roundtrip("PIVOT Cities ON Year USING SUM(Population) GROUP BY Country, Name");
58363 }
58364
58365 #[test]
58366 fn test_pivot_roundtrip_duckdb_first() {
58367 assert_pivot_roundtrip("PIVOT Cities ON Year USING FIRST(Population)");
58368 }
58369
58370 #[test]
58371 fn test_unpivot_roundtrip_duckdb_basic() {
58372 assert_pivot_roundtrip(
58373 "UNPIVOT monthly_sales ON jan, feb, mar, apr, may, jun INTO NAME month VALUE sales",
58374 );
58375 }
58376
58377 #[test]
58378 fn test_unpivot_roundtrip_duckdb_subquery() {
58379 assert_pivot_roundtrip("UNPIVOT (SELECT 1 AS col1, 2 AS col2) ON foo, bar");
58380 }
58381
58382 #[test]
58383 fn test_pivot_roundtrip_duckdb_cte() {
58384 assert_pivot_roundtrip("WITH pivot_alias AS (PIVOT Cities ON Year USING SUM(Population) GROUP BY Country) SELECT * FROM pivot_alias");
58385 }
58386
58387 #[test]
58388 fn test_pivot_roundtrip_duckdb_subquery() {
58389 assert_pivot_roundtrip("SELECT * FROM (PIVOT Cities ON Year USING SUM(Population) GROUP BY Country) AS pivot_alias");
58390 }
58391
58392 #[test]
58393 fn test_pivot_roundtrip_standard_from() {
58394 assert_pivot_roundtrip("SELECT * FROM cities PIVOT(SUM(population) FOR year IN (2000, 2010, 2020) GROUP BY country)");
58395 }
58396
58397 #[test]
58398 fn test_pivot_roundtrip_standard_bare_in() {
58399 assert_pivot_roundtrip("SELECT * FROM t PIVOT(SUM(y) FOR foo IN y_enum)");
58400 }
58401
58402 #[test]
58403 fn test_unpivot_roundtrip_bigquery() {
58404 assert_pivot_roundtrip_bq("SELECT * FROM q UNPIVOT(values FOR quarter IN (b, c))");
58405 }
58406
58407 #[test]
58408 fn test_pivot_roundtrip_bigquery_aliases() {
58409 assert_pivot_roundtrip_bq("SELECT cars, apples FROM some_table PIVOT(SUM(total_counts) FOR products IN ('general.cars' AS cars, 'food.apples' AS apples))");
58410 }
58411
58412 #[test]
58413 fn test_unpivot_roundtrip_bigquery_parens() {
58414 assert_pivot_roundtrip_bq(
58415 "SELECT * FROM (SELECT * FROM `t`) AS a UNPIVOT((c) FOR c_name IN (v1, v2))",
58416 );
58417 }
58418
58419 #[test]
58420 fn test_pivot_roundtrip_bigquery_multi_agg() {
58421 let sql = "SELECT * FROM (SELECT a, b, c FROM test) PIVOT(SUM(b) AS d, COUNT(*) AS e FOR c IN ('x', 'y'))";
58423 assert_pivot_roundtrip_bq(sql);
58424 }
58425
58426 #[test]
58428 fn test_unpivot_roundtrip_duckdb_columns_exclude() {
58429 assert_pivot_roundtrip(
58430 "UNPIVOT monthly_sales ON COLUMNS(* EXCLUDE (empid, dept)) INTO NAME month VALUE sales",
58431 );
58432 }
58433
58434 #[test]
58435 fn test_unpivot_roundtrip_duckdb_grouped_columns() {
58436 assert_pivot_roundtrip("UNPIVOT monthly_sales ON (jan, feb, mar) AS q1, (apr, may, jun) AS q2 INTO NAME quarter VALUE month_1_sales, month_2_sales, month_3_sales");
58437 }
58438
58439 #[test]
58440 fn test_unpivot_roundtrip_duckdb_cte_columns() {
58441 assert_pivot_roundtrip("WITH unpivot_alias AS (UNPIVOT monthly_sales ON COLUMNS(* EXCLUDE (empid, dept)) INTO NAME month VALUE sales) SELECT * FROM unpivot_alias");
58442 }
58443
58444 #[test]
58445 fn test_unpivot_roundtrip_duckdb_subquery_columns() {
58446 assert_pivot_roundtrip("SELECT * FROM (UNPIVOT monthly_sales ON COLUMNS(* EXCLUDE (empid, dept)) INTO NAME month VALUE sales) AS unpivot_alias");
58447 }
58448
58449 #[test]
58450 fn test_pivot_roundtrip_duckdb_cte_with_columns() {
58451 assert_pivot_roundtrip("WITH cities(country, name, year, population) AS (SELECT 'NL', 'Amsterdam', 2000, 1005 UNION ALL SELECT 'US', 'Seattle', 2020, 738) PIVOT cities ON year USING SUM(population)");
58452 }
58453
58454 #[test]
58455 fn test_pivot_roundtrip_standard_first_with_alias() {
58456 let sql = "SELECT * FROM t PIVOT(FIRST(t) AS t, FOR quarter IN ('Q1', 'Q2'))";
58458 let expected = "SELECT * FROM t PIVOT(FIRST(t) AS t FOR quarter IN ('Q1', 'Q2'))";
58459 let parsed = crate::parse(sql, crate::DialectType::DuckDB);
58460 assert!(
58461 parsed.is_ok(),
58462 "Failed to parse: {} - {:?}",
58463 sql,
58464 parsed.err()
58465 );
58466 let stmts = parsed.unwrap();
58467 assert_eq!(stmts.len(), 1);
58468 let generated = crate::generate(&stmts[0], crate::DialectType::DuckDB);
58469 assert!(
58470 generated.is_ok(),
58471 "Failed to generate: {} - {:?}",
58472 sql,
58473 generated.err()
58474 );
58475 let result = generated.unwrap();
58476 assert_eq!(result.trim(), expected, "Round-trip mismatch");
58477 }
58478
58479 #[test]
58480 fn test_pivot_roundtrip_bigquery_implicit_alias() {
58481 let sql = "SELECT * FROM (SELECT a, b, c FROM test) PIVOT(SUM(b) d, COUNT(*) e FOR c IN ('x', 'y'))";
58483 let expected = "SELECT * FROM (SELECT a, b, c FROM test) PIVOT(SUM(b) AS d, COUNT(*) AS e FOR c IN ('x', 'y'))";
58484 let parsed = crate::parse(sql, crate::DialectType::BigQuery);
58485 assert!(
58486 parsed.is_ok(),
58487 "Failed to parse: {} - {:?}",
58488 sql,
58489 parsed.err()
58490 );
58491 let stmts = parsed.unwrap();
58492 assert_eq!(stmts.len(), 1);
58493 let generated = crate::generate(&stmts[0], crate::DialectType::BigQuery);
58494 assert!(
58495 generated.is_ok(),
58496 "Failed to generate: {} - {:?}",
58497 sql,
58498 generated.err()
58499 );
58500 let result = generated.unwrap();
58501 assert_eq!(result.trim(), expected, "Round-trip mismatch");
58502 }
58503
58504 #[test]
58505 fn test_duckdb_struct_enum_union_row_types() {
58506 use crate::DialectType;
58507
58508 fn check(sql: &str, expected: Option<&str>) {
58510 let sql = sql.to_string();
58511 let expected = expected.map(|s| s.to_string());
58512 let result = std::thread::Builder::new()
58513 .stack_size(16 * 1024 * 1024) .spawn(move || {
58515 let expected_out = expected.as_deref().unwrap_or(&sql);
58516 let parsed = crate::parse(&sql, DialectType::DuckDB);
58517 assert!(
58518 parsed.is_ok(),
58519 "Failed to parse: {} - {:?}",
58520 sql,
58521 parsed.err()
58522 );
58523 let stmts = parsed.unwrap();
58524 assert!(!stmts.is_empty(), "No statements parsed: {}", sql);
58525 let generated = crate::generate(&stmts[0], DialectType::DuckDB);
58526 assert!(
58527 generated.is_ok(),
58528 "Failed to generate: {} - {:?}",
58529 sql,
58530 generated.err()
58531 );
58532 let result = generated.unwrap();
58533 assert_eq!(result.trim(), expected_out, "Mismatch for: {}", sql);
58534 })
58535 .expect("Failed to spawn test thread")
58536 .join();
58537 assert!(result.is_ok(), "Test thread panicked");
58538 }
58539
58540 check("CREATE TABLE tbl1 (u UNION(num INT, str TEXT))", None);
58542 check(
58544 "CREATE TABLE color (name ENUM('RED', 'GREEN', 'BLUE'))",
58545 None,
58546 );
58547 check(
58549 "SELECT CAST(ROW(1, 2) AS ROW(a INTEGER, b INTEGER))",
58550 Some("SELECT CAST(ROW(1, 2) AS STRUCT(a INT, b INT))"),
58551 );
58552 check("CAST(x AS STRUCT(number BIGINT))", None);
58554 check(
58556 "CAST({'i': 1, 's': 'foo'} AS STRUCT(\"s\" TEXT, \"i\" INT))",
58557 None,
58558 );
58559 check(
58561 "CAST(ROW(1, ROW(1)) AS STRUCT(number BIGINT, row STRUCT(number BIGINT)))",
58562 None,
58563 );
58564 check("CAST(x AS STRUCT(a BIGINT)[][])", None);
58567 check("CAST(x AS STRUCT(a BIGINT)[])", None);
58568 check("CAST({'a': 'b'} AS STRUCT(a TEXT))", None);
58570 }
58571
58572 fn roundtrip(sql: &str) -> String {
58574 let ast =
58575 Parser::parse_sql(sql).unwrap_or_else(|e| panic!("Parse error for '{}': {}", sql, e));
58576 crate::generator::Generator::sql(&ast[0])
58577 .unwrap_or_else(|e| panic!("Generate error for '{}': {}", sql, e))
58578 }
58579
58580 fn assert_roundtrip(sql: &str) {
58581 let result = roundtrip(sql);
58582 assert_eq!(result, sql, "\n Input: {}\n Output: {}", sql, result);
58583 }
58584
58585 fn assert_roundtrip_expected(sql: &str, expected: &str) {
58586 let result = roundtrip(sql);
58587 assert_eq!(
58588 result, expected,
58589 "\n Input: {}\n Expected: {}\n Output: {}",
58590 sql, expected, result
58591 );
58592 }
58593
58594 #[test]
58595 fn test_xmlelement_basic() {
58596 assert_roundtrip("SELECT XMLELEMENT(NAME foo)");
58597 }
58598
58599 #[test]
58600 fn test_xmlelement_with_xmlattributes() {
58601 assert_roundtrip("SELECT XMLELEMENT(NAME foo, XMLATTRIBUTES('xyz' AS bar))");
58602 }
58603
58604 #[test]
58605 fn test_xmlelement_with_multiple_attrs() {
58606 assert_roundtrip("SELECT XMLELEMENT(NAME test, XMLATTRIBUTES(a, b)) FROM test");
58607 }
58608
58609 #[test]
58610 fn test_xmlelement_with_content() {
58611 assert_roundtrip(
58612 "SELECT XMLELEMENT(NAME foo, XMLATTRIBUTES(CURRENT_DATE AS bar), 'cont', 'ent')",
58613 );
58614 }
58615
58616 #[test]
58617 fn test_xmlelement_nested() {
58618 assert_roundtrip("SELECT XMLELEMENT(NAME foo, XMLATTRIBUTES('xyz' AS bar), XMLELEMENT(NAME abc), XMLCOMMENT('test'), XMLELEMENT(NAME xyz))");
58619 }
58620
58621 #[test]
58622 fn test_on_conflict_do_update() {
58623 assert_roundtrip("INSERT INTO newtable AS t(a, b, c) VALUES (1, 2, 3) ON CONFLICT(c) DO UPDATE SET a = t.a + 1 WHERE t.a < 1");
58624 }
58625
58626 #[test]
58627 fn test_on_conflict_do_nothing() {
58628 assert_roundtrip_expected(
58630 "INSERT INTO test (id, name) VALUES (1, 'test') ON CONFLICT (id) DO NOTHING",
58631 "INSERT INTO test (id, name) VALUES (1, 'test') ON CONFLICT(id) DO NOTHING",
58632 );
58633 }
58634
58635 #[test]
58636 fn test_truncate_restart_identity() {
58637 assert_roundtrip("TRUNCATE TABLE t1 RESTART IDENTITY");
58638 }
58639
58640 #[test]
58641 fn test_truncate_restart_identity_restrict() {
58642 assert_roundtrip("TRUNCATE TABLE t1 RESTART IDENTITY RESTRICT");
58643 }
58644
58645 #[test]
58646 fn test_insert_by_name() {
58647 assert_roundtrip("INSERT INTO x BY NAME SELECT 1 AS y");
58648 }
58649
58650 #[test]
58651 fn test_insert_default_values_returning() {
58652 assert_roundtrip("INSERT INTO t DEFAULT VALUES RETURNING (c1)");
58653 }
58654
58655 #[test]
58656 fn test_union_all_by_name() {
58657 assert_roundtrip("SELECT 1 AS x UNION ALL BY NAME SELECT 2 AS x");
58658 }
58659
58660 #[test]
58661 fn test_minus_as_except() {
58662 assert_roundtrip_expected(
58664 "SELECT foo, bar FROM table_1 MINUS SELECT foo, bar FROM table_2",
58665 "SELECT foo, bar FROM table_1 EXCEPT SELECT foo, bar FROM table_2",
58666 );
58667 }
58668
58669 #[test]
58670 fn test_filter_without_where() {
58671 assert_roundtrip_expected(
58672 "SELECT SUM(x) FILTER (x = 1)",
58673 "SELECT SUM(x) FILTER(WHERE x = 1)",
58674 );
58675 }
58676
58677 #[test]
58678 fn test_comment_on_materialized_view() {
58679 assert_roundtrip("COMMENT ON MATERIALIZED VIEW my_view IS 'this'");
58680 }
58681
58682 #[test]
58683 fn test_create_index_concurrently() {
58684 assert_roundtrip("CREATE INDEX CONCURRENTLY idx ON t(c)");
58685 }
58686
58687 #[test]
58688 fn test_create_index_if_not_exists() {
58689 assert_roundtrip("CREATE INDEX IF NOT EXISTS idx ON t(c)");
58690 }
58691
58692 #[test]
58693 fn test_alter_table_partition_hive() {
58694 assert_roundtrip("ALTER TABLE x PARTITION(y = z) ADD COLUMN a VARCHAR(10)");
58696 }
58697
58698 #[test]
58699 fn test_alter_table_change_column_hive() {
58700 assert_roundtrip("ALTER TABLE x CHANGE COLUMN a a VARCHAR(10)");
58702 }
58703
58704 #[test]
58705 fn test_alter_table_add_columns_hive() {
58706 assert_roundtrip("ALTER TABLE X ADD COLUMNS (y INT, z STRING)");
58708 }
58709
58710 #[test]
58711 fn test_alter_table_add_columns_cascade_hive() {
58712 assert_roundtrip("ALTER TABLE X ADD COLUMNS (y INT, z STRING) CASCADE");
58714 }
58715
58716 #[test]
58717 fn test_group_by_with_cube() {
58718 let sql = "SELECT key, value FROM T1 GROUP BY key, value WITH CUBE";
58720 let result = Parser::parse_sql(sql).unwrap();
58721 let select = result[0].as_select().unwrap();
58722
58723 if let Some(group_by) = &select.group_by {
58724 eprintln!("GROUP BY expressions: {:?}", group_by.expressions);
58726
58727 let has_cube = group_by.expressions.iter().any(|e| {
58729 if let Expression::Cube(c) = e {
58730 c.expressions.is_empty()
58731 } else {
58732 false
58733 }
58734 });
58735 assert!(
58736 has_cube,
58737 "Should have a Cube expression with empty expressions in GROUP BY"
58738 );
58739 } else {
58740 panic!("Should have GROUP BY clause");
58741 }
58742 }
58743
58744 #[test]
58745 fn test_group_by_with_rollup() {
58746 let sql = "SELECT key, value FROM T1 GROUP BY key, value WITH ROLLUP";
58748 let result = Parser::parse_sql(sql).unwrap();
58749 let select = result[0].as_select().unwrap();
58750
58751 if let Some(group_by) = &select.group_by {
58752 let has_rollup = group_by.expressions.iter().any(|e| {
58754 if let Expression::Rollup(r) = e {
58755 r.expressions.is_empty()
58756 } else {
58757 false
58758 }
58759 });
58760 assert!(
58761 has_rollup,
58762 "Should have a Rollup expression with empty expressions in GROUP BY"
58763 );
58764 } else {
58765 panic!("Should have GROUP BY clause");
58766 }
58767 }
58768
58769 #[test]
58770 fn test_opendatasource_dot_access() {
58771 use crate::dialects::DialectType;
58772 use crate::transpile;
58773
58774 let sql =
58776 "SELECT * FROM OPENDATASOURCE('SQLNCLI', 'Data Source=remote;').Catalog.dbo.Products";
58777 let result = transpile(sql, DialectType::TSQL, DialectType::TSQL).unwrap();
58778 assert_eq!(result[0], sql);
58779
58780 let sql2 = "SELECT * FROM OPENDATASOURCE('SQLNCLI', 'x').schema1.table1";
58782 let result2 = transpile(sql2, DialectType::TSQL, DialectType::TSQL).unwrap();
58783 assert_eq!(result2[0], sql2);
58784
58785 let sql3 = "SELECT * FROM OPENDATASOURCE('SQLNCLI', 'x').table1";
58787 let result3 = transpile(sql3, DialectType::TSQL, DialectType::TSQL).unwrap();
58788 assert_eq!(result3[0], sql3);
58789
58790 let sql4 = "SELECT * FROM OPENDATASOURCE('SQLNCLI', 'x')";
58792 let result4 = transpile(sql4, DialectType::TSQL, DialectType::TSQL).unwrap();
58793 assert_eq!(result4[0], sql4);
58794 }
58795
58796 #[test]
58797 fn test_exec_output_param() {
58798 use crate::dialects::DialectType;
58799 use crate::transpile;
58800
58801 let sql = "EXECUTE sp_CountOrders @region = 'US', @total = @count OUTPUT";
58803 let result = transpile(sql, DialectType::TSQL, DialectType::TSQL);
58804 assert!(
58805 result.is_ok(),
58806 "OUTPUT param should parse: {:?}",
58807 result.err()
58808 );
58809 assert_eq!(result.unwrap()[0], sql);
58810
58811 let sql2 = "EXEC sp_GetReport WITH RESULT SETS ((id INT, name NVARCHAR(100)))";
58813 let result2 = Parser::parse_sql(sql2);
58814 assert!(
58815 result2.is_ok(),
58816 "RESULT SETS should parse: {:?}",
58817 result2.err()
58818 );
58819
58820 let sql3 = "EXECUTE (@sql)";
58822 let result3 = transpile(sql3, DialectType::TSQL, DialectType::TSQL);
58823 assert!(
58824 result3.is_ok(),
58825 "Dynamic SQL should parse: {:?}",
58826 result3.err()
58827 );
58828 }
58829}
58830
58831#[cfg(test)]
58832mod join_marker_tests {
58833 use super::*;
58834 use crate::dialects::DialectType;
58835
58836 #[test]
58837 fn test_oracle_join_marker_simple() {
58838 let sql = "select a.baz from a where a.baz = b.baz (+)";
58839 let result = Parser::parse_sql(sql);
58840 println!("Result: {:?}", result);
58841 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58842 }
58843
58844 #[test]
58845 fn test_oracle_join_marker_with_comma_join_and_aliases() {
58846 let sql = "SELECT e1.x, e2.x FROM e e1, e e2 WHERE e1.y = e2.y (+)";
58847 let result = crate::dialects::Dialect::get(DialectType::Oracle).parse(sql);
58848 println!("Result: {:?}", result);
58849 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58850 }
58851
58852 #[test]
58853 fn test_oracle_xmltable_with_quoted_dot_columns() {
58854 let sql = "SELECT warehouse_name warehouse,\n warehouse2.\"Water\", warehouse2.\"Rail\"\n FROM warehouses,\n XMLTABLE('/Warehouse'\n PASSING warehouses.warehouse_spec\n COLUMNS\n \"Water\" varchar2(6) PATH 'WaterAccess',\n \"Rail\" varchar2(6) PATH 'RailAccess')\n warehouse2";
58855 let result = crate::dialects::Dialect::get(DialectType::Oracle).parse(sql);
58856 println!("Result: {:?}", result);
58857 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58858 }
58859
58860 #[test]
58861 fn test_optimize_table_mysql() {
58862 use crate::dialects::DialectType;
58863 use crate::transpile;
58864
58865 let sql1 = "TRUNCATE TABLE session_logs";
58867 let r1 = transpile(sql1, DialectType::MySQL, DialectType::MySQL);
58868 assert!(r1.is_ok(), "TRUNCATE should parse: {:?}", r1.err());
58869
58870 let sql2 = "OPTIMIZE TABLE temp_exports";
58871 let r2 = transpile(sql2, DialectType::MySQL, DialectType::MySQL);
58872 assert!(r2.is_ok(), "OPTIMIZE should parse: {:?}", r2.err());
58873 assert_eq!(r2.unwrap()[0], sql2);
58874 }
58875
58876 #[test]
58877 fn test_mysql_index_hints() {
58878 use crate::dialects::DialectType;
58879 use crate::transpile;
58880
58881 let sql1 = "SELECT * FROM t e USE INDEX (idx1) WHERE a = 1";
58883 let r1 = transpile(sql1, DialectType::MySQL, DialectType::MySQL);
58884 assert!(r1.is_ok(), "USE INDEX with alias: {:?}", r1.err());
58885
58886 let sql2 = "SELECT * FROM t1 JOIN t2 IGNORE INDEX (PRIMARY) ON t1.id = t2.id";
58888 let r2 = transpile(sql2, DialectType::MySQL, DialectType::MySQL);
58889 assert!(r2.is_ok(), "IGNORE INDEX PRIMARY: {:?}", r2.err());
58890
58891 let sql3 = "SELECT e.name, d.department_name FROM employees e USE INDEX (idx_dept, idx_salary) JOIN departments d IGNORE INDEX (PRIMARY) ON e.department_id = d.department_id WHERE e.salary > 60000";
58893 let r3 = transpile(sql3, DialectType::MySQL, DialectType::MySQL);
58894 assert!(r3.is_ok(), "Full example: {:?}", r3.err());
58895 }
58896
58897 #[test]
58898 fn test_oracle_quoted_dot_projection() {
58899 let sql = "SELECT warehouse2.\"Water\", warehouse2.\"Rail\" FROM warehouses warehouse2";
58900 let result = crate::dialects::Dialect::get(DialectType::Oracle).parse(sql);
58901 println!("Result: {:?}", result);
58902 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58903 }
58904
58905 #[test]
58906 fn test_oracle_xmltable_columns_only() {
58907 let sql = "SELECT * FROM XMLTABLE('/Warehouse' PASSING warehouses.warehouse_spec COLUMNS \"Water\" varchar2(6) PATH 'WaterAccess', \"Rail\" varchar2(6) PATH 'RailAccess') warehouse2";
58908 let result = crate::dialects::Dialect::get(DialectType::Oracle).parse(sql);
58909 println!("Result: {:?}", result);
58910 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58911 }
58912
58913 #[test]
58914 fn test_spark_limit() {
58915 use crate::dialects::DialectType;
58916 use crate::transpile;
58917
58918 let sql = "SELECT * FROM something LIMIT 100";
58920 let r = transpile(sql, DialectType::Spark, DialectType::Spark);
58921 assert!(r.is_ok(), "Spark LIMIT: {:?}", r.err());
58922 assert_eq!(r.unwrap()[0], sql);
58923
58924 let r2 = transpile(sql, DialectType::Hive, DialectType::Hive);
58926 assert!(r2.is_ok(), "Hive LIMIT: {:?}", r2.err());
58927 }
58928
58929 #[test]
58930 fn test_oracle_projection_alias_then_quoted_dot() {
58931 let sql =
58932 "SELECT warehouse_name warehouse, warehouse2.\"Water\" FROM warehouses warehouse2";
58933 let result = crate::dialects::Dialect::get(DialectType::Oracle).parse(sql);
58934 println!("Result: {:?}", result);
58935 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58936 }
58937}
58938
58939#[cfg(test)]
58940mod clickhouse_parser_regression_tests {
58941 use crate::dialects::DialectType;
58942
58943 #[test]
58944 fn test_clickhouse_select_format_clause_not_alias() {
58945 let sql = "SELECT 1 FORMAT TabSeparated";
58946 let result = crate::dialects::Dialect::get(DialectType::ClickHouse).parse(sql);
58947 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58948 }
58949
58950 #[test]
58951 fn test_clickhouse_projection_select_group_by_parses() {
58952 let sql = "CREATE TABLE t (a String, b String, c UInt64, PROJECTION p1 (SELECT a, sum(c) GROUP BY a, b), PROJECTION p2 (SELECT b, sum(c) GROUP BY b)) ENGINE=MergeTree()";
58953 let result = crate::dialects::Dialect::get(DialectType::ClickHouse).parse(sql);
58954 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58955 }
58956
58957 #[test]
58962 fn test_clickhouse_ternary_ast_structure() {
58963 use crate::expressions::Expression;
58964
58965 let result = crate::parse_one("x ? (y ? 1 : 2) : 3", DialectType::ClickHouse);
58966 assert!(result.is_ok(), "Parse error: {:?}", result.err());
58967 let ternary = result.unwrap();
58968
58969 let if_func = match &ternary {
58971 Expression::IfFunc(f) => f,
58972 other => panic!("Expected IfFunc, got {:?}", std::mem::discriminant(other)),
58973 };
58974
58975 assert!(
58977 matches!(&if_func.condition, Expression::Column(_)),
58978 "Expected condition to be Column, got {:?}",
58979 std::mem::discriminant(&if_func.condition)
58980 );
58981
58982 assert!(
58984 matches!(&if_func.true_value, Expression::Paren(_)),
58985 "Expected true_value to be Paren, got {:?}",
58986 std::mem::discriminant(&if_func.true_value)
58987 );
58988
58989 let false_value = if_func.false_value.as_ref().expect("Expected false_value");
58991 assert!(
58992 matches!(false_value, Expression::Literal(_)),
58993 "Expected false_value to be Literal, got {:?}",
58994 std::mem::discriminant(false_value)
58995 );
58996
58997 let inner_paren = match &if_func.true_value {
58999 Expression::Paren(p) => p,
59000 _ => unreachable!(),
59001 };
59002 let nested_if = match &inner_paren.this {
59003 Expression::IfFunc(f) => f,
59004 other => panic!(
59005 "Expected nested IfFunc, got {:?}",
59006 std::mem::discriminant(other)
59007 ),
59008 };
59009
59010 assert!(
59012 matches!(&nested_if.condition, Expression::Column(_)),
59013 "Expected nested condition to be Column, got {:?}",
59014 std::mem::discriminant(&nested_if.condition)
59015 );
59016
59017 assert!(
59019 matches!(&nested_if.true_value, Expression::Literal(_)),
59020 "Expected nested true_value to be Literal, got {:?}",
59021 std::mem::discriminant(&nested_if.true_value)
59022 );
59023
59024 let nested_false = nested_if
59026 .false_value
59027 .as_ref()
59028 .expect("Expected nested false_value");
59029 assert!(
59030 matches!(nested_false, Expression::Literal(_)),
59031 "Expected nested false_value to be Literal, got {:?}",
59032 std::mem::discriminant(nested_false)
59033 );
59034 }
59035
59036 #[test]
59040 fn test_clickhouse_ternary_and_precedence() {
59041 use crate::expressions::Expression;
59042
59043 let result = crate::parse_one("a and b ? 1 : 2", DialectType::ClickHouse);
59044 assert!(result.is_ok(), "Parse error: {:?}", result.err());
59045 let ternary = result.unwrap();
59046
59047 let if_func = match &ternary {
59048 Expression::IfFunc(f) => f,
59049 other => panic!("Expected IfFunc, got {:?}", std::mem::discriminant(other)),
59050 };
59051
59052 assert!(
59054 matches!(&if_func.condition, Expression::And(_)),
59055 "Expected condition to be And, got {:?}",
59056 std::mem::discriminant(&if_func.condition)
59057 );
59058 }
59059
59060 #[test]
59061 fn test_parse_interval_bare_number_duckdb() {
59062 use crate::dialects::{Dialect, DialectType};
59063 let sql = "SELECT CAST('2018-01-01 00:00:00' AS DATE) + INTERVAL 3 DAY";
59064 let d = Dialect::get(DialectType::DuckDB);
59065 match d.parse(sql) {
59066 Ok(result) => {
59067 assert!(!result.is_empty(), "Should parse to at least one statement");
59068 let output_duckdb = d.transpile_to(sql, DialectType::DuckDB).unwrap();
59070 assert_eq!(
59071 output_duckdb[0],
59072 "SELECT CAST('2018-01-01 00:00:00' AS DATE) + INTERVAL '3' DAY",
59073 "DuckDB output should have quoted interval value"
59074 );
59075 let output_hive = d.transpile_to(sql, DialectType::Hive).unwrap();
59077 assert_eq!(
59078 output_hive[0], "SELECT CAST('2018-01-01 00:00:00' AS DATE) + INTERVAL '3' DAY",
59079 "Hive output should have quoted interval value"
59080 );
59081 }
59082 Err(e) => panic!("Failed to parse DuckDB INTERVAL 3 DAY: {}", e),
59083 }
59084 }
59085}