gitql_parser/
parser.rs

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