1use std::collections::HashMap;
2use std::vec;
3
4use gitql_ast::expression::ArithmeticExpr;
5use gitql_ast::expression::ArrayExpr;
6use gitql_ast::expression::AssignmentExpr;
7use gitql_ast::expression::BetweenExpr;
8use gitql_ast::expression::BitwiseExpr;
9use gitql_ast::expression::*;
10use gitql_ast::operator::ArithmeticOperator;
11use gitql_ast::operator::BinaryBitwiseOperator;
12use gitql_ast::operator::BinaryLogicalOperator;
13use gitql_ast::operator::PrefixUnaryOperator;
14use gitql_ast::statement::*;
15use gitql_ast::types::any::AnyType;
16use gitql_ast::types::array::ArrayType;
17use gitql_ast::types::boolean::BoolType;
18use gitql_ast::types::composite::CompositeType;
19use gitql_ast::types::undefined::UndefType;
20use gitql_ast::types::DataType;
21use gitql_core::environment::Environment;
22
23use crate::context::ParserContext;
24use crate::diagnostic::Diagnostic;
25use crate::parse_cast::parse_cast_call_expression;
26use crate::parse_cast::parse_cast_operator_expression;
27use crate::parse_comparisons::parse_comparison_expression;
28use crate::parse_function_call::parse_function_call_expression;
29use crate::parse_function_call::parse_over_window_definition;
30use crate::parse_interval::parse_interval_expression;
31use crate::token::SourceLocation;
32use crate::token::Token;
33use crate::token::TokenKind;
34use crate::type_checker::check_all_values_are_same_type;
35use crate::type_checker::type_check_and_classify_selected_fields;
36use crate::type_checker::type_check_projection_symbols;
37
38pub fn parse_gql(tokens: Vec<Token>, env: &mut Environment) -> Result<Vec<Query>, Box<Diagnostic>> {
39 let mut queries: Vec<Query> = vec![];
40 let mut position = 0;
41
42 while position < tokens.len() {
43 env.clear_session();
44
45 let query = match &tokens[position].kind {
46 TokenKind::Do => parse_do_query(env, &tokens, &mut position),
47 TokenKind::Set => parse_set_query(env, &tokens, &mut position),
48 TokenKind::Select => parse_select_query(env, &tokens, &mut position),
49 TokenKind::Describe => parse_describe_query(env, &tokens, &mut position),
50 TokenKind::Show => parse_show_query(&tokens, &mut position),
51 _ => Err(un_expected_statement_error(&tokens, &mut position)),
52 }?;
53
54 if let Some(last_token) = tokens.get(position) {
56 if last_token.kind == TokenKind::Semicolon {
57 position += 1;
58 }
59 }
60
61 queries.push(query);
62 }
63
64 if position < tokens.len() {
66 return Err(un_expected_content_after_correct_statement(
67 &tokens[0].to_string(),
68 &tokens,
69 &mut position,
70 ));
71 }
72
73 Ok(queries)
74}
75
76fn parse_do_query(
77 env: &mut Environment,
78 tokens: &[Token],
79 position: &mut usize,
80) -> Result<Query, Box<Diagnostic>> {
81 *position += 1;
83
84 if *position >= tokens.len() {
85 return Err(
86 Diagnostic::error("Expect expression after Do Statement keyword")
87 .with_location(calculate_safe_location(tokens, *position - 1))
88 .as_boxed(),
89 );
90 }
91
92 let mut context = ParserContext::default();
93 let expression = parse_expression(&mut context, env, tokens, position)?;
94 Ok(Query::Do(DoStatement { expression }))
95}
96
97fn parse_set_query(
98 env: &mut Environment,
99 tokens: &[Token],
100 position: &mut usize,
101) -> Result<Query, Box<Diagnostic>> {
102 let len = tokens.len();
103 let mut context = ParserContext::default();
104
105 *position += 1;
107
108 if !is_current_token_with_condition(tokens, position, |token| {
109 matches!(token.kind, TokenKind::GlobalVariable(_))
110 }) {
111 return Err(Diagnostic::error(
112 "Expect Global variable name start with `@` after `SET` keyword",
113 )
114 .with_location(calculate_safe_location(tokens, *position - 1))
115 .as_boxed());
116 }
117
118 let name = &tokens[*position].to_string();
119
120 *position += 1;
122
123 if *position >= len || !is_assignment_operator(&tokens[*position]) {
124 return Err(
125 Diagnostic::error("Expect `=` or `:=` and Value after Variable name")
126 .with_location(calculate_safe_location(tokens, *position - 1))
127 .as_boxed(),
128 );
129 }
130
131 *position += 1;
133
134 let aggregations_count_before = context.aggregations.len();
135 let value = parse_expression(&mut context, env, tokens, position)?;
136 let has_aggregations = context.aggregations.len() != aggregations_count_before;
137
138 if has_aggregations {
140 return Err(
141 Diagnostic::error("Aggregation value can't be assigned to global variable")
142 .with_location(calculate_safe_location(tokens, *position - 1))
143 .as_boxed(),
144 );
145 }
146
147 env.define_global(name.to_string(), value.expr_type());
148
149 Ok(Query::GlobalVariableDeclaration(GlobalVariableStatement {
150 name: name.to_string(),
151 value,
152 }))
153}
154
155fn parse_describe_query(
156 env: &mut Environment,
157 tokens: &[Token],
158 position: &mut usize,
159) -> Result<Query, Box<Diagnostic>> {
160 *position += 1;
162
163 if *position >= tokens.len() || !matches!(tokens[*position].kind, TokenKind::Symbol(_)) {
164 return Err(
165 Diagnostic::error("Expect table name after DESCRIBE Statement")
166 .with_location(calculate_safe_location(tokens, *position))
167 .as_boxed(),
168 );
169 }
170
171 let table_name = tokens[*position].to_string();
173 if !env
174 .schema
175 .tables_fields_names
176 .contains_key(table_name.as_str())
177 {
178 return Err(
179 Diagnostic::error(&format!("Unresolved table name `{}`", table_name))
180 .add_help("You can use the `SHOW TABLES` query to get list of current tables")
181 .add_help("Check the documentations to see available tables")
182 .with_location(calculate_safe_location(tokens, *position))
183 .as_boxed(),
184 );
185 }
186
187 *position += 1;
189
190 Ok(Query::Describe(DescribeStatement { table_name }))
191}
192
193fn parse_show_query(tokens: &[Token], position: &mut usize) -> Result<Query, Box<Diagnostic>> {
194 *position += 1;
196
197 if *position >= tokens.len() || tokens[*position].to_string() != "tables" {
198 return Err(
199 Diagnostic::error("Show can not be followed by names other than tables")
200 .add_help("A correct statement will be `SHOW TABLES`")
201 .with_location(calculate_safe_location(tokens, *position - 1))
202 .as_boxed(),
203 );
204 }
205
206 *position += 1;
207 Ok(Query::ShowTables)
208}
209
210fn parse_select_query(
211 env: &mut Environment,
212 tokens: &[Token],
213 position: &mut usize,
214) -> Result<Query, Box<Diagnostic>> {
215 let len = tokens.len();
216
217 let mut context = ParserContext::default();
218 let mut statements: HashMap<&'static str, Box<dyn Statement>> = HashMap::new();
219
220 while *position < len {
221 let token = &tokens[*position];
222
223 match &token.kind {
224 TokenKind::Select => {
225 if statements.contains_key("select") {
226 return Err(Diagnostic::error("You already used `SELECT` statement")
227 .add_note("Can't use more than one `SELECT` statement in the same query")
228 .add_help("If you have more than one query, end each one with `;`")
229 .with_location(token.location)
230 .as_boxed());
231 }
232 let statement = parse_select_statement(&mut context, env, tokens, position)?;
233 statements.insert("select", statement);
234 context.is_single_value_query = !context.aggregations.is_empty();
235 context.has_select_statement = true;
236 }
237 TokenKind::Where => {
238 if statements.contains_key("where") {
239 return Err(Diagnostic::error("You already used `WHERE` statement")
240 .add_note("Can't use more than one `WHERE` statement in the same query")
241 .with_location(token.location)
242 .as_boxed());
243 }
244
245 let statement = parse_where_statement(&mut context, env, tokens, position)?;
246 statements.insert("where", statement);
247 }
248 TokenKind::Group => {
249 if statements.contains_key("group") {
250 return Err(Diagnostic::error("`You already used `GROUP BY` statement")
251 .add_note("Can't use more than one `GROUP BY` statement in the same query")
252 .with_location(token.location)
253 .as_boxed());
254 }
255
256 let statement = parse_group_by_statement(&mut context, env, tokens, position)?;
257 statements.insert("group", statement);
258 }
259 TokenKind::Having => {
260 if statements.contains_key("having") {
261 return Err(Diagnostic::error("You already used `HAVING` statement")
262 .add_note("Can't use more than one `HAVING` statement in the same query")
263 .with_location(token.location)
264 .as_boxed());
265 }
266
267 if !statements.contains_key("group") {
268 return Err(Diagnostic::error(
269 "`HAVING` must be used after `GROUP BY` statement",
270 )
271 .add_note(
272 "`HAVING` statement must be used in a query that has `GROUP BY` statement",
273 )
274 .with_location(token.location)
275 .as_boxed());
276 }
277
278 let statement = parse_having_statement(&mut context, env, tokens, position)?;
279 statements.insert("having", statement);
280 }
281 TokenKind::Limit => {
282 if statements.contains_key("limit") {
283 return Err(Diagnostic::error("You already used `LIMIT` statement")
284 .add_note("Can't use more than one `LIMIT` statement in the same query")
285 .with_location(token.location)
286 .as_boxed());
287 }
288
289 let statement = parse_limit_statement(tokens, position)?;
290 statements.insert("limit", statement);
291
292 if is_current_token(tokens, position, TokenKind::Comma) {
294 if statements.contains_key("offset") {
296 return Err(Diagnostic::error("You already used `OFFSET` statement")
297 .add_note(
298 "Can't use more than one `OFFSET` statement in the same query",
299 )
300 .with_location(token.location)
301 .as_boxed());
302 }
303
304 *position += 1;
306
307 if *position >= len || !matches!(tokens[*position].kind, TokenKind::Integer(_))
308 {
309 return Err(Diagnostic::error(
310 "Expects `OFFSET` amount as Integer value after `,`",
311 )
312 .add_help("Try to add constant Integer after comma")
313 .add_note("`OFFSET` value must be a constant Integer")
314 .with_location(token.location)
315 .as_boxed());
316 }
317
318 match tokens[*position].kind {
319 TokenKind::Integer(integer) => {
320 *position += 1;
322
323 if integer < 0 {
324 return Err(Diagnostic::error(
325 "Expect positive number after `OFFSET` keyword",
326 )
327 .with_location(calculate_safe_location(tokens, *position - 1))
328 .as_boxed());
329 }
330
331 let count = integer as usize;
332 statements.insert("offset", Box::new(OffsetStatement { count }));
333 }
334 _ => {
335 return Err(Diagnostic::error("`OFFSET` integer value is invalid")
336 .add_help(&format!(
337 "`OFFSET` value must be between 0 and {}",
338 usize::MAX
339 ))
340 .with_location(token.location)
341 .as_boxed())
342 }
343 }
344 }
345 }
346 TokenKind::Offset => {
347 if statements.contains_key("offset") {
348 return Err(Diagnostic::error("You already used `OFFSET` statement")
349 .add_note("Can't use more than one `OFFSET` statement in the same query")
350 .with_location(token.location)
351 .as_boxed());
352 }
353
354 let statement = parse_offset_statement(tokens, position)?;
355 statements.insert("offset", statement);
356 }
357 TokenKind::Order => {
358 if statements.contains_key("order") {
359 return Err(Diagnostic::error("You already used `ORDER BY` statement")
360 .add_note("Can't use more than one `ORDER BY` statement in the same query")
361 .with_location(token.location)
362 .as_boxed());
363 }
364
365 let statement = parse_order_by_statement(&mut context, env, tokens, position)?;
366 statements.insert("order", statement);
367 }
368 TokenKind::Into => {
369 if statements.contains_key("into") {
370 return Err(Diagnostic::error("You already used `INTO` statement")
371 .add_note("Can't use more than one `INTO` statement in the same query")
372 .with_location(token.location)
373 .as_boxed());
374 }
375 let statement = parse_into_statement(tokens, position)?;
376 statements.insert("into", statement);
377 }
378 TokenKind::Window => {
379 parse_window_named_over_clause(&mut context, env, tokens, position)?;
380 continue;
381 }
382 _ => break,
383 }
384 }
385
386 if !context.aggregations.is_empty() {
388 let aggregation_functions = AggregationsStatement {
389 aggregations: context.aggregations,
390 };
391 statements.insert("aggregation", Box::new(aggregation_functions));
392 }
393
394 if !context.window_functions.is_empty() {
396 for (_, window_value) in context.window_functions.iter_mut() {
401 if let WindowValue::Function(function) = window_value {
402 if let Some(window_name) = &function.window_definition.name {
403 if !context.named_window_clauses.contains_key(window_name) {
404 return Err(Diagnostic::error(&format!(
405 "Can't resolve `WINDOW Definition` with name {}",
406 window_name
407 ))
408 .add_note("Make sure you already defined window over clause with this name")
409 .as_boxed());
410 }
411
412 function.window_definition = context.named_window_clauses[window_name].clone();
413 }
414 }
415 }
416
417 statements.insert(
418 "window_functions",
419 Box::new(WindowFunctionsStatement {
420 window_values: context.window_functions,
421 }),
422 );
423 }
424
425 let hidden_selections: Vec<String> = context
427 .hidden_selections
428 .iter()
429 .filter(|n| !context.selected_fields.contains(n))
430 .cloned()
431 .collect();
432
433 type_check_projection_symbols(
434 env,
435 &context.selected_tables,
436 &context.projection_names,
437 &context.projection_locations,
438 )?;
439
440 let hidden_selection_per_table =
441 classify_hidden_selection(env, &context.selected_tables, &hidden_selections);
442
443 Ok(Query::Select(GQLQuery {
444 statements,
445 has_aggregation_function: context.is_single_value_query,
446 has_group_by_statement: context.has_group_by_statement,
447 hidden_selections: hidden_selection_per_table,
448 alias_table: context.name_alias_table,
449 }))
450}
451
452fn classify_hidden_selection(
454 env: &mut Environment,
455 tables: &[String],
456 hidden_selections: &[String],
457) -> HashMap<String, Vec<String>> {
458 let mut table_hidden_selections: HashMap<String, Vec<String>> = HashMap::new();
459 for table in tables {
460 table_hidden_selections.insert(table.to_string(), vec![]);
461 }
462
463 for hidden_selection in hidden_selections {
464 let mut is_resolved = false;
465 for table in tables {
466 let table_columns = env.schema.tables_fields_names.get(table.as_str()).unwrap();
467 if table_columns.contains(&hidden_selection.as_str()) {
468 let hidden_selection_for_table = table_hidden_selections.get_mut(table).unwrap();
469 if !hidden_selection_for_table.contains(hidden_selection) {
470 hidden_selection_for_table.push(hidden_selection.to_string());
471 }
472 is_resolved = true;
474 break;
475 }
476 }
477
478 if !is_resolved && !table_hidden_selections.is_empty() {
480 table_hidden_selections
481 .get_mut(&tables[0])
482 .unwrap()
483 .push(hidden_selection.to_string());
484 }
485 }
486
487 table_hidden_selections
488}
489
490fn parse_select_statement(
491 context: &mut ParserContext,
492 env: &mut Environment,
493 tokens: &[Token],
494 position: &mut usize,
495) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
496 *position += 1;
498
499 if *position >= tokens.len() {
500 return Err(Diagnostic::error("Incomplete input for select statement")
501 .add_help("Try select one or more values in the `SELECT` statement")
502 .add_note("Select statements requires at least selecting one value")
503 .with_location(calculate_safe_location(tokens, *position - 1))
504 .as_boxed());
505 }
506
507 let distinct = parse_select_distinct_option(context, tokens, position)?;
509
510 let mut fields_names: Vec<String> = vec![];
512 let mut selected_expr_titles: Vec<String> = vec![];
513 let mut selected_expr: Vec<Box<dyn Expr>> = vec![];
514 let mut is_select_all = false;
515
516 context.inside_selections = true;
517 parse_select_all_or_expressions(
518 context,
519 env,
520 tokens,
521 position,
522 &mut fields_names,
523 &mut selected_expr_titles,
524 &mut selected_expr,
525 &mut is_select_all,
526 )?;
527 context.inside_selections = false;
528
529 let mut joins: Vec<Join> = vec![];
531 let mut tables_to_select_from: Vec<String> = vec![];
532 parse_from_option(
533 context,
534 env,
535 &mut tables_to_select_from,
536 &mut joins,
537 tokens,
538 position,
539 )?;
540
541 if tables_to_select_from.is_empty() && !context.aggregations.is_empty() {
543 return Err(
544 Diagnostic::error("Aggregations functions should be used only with tables")
545 .add_note("Try to select from one of the available tables in current schema")
546 .with_location(calculate_safe_location(tokens, *position))
547 .as_boxed(),
548 );
549 }
550
551 if is_select_all && tables_to_select_from.is_empty() {
553 return Err(
554 Diagnostic::error("Expect `FROM` and table name after `SELECT *`")
555 .add_help("Select all must be used with valid table name")
556 .with_location(calculate_safe_location(tokens, *position))
557 .as_boxed(),
558 );
559 }
560
561 if !is_select_all && fields_names.is_empty() {
563 return Err(Diagnostic::error("Incomplete input for select statement")
564 .add_help("Try select one or more values in the `SELECT` statement")
565 .add_note("Select statements requires at least selecting one value")
566 .with_location(calculate_safe_location(tokens, *position - 1))
567 .as_boxed());
568 }
569
570 if is_select_all {
572 select_all_table_fields(
573 env,
574 &tables_to_select_from,
575 &mut context.selected_fields,
576 &mut fields_names,
577 );
578 }
579
580 let table_selections = type_check_and_classify_selected_fields(
582 env,
583 &tables_to_select_from,
584 &fields_names,
585 calculate_safe_location(tokens, *position),
586 )?;
587
588 Ok(Box::new(SelectStatement {
589 table_selections,
590 joins,
591 selected_expr_titles,
592 selected_expr,
593 distinct,
594 }))
595}
596
597fn parse_select_distinct_option(
598 context: &mut ParserContext,
599 tokens: &[Token],
600 position: &mut usize,
601) -> Result<Distinct, Box<Diagnostic>> {
602 if is_current_token(tokens, position, TokenKind::Distinct) {
603 *position += 1;
605
606 if is_current_token(tokens, position, TokenKind::On) {
607 *position += 1;
609
610 if !is_current_token(tokens, position, TokenKind::LeftParen) {
611 return Err(Diagnostic::error("Expect `(` after `DISTINCT ON`")
612 .add_help("Try to add `(` after ON and before fields")
613 .with_location(calculate_safe_location(tokens, *position))
614 .as_boxed());
615 }
616
617 *position += 1;
619
620 let mut distinct_fields: Vec<String> = vec![];
621 while !is_current_token(tokens, position, TokenKind::RightParen) {
622 let field_token = &tokens[*position];
623 let literal = &field_token.to_string();
624 let location = field_token.location;
625
626 distinct_fields.push(literal.to_string());
627
628 context.hidden_selections.push(literal.to_string());
629 context.projection_names.push(literal.to_string());
630 context.projection_locations.push(location);
631
632 *position += 1;
634
635 if is_current_token(tokens, position, TokenKind::Comma) {
636 *position += 1;
638 } else {
639 break;
640 }
641 }
642
643 consume_token_or_error(
645 tokens,
646 position,
647 TokenKind::RightParen,
648 "Expect `)` after `DISTINCT ON fields`",
649 )?;
650
651 if distinct_fields.is_empty() {
653 return Err(Diagnostic::error(
654 "DISTINCT ON(...) must be used with one of more column",
655 )
656 .add_help("Try to add one or more columns from current table")
657 .with_location(calculate_safe_location(tokens, *position))
658 .as_boxed());
659 }
660
661 if is_current_token(tokens, position, TokenKind::Comma) {
663 return Err(
664 Diagnostic::error("No need to add Comma `,` after DISTINCT ON")
665 .add_help("Try to remove `,` after DISTINCT ON fields")
666 .with_location(calculate_safe_location(tokens, *position))
667 .as_boxed(),
668 );
669 }
670
671 return Ok(Distinct::DistinctOn(distinct_fields));
672 }
673 return Ok(Distinct::DistinctAll);
674 }
675
676 Ok(Distinct::None)
677}
678
679#[allow(clippy::too_many_arguments)]
680fn parse_select_all_or_expressions(
681 context: &mut ParserContext,
682 env: &mut Environment,
683 tokens: &[Token],
684 position: &mut usize,
685 fields_names: &mut Vec<String>,
686 selected_expr_titles: &mut Vec<String>,
687 selected_expr: &mut Vec<Box<dyn Expr>>,
688 is_select_all: &mut bool,
689) -> Result<(), Box<Diagnostic>> {
690 if is_current_token(tokens, position, TokenKind::Star) {
692 *position += 1;
694 *is_select_all = true;
695 return Ok(());
696 }
697
698 while !is_current_token(tokens, position, TokenKind::From) {
700 let expression = parse_expression(context, env, tokens, position)?;
701 let expr_type = expression.expr_type().clone();
702 let field_name = expression_literal(&expression)
703 .unwrap_or_else(|| context.name_generator.generate_column_name());
704
705 if fields_names.contains(&field_name) {
707 return Err(Diagnostic::error("Can't select the same field twice")
708 .with_location(calculate_safe_location(tokens, *position - 1))
709 .as_boxed());
710 }
711
712 if is_current_token(tokens, position, TokenKind::As) {
714 *position += 1;
716
717 let alias_name = consume_conditional_token_or_errors(
719 tokens,
720 position,
721 |token| matches!(token.kind, TokenKind::Symbol(_) | TokenKind::String(_)),
722 "Expect `Symbol` or `Text` as field alias name",
723 )?
724 .to_string();
725
726 if env
728 .schema
729 .tables_fields_types
730 .contains_key(alias_name.as_str())
731 {
732 return Err(Diagnostic::error("Can't use column name as Alias")
733 .add_note("Until supporting `table.column` you should use different alias name")
734 .with_location(tokens[*position - 1].location)
735 .as_boxed());
736 }
737
738 if field_name != alias_name {
741 if context.selected_fields.contains(&alias_name)
742 || context.name_alias_table.contains_key(&alias_name)
743 {
744 return Err(
745 Diagnostic::error("You already have field with the same name")
746 .add_help("Try to use a new unique name for alias")
747 .with_location(tokens[*position - 1].location)
748 .as_boxed(),
749 );
750 }
751
752 env.define(alias_name.to_string(), expr_type.clone());
754
755 context.selected_fields.push(alias_name.clone());
756 context
757 .name_alias_table
758 .insert(field_name.to_string(), alias_name.to_string());
759 }
760
761 selected_expr_titles.push(alias_name.to_owned());
762 } else {
763 selected_expr_titles.push(field_name.to_owned());
764 }
765
766 env.define(field_name.to_string(), expr_type);
768
769 fields_names.push(field_name.to_owned());
770 context.selected_fields.push(field_name.to_owned());
771
772 selected_expr.push(expression);
773
774 if is_current_token(tokens, position, TokenKind::Comma) {
776 *position += 1;
777 } else {
778 break;
779 }
780 }
781
782 Ok(())
783}
784
785fn parse_from_option(
786 context: &mut ParserContext,
787 env: &mut Environment,
788 tables_to_select_from: &mut Vec<String>,
789 joins: &mut Vec<Join>,
790 tokens: &[Token],
791 position: &mut usize,
792) -> Result<(), Box<Diagnostic>> {
793 if is_current_token(tokens, position, TokenKind::From) {
794 *position += 1;
796
797 let table_name = consume_conditional_token_or_errors(
799 tokens,
800 position,
801 |token| matches!(token.kind, TokenKind::Symbol(_)),
802 "Expect `Table` value after `FROM` keyword",
803 )?
804 .to_string();
805
806 if !env
807 .schema
808 .tables_fields_names
809 .contains_key(table_name.as_str())
810 {
811 return Err(Diagnostic::error("Unresolved table name")
812 .add_help("You can use the `SHOW TABLES` query to get list of current tables")
813 .add_help("Check the documentations to see available tables")
814 .with_location(tokens[*position - 1].location)
815 .as_boxed());
816 }
817
818 tables_to_select_from.push(table_name.to_string());
820 context.selected_tables.push(table_name.to_string());
821 register_current_table_fields_types(env, &table_name)?;
822
823 let mut number_previous_of_joins = 0;
825 while is_join_or_join_type_token(tokens, position) {
826 let join_token = &tokens[*position];
827
828 let mut join_kind = JoinKind::Default;
830 if join_token.kind != TokenKind::Join {
831 join_kind = match join_token.kind {
832 TokenKind::Left => JoinKind::Left,
833 TokenKind::Right => JoinKind::Right,
834 TokenKind::Cross => JoinKind::Cross,
835 TokenKind::Inner => JoinKind::Inner,
836 _ => JoinKind::Default,
837 };
838
839 *position += 1;
841
842 if is_current_token(tokens, position, TokenKind::Outer) {
844 if !matches!(join_kind, JoinKind::Left | JoinKind::Right) {
845 return Err(Diagnostic::error(
846 "`OUTER` keyword used with LEFT or RIGHT JOIN only",
847 )
848 .with_location(calculate_safe_location(tokens, *position))
849 .as_boxed());
850 }
851
852 *position += 1;
854 }
855
856 if *position >= tokens.len() || tokens[*position].kind != TokenKind::Join {
857 return Err(Diagnostic::error(
858 "Expect `JOIN` keyword after Cross, Left, Right, Inner",
859 )
860 .with_location(calculate_safe_location(tokens, *position))
861 .as_boxed());
862 }
863 }
864
865 let join_location = tokens[*position].location;
867 *position += 1;
868
869 if *position >= tokens.len() || !matches!(tokens[*position].kind, TokenKind::Symbol(_))
870 {
871 return Err(Diagnostic::error("Expect table name after `JOIN` keyword")
872 .with_location(calculate_safe_location(tokens, *position))
873 .as_boxed());
874 }
875
876 let other_table = &tokens[*position];
877 let other_table_name = &other_table.to_string();
878
879 if number_previous_of_joins == 0 && table_name.eq(other_table_name) {
881 return Err(Diagnostic::error(
882 "The two tables of join must be unique or have different alias",
883 )
884 .with_location(calculate_safe_location(tokens, *position))
885 .as_boxed());
886 }
887
888 tables_to_select_from.push(other_table_name.to_string());
889 context.selected_tables.push(other_table_name.to_string());
890 register_current_table_fields_types(env, other_table_name)?;
891
892 *position += 1;
894
895 let mut predicate: Option<Box<dyn Expr>> = None;
897 if is_current_token(tokens, position, TokenKind::On) {
898 *position += 1;
900 predicate = Some(parse_expression(context, env, tokens, position)?);
901 }
902
903 if predicate.is_none() && matches!(join_kind, JoinKind::Right | JoinKind::Left) {
905 return Err(Diagnostic::error(
906 "You must set predicate condition using `ON` Keyword for `LEFT` OR `RIGHT` JOINS",
907 )
908 .with_location(join_location)
909 .as_boxed());
910 }
911
912 let join_operand = if number_previous_of_joins == 0 {
913 JoinOperand::OuterAndInner(table_name.to_string(), other_table_name.to_string())
914 } else {
915 JoinOperand::Inner(other_table_name.to_string())
916 };
917
918 joins.push(Join {
919 operand: join_operand,
920 kind: join_kind,
921 predicate,
922 });
923
924 number_previous_of_joins += 1;
925 }
926 }
927 Ok(())
928}
929
930fn parse_where_statement(
931 context: &mut ParserContext,
932 env: &mut Environment,
933 tokens: &[Token],
934 position: &mut usize,
935) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
936 *position += 1;
937 if *position >= tokens.len() {
938 return Err(Diagnostic::error("Expect expression after `WHERE` keyword")
939 .add_help("Try to add boolean expression after `WHERE` keyword")
940 .add_note("`WHERE` statement expects expression as condition")
941 .with_location(calculate_safe_location(tokens, *position - 1))
942 .as_boxed());
943 }
944
945 let aggregations_count_before = context.aggregations.len();
946
947 let condition_location = tokens[*position].location;
949 let mut condition = parse_expression(context, env, tokens, position)?;
950
951 if !condition.expr_type().is_bool() {
953 let expected_type: Box<dyn DataType> = Box::new(BoolType);
954 if !expected_type.has_implicit_cast_from(&condition) {
955 return Err(Diagnostic::error(&format!(
956 "Expect `WHERE` condition to be type {} but got {}",
957 "Boolean",
958 condition.expr_type().literal()
959 ))
960 .add_note("`WHERE` statement condition must be Boolean")
961 .with_location(condition_location)
962 .as_boxed());
963 }
964
965 condition = Box::new(CastExpr {
967 value: condition,
968 result_type: expected_type.clone(),
969 })
970 }
971
972 let aggregations_count_after = context.aggregations.len();
973 if aggregations_count_before != aggregations_count_after {
974 return Err(
975 Diagnostic::error("Can't use Aggregation functions in `WHERE` statement")
976 .add_note("Aggregation functions must be used after `GROUP BY` statement")
977 .add_note("Aggregation functions evaluated after later after `GROUP BY` statement")
978 .with_location(condition_location)
979 .as_boxed(),
980 );
981 }
982
983 Ok(Box::new(WhereStatement { condition }))
984}
985
986fn parse_group_by_statement(
987 context: &mut ParserContext,
988 env: &mut Environment,
989 tokens: &[Token],
990 position: &mut usize,
991) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
992 *position += 1;
994
995 consume_token_or_error(
997 tokens,
998 position,
999 TokenKind::By,
1000 "Expect keyword `BY` after keyword `group`",
1001 )?;
1002
1003 let mut values: Vec<Box<dyn Expr>> = vec![];
1005 while *position < tokens.len() {
1006 values.push(parse_expression(context, env, tokens, position)?);
1007 if is_current_token(tokens, position, TokenKind::Comma) {
1008 *position += 1;
1010 continue;
1011 }
1012 break;
1013 }
1014
1015 let mut has_with_rollup = false;
1016 if is_current_token(tokens, position, TokenKind::With) {
1017 *position += 1;
1019
1020 consume_token_or_error(
1022 tokens,
1023 position,
1024 TokenKind::Rollup,
1025 "Expect keyword `ROLLUP` after keyword `with`",
1026 )?;
1027
1028 has_with_rollup = true;
1029 }
1030
1031 context.has_group_by_statement = true;
1032 Ok(Box::new(GroupByStatement {
1033 values,
1034 has_with_roll_up: has_with_rollup,
1035 }))
1036}
1037
1038fn parse_having_statement(
1039 context: &mut ParserContext,
1040 env: &mut Environment,
1041 tokens: &[Token],
1042 position: &mut usize,
1043) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
1044 context.inside_having = true;
1045
1046 *position += 1;
1048
1049 if *position >= tokens.len() {
1050 return Err(
1051 Diagnostic::error("Expect expression after `HAVING` keyword")
1052 .add_help("Try to add boolean expression after `HAVING` keyword")
1053 .add_note("`HAVING` statement expects expression as condition")
1054 .with_location(calculate_safe_location(tokens, *position - 1))
1055 .as_boxed(),
1056 );
1057 }
1058
1059 let condition_location = tokens[*position].location;
1061 let mut condition = parse_expression(context, env, tokens, position)?;
1062
1063 if !condition.expr_type().is_bool() {
1065 let expected_type: Box<dyn DataType> = Box::new(BoolType);
1066 if !expected_type.has_implicit_cast_from(&condition) {
1067 return Err(Diagnostic::error(&format!(
1068 "Expect `HAVING` condition to be type {} but got {}",
1069 "Boolean",
1070 condition.expr_type().literal()
1071 ))
1072 .add_note("`HAVING` statement condition must be Boolean")
1073 .with_location(condition_location)
1074 .as_boxed());
1075 }
1076
1077 condition = Box::new(CastExpr {
1079 value: condition,
1080 result_type: expected_type.clone(),
1081 })
1082 }
1083
1084 context.inside_having = false;
1085 Ok(Box::new(HavingStatement { condition }))
1086}
1087
1088fn parse_limit_statement(
1089 tokens: &[Token],
1090 position: &mut usize,
1091) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
1092 *position += 1;
1094
1095 if *position >= tokens.len() {
1096 return Err(Diagnostic::error("Expect number after `LIMIT` keyword")
1097 .with_location(calculate_safe_location(tokens, *position - 1))
1098 .as_boxed());
1099 }
1100
1101 match tokens[*position].kind {
1102 TokenKind::Integer(integer) => {
1103 *position += 1;
1105
1106 if integer < 0 {
1108 return Err(
1109 Diagnostic::error("Expect positive number after `LIMIT` keyword")
1110 .with_location(calculate_safe_location(tokens, *position - 1))
1111 .as_boxed(),
1112 );
1113 }
1114
1115 let count = integer as usize;
1116 Ok(Box::new(LimitStatement { count }))
1117 }
1118 _ => Err(Diagnostic::error("Expect number after `LIMIT` keyword")
1119 .with_location(calculate_safe_location(tokens, *position - 1))
1120 .as_boxed()),
1121 }
1122}
1123
1124fn parse_offset_statement(
1125 tokens: &[Token],
1126 position: &mut usize,
1127) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
1128 *position += 1;
1130
1131 if *position >= tokens.len() {
1132 return Err(Diagnostic::error("Expect number after `OFFSET` keyword")
1133 .with_location(calculate_safe_location(tokens, *position - 1))
1134 .as_boxed());
1135 }
1136
1137 match tokens[*position].kind {
1138 TokenKind::Integer(integer) => {
1139 *position += 1;
1141
1142 if integer < 0 {
1144 return Err(
1145 Diagnostic::error("Expect positive number after `OFFSET` keyword")
1146 .with_location(calculate_safe_location(tokens, *position - 1))
1147 .as_boxed(),
1148 );
1149 }
1150
1151 let count = integer as usize;
1152 Ok(Box::new(OffsetStatement { count }))
1153 }
1154 _ => Err(Diagnostic::error("Expect number after `OFFSET` keyword")
1155 .with_location(calculate_safe_location(tokens, *position - 1))
1156 .as_boxed()),
1157 }
1158}
1159
1160pub(crate) fn parse_order_by_statement(
1161 context: &mut ParserContext,
1162 env: &mut Environment,
1163 tokens: &[Token],
1164 position: &mut usize,
1165) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
1166 *position += 1;
1168
1169 context.inside_order_by = true;
1170
1171 consume_token_or_error(
1173 tokens,
1174 position,
1175 TokenKind::By,
1176 "Expect keyword `BY` after keyword `ORDER",
1177 )?;
1178
1179 let mut arguments: Vec<Box<dyn Expr>> = vec![];
1180 let mut sorting_orders: Vec<SortingOrder> = vec![];
1181 let mut null_ordering_policies: Vec<NullsOrderPolicy> = vec![];
1182
1183 loop {
1184 let argument = parse_expression(context, env, tokens, position)?;
1185 let sorting_order = parse_sorting_order(tokens, position)?;
1186 let null_ordering_policy = parse_order_by_nulls_policy(tokens, position, &sorting_order)?;
1187
1188 arguments.push(argument);
1189 sorting_orders.push(sorting_order);
1190 null_ordering_policies.push(null_ordering_policy);
1191
1192 if is_current_token(tokens, position, TokenKind::Comma) {
1193 *position += 1;
1195 } else {
1196 break;
1197 }
1198 }
1199
1200 context.inside_order_by = false;
1201
1202 Ok(Box::new(OrderByStatement {
1203 arguments,
1204 sorting_orders,
1205 nulls_order_policies: null_ordering_policies,
1206 }))
1207}
1208
1209fn parse_sorting_order(
1210 tokens: &[Token],
1211 position: &mut usize,
1212) -> Result<SortingOrder, Box<Diagnostic>> {
1213 let mut sorting_order = SortingOrder::Ascending;
1214 if *position >= tokens.len() {
1215 return Ok(sorting_order);
1216 }
1217
1218 if is_asc_or_desc(&tokens[*position]) {
1220 if tokens[*position].kind == TokenKind::Descending {
1221 sorting_order = SortingOrder::Descending;
1222 }
1223
1224 *position += 1;
1226 return Ok(sorting_order);
1227 }
1228
1229 if tokens[*position].kind == TokenKind::Using {
1231 *position += 1;
1233
1234 if *position < tokens.len() && is_order_by_using_operator(&tokens[*position]) {
1235 if tokens[*position].kind == TokenKind::Greater {
1236 sorting_order = SortingOrder::Descending;
1237 }
1238
1239 *position += 1;
1241 return Ok(sorting_order);
1242 }
1243
1244 return Err(Diagnostic::error("Expect `>` or `<` after `USING` keyword")
1245 .with_location(tokens[*position - 1].location)
1246 .as_boxed());
1247 }
1248
1249 Ok(sorting_order)
1251}
1252
1253fn parse_order_by_nulls_policy(
1254 tokens: &[Token],
1255 position: &mut usize,
1256 sorting_order: &SortingOrder,
1257) -> Result<NullsOrderPolicy, Box<Diagnostic>> {
1258 if is_current_token(tokens, position, TokenKind::Nulls) {
1260 *position += 1;
1262
1263 if is_current_token(tokens, position, TokenKind::First) {
1265 *position += 1;
1266 return Ok(NullsOrderPolicy::NullsFirst);
1267 }
1268
1269 if is_current_token(tokens, position, TokenKind::Last) {
1271 *position += 1;
1272 return Ok(NullsOrderPolicy::NullsLast);
1273 }
1274
1275 return Err(Diagnostic::error("Unexpected NULL ordering policy")
1276 .add_note("Null ordering policy must be `FIRST` or `LAST`")
1277 .add_help("Please use `NULL FIRST` or `NULL LAST`")
1278 .with_location(tokens[*position].location)
1279 .as_boxed());
1280 }
1281
1282 let default_null_ordering_policy = match sorting_order {
1283 SortingOrder::Ascending => NullsOrderPolicy::NullsLast,
1284 SortingOrder::Descending => NullsOrderPolicy::NullsFirst,
1285 };
1286
1287 Ok(default_null_ordering_policy)
1288}
1289
1290fn parse_into_statement(
1291 tokens: &[Token],
1292 position: &mut usize,
1293) -> Result<Box<dyn Statement>, Box<Diagnostic>> {
1294 *position += 1;
1296
1297 if *position >= tokens.len()
1299 || (tokens[*position].kind != TokenKind::Outfile
1300 && tokens[*position].kind != TokenKind::Dumpfile)
1301 {
1302 return Err(Diagnostic::error(
1303 "Expect Keyword `OUTFILE` or `DUMPFILE` after keyword `INTO`",
1304 )
1305 .with_location(calculate_safe_location(tokens, *position))
1306 .as_boxed());
1307 }
1308
1309 let file_format_kind = &tokens[*position].kind;
1311 *position += 1;
1312
1313 if *position >= tokens.len() || !matches!(tokens[*position].kind, TokenKind::String(_)) {
1315 return Err(Diagnostic::error(
1316 "Expect String literal as file path after OUTFILE or DUMPFILE keyword",
1317 )
1318 .with_location(calculate_safe_location(tokens, *position))
1319 .as_boxed());
1320 }
1321
1322 let file_path = &tokens[*position].to_string();
1323
1324 *position += 1;
1326
1327 let is_dump_file = *file_format_kind == TokenKind::Dumpfile;
1328
1329 let mut lines_terminated = if is_dump_file { "" } else { "\n" }.to_string();
1330 let mut lines_terminated_used = false;
1331
1332 let mut fields_terminated = if is_dump_file { "" } else { "," }.to_string();
1333 let mut fields_terminated_used = false;
1334
1335 let mut enclosed = String::new();
1336 let mut enclosed_used = false;
1337
1338 while *position < tokens.len() {
1339 let token = &tokens[*position];
1340
1341 if token.kind == TokenKind::Lines {
1342 if is_dump_file {
1343 return Err(Diagnostic::error(
1344 "`LINES TERMINATED` option can't be used with INTO DUMPFILE",
1345 )
1346 .add_help("To customize the format replace `DUMPFILE` with `OUTFILE` option")
1347 .with_location(tokens[*position].location)
1348 .as_boxed());
1349 }
1350
1351 if lines_terminated_used {
1352 return Err(
1353 Diagnostic::error("You already used `LINES TERMINATED` option")
1354 .with_location(tokens[*position].location)
1355 .as_boxed(),
1356 );
1357 }
1358
1359 *position += 1;
1361
1362 consume_token_or_error(
1364 tokens,
1365 position,
1366 TokenKind::Terminated,
1367 "Expect `TERMINATED` keyword after `LINES` keyword",
1368 )?;
1369
1370 consume_token_or_error(
1372 tokens,
1373 position,
1374 TokenKind::By,
1375 "Expect `BY` after `TERMINATED` keyword",
1376 )?;
1377
1378 if *position >= tokens.len() || !matches!(tokens[*position].kind, TokenKind::String(_))
1379 {
1380 return Err(Diagnostic::error(
1381 "Expect String literal as lines terminated value after BY keyword",
1382 )
1383 .with_location(calculate_safe_location(tokens, *position))
1384 .as_boxed());
1385 }
1386
1387 lines_terminated = tokens[*position].to_string();
1389 lines_terminated_used = true;
1390 *position += 1;
1391 continue;
1392 }
1393
1394 if token.kind == TokenKind::Fields {
1395 if is_dump_file {
1396 return Err(Diagnostic::error(
1397 "`FIELDS TERMINATED` option can't be used with INTO DUMPFILE",
1398 )
1399 .add_help("To customize the format replace `DUMPFILE` with `OUTFILE` option")
1400 .with_location(tokens[*position].location)
1401 .as_boxed());
1402 }
1403
1404 if fields_terminated_used {
1405 return Err(
1406 Diagnostic::error("You already used `FIELDS TERMINATED` option")
1407 .with_location(tokens[*position].location)
1408 .as_boxed(),
1409 );
1410 }
1411
1412 *position += 1;
1414
1415 consume_token_or_error(
1417 tokens,
1418 position,
1419 TokenKind::Terminated,
1420 "Expect `TERMINATED` keyword after `LINES` keyword",
1421 )?;
1422
1423 consume_token_or_error(
1425 tokens,
1426 position,
1427 TokenKind::By,
1428 "Expect `BY` after `TERMINATED` keyword",
1429 )?;
1430
1431 if *position >= tokens.len() || !matches!(tokens[*position].kind, TokenKind::String(_))
1432 {
1433 return Err(Diagnostic::error(
1434 "Expect String literal as Field terminated value after BY keyword",
1435 )
1436 .with_location(calculate_safe_location(tokens, *position))
1437 .as_boxed());
1438 }
1439
1440 fields_terminated = tokens[*position].to_string();
1442 fields_terminated_used = true;
1443 *position += 1;
1444 continue;
1445 }
1446
1447 if token.kind == TokenKind::Enclosed {
1448 if is_dump_file {
1449 return Err(Diagnostic::error(
1450 "`ENCLOSED` option can't be used with INTO DUMPFILE",
1451 )
1452 .add_help("To customize the format replace `DUMPFILE` with `OUTFILE` option")
1453 .with_location(tokens[*position].location)
1454 .as_boxed());
1455 }
1456
1457 if enclosed_used {
1458 return Err(Diagnostic::error("You already used ENCLOSED option")
1459 .with_location(tokens[*position].location)
1460 .as_boxed());
1461 }
1462
1463 *position += 1;
1465
1466 if *position >= tokens.len() || !matches!(tokens[*position].kind, TokenKind::String(_))
1467 {
1468 return Err(Diagnostic::error(
1469 "Expect String literal as enclosed value after ENCLOSED keyword",
1470 )
1471 .with_location(calculate_safe_location(tokens, *position))
1472 .as_boxed());
1473 }
1474
1475 enclosed = tokens[*position].to_string();
1477 enclosed_used = true;
1478 *position += 1;
1479 continue;
1480 }
1481
1482 break;
1483 }
1484
1485 Ok(Box::new(IntoStatement {
1486 file_path: file_path.to_string(),
1487 lines_terminated,
1488 fields_terminated,
1489 enclosed,
1490 }))
1491}
1492
1493fn parse_window_named_over_clause(
1494 context: &mut ParserContext,
1495 env: &mut Environment,
1496 tokens: &[Token],
1497 position: &mut usize,
1498) -> Result<(), Box<Diagnostic>> {
1499 consume_token_or_error(
1500 tokens,
1501 position,
1502 TokenKind::Window,
1503 "Expect `WINDOW` keyword.",
1504 )?;
1505
1506 let window_name_token = consume_conditional_token_or_errors(
1507 tokens,
1508 position,
1509 |t| matches!(t.kind, TokenKind::Symbol(_)),
1510 "Expect `Identifier` as window over clauses name.",
1511 )?;
1512
1513 let location = window_name_token.location;
1514 let window_name = window_name_token.to_string();
1515
1516 consume_token_or_error(
1517 tokens,
1518 position,
1519 TokenKind::As,
1520 "Expect `AS` keyword after window name.",
1521 )?;
1522
1523 let over_clauses = parse_over_window_definition(context, env, tokens, position)?;
1524
1525 if context.named_window_clauses.contains_key(&window_name) {
1527 return Err(Diagnostic::error(&format!(
1528 "There is already defined window clauses with name {}",
1529 window_name
1530 ))
1531 .add_note("Window over clauses names must be unique from each other")
1532 .with_location(location)
1533 .as_boxed());
1534 }
1535
1536 context
1538 .named_window_clauses
1539 .insert(window_name, over_clauses);
1540
1541 Ok(())
1542}
1543
1544pub(crate) fn parse_expression(
1545 context: &mut ParserContext,
1546 env: &mut Environment,
1547 tokens: &[Token],
1548 position: &mut usize,
1549) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
1550 let aggregation_count_before = context.aggregations.len();
1551 let window_count_before = context.window_functions.len();
1552 let expression = parse_assignment_expression(context, env, tokens, position)?;
1553
1554 if expression.kind() != ExprKind::Symbol {
1555 if aggregation_count_before != context.aggregations.len() {
1557 let column_name = context.name_generator.generate_column_name();
1558 let expr_type = expression.expr_type();
1559 env.define(column_name.to_string(), expr_type.clone());
1560
1561 if context.has_group_by_statement && !context.hidden_selections.contains(&column_name) {
1563 context.hidden_selections.push(column_name.to_string());
1564 }
1565
1566 context
1567 .aggregations
1568 .insert(column_name.clone(), AggregateValue::Expression(expression));
1569
1570 return Ok(Box::new(SymbolExpr {
1571 value: column_name,
1572 expr_type,
1573 flag: SymbolFlag::None,
1574 }));
1575 }
1576
1577 if window_count_before != context.window_functions.len() {
1579 let column_name = context.name_generator.generate_column_name();
1580 let expr_type = expression.expr_type();
1581 env.define(column_name.to_string(), expr_type.clone());
1582
1583 if context.has_group_by_statement && !context.hidden_selections.contains(&column_name) {
1585 context.hidden_selections.push(column_name.to_string());
1586 }
1587
1588 context
1589 .window_functions
1590 .insert(column_name.clone(), WindowValue::Expression(expression));
1591
1592 return Ok(Box::new(SymbolExpr {
1593 value: column_name,
1594 expr_type,
1595 flag: SymbolFlag::None,
1596 }));
1597 }
1598
1599 return Ok(expression);
1600 }
1601
1602 Ok(expression)
1603}
1604
1605fn parse_assignment_expression(
1606 context: &mut ParserContext,
1607 env: &mut Environment,
1608 tokens: &[Token],
1609 position: &mut usize,
1610) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
1611 let expression = parse_regex_expression(context, env, tokens, position)?;
1612 if is_current_token(tokens, position, TokenKind::ColonEqual) {
1613 if expression.kind() != ExprKind::GlobalVariable {
1614 return Err(Diagnostic::error(
1615 "Assignment expressions expect global variable name before `:=`",
1616 )
1617 .with_location(tokens[*position].location)
1618 .as_boxed());
1619 }
1620
1621 let expr = expression
1622 .as_any()
1623 .downcast_ref::<GlobalVariableExpr>()
1624 .unwrap();
1625
1626 let variable_name = expr.name.to_string();
1627
1628 *position += 1;
1630
1631 let value = parse_regex_expression(context, env, tokens, position)?;
1632 env.define_global(variable_name.clone(), value.expr_type());
1633
1634 return Ok(Box::new(AssignmentExpr {
1635 symbol: variable_name.clone(),
1636 value,
1637 }));
1638 }
1639 Ok(expression)
1640}
1641
1642fn parse_regex_expression(
1643 context: &mut ParserContext,
1644 env: &mut Environment,
1645 tokens: &[Token],
1646 position: &mut usize,
1647) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
1648 let lhs = parse_is_null_expression(context, env, tokens, position)?;
1649
1650 if is_current_token(tokens, position, TokenKind::RegExp)
1654 || (is_current_token(tokens, position, TokenKind::Not)
1655 && is_next_token(tokens, position, TokenKind::RegExp))
1656 {
1657 let has_not_keyword = is_current_token(tokens, position, TokenKind::Not);
1658 let operator_location = if has_not_keyword {
1659 *position += 2;
1661 let mut not_location = tokens[*position - 2].location;
1662 let between_location = tokens[*position - 1].location;
1663 not_location.expand_until(between_location);
1664 not_location
1665 } else {
1666 *position += 1;
1668 tokens[*position - 1].location
1669 };
1670
1671 let pattern = parse_is_null_expression(context, env, tokens, position)?;
1672
1673 let lhs_type = lhs.expr_type();
1674 let rhs_type = pattern.expr_type();
1675
1676 let expected_rhs_types = lhs_type.can_perform_regexp_op_with();
1678 if expected_rhs_types.contains(&rhs_type) {
1679 let regex_expr = Box::new(RegexExpr {
1680 input: lhs,
1681 pattern,
1682 });
1683
1684 return Ok(apply_not_keyword_if_exists(regex_expr, has_not_keyword));
1685 }
1686
1687 for expected_type in expected_rhs_types.iter() {
1690 if !expected_type.has_implicit_cast_from(&pattern) {
1691 continue;
1692 }
1693
1694 let casting = Box::new(CastExpr {
1695 value: pattern,
1696 result_type: expected_type.clone(),
1697 });
1698
1699 let expr = Box::new(RegexExpr {
1700 input: lhs,
1701 pattern: casting,
1702 });
1703
1704 return Ok(apply_not_keyword_if_exists(expr, has_not_keyword));
1705 }
1706
1707 return Err(Diagnostic::error(&format!(
1709 "Operator `REGEXP` can't be performed between types `{}` and `{}`",
1710 lhs_type, rhs_type
1711 ))
1712 .with_location(operator_location)
1713 .as_boxed());
1714 }
1715
1716 Ok(lhs)
1717}
1718
1719fn parse_is_null_expression(
1720 context: &mut ParserContext,
1721 env: &mut Environment,
1722 tokens: &[Token],
1723 position: &mut usize,
1724) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
1725 let expression = parse_in_expression(context, env, tokens, position)?;
1726 if is_current_token(tokens, position, TokenKind::Is) {
1727 let is_location = tokens[*position].location;
1728
1729 *position += 1;
1731
1732 let has_not_keyword = if is_current_token(tokens, position, TokenKind::Not) {
1733 *position += 1;
1735 true
1736 } else {
1737 false
1738 };
1739
1740 if is_current_token(tokens, position, TokenKind::Null) {
1741 *position += 1;
1743
1744 return Ok(Box::new(IsNullExpr {
1745 argument: expression,
1746 has_not: has_not_keyword,
1747 }));
1748 }
1749
1750 return Err(
1751 Diagnostic::error("Expects `NULL` Keyword after `IS` or `IS NOT`")
1752 .with_location(is_location)
1753 .as_boxed(),
1754 );
1755 }
1756 Ok(expression)
1757}
1758
1759fn parse_in_expression(
1760 context: &mut ParserContext,
1761 env: &mut Environment,
1762 tokens: &[Token],
1763 position: &mut usize,
1764) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
1765 let expression = parse_logical_or_expression(context, env, tokens, position)?;
1766
1767 let has_not_keyword = if *position < tokens.len() - 1
1769 && tokens[*position].kind == TokenKind::Not
1770 && tokens[*position + 1].kind == TokenKind::In
1771 {
1772 *position += 1;
1773 true
1774 } else {
1775 false
1776 };
1777
1778 if is_current_token(tokens, position, TokenKind::In) {
1779 let in_location = tokens[*position].location;
1780
1781 *position += 1;
1783
1784 if !is_current_token(tokens, position, TokenKind::LeftParen) {
1785 return Err(Diagnostic::error("Expects `(` After `IN` Keyword")
1786 .with_location(in_location)
1787 .as_boxed());
1788 }
1789
1790 let values =
1791 parse_zero_or_more_values_with_comma_between(context, env, tokens, position, "IN")?;
1792
1793 if values.is_empty() {
1795 let is_true = has_not_keyword;
1796 return Ok(Box::new(BooleanExpr { is_true }));
1797 }
1798
1799 let values_type_result = check_all_values_are_same_type(&values);
1800 if values_type_result.is_none() {
1801 return Err(Diagnostic::error(
1802 "Expects values between `(` and `)` to have the same type",
1803 )
1804 .with_location(in_location)
1805 .as_boxed());
1806 }
1807
1808 let values_type = values_type_result.unwrap();
1810 if !values_type.is_any() && !expression.expr_type().equals(&values_type) {
1811 return Err(Diagnostic::error(
1812 "Argument and Values of In Expression must have the same type",
1813 )
1814 .with_location(in_location)
1815 .as_boxed());
1816 }
1817
1818 return Ok(Box::new(InExpr {
1819 argument: expression,
1820 values,
1821 values_type,
1822 has_not_keyword,
1823 }));
1824 }
1825
1826 Ok(expression)
1827}
1828
1829fn parse_logical_or_expression(
1830 context: &mut ParserContext,
1831 env: &mut Environment,
1832 tokens: &[Token],
1833 position: &mut usize,
1834) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
1835 let mut lhs = parse_logical_and_expression(context, env, tokens, position)?;
1836
1837 'parse_expr: while is_logical_or_operator(tokens, position) {
1838 let operator = &tokens[*position];
1839
1840 *position += 1;
1842
1843 let rhs = parse_logical_and_expression(context, env, tokens, position)?;
1844
1845 let lhs_type = lhs.expr_type();
1846 let rhs_type = rhs.expr_type();
1847
1848 let expected_rhs_types = lhs_type.can_perform_logical_or_op_with();
1849
1850 if expected_rhs_types.contains(&rhs_type) {
1852 lhs = Box::new(LogicalExpr {
1853 left: lhs,
1854 operator: BinaryLogicalOperator::Or,
1855 right: rhs,
1856 });
1857
1858 continue 'parse_expr;
1859 }
1860
1861 for expected_type in expected_rhs_types {
1864 if !expected_type.has_implicit_cast_from(&lhs) {
1865 continue;
1866 }
1867
1868 let casting = Box::new(CastExpr {
1869 value: rhs,
1870 result_type: expected_type.clone(),
1871 });
1872
1873 lhs = Box::new(LogicalExpr {
1874 left: lhs,
1875 operator: BinaryLogicalOperator::Or,
1876 right: casting,
1877 });
1878
1879 continue 'parse_expr;
1880 }
1881
1882 let expected_lhs_types = rhs_type.can_perform_logical_or_op_with();
1885 for expected_type in expected_lhs_types.iter() {
1886 if !expected_type.has_implicit_cast_from(&lhs) {
1887 continue;
1888 }
1889
1890 let casting = Box::new(CastExpr {
1891 value: lhs,
1892 result_type: expected_type.clone(),
1893 });
1894
1895 lhs = Box::new(LogicalExpr {
1896 left: casting,
1897 operator: BinaryLogicalOperator::Or,
1898 right: rhs,
1899 });
1900
1901 continue 'parse_expr;
1902 }
1903
1904 return Err(Diagnostic::error(&format!(
1906 "Operator `OR` can't be performed between types `{}` and `{}`",
1907 lhs_type, rhs_type
1908 ))
1909 .with_location(operator.location)
1910 .as_boxed());
1911 }
1912
1913 Ok(lhs)
1914}
1915
1916fn parse_logical_and_expression(
1917 context: &mut ParserContext,
1918 env: &mut Environment,
1919 tokens: &[Token],
1920 position: &mut usize,
1921) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
1922 let mut lhs = parse_bitwise_or_expression(context, env, tokens, position)?;
1923
1924 'parse_expr: while is_logical_and_operator(tokens, position) {
1925 let operator = &tokens[*position];
1926
1927 *position += 1;
1929
1930 let rhs = parse_bitwise_or_expression(context, env, tokens, position)?;
1931
1932 let lhs_type = lhs.expr_type();
1933 let rhs_type = rhs.expr_type();
1934
1935 let expected_rhs_types = lhs_type.can_perform_logical_and_op_with();
1936
1937 if expected_rhs_types.contains(&rhs_type) {
1939 lhs = Box::new(LogicalExpr {
1940 left: lhs,
1941 operator: BinaryLogicalOperator::And,
1942 right: rhs,
1943 });
1944
1945 continue 'parse_expr;
1946 }
1947
1948 for expected_type in expected_rhs_types.iter() {
1951 if !expected_type.has_implicit_cast_from(&rhs) {
1952 continue;
1953 }
1954
1955 let casting = Box::new(CastExpr {
1956 value: rhs,
1957 result_type: expected_type.clone(),
1958 });
1959
1960 lhs = Box::new(LogicalExpr {
1961 left: lhs,
1962 operator: BinaryLogicalOperator::And,
1963 right: casting,
1964 });
1965
1966 continue 'parse_expr;
1967 }
1968
1969 let expected_lhs_types = rhs_type.can_perform_logical_and_op_with();
1972 for expected_type in expected_lhs_types.iter() {
1973 if !expected_type.has_implicit_cast_from(&lhs) {
1974 continue;
1975 }
1976
1977 let casting = Box::new(CastExpr {
1978 value: lhs,
1979 result_type: expected_type.clone(),
1980 });
1981
1982 lhs = Box::new(LogicalExpr {
1983 left: casting,
1984 operator: BinaryLogicalOperator::And,
1985 right: rhs,
1986 });
1987
1988 continue 'parse_expr;
1989 }
1990
1991 return Err(Diagnostic::error(&format!(
1993 "Operator `AND` can't be performed between types `{}` and `{}`",
1994 lhs_type, rhs_type
1995 ))
1996 .with_location(operator.location)
1997 .as_boxed());
1998 }
1999
2000 Ok(lhs)
2001}
2002
2003fn parse_bitwise_or_expression(
2004 context: &mut ParserContext,
2005 env: &mut Environment,
2006 tokens: &[Token],
2007 position: &mut usize,
2008) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2009 let mut lhs = parse_bitwise_xor_expression(context, env, tokens, position)?;
2010
2011 'parse_expr: while is_current_token(tokens, position, TokenKind::BitwiseOr) {
2012 let operator = &tokens[*position];
2013
2014 *position += 1;
2016
2017 let rhs = parse_bitwise_xor_expression(context, env, tokens, position)?;
2018
2019 let lhs_type = lhs.expr_type();
2020 let rhs_type = rhs.expr_type();
2021
2022 let expected_rhs_types = lhs_type.can_perform_or_op_with();
2023
2024 if expected_rhs_types.contains(&rhs_type) {
2026 lhs = Box::new(BitwiseExpr {
2027 left: lhs,
2028 operator: BinaryBitwiseOperator::Or,
2029 right: rhs,
2030 result_type: lhs_type.or_op_result_type(&rhs_type),
2031 });
2032
2033 continue 'parse_expr;
2034 }
2035
2036 for expected_type in expected_rhs_types.iter() {
2039 if !expected_type.has_implicit_cast_from(&rhs) {
2040 continue;
2041 }
2042
2043 let casting = Box::new(CastExpr {
2044 value: rhs,
2045 result_type: expected_type.clone(),
2046 });
2047
2048 lhs = Box::new(BitwiseExpr {
2049 left: lhs,
2050 operator: BinaryBitwiseOperator::Or,
2051 right: casting,
2052 result_type: lhs_type.or_op_result_type(expected_type),
2053 });
2054
2055 continue 'parse_expr;
2056 }
2057
2058 let expected_lhs_types = rhs_type.can_perform_or_op_with();
2061 for expected_type in expected_lhs_types.iter() {
2062 if !expected_type.has_implicit_cast_from(&lhs) {
2063 continue;
2064 }
2065
2066 let casting = Box::new(CastExpr {
2067 value: lhs,
2068 result_type: expected_type.clone(),
2069 });
2070
2071 lhs = Box::new(BitwiseExpr {
2072 left: casting,
2073 operator: BinaryBitwiseOperator::Or,
2074 right: rhs,
2075 result_type: rhs_type.or_op_result_type(expected_type),
2076 });
2077
2078 continue 'parse_expr;
2079 }
2080
2081 return Err(Diagnostic::error(&format!(
2083 "Operator `|` can't be performed between types `{}` and `{}`",
2084 lhs_type, rhs_type
2085 ))
2086 .with_location(operator.location)
2087 .as_boxed());
2088 }
2089
2090 Ok(lhs)
2091}
2092
2093fn parse_bitwise_xor_expression(
2094 context: &mut ParserContext,
2095 env: &mut Environment,
2096 tokens: &[Token],
2097 position: &mut usize,
2098) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2099 let mut lhs = parse_logical_xor_expression(context, env, tokens, position)?;
2100
2101 'parse_expr: while is_current_token(tokens, position, TokenKind::BitwiseXor) {
2102 let operator = &tokens[*position];
2103
2104 *position += 1;
2106
2107 let rhs = parse_logical_xor_expression(context, env, tokens, position)?;
2108
2109 let lhs_type = lhs.expr_type();
2110 let rhs_type = rhs.expr_type();
2111
2112 let expected_rhs_types = lhs_type.can_perform_xor_op_with();
2113
2114 if expected_rhs_types.contains(&rhs_type) {
2116 lhs = Box::new(BitwiseExpr {
2117 left: lhs,
2118 operator: BinaryBitwiseOperator::Xor,
2119 right: rhs,
2120 result_type: lhs_type.xor_op_result_type(&rhs_type),
2121 });
2122
2123 continue 'parse_expr;
2124 }
2125
2126 for expected_type in expected_rhs_types.iter() {
2129 if !expected_type.has_implicit_cast_from(&rhs) {
2130 continue;
2131 }
2132
2133 let casting = Box::new(CastExpr {
2134 value: rhs,
2135 result_type: expected_type.clone(),
2136 });
2137
2138 lhs = Box::new(BitwiseExpr {
2139 left: lhs,
2140 operator: BinaryBitwiseOperator::Xor,
2141 right: casting,
2142 result_type: lhs_type.or_op_result_type(expected_type),
2143 });
2144
2145 continue 'parse_expr;
2146 }
2147
2148 let expected_lhs_types = rhs_type.can_perform_xor_op_with();
2151 for expected_type in expected_lhs_types.iter() {
2152 if !expected_type.has_implicit_cast_from(&lhs) {
2153 continue;
2154 }
2155
2156 let casting = Box::new(CastExpr {
2157 value: lhs,
2158 result_type: expected_type.clone(),
2159 });
2160
2161 lhs = Box::new(BitwiseExpr {
2162 left: casting,
2163 operator: BinaryBitwiseOperator::Xor,
2164 right: rhs,
2165 result_type: rhs_type.or_op_result_type(expected_type),
2166 });
2167
2168 continue 'parse_expr;
2169 }
2170
2171 return Err(Diagnostic::error(&format!(
2173 "Operator `#` can't be performed between types `{}` and `{}`",
2174 lhs_type, rhs_type
2175 ))
2176 .with_location(operator.location)
2177 .as_boxed());
2178 }
2179
2180 Ok(lhs)
2181}
2182
2183fn parse_logical_xor_expression(
2184 context: &mut ParserContext,
2185 env: &mut Environment,
2186 tokens: &[Token],
2187 position: &mut usize,
2188) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2189 let mut lhs = parse_bitwise_and_expression(context, env, tokens, position)?;
2190
2191 'parse_expr: while is_current_token(tokens, position, TokenKind::XorKeyword) {
2192 let operator = &tokens[*position];
2193
2194 *position += 1;
2196
2197 let rhs = parse_bitwise_and_expression(context, env, tokens, position)?;
2198
2199 let lhs_type = lhs.expr_type();
2200 let rhs_type = rhs.expr_type();
2201
2202 let expected_rhs_types = lhs_type.can_perform_logical_xor_op_with();
2203
2204 if expected_rhs_types.contains(&rhs_type) {
2206 lhs = Box::new(LogicalExpr {
2207 left: lhs,
2208 operator: BinaryLogicalOperator::Xor,
2209 right: rhs,
2210 });
2211
2212 continue 'parse_expr;
2213 }
2214
2215 for expected_type in expected_rhs_types.iter() {
2218 if !expected_type.has_implicit_cast_from(&rhs) {
2219 continue;
2220 }
2221
2222 let casting = Box::new(CastExpr {
2223 value: rhs,
2224 result_type: expected_type.clone(),
2225 });
2226
2227 lhs = Box::new(LogicalExpr {
2228 left: lhs,
2229 operator: BinaryLogicalOperator::Xor,
2230 right: casting,
2231 });
2232
2233 continue 'parse_expr;
2234 }
2235
2236 let expected_lhs_types = rhs_type.can_perform_logical_xor_op_with();
2239 for expected_type in expected_lhs_types.iter() {
2240 if !expected_type.has_implicit_cast_from(&lhs) {
2241 continue;
2242 }
2243
2244 let casting = Box::new(CastExpr {
2245 value: lhs,
2246 result_type: expected_type.clone(),
2247 });
2248
2249 lhs = Box::new(LogicalExpr {
2250 left: casting,
2251 operator: BinaryLogicalOperator::Xor,
2252 right: rhs,
2253 });
2254
2255 continue 'parse_expr;
2256 }
2257
2258 return Err(Diagnostic::error(&format!(
2260 "Operator `XOR` can't be performed between types `{}` and `{}`",
2261 lhs_type, rhs_type
2262 ))
2263 .with_location(operator.location)
2264 .as_boxed());
2265 }
2266
2267 Ok(lhs)
2268}
2269
2270fn parse_bitwise_and_expression(
2271 context: &mut ParserContext,
2272 env: &mut Environment,
2273 tokens: &[Token],
2274 position: &mut usize,
2275) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2276 let mut lhs = parse_comparison_expression(context, env, tokens, position)?;
2277
2278 'parse_expr: while is_current_token(tokens, position, TokenKind::BitwiseAnd) {
2279 let operator = &tokens[*position];
2280
2281 *position += 1;
2283
2284 let rhs = parse_comparison_expression(context, env, tokens, position)?;
2285
2286 let lhs_type = lhs.expr_type();
2287 let rhs_type = rhs.expr_type();
2288
2289 let expected_rhs_types = lhs_type.can_perform_and_op_with();
2290
2291 if expected_rhs_types.contains(&rhs_type) {
2293 lhs = Box::new(BitwiseExpr {
2294 left: lhs,
2295 operator: BinaryBitwiseOperator::And,
2296 right: rhs,
2297 result_type: lhs_type.or_op_result_type(&rhs_type),
2298 });
2299
2300 continue 'parse_expr;
2301 }
2302
2303 for expected_type in expected_rhs_types.iter() {
2306 if !expected_type.has_implicit_cast_from(&rhs) {
2307 continue;
2308 }
2309
2310 let casting = Box::new(CastExpr {
2311 value: rhs,
2312 result_type: expected_type.clone(),
2313 });
2314
2315 lhs = Box::new(BitwiseExpr {
2316 left: lhs,
2317 operator: BinaryBitwiseOperator::And,
2318 right: casting,
2319 result_type: lhs_type.or_op_result_type(expected_type),
2320 });
2321
2322 continue 'parse_expr;
2323 }
2324
2325 let expected_lhs_types = rhs_type.can_perform_and_op_with();
2328 for expected_type in expected_lhs_types.iter() {
2329 if expected_type.has_implicit_cast_from(&lhs) {
2330 let casting = Box::new(CastExpr {
2331 value: lhs,
2332 result_type: expected_type.clone(),
2333 });
2334
2335 lhs = Box::new(BitwiseExpr {
2336 left: casting,
2337 operator: BinaryBitwiseOperator::And,
2338 right: rhs,
2339 result_type: rhs_type.or_op_result_type(expected_type),
2340 });
2341
2342 continue 'parse_expr;
2343 }
2344 }
2345
2346 return Err(Diagnostic::error(&format!(
2348 "Operator `&&` can't be performed between types `{}` and `{}`",
2349 lhs_type, rhs_type
2350 ))
2351 .with_location(operator.location)
2352 .as_boxed());
2353 }
2354
2355 Ok(lhs)
2356}
2357
2358pub(crate) fn parse_contains_expression(
2359 context: &mut ParserContext,
2360 env: &mut Environment,
2361 tokens: &[Token],
2362 position: &mut usize,
2363) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2364 let lhs = parse_contained_by_expression(context, env, tokens, position)?;
2365
2366 if is_current_token(tokens, position, TokenKind::AtRightArrow) {
2367 let operator = &tokens[*position];
2368
2369 *position += 1;
2371
2372 let rhs = parse_contained_by_expression(context, env, tokens, position)?;
2373
2374 let lhs_type = lhs.expr_type();
2375 let rhs_type = rhs.expr_type();
2376
2377 let expected_rhs_types = lhs_type.can_perform_contains_op_with();
2378
2379 if expected_rhs_types.contains(&rhs_type) {
2381 return Ok(Box::new(ContainsExpr {
2382 left: lhs,
2383 right: rhs,
2384 }));
2385 }
2386
2387 for expected_type in expected_rhs_types.iter() {
2389 if !expected_type.has_implicit_cast_from(&rhs) {
2390 continue;
2391 }
2392
2393 let casting = Box::new(CastExpr {
2394 value: rhs,
2395 result_type: expected_type.clone(),
2396 });
2397
2398 return Ok(Box::new(ContainsExpr {
2399 left: lhs,
2400 right: casting,
2401 }));
2402 }
2403
2404 return Err(Diagnostic::error(&format!(
2406 "Operator `@>` can't be performed between types `{}` and `{}`",
2407 lhs_type, rhs_type
2408 ))
2409 .with_location(operator.location)
2410 .as_boxed());
2411 }
2412
2413 Ok(lhs)
2414}
2415
2416fn parse_contained_by_expression(
2417 context: &mut ParserContext,
2418 env: &mut Environment,
2419 tokens: &[Token],
2420 position: &mut usize,
2421) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2422 let lhs = parse_bitwise_shift_expression(context, env, tokens, position)?;
2423
2424 if is_current_token(tokens, position, TokenKind::ArrowRightAt) {
2425 let operator = &tokens[*position];
2426
2427 *position += 1;
2429
2430 let rhs = parse_bitwise_shift_expression(context, env, tokens, position)?;
2431
2432 let lhs_type = lhs.expr_type();
2433 let rhs_type = rhs.expr_type();
2434
2435 let expected_lhs_types = rhs_type.can_perform_contains_op_with();
2436
2437 if expected_lhs_types.contains(&lhs_type) {
2439 return Ok(Box::new(ContainedByExpr {
2440 left: lhs,
2441 right: rhs,
2442 }));
2443 }
2444
2445 for expected_type in expected_lhs_types.iter() {
2447 if !expected_type.has_implicit_cast_from(&lhs) {
2448 continue;
2449 }
2450
2451 let casting = Box::new(CastExpr {
2452 value: lhs,
2453 result_type: expected_type.clone(),
2454 });
2455
2456 return Ok(Box::new(ContainedByExpr {
2457 left: casting,
2458 right: rhs,
2459 }));
2460 }
2461
2462 return Err(Diagnostic::error(&format!(
2464 "Operator `<@` can't be performed between types `{}` and `{}`",
2465 lhs_type, rhs_type
2466 ))
2467 .with_location(operator.location)
2468 .as_boxed());
2469 }
2470
2471 Ok(lhs)
2472}
2473
2474fn parse_bitwise_shift_expression(
2475 context: &mut ParserContext,
2476 env: &mut Environment,
2477 tokens: &[Token],
2478 position: &mut usize,
2479) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2480 let mut lhs = parse_term_expression(context, env, tokens, position)?;
2481
2482 'parse_expr: while is_bitwise_shift_operator(tokens, position) {
2483 let operator = &tokens[*position];
2484
2485 *position += 1;
2487
2488 let rhs = parse_term_expression(context, env, tokens, position)?;
2489 let lhs_type = lhs.expr_type();
2490 let rhs_type = rhs.expr_type();
2491
2492 if operator.kind == TokenKind::BitwiseRightShift {
2494 let expected_rhs_types = lhs_type.can_perform_shr_op_with();
2495
2496 if expected_rhs_types.contains(&rhs_type) {
2498 lhs = Box::new(BitwiseExpr {
2499 left: lhs,
2500 operator: BinaryBitwiseOperator::RightShift,
2501 right: rhs,
2502 result_type: rhs_type.shr_op_result_type(&rhs_type),
2503 });
2504
2505 continue 'parse_expr;
2506 }
2507
2508 for expected_type in expected_rhs_types.iter() {
2511 if !expected_type.has_implicit_cast_from(&rhs) {
2512 continue;
2513 }
2514
2515 let casting = Box::new(CastExpr {
2516 value: rhs,
2517 result_type: expected_type.clone(),
2518 });
2519
2520 lhs = Box::new(BitwiseExpr {
2521 left: lhs,
2522 operator: BinaryBitwiseOperator::RightShift,
2523 right: casting,
2524 result_type: lhs_type.shr_op_result_type(expected_type),
2525 });
2526
2527 continue 'parse_expr;
2528 }
2529
2530 let expected_lhs_types = rhs_type.can_perform_shr_op_with();
2533 for expected_type in expected_lhs_types.iter() {
2534 if !expected_type.has_implicit_cast_from(&lhs) {
2535 continue;
2536 }
2537
2538 let casting = Box::new(CastExpr {
2539 value: lhs,
2540 result_type: expected_type.clone(),
2541 });
2542
2543 lhs = Box::new(BitwiseExpr {
2544 left: casting,
2545 operator: BinaryBitwiseOperator::RightShift,
2546 right: rhs,
2547 result_type: rhs_type.shr_op_result_type(expected_type),
2548 });
2549
2550 continue 'parse_expr;
2551 }
2552
2553 return Err(Diagnostic::error(&format!(
2555 "Operator `>>` can't be performed between types `{}` and `{}`",
2556 lhs_type, rhs_type
2557 ))
2558 .with_location(operator.location)
2559 .as_boxed());
2560 }
2561
2562 if operator.kind == TokenKind::BitwiseLeftShift {
2564 let expected_rhs_types = lhs_type.can_perform_shl_op_with();
2565
2566 if expected_rhs_types.contains(&rhs_type) {
2568 lhs = Box::new(BitwiseExpr {
2569 left: lhs,
2570 operator: BinaryBitwiseOperator::LeftShift,
2571 right: rhs,
2572 result_type: lhs_type.shl_op_result_type(&rhs_type),
2573 });
2574
2575 continue 'parse_expr;
2576 }
2577
2578 for expected_type in expected_rhs_types.iter() {
2581 if !expected_type.has_implicit_cast_from(&rhs) {
2582 continue;
2583 }
2584
2585 let casting = Box::new(CastExpr {
2586 value: rhs,
2587 result_type: expected_type.clone(),
2588 });
2589
2590 lhs = Box::new(BitwiseExpr {
2591 left: lhs,
2592 operator: BinaryBitwiseOperator::LeftShift,
2593 right: casting,
2594 result_type: lhs_type.shr_op_result_type(expected_type),
2595 });
2596
2597 continue 'parse_expr;
2598 }
2599
2600 let expected_lhs_types = rhs_type.can_perform_shr_op_with();
2603 for expected_type in expected_lhs_types.iter() {
2604 if !expected_type.has_implicit_cast_from(&lhs) {
2605 continue;
2606 }
2607
2608 let casting = Box::new(CastExpr {
2609 value: lhs,
2610 result_type: expected_type.clone(),
2611 });
2612
2613 lhs = Box::new(BitwiseExpr {
2614 left: casting,
2615 operator: BinaryBitwiseOperator::LeftShift,
2616 right: rhs,
2617 result_type: rhs_type.shr_op_result_type(expected_type),
2618 });
2619
2620 continue 'parse_expr;
2621 }
2622
2623 return Err(Diagnostic::error(&format!(
2625 "Operator `<<` can't be performed between types `{}` and `{}`",
2626 lhs_type, rhs_type
2627 ))
2628 .with_location(operator.location)
2629 .as_boxed());
2630 }
2631 }
2632
2633 Ok(lhs)
2634}
2635
2636fn parse_term_expression(
2637 context: &mut ParserContext,
2638 env: &mut Environment,
2639 tokens: &[Token],
2640 position: &mut usize,
2641) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2642 let mut lhs = parse_factor_expression(context, env, tokens, position)?;
2643
2644 'parse_expr: while *position < tokens.len() && is_term_operator(&tokens[*position]) {
2645 let operator = &tokens[*position];
2646
2647 *position += 1;
2649
2650 let rhs = parse_factor_expression(context, env, tokens, position)?;
2651
2652 let lhs_type = lhs.expr_type();
2653 let rhs_type = rhs.expr_type();
2654
2655 if operator.kind == TokenKind::Plus {
2657 let expected_rhs_types = lhs_type.can_perform_add_op_with();
2658
2659 if expected_rhs_types.contains(&rhs_type) {
2661 lhs = Box::new(ArithmeticExpr {
2662 left: lhs,
2663 operator: ArithmeticOperator::Plus,
2664 right: rhs,
2665 result_type: lhs_type.add_op_result_type(&rhs_type),
2666 });
2667
2668 continue 'parse_expr;
2669 }
2670
2671 for expected_type in expected_rhs_types.iter() {
2674 if !expected_type.has_implicit_cast_from(&rhs) {
2675 continue;
2676 }
2677
2678 let casting = Box::new(CastExpr {
2679 value: rhs,
2680 result_type: expected_type.clone(),
2681 });
2682
2683 lhs = Box::new(ArithmeticExpr {
2684 left: lhs,
2685 operator: ArithmeticOperator::Plus,
2686 right: casting,
2687 result_type: lhs_type.add_op_result_type(expected_type),
2688 });
2689
2690 continue 'parse_expr;
2691 }
2692
2693 let expected_lhs_types = rhs_type.can_perform_add_op_with();
2696 for expected_type in expected_lhs_types.iter() {
2697 if !expected_type.has_implicit_cast_from(&lhs) {
2698 continue;
2699 }
2700
2701 let casting = Box::new(CastExpr {
2702 value: lhs,
2703 result_type: expected_type.clone(),
2704 });
2705
2706 lhs = Box::new(ArithmeticExpr {
2707 left: casting,
2708 operator: ArithmeticOperator::Plus,
2709 right: rhs,
2710 result_type: rhs_type.add_op_result_type(expected_type),
2711 });
2712
2713 continue 'parse_expr;
2714 }
2715
2716 return Err(Diagnostic::error(&format!(
2718 "Operator `+` can't be performed between types `{}` and `{}`",
2719 lhs_type, rhs_type
2720 ))
2721 .add_help(
2722 "You can use `CONCAT(Any, Any, ...Any)` function to concatenate values with different types",
2723 )
2724 .with_location(operator.location)
2725 .as_boxed());
2726 }
2727
2728 if operator.kind == TokenKind::Minus {
2730 let expected_rhs_types = lhs_type.can_perform_sub_op_with();
2731
2732 if expected_rhs_types.contains(&rhs_type) {
2734 lhs = Box::new(ArithmeticExpr {
2735 left: lhs,
2736 operator: ArithmeticOperator::Minus,
2737 right: rhs,
2738 result_type: lhs_type.sub_op_result_type(&rhs_type),
2739 });
2740 continue 'parse_expr;
2741 }
2742
2743 for expected_type in expected_rhs_types.iter() {
2746 if !expected_type.has_implicit_cast_from(&rhs) {
2747 continue;
2748 }
2749
2750 let casting = Box::new(CastExpr {
2751 value: rhs,
2752 result_type: expected_type.clone(),
2753 });
2754
2755 lhs = Box::new(ArithmeticExpr {
2756 left: lhs,
2757 operator: ArithmeticOperator::Minus,
2758 right: casting,
2759 result_type: lhs_type.sub_op_result_type(expected_type),
2760 });
2761
2762 continue 'parse_expr;
2763 }
2764
2765 let expected_lhs_types = rhs_type.can_perform_sub_op_with();
2768 for expected_type in expected_lhs_types.iter() {
2769 if !expected_type.has_implicit_cast_from(&lhs) {
2770 continue;
2771 }
2772
2773 let casting = Box::new(CastExpr {
2774 value: lhs,
2775 result_type: expected_type.clone(),
2776 });
2777
2778 lhs = Box::new(ArithmeticExpr {
2779 left: casting,
2780 operator: ArithmeticOperator::Minus,
2781 right: rhs,
2782 result_type: rhs_type.sub_op_result_type(expected_type),
2783 });
2784
2785 continue 'parse_expr;
2786 }
2787
2788 return Err(Diagnostic::error(&format!(
2790 "Operator `-` can't be performed between types `{}` and `{}`",
2791 lhs_type, rhs_type
2792 ))
2793 .with_location(operator.location)
2794 .as_boxed());
2795 }
2796 }
2797
2798 Ok(lhs)
2799}
2800
2801fn parse_factor_expression(
2802 context: &mut ParserContext,
2803 env: &mut Environment,
2804 tokens: &[Token],
2805 position: &mut usize,
2806) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
2807 let mut lhs = parse_like_expression(context, env, tokens, position)?;
2808
2809 'parse_expr: while is_factor_operator(tokens, position) {
2810 let operator = &tokens[*position];
2811
2812 *position += 1;
2814
2815 let rhs = parse_like_expression(context, env, tokens, position)?;
2816
2817 let lhs_type = lhs.expr_type();
2818 let rhs_type = rhs.expr_type();
2819
2820 if operator.kind == TokenKind::Star {
2822 let expected_rhs_types = lhs_type.can_perform_mul_op_with();
2823
2824 if expected_rhs_types.contains(&rhs_type) {
2826 lhs = Box::new(ArithmeticExpr {
2827 left: lhs,
2828 operator: ArithmeticOperator::Star,
2829 right: rhs,
2830 result_type: lhs_type.mul_op_result_type(&rhs_type),
2831 });
2832
2833 continue 'parse_expr;
2834 }
2835
2836 for expected_type in expected_rhs_types.iter() {
2839 if !expected_type.has_implicit_cast_from(&rhs) {
2840 continue;
2841 }
2842
2843 let casting = Box::new(CastExpr {
2844 value: rhs,
2845 result_type: expected_type.clone(),
2846 });
2847
2848 lhs = Box::new(ArithmeticExpr {
2849 left: lhs,
2850 operator: ArithmeticOperator::Star,
2851 right: casting,
2852 result_type: lhs_type.mul_op_result_type(expected_type),
2853 });
2854
2855 continue 'parse_expr;
2856 }
2857
2858 let expected_lhs_types = rhs_type.can_perform_mul_op_with();
2861 for expected_type in expected_lhs_types.iter() {
2862 if !expected_type.has_implicit_cast_from(&lhs) {
2863 continue;
2864 }
2865
2866 let casting = Box::new(CastExpr {
2867 value: lhs,
2868 result_type: expected_type.clone(),
2869 });
2870
2871 lhs = Box::new(ArithmeticExpr {
2872 left: casting,
2873 operator: ArithmeticOperator::Star,
2874 right: rhs,
2875 result_type: rhs_type.mul_op_result_type(expected_type),
2876 });
2877
2878 continue 'parse_expr;
2879 }
2880
2881 return Err(Diagnostic::error(&format!(
2883 "Operator `*` can't be performed between types `{}` and `{}`",
2884 lhs_type, rhs_type
2885 ))
2886 .with_location(operator.location)
2887 .as_boxed());
2888 }
2889
2890 if operator.kind == TokenKind::Slash {
2892 let expected_rhs_types = lhs_type.can_perform_div_op_with();
2893
2894 if expected_rhs_types.contains(&rhs_type) {
2896 lhs = Box::new(ArithmeticExpr {
2897 left: lhs,
2898 operator: ArithmeticOperator::Slash,
2899 right: rhs,
2900 result_type: lhs_type.div_op_result_type(&rhs_type),
2901 });
2902
2903 continue 'parse_expr;
2904 }
2905
2906 for expected_type in expected_rhs_types.iter() {
2909 if !expected_type.has_implicit_cast_from(&rhs) {
2910 continue;
2911 }
2912
2913 let casting = Box::new(CastExpr {
2914 value: rhs,
2915 result_type: expected_type.clone(),
2916 });
2917
2918 lhs = Box::new(ArithmeticExpr {
2919 left: lhs,
2920 operator: ArithmeticOperator::Slash,
2921 right: casting,
2922 result_type: lhs_type.div_op_result_type(expected_type),
2923 });
2924
2925 continue 'parse_expr;
2926 }
2927
2928 let expected_lhs_types = rhs_type.can_perform_div_op_with();
2931 for expected_type in expected_lhs_types.iter() {
2932 if !expected_type.has_implicit_cast_from(&lhs) {
2933 continue;
2934 }
2935
2936 let casting = Box::new(CastExpr {
2937 value: lhs,
2938 result_type: expected_type.clone(),
2939 });
2940
2941 lhs = Box::new(ArithmeticExpr {
2942 left: casting,
2943 operator: ArithmeticOperator::Slash,
2944 right: rhs,
2945 result_type: rhs_type.div_op_result_type(expected_type),
2946 });
2947
2948 continue 'parse_expr;
2949 }
2950
2951 return Err(Diagnostic::error(&format!(
2953 "Operator `/` can't be performed between types `{}` and `{}`",
2954 lhs_type, rhs_type
2955 ))
2956 .with_location(operator.location)
2957 .as_boxed());
2958 }
2959
2960 if operator.kind == TokenKind::Percentage {
2962 let expected_rhs_types = lhs_type.can_perform_rem_op_with();
2963
2964 if expected_rhs_types.contains(&rhs_type) {
2966 lhs = Box::new(ArithmeticExpr {
2967 left: lhs,
2968 operator: ArithmeticOperator::Modulus,
2969 right: rhs,
2970 result_type: lhs_type.rem_op_result_type(&rhs_type),
2971 });
2972
2973 continue 'parse_expr;
2974 }
2975
2976 for expected_type in expected_rhs_types.iter() {
2979 if !expected_type.has_implicit_cast_from(&rhs) {
2980 continue;
2981 }
2982
2983 let casting = Box::new(CastExpr {
2984 value: rhs,
2985 result_type: expected_type.clone(),
2986 });
2987
2988 lhs = Box::new(ArithmeticExpr {
2989 left: lhs,
2990 operator: ArithmeticOperator::Modulus,
2991 right: casting,
2992 result_type: lhs_type.rem_op_result_type(expected_type),
2993 });
2994
2995 continue 'parse_expr;
2996 }
2997
2998 let expected_lhs_types = rhs_type.can_perform_rem_op_with();
3001 for expected_type in expected_lhs_types.iter() {
3002 if !expected_type.has_implicit_cast_from(&lhs) {
3003 continue;
3004 }
3005
3006 let casting = Box::new(CastExpr {
3007 value: lhs,
3008 result_type: expected_type.clone(),
3009 });
3010
3011 lhs = Box::new(ArithmeticExpr {
3012 left: casting,
3013 operator: ArithmeticOperator::Modulus,
3014 right: rhs,
3015 result_type: rhs_type.rem_op_result_type(expected_type),
3016 });
3017
3018 continue 'parse_expr;
3019 }
3020
3021 return Err(Diagnostic::error(&format!(
3023 "Operator `%` can't be performed between types `{}` and `{}`",
3024 lhs_type, rhs_type
3025 ))
3026 .with_location(operator.location)
3027 .as_boxed());
3028 }
3029
3030 if operator.kind == TokenKind::Caret {
3032 let expected_rhs_types = lhs_type.can_perform_caret_op_with();
3033
3034 if expected_rhs_types.contains(&rhs_type) {
3035 lhs = Box::new(ArithmeticExpr {
3036 left: lhs,
3037 operator: ArithmeticOperator::Exponentiation,
3038 right: rhs,
3039 result_type: lhs_type.caret_op_result_type(&rhs_type),
3040 });
3041
3042 continue 'parse_expr;
3043 }
3044
3045 for expected_type in expected_rhs_types.iter() {
3048 if !expected_type.has_implicit_cast_from(&rhs) {
3049 continue;
3050 }
3051
3052 let casting = Box::new(CastExpr {
3053 value: rhs,
3054 result_type: expected_type.clone(),
3055 });
3056
3057 lhs = Box::new(ArithmeticExpr {
3058 left: lhs,
3059 operator: ArithmeticOperator::Exponentiation,
3060 right: casting,
3061 result_type: lhs_type.caret_op_result_type(expected_type),
3062 });
3063
3064 continue 'parse_expr;
3065 }
3066
3067 let expected_lhs_types = rhs_type.can_perform_caret_op_with();
3070 for expected_type in expected_lhs_types.iter() {
3071 if !expected_type.has_implicit_cast_from(&lhs) {
3072 continue;
3073 }
3074
3075 let casting = Box::new(CastExpr {
3076 value: lhs,
3077 result_type: expected_type.clone(),
3078 });
3079
3080 lhs = Box::new(ArithmeticExpr {
3081 left: casting,
3082 operator: ArithmeticOperator::Exponentiation,
3083 right: rhs,
3084 result_type: rhs_type.caret_op_result_type(expected_type),
3085 });
3086
3087 continue 'parse_expr;
3088 }
3089
3090 return Err(Diagnostic::error(&format!(
3092 "Operator `^` can't be performed between types `{}` and `{}`",
3093 lhs_type, rhs_type
3094 ))
3095 .with_location(operator.location)
3096 .as_boxed());
3097 }
3098 }
3099
3100 Ok(lhs)
3101}
3102
3103fn parse_like_expression(
3104 context: &mut ParserContext,
3105 env: &mut Environment,
3106 tokens: &[Token],
3107 position: &mut usize,
3108) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3109 let lhs = parse_glob_expression(context, env, tokens, position)?;
3110
3111 if is_current_token(tokens, position, TokenKind::Like)
3115 || (is_current_token(tokens, position, TokenKind::Not)
3116 && is_next_token(tokens, position, TokenKind::Like))
3117 {
3118 let has_not_keyword = is_current_token(tokens, position, TokenKind::Not);
3119 let operator_location: SourceLocation = if has_not_keyword {
3120 *position += 2;
3122 let mut not_location = tokens[*position - 2].location;
3123 let between_location = tokens[*position - 1].location;
3124 not_location.expand_until(between_location);
3125 not_location
3126 } else {
3127 *position += 1;
3129 tokens[*position - 1].location
3130 };
3131
3132 let pattern = parse_glob_expression(context, env, tokens, position)?;
3133
3134 let lhs_type = lhs.expr_type();
3135 let rhs_type = pattern.expr_type();
3136
3137 let expected_rhs_types = lhs_type.can_perform_like_op_with();
3139 if expected_rhs_types.contains(&rhs_type) {
3140 let expr = Box::new(LikeExpr {
3141 input: lhs,
3142 pattern,
3143 });
3144
3145 return Ok(apply_not_keyword_if_exists(expr, has_not_keyword));
3146 }
3147
3148 for expected_type in expected_rhs_types.iter() {
3151 if !expected_type.has_implicit_cast_from(&pattern) {
3152 continue;
3153 }
3154
3155 let casting = Box::new(CastExpr {
3156 value: pattern,
3157 result_type: expected_type.clone(),
3158 });
3159
3160 let expr = Box::new(LikeExpr {
3161 input: lhs,
3162 pattern: casting,
3163 });
3164
3165 return Ok(apply_not_keyword_if_exists(expr, has_not_keyword));
3166 }
3167
3168 return Err(Diagnostic::error(&format!(
3170 "Operator `LIKE` can't be performed between types `{}` and `{}`",
3171 lhs_type, rhs_type
3172 ))
3173 .with_location(operator_location)
3174 .as_boxed());
3175 }
3176
3177 Ok(lhs)
3178}
3179
3180fn parse_glob_expression(
3181 context: &mut ParserContext,
3182 env: &mut Environment,
3183 tokens: &[Token],
3184 position: &mut usize,
3185) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3186 let lhs = parse_cast_operator_expression(context, env, tokens, position)?;
3187
3188 if is_current_token(tokens, position, TokenKind::Glob) {
3189 let glob_location = tokens[*position].location;
3190
3191 *position += 1;
3193
3194 let pattern = parse_cast_operator_expression(context, env, tokens, position)?;
3195
3196 let lhs_type = lhs.expr_type();
3197 let rhs_type = pattern.expr_type();
3198
3199 let expected_rhs_types = lhs_type.can_perform_glob_op_with();
3201 if expected_rhs_types.contains(&rhs_type) {
3202 return Ok(Box::new(GlobExpr {
3203 input: lhs,
3204 pattern,
3205 }));
3206 }
3207
3208 for expected_type in expected_rhs_types.iter() {
3211 if !expected_type.has_implicit_cast_from(&pattern) {
3212 continue;
3213 }
3214
3215 let casting = Box::new(CastExpr {
3216 value: pattern,
3217 result_type: expected_type.clone(),
3218 });
3219
3220 return Ok(Box::new(GlobExpr {
3221 input: lhs,
3222 pattern: casting,
3223 }));
3224 }
3225
3226 return Err(Diagnostic::error(&format!(
3228 "Operator `GLOB` can't be performed between types `{}` and `{}`",
3229 lhs_type, rhs_type
3230 ))
3231 .with_location(glob_location)
3232 .as_boxed());
3233 }
3234
3235 Ok(lhs)
3236}
3237
3238pub(crate) fn parse_index_or_slice_expression(
3239 context: &mut ParserContext,
3240 env: &mut Environment,
3241 tokens: &[Token],
3242 position: &mut usize,
3243) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3244 let mut lhs = parse_prefix_unary_expression(context, env, tokens, position)?;
3245
3246 'parse_expr: while *position < tokens.len() && tokens[*position].kind == TokenKind::LeftBracket
3247 {
3248 let operator = &tokens[*position];
3249
3250 *position += 1;
3252
3253 let lhs_type = lhs.expr_type();
3254
3255 if is_current_token(tokens, position, TokenKind::Colon) {
3257 *position += 1;
3259
3260 if is_current_token(tokens, position, TokenKind::RightBracket) {
3263 *position += 1;
3265 return Ok(lhs);
3266 }
3267
3268 let slice_end = parse_prefix_unary_expression(context, env, tokens, position)?;
3269 let end_type = slice_end.expr_type();
3270
3271 if !lhs_type.can_perform_slice_op() {
3273 return Err(Diagnostic::error(&format!(
3274 "Operator `[:]` can't be performed on type `{}`",
3275 lhs_type
3276 ))
3277 .with_location(calculate_safe_location(tokens, *position))
3278 .as_boxed());
3279 }
3280
3281 let rhs_expected_types = lhs_type.can_perform_slice_op_with();
3283 if !rhs_expected_types.contains(&end_type) {
3284 return Err(Diagnostic::error(&format!(
3285 "Operator `[:]` can't be performed with type of index `{}`",
3286 end_type.literal()
3287 ))
3288 .with_location(calculate_safe_location(tokens, *position))
3289 .as_boxed());
3290 }
3291
3292 consume_token_or_error(
3294 tokens,
3295 position,
3296 TokenKind::RightBracket,
3297 "Expect `]` After Slice expression",
3298 )?;
3299
3300 lhs = Box::new(SliceExpr {
3301 collection: lhs,
3302 start: None,
3303 end: Some(slice_end),
3304 result_type: lhs_type.clone(),
3305 });
3306
3307 continue 'parse_expr;
3308 }
3309
3310 let index = parse_prefix_unary_expression(context, env, tokens, position)?;
3311 let index_type = index.expr_type();
3312
3313 if is_current_token(tokens, position, TokenKind::Colon) {
3315 *position += 1;
3317
3318 if is_current_token(tokens, position, TokenKind::RightBracket) {
3320 *position += 1;
3322
3323 let rhs_expected_types = lhs_type.can_perform_slice_op_with();
3324 if rhs_expected_types.contains(&index_type) {
3325 return Ok(Box::new(SliceExpr {
3326 collection: lhs,
3327 start: Some(index),
3328 end: None,
3329 result_type: lhs_type.clone(),
3330 }));
3331 }
3332
3333 return Err(Diagnostic::error(&format!(
3334 "Operator Slice `[:]` can't be performed between on {} with start `{}` and end `{}`",
3335 lhs_type,
3336 index_type.literal(),
3337 "None"
3338 ))
3339 .with_location(operator.location)
3340 .as_boxed());
3341 }
3342
3343 let slice_end = parse_prefix_unary_expression(context, env, tokens, position)?;
3344 let end_type = slice_end.expr_type();
3345
3346 if !index_type.equals(&end_type) {
3348 return Err(Diagnostic::error(&format!(
3349 "Operator Slice `[:]` start and end types must be equals but found `{}` and `{}`",
3350 index_type.literal(),
3351 end_type.literal()
3352 ))
3353 .with_location(operator.location)
3354 .as_boxed());
3355 }
3356
3357 let rhs_expected_types = lhs_type.can_perform_slice_op_with();
3358 if !rhs_expected_types.contains(&end_type) {
3359 return Err(Diagnostic::error(&format!(
3360 "Operator Slice `[:]` can't be performed between on {} with start `{}` and end `{}`",
3361 lhs_type,
3362 index_type.literal(),
3363 end_type.literal()
3364 ))
3365 .with_location(operator.location)
3366 .as_boxed());
3367 }
3368
3369 consume_token_or_error(
3371 tokens,
3372 position,
3373 TokenKind::RightBracket,
3374 "Expect `]` After Slice expression",
3375 )?;
3376
3377 lhs = Box::new(SliceExpr {
3378 collection: lhs,
3379 start: Some(index),
3380 end: Some(slice_end),
3381 result_type: lhs_type.clone(),
3382 });
3383
3384 continue 'parse_expr;
3385 }
3386
3387 let rhs_expected_types = lhs_type.can_perform_index_op_with();
3389 if !rhs_expected_types.contains(&index_type) {
3390 return Err(Diagnostic::error(&format!(
3391 "Operator Index `[ ]` can't be performed on type `{}` with index type `{}`",
3392 lhs_type,
3393 index_type.literal(),
3394 ))
3395 .add_help("Check the Type documentation to know the available Index types")
3396 .with_location(operator.location)
3397 .as_boxed());
3398 }
3399
3400 consume_token_or_error(
3402 tokens,
3403 position,
3404 TokenKind::RightBracket,
3405 "Expect `]` After Index expression",
3406 )?;
3407
3408 let array_element_type =
3409 if let Some(array_type) = lhs_type.as_any().downcast_ref::<ArrayType>() {
3410 array_type.base.clone()
3411 } else {
3412 Box::new(AnyType)
3413 };
3414
3415 let result_type = lhs_type.index_op_result_type(&index_type);
3416
3417 lhs = Box::new(IndexExpr {
3418 collection: lhs,
3419 element_type: array_element_type.clone(),
3420 index,
3421 result_type,
3422 });
3423
3424 continue 'parse_expr;
3425 }
3426
3427 Ok(lhs)
3428}
3429
3430fn parse_prefix_unary_expression(
3431 context: &mut ParserContext,
3432 env: &mut Environment,
3433 tokens: &[Token],
3434 position: &mut usize,
3435) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3436 if *position < tokens.len() && is_prefix_unary_operator(&tokens[*position]) {
3437 let operator = &tokens[*position];
3438
3439 *position += 1;
3441
3442 let rhs = parse_prefix_unary_expression(context, env, tokens, position)?;
3443 let rhs_type = rhs.expr_type();
3444
3445 if operator.kind == TokenKind::Bang || operator.kind == TokenKind::Not {
3447 if rhs_type.can_perform_bang_op() {
3449 return Ok(Box::new(UnaryExpr {
3450 right: rhs,
3451 operator: PrefixUnaryOperator::Bang,
3452 result_type: rhs_type.bang_op_result_type(),
3453 }));
3454 }
3455
3456 let op_name = if operator.kind == TokenKind::Bang {
3458 "!"
3459 } else {
3460 "NOT"
3461 };
3462
3463 return Err(Diagnostic::error(&format!(
3464 "Operator unary `{}` can't be performed on type `{}`",
3465 op_name, rhs_type
3466 ))
3467 .with_location(operator.location)
3468 .as_boxed());
3469 }
3470
3471 if operator.kind == TokenKind::Minus {
3473 if rhs_type.can_perform_neg_op() {
3475 return Ok(Box::new(UnaryExpr {
3476 right: rhs,
3477 operator: PrefixUnaryOperator::Negative,
3478 result_type: rhs_type.neg_op_result_type(),
3479 }));
3480 }
3481
3482 return Err(Diagnostic::error(&format!(
3484 "Operator unary `-` can't be performed on type `{}`",
3485 rhs_type
3486 ))
3487 .with_location(operator.location)
3488 .as_boxed());
3489 }
3490
3491 if operator.kind == TokenKind::BitwiseNot {
3493 if rhs_type.can_perform_not_op() {
3495 return Ok(Box::new(UnaryExpr {
3496 right: rhs,
3497 operator: PrefixUnaryOperator::Not,
3498 result_type: rhs_type.not_op_result_type(),
3499 }));
3500 }
3501
3502 return Err(Diagnostic::error(&format!(
3504 "Operator unary `~` can't be performed on type `{}`",
3505 rhs_type
3506 ))
3507 .with_location(operator.location)
3508 .as_boxed());
3509 }
3510 }
3511
3512 parse_between_expression(context, env, tokens, position)
3513}
3514
3515fn parse_between_expression(
3516 context: &mut ParserContext,
3517 env: &mut Environment,
3518 tokens: &[Token],
3519 position: &mut usize,
3520) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3521 let expression = parse_function_call_expression(context, env, tokens, position)?;
3522
3523 if is_current_token(tokens, position, TokenKind::Between)
3527 || (is_current_token(tokens, position, TokenKind::Not)
3528 && is_next_token(tokens, position, TokenKind::Between))
3529 {
3530 let has_not_keyword = is_current_token(tokens, position, TokenKind::Not);
3531 let operator_location = if has_not_keyword {
3532 *position += 2;
3534 let mut not_location = tokens[*position - 2].location;
3535 let between_location = tokens[*position - 1].location;
3536 not_location.expand_until(between_location);
3537 not_location
3538 } else {
3539 *position += 1;
3541 tokens[*position - 1].location
3542 };
3543
3544 let kind = parse_between_expr_kind(tokens, position);
3545 let range_start = parse_function_call_expression(context, env, tokens, position)?;
3546
3547 consume_token_or_error(
3549 tokens,
3550 position,
3551 TokenKind::AndKeyword,
3552 "Expect `AND` after `BETWEEN` range start",
3553 )?;
3554
3555 let range_end = parse_function_call_expression(context, env, tokens, position)?;
3556
3557 let lhs_type = expression.expr_type();
3558 let range_start_type = &range_start.expr_type();
3559 let range_end_type = &range_end.expr_type();
3560
3561 if !lhs_type.equals(range_start_type) || !lhs_type.equals(range_end_type) {
3563 return Err(Diagnostic::error(&format!(
3564 "Expect `BETWEEN` Left hand side type, range start and end to has same type but got {}, {} and {}",
3565 lhs_type,
3566 range_start_type.literal(),
3567 range_end_type.literal()
3568 ))
3569 .add_help("Try to make sure all of them has same type")
3570 .with_location(operator_location)
3571 .as_boxed());
3572 }
3573
3574 if !lhs_type.can_perform_gte_op_with().contains(&lhs_type) {
3576 return Err(Diagnostic::error(&format!(
3577 "Type `{}` used in Between expression can't support `>=` operator",
3578 lhs_type
3579 ))
3580 .with_location(operator_location)
3581 .as_boxed());
3582 }
3583
3584 if !lhs_type.can_perform_lte_op_with().contains(&lhs_type) {
3586 return Err(Diagnostic::error(&format!(
3587 "Type `{}` used in Between expression can't support `<=` operator",
3588 lhs_type
3589 ))
3590 .with_location(operator_location)
3591 .as_boxed());
3592 }
3593
3594 let between_expr = Box::new(BetweenExpr {
3595 value: expression,
3596 range_start,
3597 range_end,
3598 kind,
3599 });
3600
3601 return Ok(apply_not_keyword_if_exists(between_expr, has_not_keyword));
3602 }
3603
3604 Ok(expression)
3605}
3606
3607fn parse_between_expr_kind(tokens: &[Token], position: &mut usize) -> BetweenKind {
3608 if *position < tokens.len() {
3609 let token_kind = &tokens[*position].kind;
3610 if matches!(token_kind, TokenKind::Asymmetric | TokenKind::Symmetric) {
3611 *position += 1;
3612 return if token_kind == &TokenKind::Asymmetric {
3613 BetweenKind::Asymmetric
3614 } else {
3615 BetweenKind::Symmetric
3616 };
3617 }
3618 }
3619 BetweenKind::Asymmetric
3620}
3621
3622pub(crate) fn parse_zero_or_more_values_with_comma_between(
3623 context: &mut ParserContext,
3624 env: &mut Environment,
3625 tokens: &[Token],
3626 position: &mut usize,
3627 expression_name: &str,
3628) -> Result<Vec<Box<dyn Expr>>, Box<Diagnostic>> {
3629 consume_token_or_error(
3631 tokens,
3632 position,
3633 TokenKind::LeftParen,
3634 &format!("Expect `(` after {}", expression_name),
3635 )?;
3636
3637 let mut arguments: Vec<Box<dyn Expr>> = vec![];
3638 while *position < tokens.len() && tokens[*position].kind != TokenKind::RightParen {
3639 let argument = parse_expression(context, env, tokens, position)?;
3640 if let Some(argument_literal) = expression_literal(&argument) {
3641 context.hidden_selections.push(argument_literal);
3642 }
3643
3644 arguments.push(argument);
3645
3646 if *position < tokens.len() && tokens[*position].kind == TokenKind::Comma {
3647 *position += 1;
3648 } else {
3649 break;
3650 }
3651 }
3652
3653 consume_token_or_error(
3655 tokens,
3656 position,
3657 TokenKind::RightParen,
3658 "Expect `)` at the end of zero or more values",
3659 )?;
3660
3661 Ok(arguments)
3662}
3663
3664pub(crate) fn parse_member_access_expression(
3665 context: &mut ParserContext,
3666 env: &mut Environment,
3667 tokens: &[Token],
3668 position: &mut usize,
3669) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3670 let expr = parse_primary_expression(context, env, tokens, position)?;
3671
3672 if is_current_token(tokens, position, TokenKind::Dot) {
3673 let dot_token = &tokens[*position];
3674
3675 if expr.kind() != ExprKind::Grouping {
3678 return Err(
3679 Diagnostic::error("Dot token expect composite value between `(` and `)`")
3680 .add_note("The syntax for accessing composite element is (composite).member")
3681 .with_location(dot_token.location)
3682 .as_boxed(),
3683 );
3684 }
3685
3686 *position += 1;
3688
3689 if let Some(composite_type) = expr.expr_type().as_any().downcast_ref::<CompositeType>() {
3691 if *position < tokens.len() && matches!(tokens[*position].kind, TokenKind::Symbol(_)) {
3692 let member_token = &tokens[*position];
3693
3694 *position += 1;
3696
3697 let member_name = member_token.to_string();
3698
3699 if !composite_type.members.contains_key(&member_name) {
3701 return Err(Diagnostic::error(&format!(
3702 "Compose type {} has no member with name {}",
3703 composite_type.name, member_name
3704 ))
3705 .add_help("Check the Composite type to see what are his members")
3706 .with_location(member_token.location)
3707 .as_boxed());
3708 }
3709
3710 let member_type = composite_type.members.get(&member_name).unwrap().clone();
3711 return Ok(Box::new(MemberAccessExpr {
3712 composite: expr,
3713 member_name,
3714 member_type,
3715 }));
3716 }
3717
3718 return Err(Diagnostic::error("Member access expect symbol after `.`")
3720 .add_note("The syntax for accessing composite element is (composite).member")
3721 .with_location(dot_token.location)
3722 .as_boxed());
3723 }
3724
3725 return Err(Diagnostic::error(&format!(
3727 "Member access expect Composite type between `(` and `)` but got {}",
3728 expr.expr_type().literal()
3729 ))
3730 .with_location(dot_token.location)
3731 .as_boxed());
3732 }
3733
3734 Ok(expr)
3735}
3736
3737fn parse_primary_expression(
3738 context: &mut ParserContext,
3739 env: &mut Environment,
3740 tokens: &[Token],
3741 position: &mut usize,
3742) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3743 if *position >= tokens.len() {
3744 return Err(un_expected_expression_error(tokens, position));
3745 }
3746
3747 match &tokens[*position].kind {
3748 TokenKind::Integer(_) => parse_const_integer_expression(tokens, position),
3749 TokenKind::Float(_) => parse_const_float_expression(tokens, position),
3750 TokenKind::Infinity => parse_float_infinity_or_nan_expression(tokens, position),
3751 TokenKind::NaN => parse_float_infinity_or_nan_expression(tokens, position),
3752 TokenKind::Symbol(_) => parse_symbol_expression(context, env, tokens, position),
3753 TokenKind::Array => parse_array_value_expression(context, env, tokens, position),
3754 TokenKind::LeftBracket => parse_array_value_expression(context, env, tokens, position),
3755 TokenKind::LeftParen => parse_group_expression(context, env, tokens, position),
3756 TokenKind::Case => parse_case_expression(context, env, tokens, position),
3757 TokenKind::Cast => parse_cast_call_expression(context, env, tokens, position),
3758 TokenKind::Benchmark => parse_benchmark_call_expression(context, env, tokens, position),
3759 TokenKind::GlobalVariable(_) => parse_global_variable_expression(env, tokens, position),
3760 TokenKind::Interval => parse_interval_expression(tokens, position),
3761 TokenKind::String(str) => {
3762 *position += 1;
3763 let value = str.to_string();
3764 Ok(Box::new(StringExpr { value }))
3765 }
3766 TokenKind::True => {
3767 *position += 1;
3768 Ok(Box::new(BooleanExpr { is_true: true }))
3769 }
3770 TokenKind::False => {
3771 *position += 1;
3772 Ok(Box::new(BooleanExpr { is_true: false }))
3773 }
3774 TokenKind::Null => {
3775 *position += 1;
3776 Ok(Box::new(NullExpr {}))
3777 }
3778 _ => Err(un_expected_expression_error(tokens, position)),
3779 }
3780}
3781
3782fn parse_const_integer_expression(
3783 tokens: &[Token],
3784 position: &mut usize,
3785) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3786 match tokens[*position].kind {
3787 TokenKind::Integer(integer) => {
3788 *position += 1;
3789 let value = Number::Int(integer);
3790 Ok(Box::new(NumberExpr { value }))
3791 }
3792 _ => Err(Diagnostic::error("Too big Integer value")
3793 .add_help("Try to use smaller value")
3794 .add_note(&format!(
3795 "Integer value must be between {} and {}",
3796 i64::MIN,
3797 i64::MAX
3798 ))
3799 .with_location(tokens[*position].location)
3800 .as_boxed()),
3801 }
3802}
3803
3804fn parse_const_float_expression(
3805 tokens: &[Token],
3806 position: &mut usize,
3807) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3808 match tokens[*position].kind {
3809 TokenKind::Float(float) => {
3810 *position += 1;
3811 let value = Number::Float(float);
3812 Ok(Box::new(NumberExpr { value }))
3813 }
3814 _ => Err(Diagnostic::error("Too big Float value")
3815 .add_help("Try to use smaller value")
3816 .add_note(&format!(
3817 "Float value must be between {} and {}",
3818 f64::MIN,
3819 f64::MAX
3820 ))
3821 .with_location(tokens[*position].location)
3822 .as_boxed()),
3823 }
3824}
3825
3826fn parse_float_infinity_or_nan_expression(
3827 tokens: &[Token],
3828 position: &mut usize,
3829) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3830 if tokens[*position].kind == TokenKind::Infinity {
3831 *position += 1;
3832 let value = Number::Float(f64::INFINITY);
3833 return Ok(Box::new(NumberExpr { value }));
3834 }
3835
3836 *position += 1;
3837
3838 let value = Number::Float(f64::NAN);
3839 Ok(Box::new(NumberExpr { value }))
3840}
3841
3842fn parse_symbol_expression(
3843 context: &mut ParserContext,
3844 env: &mut Environment,
3845 tokens: &[Token],
3846 position: &mut usize,
3847) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3848 let mut value = tokens[*position].to_string();
3849 let location = tokens[*position].location;
3850
3851 if !context.has_select_statement {
3853 context.projection_names.push(value.to_string());
3854 context.projection_locations.push(location);
3855
3856 if let Some(symbol_type) = env.schema.tables_fields_types.get(&value.as_str()) {
3859 if symbol_type.is_composite() && !context.hidden_selections.contains(&value) {
3860 context.hidden_selections.push(value.to_string());
3861 }
3862 }
3863 }
3864
3865 if context.inside_over_clauses
3867 && env.schema.tables_fields_types.contains_key(&value.as_str())
3868 && !context.hidden_selections.contains(&value)
3869 {
3870 context.hidden_selections.push(value.to_string());
3871 }
3872
3873 if context.has_select_statement {
3874 if context.name_alias_table.contains_key(&value) {
3878 value = context.name_alias_table[&value].to_string();
3879 }
3880
3881 if !env.scopes.contains_key(&value) {
3882 return Err(Diagnostic::error("Unresolved column or variable name")
3883 .add_help("Please check schema from docs website or SHOW query")
3884 .with_location(tokens[*position].location)
3885 .as_boxed());
3886 }
3887
3888 if !context.selected_fields.contains(&value) {
3889 context.hidden_selections.push(value.to_string());
3890 }
3891 }
3892
3893 let mut symbol_name = &value;
3894
3895 let has_alias = context.name_alias_table.values().any(|v| v.eq(symbol_name));
3897 if has_alias {
3898 for (key, value) in context.name_alias_table.iter() {
3899 if value.eq(symbol_name) {
3900 symbol_name = key;
3901 break;
3902 }
3903 }
3904 }
3905
3906 if context.aggregations.contains_key(symbol_name)
3908 && !(context.inside_selections || context.inside_having || context.inside_order_by)
3909 {
3910 return Err(Diagnostic::error(
3911 "Can't use the value of aggregation function outside selection or order by",
3912 )
3913 .with_location(calculate_safe_location(tokens, *position))
3914 .as_boxed());
3915 }
3916
3917 if context.window_functions.contains_key(symbol_name)
3919 && !(context.inside_selections || context.inside_order_by)
3920 {
3921 return Err(Diagnostic::error(
3922 "Can't use the value of window function outside selection or order by",
3923 )
3924 .with_location(calculate_safe_location(tokens, *position))
3925 .as_boxed());
3926 }
3927
3928 *position += 1;
3930
3931 let result_type = resolve_symbol_type_or_undefine(env, &value);
3932
3933 Ok(Box::new(SymbolExpr {
3934 value,
3935 expr_type: result_type,
3936 flag: SymbolFlag::None,
3937 }))
3938}
3939
3940fn parse_array_value_expression(
3941 context: &mut ParserContext,
3942 env: &mut Environment,
3943 tokens: &[Token],
3944 position: &mut usize,
3945) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
3946 if *position < tokens.len() && tokens[*position].kind == TokenKind::Array {
3948 *position += 1;
3950
3951 if *position >= tokens.len() || tokens[*position].kind != TokenKind::LeftBracket {
3953 return Err(Diagnostic::error("Expect `[` after `ARRAY` keyword")
3954 .with_location(calculate_safe_location(tokens, *position))
3955 .add_help("Try to add '[' after `ARRAY` keyword")
3956 .as_boxed());
3957 }
3958 }
3959
3960 *position += 1;
3962
3963 let mut array_values: Vec<Box<dyn Expr>> = vec![];
3965 let mut array_data_type: Box<dyn DataType> = Box::new(AnyType);
3966 while *position < tokens.len() && tokens[*position].kind != TokenKind::RightBracket {
3967 let value = parse_expression(context, env, tokens, position)?;
3968 let value_type = value.expr_type();
3969 if !value_type.equals(&array_data_type) {
3970 return Err(Diagnostic::error("Expect Array values to have same types")
3971 .with_location(calculate_safe_location(tokens, *position))
3972 .as_boxed());
3973 }
3974
3975 array_data_type = value_type;
3976 array_values.push(value);
3977
3978 if *position < tokens.len() && tokens[*position].kind == TokenKind::Comma {
3979 *position += 1;
3980 } else {
3981 break;
3982 }
3983 }
3984
3985 if *position >= tokens.len() || tokens[*position].kind != TokenKind::RightBracket {
3987 return Err(Diagnostic::error("Expect `]` at the end of array values")
3988 .with_location(calculate_safe_location(tokens, *position))
3989 .add_help("Try to add ']' at the end of array values")
3990 .as_boxed());
3991 }
3992
3993 *position += 1;
3995
3996 Ok(Box::new(ArrayExpr {
3997 values: array_values,
3998 element_type: array_data_type,
3999 }))
4000}
4001
4002fn parse_group_expression(
4003 context: &mut ParserContext,
4004 env: &mut Environment,
4005 tokens: &[Token],
4006 position: &mut usize,
4007) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
4008 *position += 1;
4010
4011 let expression = parse_expression(context, env, tokens, position)?;
4012 if tokens[*position].kind != TokenKind::RightParen {
4013 return Err(Diagnostic::error("Expect `)` to end group expression")
4014 .with_location(calculate_safe_location(tokens, *position))
4015 .add_help("Try to add ')' at the end of group expression")
4016 .as_boxed());
4017 }
4018
4019 *position += 1;
4021
4022 Ok(Box::new(GroupExpr { expr: expression }))
4023}
4024
4025fn parse_case_expression(
4026 context: &mut ParserContext,
4027 env: &mut Environment,
4028 tokens: &[Token],
4029 position: &mut usize,
4030) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
4031 let mut conditions: Vec<Box<dyn Expr>> = vec![];
4032 let mut values: Vec<Box<dyn Expr>> = vec![];
4033 let mut default_value: Option<Box<dyn Expr>> = None;
4034
4035 let case_location = tokens[*position].location;
4037 *position += 1;
4038
4039 let mut has_else_branch = false;
4040
4041 while *position < tokens.len() && tokens[*position].kind != TokenKind::End {
4042 if tokens[*position].kind == TokenKind::Else {
4044 if has_else_branch {
4045 return Err(
4046 Diagnostic::error("This `CASE` expression already has else branch")
4047 .add_note("`CASE` expression can has only one `ELSE` branch")
4048 .with_location(calculate_safe_location(tokens, *position))
4049 .as_boxed(),
4050 );
4051 }
4052
4053 *position += 1;
4055
4056 let default_value_expr = parse_expression(context, env, tokens, position)?;
4057 default_value = Some(default_value_expr);
4058 has_else_branch = true;
4059 continue;
4060 }
4061
4062 consume_token_or_error(
4064 tokens,
4065 position,
4066 TokenKind::When,
4067 "Expect `when` before case condition",
4068 )?;
4069
4070 let condition = parse_expression(context, env, tokens, position)?;
4071 if !condition.expr_type().is_bool() {
4072 return Err(Diagnostic::error("Case condition must be a boolean type")
4073 .with_location(calculate_safe_location(tokens, *position))
4074 .as_boxed());
4075 }
4076
4077 conditions.push(condition);
4078
4079 consume_token_or_error(
4081 tokens,
4082 position,
4083 TokenKind::Then,
4084 "Expect `THEN` after case condition",
4085 )?;
4086
4087 let expression = parse_expression(context, env, tokens, position)?;
4088 values.push(expression);
4089 }
4090
4091 if conditions.is_empty() && !has_else_branch {
4093 return Err(
4094 Diagnostic::error("Case expression must has at least else branch")
4095 .with_location(calculate_safe_location(tokens, *position))
4096 .as_boxed(),
4097 );
4098 }
4099
4100 if *position >= tokens.len() || tokens[*position].kind != TokenKind::End {
4102 return Err(Diagnostic::error("Expect `END` after case branches")
4103 .with_location(calculate_safe_location(tokens, *position))
4104 .as_boxed());
4105 }
4106
4107 *position += 1;
4109
4110 if !has_else_branch {
4112 return Err(Diagnostic::error("Case expression must has else branch")
4113 .with_location(calculate_safe_location(tokens, *position))
4114 .as_boxed());
4115 }
4116
4117 let values_type = values[0].expr_type();
4119 for (i, value) in values.iter().enumerate().skip(1) {
4120 if !values_type.equals(&value.expr_type()) {
4121 return Err(Diagnostic::error(&format!(
4122 "Case value in branch {} has different type than the last branch",
4123 i + 1
4124 ))
4125 .add_note("All values in `CASE` expression must has the same Type")
4126 .with_location(case_location)
4127 .as_boxed());
4128 }
4129 }
4130
4131 Ok(Box::new(CaseExpr {
4132 conditions,
4133 values,
4134 default_value,
4135 values_type,
4136 }))
4137}
4138
4139fn parse_benchmark_call_expression(
4140 context: &mut ParserContext,
4141 env: &mut Environment,
4142 tokens: &[Token],
4143 position: &mut usize,
4144) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
4145 *position += 1;
4147
4148 if *position >= tokens.len() || tokens[*position].kind != TokenKind::LeftParen {
4149 return Err(Diagnostic::error("Expect `(` after `Benchmark` keyword")
4150 .with_location(calculate_safe_location(tokens, *position))
4151 .add_help("Try to add '(' right after `Benchmark` keyword")
4152 .as_boxed());
4153 }
4154
4155 *position += 1;
4157
4158 let count = parse_expression(context, env, tokens, position)?;
4159 if !count.expr_type().is_int() {
4160 return Err(
4161 Diagnostic::error("Benchmark expect first argument to be integer")
4162 .with_location(calculate_safe_location(tokens, *position))
4163 .add_help("Try to integer value as first argument, eg: `Benchmark(10, 1 + 1)`")
4164 .as_boxed(),
4165 );
4166 }
4167
4168 if *position >= tokens.len() || tokens[*position].kind != TokenKind::Comma {
4169 return Err(
4170 Diagnostic::error("Expect `,` after Benchmark first argument value")
4171 .with_location(calculate_safe_location(tokens, *position))
4172 .add_help("Make sure you passed two arguments to the Benchmark function")
4173 .as_boxed(),
4174 );
4175 }
4176
4177 *position += 1;
4179
4180 let expression = parse_expression(context, env, tokens, position)?;
4181
4182 if *position >= tokens.len() || tokens[*position].kind != TokenKind::RightParen {
4183 return Err(Diagnostic::error("Expect `)` after `Benchmark` arguments")
4184 .with_location(calculate_safe_location(tokens, *position))
4185 .add_help("Try to add ')` after `Benchmark` arguments")
4186 .as_boxed());
4187 }
4188
4189 *position += 1;
4191
4192 Ok(Box::new(BenchmarkCallExpr { expression, count }))
4193}
4194
4195fn parse_global_variable_expression(
4196 env: &mut Environment,
4197 tokens: &[Token],
4198 position: &mut usize,
4199) -> Result<Box<dyn Expr>, Box<Diagnostic>> {
4200 let name = tokens[*position].to_string();
4201 *position += 1;
4202 let result_type = if env.globals_types.contains_key(&name) {
4203 env.globals_types[name.as_str()].clone()
4204 } else {
4205 Box::new(UndefType)
4206 };
4207 Ok(Box::new(GlobalVariableExpr { name, result_type }))
4208}
4209
4210fn un_expected_statement_error(tokens: &[Token], position: &mut usize) -> Box<Diagnostic> {
4211 let token: &Token = &tokens[*position];
4212 let location = token.location;
4213
4214 if *position == 0 {
4216 return Diagnostic::error("Unexpected statement")
4217 .add_help("Expect query to start with `SELECT` or `SET` keyword")
4218 .with_location(location)
4219 .as_boxed();
4220 }
4221
4222 Diagnostic::error("Unexpected statement")
4224 .with_location(location)
4225 .as_boxed()
4226}
4227
4228fn un_expected_expression_error(tokens: &[Token], position: &usize) -> Box<Diagnostic> {
4229 let location = calculate_safe_location(tokens, *position);
4230
4231 if *position == 0 || *position >= tokens.len() {
4232 return Diagnostic::error("Can't complete parsing this expression")
4233 .with_location(location)
4234 .as_boxed();
4235 }
4236
4237 let current = &tokens[*position];
4238 let previous = &tokens[*position - 1];
4239
4240 if current.kind == TokenKind::Ascending || current.kind == TokenKind::Descending {
4242 return Diagnostic::error("`ASC` and `DESC` must be used in `ORDER BY` statement")
4243 .with_location(location)
4244 .as_boxed();
4245 }
4246
4247 if previous.kind == TokenKind::Equal && current.kind == TokenKind::Equal {
4249 return Diagnostic::error("Unexpected `==`, Just use `=` to check equality")
4250 .add_help("Try to remove the extra `=`")
4251 .with_location(location)
4252 .as_boxed();
4253 }
4254
4255 if previous.kind == TokenKind::Greater && current.kind == TokenKind::Equal {
4257 return Diagnostic::error("Unexpected `> =`, do you mean `>=`?")
4258 .add_help("Try to remove space between `> =`")
4259 .with_location(location)
4260 .as_boxed();
4261 }
4262
4263 if previous.kind == TokenKind::Less && current.kind == TokenKind::Equal {
4265 return Diagnostic::error("Unexpected `< =`, do you mean `<=`?")
4266 .add_help("Try to remove space between `< =`")
4267 .with_location(location)
4268 .as_boxed();
4269 }
4270
4271 if previous.kind == TokenKind::Greater && current.kind == TokenKind::Greater {
4273 return Diagnostic::error("Unexpected `> >`, do you mean `>>`?")
4274 .add_help("Try to remove space between `> >`")
4275 .with_location(location)
4276 .as_boxed();
4277 }
4278
4279 if previous.kind == TokenKind::Less && current.kind == TokenKind::Less {
4281 return Diagnostic::error("Unexpected `< <`, do you mean `<<`?")
4282 .add_help("Try to remove space between `< <`")
4283 .with_location(location)
4284 .as_boxed();
4285 }
4286
4287 if previous.kind == TokenKind::Less && current.kind == TokenKind::Greater {
4289 return Diagnostic::error("Unexpected `< >`, do you mean `<>`?")
4290 .add_help("Try to remove space between `< >`")
4291 .with_location(location)
4292 .as_boxed();
4293 }
4294
4295 if previous.kind == TokenKind::LessEqual && current.kind == TokenKind::Greater {
4297 return Diagnostic::error("Unexpected `<= >`, do you mean `<=>`?")
4298 .add_help("Try to remove space between `<= >`")
4299 .with_location(location)
4300 .as_boxed();
4301 }
4302
4303 Diagnostic::error("Can't complete parsing this expression")
4305 .with_location(location)
4306 .as_boxed()
4307}
4308
4309fn un_expected_content_after_correct_statement(
4311 statement_name: &str,
4312 tokens: &[Token],
4313 position: &mut usize,
4314) -> Box<Diagnostic> {
4315 let error_message = &format!(
4316 "Unexpected content after the end of `{}` statement",
4317 statement_name.to_uppercase()
4318 );
4319
4320 let last_token_location = tokens[tokens.len() - 1].location;
4322 let mut location_of_extra_content = tokens[*position].location;
4323 location_of_extra_content.expand_until(last_token_location);
4324
4325 Diagnostic::error(error_message)
4326 .add_help("Try to check if statement keyword is missing")
4327 .add_help("Try remove un expected extra content")
4328 .with_location(location_of_extra_content)
4329 .as_boxed()
4330}
4331
4332#[inline(always)]
4333#[allow(clippy::borrowed_box)]
4334fn expression_literal(expression: &Box<dyn Expr>) -> Option<String> {
4335 if let Some(symbol) = expression.as_any().downcast_ref::<SymbolExpr>() {
4336 return Some(symbol.value.to_string());
4337 }
4338 None
4339}
4340
4341#[inline(always)]
4342fn resolve_symbol_type_or_undefine(env: &mut Environment, name: &String) -> Box<dyn DataType> {
4343 if let Some(symbol_type) = env.scopes.get(name) {
4344 symbol_type.clone()
4345 } else if let Some(symbol_type) = env.globals_types.get(name) {
4346 symbol_type.clone()
4347 } else if let Some(symbol_type) = env.schema.tables_fields_types.get(name.as_str()) {
4348 symbol_type.clone()
4349 } else {
4350 Box::new(UndefType)
4351 }
4352}
4353
4354#[inline(always)]
4355fn register_current_table_fields_types(
4356 env: &mut Environment,
4357 table_name: &str,
4358) -> Result<(), Box<Diagnostic>> {
4359 let table_fields_names = &env.schema.tables_fields_names[table_name].clone();
4360 for field_name in table_fields_names {
4361 if env.schema.tables_fields_types.contains_key(field_name) {
4362 let field_type = env.schema.tables_fields_types[field_name].clone();
4363 env.define(field_name.to_string(), field_type);
4364 continue;
4365 }
4366
4367 return Err(Diagnostic::error(
4368 &format!(
4369 "Column name {} in table {} has no type registered in the schema",
4370 field_name, table_name
4371 )
4372 .to_string(),
4373 )
4374 .as_boxed());
4375 }
4376
4377 Ok(())
4378}
4379
4380#[inline(always)]
4381fn select_all_table_fields(
4382 env: &mut Environment,
4383 table_name: &[String],
4384 selected_fields: &mut Vec<String>,
4385 fields_names: &mut Vec<String>,
4386) {
4387 let mut tables_columns: Vec<&str> = vec![];
4388 for table in table_name {
4389 let columns = env.schema.tables_fields_names.get(table.as_str()).unwrap();
4390 for column in columns {
4391 tables_columns.push(column);
4392 }
4393 }
4394
4395 for field in tables_columns {
4396 if !fields_names.contains(&field.to_string()) {
4397 fields_names.push(field.to_string());
4398 selected_fields.push(field.to_string());
4399 }
4400 }
4401}
4402
4403#[inline(always)]
4404fn apply_not_keyword_if_exists(expr: Box<dyn Expr>, is_not_exists: bool) -> Box<dyn Expr> {
4405 if is_not_exists {
4406 Box::new(UnaryExpr {
4407 right: expr,
4408 operator: PrefixUnaryOperator::Bang,
4409 result_type: Box::new(BoolType),
4410 })
4411 } else {
4412 expr
4413 }
4414}
4415
4416#[inline(always)]
4417pub(crate) fn is_current_token(
4418 tokens: &[Token],
4419 position: &usize,
4420 expected_kind: TokenKind,
4421) -> bool {
4422 *position < tokens.len() && tokens[*position].kind == expected_kind
4423}
4424
4425#[inline(always)]
4426pub(crate) fn is_next_token(tokens: &[Token], position: &usize, expected_kind: TokenKind) -> bool {
4427 *position + 1 < tokens.len() && tokens[*position + 1].kind == expected_kind
4428}
4429
4430#[inline(always)]
4431pub(crate) fn is_current_token_with_condition(
4432 tokens: &[Token],
4433 position: &usize,
4434 condition: fn(&Token) -> bool,
4435) -> bool {
4436 *position < tokens.len() && condition(&tokens[*position])
4437}
4438
4439#[inline(always)]
4440pub(crate) fn consume_token_or_error<'a>(
4441 tokens: &'a [Token],
4442 position: &'a mut usize,
4443 expected_kind: TokenKind,
4444 message: &'a str,
4445) -> Result<&'a Token, Box<Diagnostic>> {
4446 if *position < tokens.len() && tokens[*position].kind == expected_kind {
4447 *position += 1;
4448 let index = *position - 1;
4449 return Ok(&tokens[index]);
4450 }
4451
4452 Err(Diagnostic::error(message)
4453 .with_location(calculate_safe_location(tokens, *position))
4454 .as_boxed())
4455}
4456
4457#[inline(always)]
4458pub(crate) fn consume_conditional_token_or_errors<'a>(
4459 tokens: &'a [Token],
4460 position: &'a mut usize,
4461 condition: fn(&Token) -> bool,
4462 message: &'a str,
4463) -> Result<&'a Token, Box<Diagnostic>> {
4464 if *position < tokens.len() && condition(&tokens[*position]) {
4465 *position += 1;
4466 let index = *position - 1;
4467 return Ok(&tokens[index]);
4468 }
4469
4470 Err(Diagnostic::error(message)
4471 .with_location(calculate_safe_location(tokens, *position))
4472 .as_boxed())
4473}
4474
4475#[inline(always)]
4476pub(crate) fn calculate_safe_location(tokens: &[Token], position: usize) -> SourceLocation {
4477 if position < tokens.len() {
4478 return tokens[position].location;
4479 }
4480 tokens[tokens.len() - 1].location
4481}
4482
4483#[inline(always)]
4484pub(crate) fn is_logical_or_operator(tokens: &[Token], position: &usize) -> bool {
4485 *position < tokens.len()
4486 && matches!(
4487 tokens[*position].kind,
4488 TokenKind::OrOr | TokenKind::OrKeyword
4489 )
4490}
4491
4492#[inline(always)]
4493pub(crate) fn is_logical_and_operator(tokens: &[Token], position: &usize) -> bool {
4494 *position < tokens.len()
4495 && matches!(
4496 tokens[*position].kind,
4497 TokenKind::AndAnd | TokenKind::AndKeyword
4498 )
4499}
4500
4501#[inline(always)]
4502fn is_assignment_operator(token: &Token) -> bool {
4503 matches!(token.kind, TokenKind::Equal | TokenKind::ColonEqual)
4504}
4505
4506#[inline(always)]
4507fn is_term_operator(token: &Token) -> bool {
4508 matches!(token.kind, TokenKind::Plus | TokenKind::Minus)
4509}
4510
4511#[inline(always)]
4512fn is_bitwise_shift_operator(tokens: &[Token], position: &usize) -> bool {
4513 *position < tokens.len()
4514 && matches!(
4515 tokens[*position].kind,
4516 TokenKind::BitwiseLeftShift | TokenKind::BitwiseRightShift
4517 )
4518}
4519
4520#[inline(always)]
4521fn is_prefix_unary_operator(token: &Token) -> bool {
4522 matches!(
4523 token.kind,
4524 TokenKind::Bang | TokenKind::Not | TokenKind::Minus | TokenKind::BitwiseNot
4525 )
4526}
4527
4528#[inline(always)]
4529fn is_factor_operator(tokens: &[Token], position: &usize) -> bool {
4530 *position < tokens.len()
4531 && matches!(
4532 tokens[*position].kind,
4533 TokenKind::Star | TokenKind::Slash | TokenKind::Percentage | TokenKind::Caret
4534 )
4535}
4536
4537#[inline(always)]
4538fn is_order_by_using_operator(token: &Token) -> bool {
4539 matches!(token.kind, TokenKind::Greater | TokenKind::Less)
4540}
4541
4542#[inline(always)]
4543fn is_join_or_join_type_token(tokens: &[Token], position: &usize) -> bool {
4544 *position < tokens.len()
4545 && matches!(
4546 tokens[*position].kind,
4547 TokenKind::Join
4548 | TokenKind::Left
4549 | TokenKind::Right
4550 | TokenKind::Cross
4551 | TokenKind::Inner
4552 )
4553}
4554
4555#[inline(always)]
4556fn is_asc_or_desc(token: &Token) -> bool {
4557 matches!(token.kind, TokenKind::Ascending | TokenKind::Descending)
4558}