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