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