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