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