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