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