1use std::collections::HashMap;
2
3use pest::iterators::Pair;
4use prost::Message;
5use substrait::proto::aggregate_rel::Grouping;
6use substrait::proto::expression::literal::LiteralType;
7use substrait::proto::expression::{Literal, RexType, nested};
8use substrait::proto::extensions::AdvancedExtension;
9use substrait::proto::fetch_rel::{CountMode, OffsetMode};
10use substrait::proto::rel::RelType;
11use substrait::proto::rel_common::{Direct, Emit, EmitKind};
12use substrait::proto::sort_field::SortKind;
13use substrait::proto::{
14 AggregateRel, CrossRel, Expression, FetchRel, FilterRel, JoinRel, NamedStruct, ProjectRel,
15 ReadRel, Rel, RelCommon, SetRel, SortField, SortRel, Type, aggregate_rel, join_rel, read_rel,
16 set_rel, r#type,
17};
18
19use super::{
20 MessageParseError, ParsePair, ParsedNamedArgs, Rule, RuleIter, ScopedParsePair,
21 sort_direction_from_str, unwrap_single_pair,
22};
23use crate::extensions::any::Any;
24use crate::extensions::registry::ExtensionError;
25use crate::extensions::{AddendumKind, ExtensionArgs, ExtensionRegistry, SimpleExtensions};
26use crate::parser::errors::{ParseContext, ParseError};
27use crate::parser::expressions::{FieldIndex, Name};
28
29pub struct RelationParsingContext<'a> {
31 pub registry: &'a ExtensionRegistry,
32 pub line_no: i64,
33 pub line: &'a str,
34}
35
36impl<'a> RelationParsingContext<'a> {
37 pub fn resolve_extension_detail(
39 &self,
40 extension_name: &str,
41 extension_args: &ExtensionArgs,
42 ) -> Result<Option<Any>, ParseError> {
43 let detail = self
44 .registry
45 .parse_extension(extension_name, extension_args);
46
47 match detail {
48 Ok(any) => Ok(Some(any)),
49 Err(ExtensionError::NotFound { .. }) => Err(ParseError::UnregisteredExtension {
50 name: extension_name.to_string(),
51 context: ParseContext::new(self.line_no, self.line.to_string()),
52 }),
53 Err(err) => Err(ParseError::ExtensionDetail(
54 ParseContext::new(self.line_no, self.line.to_string()),
55 err,
56 )),
57 }
58 }
59
60 pub(crate) fn resolve_addendum_detail(
63 &self,
64 kind: AddendumKind,
65 name: &str,
66 args: &ExtensionArgs,
67 ) -> Result<Any, ParseError> {
68 let result = match kind {
69 AddendumKind::Enhancement => self.registry.parse_enhancement(name, args),
70 AddendumKind::Optimization => self.registry.parse_optimization(name, args),
71 AddendumKind::ExtensionTable => self.registry.parse_extension_table(name, args),
72 };
73 result.map_err(|err| match err {
74 ExtensionError::NotFound { .. } => ParseError::UnregisteredExtension {
75 name: name.to_string(),
76 context: ParseContext::new(self.line_no, self.line.to_string()),
77 },
78 err => ParseError::ExtensionDetail(
79 ParseContext::new(self.line_no, self.line.to_string()),
80 err,
81 ),
82 })
83 }
84}
85
86pub trait RelationParsePair: Sized {
88 fn rule() -> Rule;
89 fn message() -> &'static str;
90
91 fn parse_pair_with_context(
97 extensions: &SimpleExtensions,
98 pair: Pair<Rule>,
99 input_children: Vec<Rel>,
100 input_field_count: usize,
101 ) -> Result<(Self, usize), MessageParseError>;
102
103 fn into_rel(self, adv_ext: Option<AdvancedExtension>) -> Rel;
106}
107
108pub struct TableName(Vec<String>);
109
110impl ParsePair for TableName {
111 fn rule() -> Rule {
112 Rule::table_name
113 }
114
115 fn message() -> &'static str {
116 "TableName"
117 }
118
119 fn parse_pair(pair: Pair<Rule>) -> Self {
120 assert_eq!(pair.as_rule(), Self::rule());
121 let pairs = pair.into_inner();
122 let mut names = Vec::with_capacity(pairs.len());
123 let mut iter = RuleIter::from(pairs);
124 while let Some(name) = iter.parse_if_next::<Name>() {
125 names.push(name.0);
126 }
127 iter.done();
128 Self(names)
129 }
130}
131
132#[derive(Debug, Clone)]
133pub struct Column {
134 pub name: String,
135 pub typ: Type,
136}
137
138impl ScopedParsePair for Column {
139 fn rule() -> Rule {
140 Rule::named_column
141 }
142
143 fn message() -> &'static str {
144 "Column"
145 }
146
147 fn parse_pair(
148 extensions: &SimpleExtensions,
149 pair: Pair<Rule>,
150 ) -> Result<Self, MessageParseError> {
151 assert_eq!(pair.as_rule(), Self::rule());
152 let mut iter = RuleIter::from(pair.into_inner());
153 let name = iter.parse_next::<Name>().0;
154 let typ = iter.parse_next_scoped(extensions)?;
155 iter.done();
156 Ok(Self { name, typ })
157 }
158}
159
160pub(crate) struct NamedColumnList(pub(crate) Vec<Column>);
161
162impl ScopedParsePair for NamedColumnList {
163 fn rule() -> Rule {
164 Rule::named_column_list
165 }
166
167 fn message() -> &'static str {
168 "NamedColumnList"
169 }
170
171 fn parse_pair(
172 extensions: &SimpleExtensions,
173 pair: Pair<Rule>,
174 ) -> Result<Self, MessageParseError> {
175 assert_eq!(pair.as_rule(), Self::rule());
176 let mut columns = Vec::new();
177 for col in pair.into_inner() {
178 columns.push(Column::parse_pair(extensions, col)?);
179 }
180 Ok(Self(columns))
181 }
182}
183
184pub(crate) fn expect_one_child(
189 message: &'static str,
190 pair: &Pair<Rule>,
191 mut input_children: Vec<Rel>,
192) -> Result<Box<Rel>, MessageParseError> {
193 match input_children.len() {
194 0 => Err(MessageParseError::invalid(
195 message,
196 pair.as_span(),
197 format!("{message} missing child"),
198 )),
199 1 => Ok(Box::new(input_children.pop().unwrap())),
200 n => Err(MessageParseError::invalid(
201 message,
202 pair.as_span(),
203 format!("{message} should have 1 input child, got {n}"),
204 )),
205 }
206}
207
208fn parse_output_mapping(pair: Pair<Rule>) -> Vec<i32> {
211 assert_eq!(pair.as_rule(), Rule::reference_list);
212 pair.into_inner()
213 .map(|p| FieldIndex::parse_pair(p).0)
214 .collect()
215}
216
217fn make_emit(output_mapping: Vec<i32>, direct_output_count: usize) -> EmitKind {
220 let is_identity = output_mapping.len() == direct_output_count
221 && output_mapping
222 .iter()
223 .enumerate()
224 .all(|(i, &v)| v == i as i32);
225 if is_identity {
226 EmitKind::Direct(Direct {})
227 } else {
228 EmitKind::Emit(Emit { output_mapping })
229 }
230}
231
232pub(crate) fn direct_common() -> RelCommon {
234 RelCommon {
235 emit_kind: Some(EmitKind::Direct(Direct {})),
236 ..Default::default()
237 }
238}
239
240fn parse_emit(reference_list: Pair<Rule>, direct_output_count: usize) -> (EmitKind, usize) {
242 let output_mapping = parse_output_mapping(reference_list);
243 let output_count = output_mapping.len();
244 let emit = make_emit(output_mapping, direct_output_count);
245 (emit, output_count)
246}
247
248fn parse_output(
249 extensions: &SimpleExtensions,
250 output: Pair<Rule>,
251) -> Result<(Vec<Column>, Option<RelCommon>, usize), MessageParseError> {
252 assert_eq!(output.as_rule(), Rule::output);
253 let output = unwrap_single_pair(output);
254 match output.as_rule() {
255 Rule::implicit_output => {
256 let mut iter = RuleIter::from(output.into_inner());
257 let columns = iter.parse_next_scoped::<NamedColumnList>(extensions)?.0;
258 iter.done();
259 let output_count = columns.len();
260 Ok((columns, Some(direct_common()), output_count))
261 }
262 Rule::direct_output => {
263 let mut iter = RuleIter::from(output.into_inner());
264 let columns = iter.parse_next_scoped::<NamedColumnList>(extensions)?.0;
265 let emit_suffix = iter.pop(Rule::emit_suffix);
266 iter.done();
267
268 let direct_output_count = columns.len();
269 let (emit, output_count) = parse_emit_suffix(emit_suffix)
270 .unwrap_or((EmitKind::Direct(Direct {}), direct_output_count));
271 let common = Some(RelCommon {
272 emit_kind: Some(emit),
273 ..Default::default()
274 });
275 Ok((columns, common, output_count))
276 }
277 other => unreachable!("Unexpected rule in output: {other:?}"),
278 }
279}
280
281fn parse_emit_suffix(suffix: Pair<Rule>) -> Option<(EmitKind, usize)> {
282 assert_eq!(suffix.as_rule(), Rule::emit_suffix);
283 let reference_list = suffix.into_inner().next()?;
284 assert_eq!(reference_list.as_rule(), Rule::reference_list);
285 let output_mapping = parse_output_mapping(reference_list);
286 let output_count = output_mapping.len();
287 Some((EmitKind::Emit(Emit { output_mapping }), output_count))
288}
289
290impl RelationParsePair for ReadRel {
291 fn rule() -> Rule {
292 Rule::read_relation
293 }
294
295 fn message() -> &'static str {
296 "ReadRel"
297 }
298
299 fn parse_pair_with_context(
300 extensions: &SimpleExtensions,
301 pair: Pair<Rule>,
302 input_children: Vec<Rel>,
303 input_field_count: usize,
304 ) -> Result<(Self, usize), MessageParseError> {
305 assert_eq!(pair.as_rule(), Self::rule());
306 if !input_children.is_empty() {
308 return Err(MessageParseError::invalid(
309 Self::message(),
310 pair.as_span(),
311 "ReadRel should have no input children",
312 ));
313 }
314 if input_field_count != 0 {
315 return Err(MessageParseError::invalid(
316 "ReadRel",
317 pair.as_span(),
318 "ReadRel should have 0 input fields",
319 ));
320 }
321
322 let mut iter = RuleIter::from(pair.into_inner());
323 let table = iter.parse_next::<TableName>().0;
324 let output_pair = iter.pop(Rule::output);
325 iter.done();
326
327 let (columns, common, output_count) = parse_output(extensions, output_pair)?;
328
329 Ok((
330 ReadRel {
331 base_schema: Some(build_named_struct(columns)),
332 read_type: Some(read_rel::ReadType::NamedTable(read_rel::NamedTable {
333 names: table,
334 advanced_extension: None,
335 })),
336 common,
337 ..Default::default()
338 },
339 output_count,
340 ))
341 }
342
343 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
344 self.advanced_extension = adv_ext;
345 Rel {
346 rel_type: Some(RelType::Read(Box::new(self))),
347 }
348 }
349}
350
351pub(crate) struct VirtualReadRel(ReadRel);
355
356impl RelationParsePair for VirtualReadRel {
357 fn rule() -> Rule {
358 Rule::virtual_read_relation
359 }
360
361 fn message() -> &'static str {
362 "VirtualReadRel"
363 }
364
365 fn parse_pair_with_context(
366 extensions: &SimpleExtensions,
367 pair: Pair<Rule>,
368 input_children: Vec<Rel>,
369 _input_field_count: usize,
370 ) -> Result<(Self, usize), MessageParseError> {
371 assert_eq!(pair.as_rule(), Self::rule());
372 if !input_children.is_empty() {
373 return Err(MessageParseError::invalid(
374 Self::message(),
375 pair.as_span(),
376 "Read:Virtual should have no input children",
377 ));
378 }
379
380 let mut iter = RuleIter::from(pair.into_inner());
381 let rows_pair = iter.pop(Rule::virtual_read_rows);
382 let filter = iter
383 .try_pop(Rule::virtual_read_filter)
384 .map(|pair| {
385 let expression_pair = unwrap_single_pair(pair);
386 Expression::parse_pair(extensions, expression_pair).map(Box::new)
387 })
388 .transpose()?;
389 let columns_pair = iter.pop(Rule::named_column_list);
390 iter.done();
391
392 let rows = parse_virtual_read_rows(extensions, rows_pair)?;
393 let columns = NamedColumnList::parse_pair(extensions, columns_pair)?.0;
394
395 let output_count = columns.len();
400 Ok((
401 VirtualReadRel(ReadRel {
402 common: Some(direct_common()),
403 base_schema: Some(build_named_struct(columns)),
404 read_type: Some(read_rel::ReadType::VirtualTable(read_rel::VirtualTable {
405 expressions: rows,
406 ..Default::default()
407 })),
408 filter,
409 ..Default::default()
410 }),
411 output_count,
412 ))
413 }
414
415 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
416 self.0.advanced_extension = adv_ext;
417 Rel {
418 rel_type: Some(RelType::Read(Box::new(self.0))),
419 }
420 }
421}
422
423pub(crate) struct ExtensionReadRel(ReadRel);
427
428impl ExtensionReadRel {
429 pub(crate) fn parse_pair_with_detail(
430 extensions: &SimpleExtensions,
431 pair: Pair<Rule>,
432 input_children: Vec<Rel>,
433 input_field_count: usize,
434 detail: Any,
435 advanced_extension: Option<AdvancedExtension>,
436 ) -> Result<(Rel, usize), MessageParseError> {
437 assert_eq!(pair.as_rule(), Rule::extension_read_relation);
438 if !input_children.is_empty() {
439 return Err(MessageParseError::invalid(
440 "ExtensionReadRel",
441 pair.as_span(),
442 "Read:Extension should have no input children",
443 ));
444 }
445 if input_field_count != 0 {
446 return Err(MessageParseError::invalid(
447 "ExtensionReadRel",
448 pair.as_span(),
449 "Read:Extension should have 0 input fields",
450 ));
451 }
452
453 let mut iter = RuleIter::from(pair.into_inner());
454 let columns = iter.parse_next_scoped::<NamedColumnList>(extensions)?.0;
455 iter.done();
456
457 let output_count = columns.len();
458 let rel = ExtensionReadRel(ReadRel {
459 common: Some(direct_common()),
460 base_schema: Some(build_named_struct(columns)),
461 read_type: Some(read_rel::ReadType::ExtensionTable(
462 read_rel::ExtensionTable {
463 detail: Some(detail.into()),
464 },
465 )),
466 advanced_extension,
467 ..Default::default()
468 })
469 .into_rel();
470
471 Ok((rel, output_count))
472 }
473
474 fn into_rel(self) -> Rel {
475 Rel {
476 rel_type: Some(RelType::Read(Box::new(self.0))),
477 }
478 }
479}
480
481pub(crate) fn build_named_struct(columns: Vec<Column>) -> NamedStruct {
483 let (names, types): (Vec<_>, Vec<_>) = columns.into_iter().map(|c| (c.name, c.typ)).unzip();
484 NamedStruct {
485 names,
486 r#struct: Some(r#type::Struct {
487 types,
488 type_variation_reference: 0,
489 nullability: r#type::Nullability::Required as i32,
490 }),
491 }
492}
493
494fn parse_virtual_read_rows(
496 extensions: &SimpleExtensions,
497 pair: Pair<Rule>,
498) -> Result<Vec<nested::Struct>, MessageParseError> {
499 assert_eq!(pair.as_rule(), Rule::virtual_read_rows);
500 let inner = unwrap_single_pair(pair);
501 match inner.as_rule() {
502 Rule::empty => Ok(vec![]),
503 Rule::virtual_row_list => inner
504 .into_inner()
505 .map(|row| parse_virtual_row(extensions, row))
506 .collect(),
507 _ => unreachable!(
508 "Unexpected rule in virtual_read_rows: {:?}",
509 inner.as_rule()
510 ),
511 }
512}
513
514fn parse_virtual_row(
516 extensions: &SimpleExtensions,
517 pair: Pair<Rule>,
518) -> Result<nested::Struct, MessageParseError> {
519 assert_eq!(pair.as_rule(), Rule::virtual_row);
520 let fields = match pair.into_inner().next() {
521 Some(expression_list) => {
522 assert_eq!(expression_list.as_rule(), Rule::expression_list);
523 parse_expression_list(extensions, expression_list)?
524 }
525 None => vec![],
527 };
528 Ok(nested::Struct { fields })
529}
530
531impl RelationParsePair for FilterRel {
532 fn rule() -> Rule {
533 Rule::filter_relation
534 }
535
536 fn message() -> &'static str {
537 "FilterRel"
538 }
539
540 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
541 self.advanced_extension = adv_ext;
542 Rel {
543 rel_type: Some(RelType::Filter(Box::new(self))),
544 }
545 }
546
547 fn parse_pair_with_context(
548 extensions: &SimpleExtensions,
549 pair: Pair<Rule>,
550 input_children: Vec<Rel>,
551 input_field_count: usize,
552 ) -> Result<(Self, usize), MessageParseError> {
553 assert_eq!(pair.as_rule(), Self::rule());
554 let input = expect_one_child(Self::message(), &pair, input_children)?;
555 let mut iter = RuleIter::from(pair.into_inner());
556 let condition = iter.parse_next_scoped::<Expression>(extensions)?;
557 let references_pair = iter.pop(Rule::reference_list);
558 iter.done();
559
560 let (emit, output_count) = parse_emit(references_pair, input_field_count);
561 let common = RelCommon {
562 emit_kind: Some(emit),
563 ..Default::default()
564 };
565
566 Ok((
567 FilterRel {
568 input: Some(input),
569 condition: Some(Box::new(condition)),
570 common: Some(common),
571 advanced_extension: None,
572 },
573 output_count,
574 ))
575 }
576}
577
578impl RelationParsePair for ProjectRel {
579 fn rule() -> Rule {
580 Rule::project_relation
581 }
582
583 fn message() -> &'static str {
584 "ProjectRel"
585 }
586
587 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
588 self.advanced_extension = adv_ext;
589 Rel {
590 rel_type: Some(RelType::Project(Box::new(self))),
591 }
592 }
593
594 fn parse_pair_with_context(
595 extensions: &SimpleExtensions,
596 pair: Pair<Rule>,
597 input_children: Vec<Rel>,
598 input_field_count: usize,
599 ) -> Result<(Self, usize), MessageParseError> {
600 assert_eq!(pair.as_rule(), Self::rule());
601 let input = expect_one_child(Self::message(), &pair, input_children)?;
602
603 let arguments_pair = unwrap_single_pair(pair);
604
605 let mut expressions = Vec::new();
606 let mut output_mapping = Vec::new();
607
608 for arg in arguments_pair.into_inner() {
609 let inner_arg = unwrap_single_pair(arg);
610 match inner_arg.as_rule() {
611 Rule::reference => {
612 let field_index = FieldIndex::parse_pair(inner_arg);
613 output_mapping.push(field_index.0);
614 }
615 Rule::expression => {
616 let expr = Expression::parse_pair(extensions, inner_arg)?;
617 expressions.push(expr);
618 output_mapping.push(input_field_count as i32 + (expressions.len() as i32 - 1));
620 }
621 _ => panic!("Unexpected inner argument rule: {:?}", inner_arg.as_rule()),
622 }
623 }
624
625 let output_count = output_mapping.len();
626 let direct_count = input_field_count + expressions.len();
627 let emit = make_emit(output_mapping, direct_count);
628 let common = RelCommon {
629 emit_kind: Some(emit),
630 ..Default::default()
631 };
632
633 Ok((
634 ProjectRel {
635 input: Some(input),
636 expressions,
637 common: Some(common),
638 advanced_extension: None,
639 },
640 output_count,
641 ))
642 }
643}
644
645impl RelationParsePair for AggregateRel {
646 fn rule() -> Rule {
647 Rule::aggregate_relation
648 }
649
650 fn message() -> &'static str {
651 "AggregateRel"
652 }
653
654 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
655 self.advanced_extension = adv_ext;
656 Rel {
657 rel_type: Some(RelType::Aggregate(Box::new(self))),
658 }
659 }
660
661 fn parse_pair_with_context(
662 extensions: &SimpleExtensions,
663 pair: Pair<Rule>,
664 input_children: Vec<Rel>,
665 _input_field_count: usize,
668 ) -> Result<(Self, usize), MessageParseError> {
669 assert_eq!(pair.as_rule(), Self::rule());
670 let input = expect_one_child(Self::message(), &pair, input_children)?;
671 let mut iter = RuleIter::from(pair.into_inner());
672 let group_by_pair = iter.pop(Rule::aggregate_group_by);
673 let output_pair = iter.pop(Rule::aggregate_output);
674 iter.done();
675
676 let inner = group_by_pair
677 .into_inner()
678 .next()
679 .expect("aggregate_group_by must have one inner item");
680
681 let grouping_sets = parse_grouping_sets(extensions, inner)?;
682 let (groupings, grouping_expressions) = build_grouping_fields(&grouping_sets);
683
684 let (measures, output_mapping) =
685 parse_aggregate_output(extensions, output_pair, &grouping_expressions)?;
686
687 let output_count = output_mapping.len();
688 let direct_count = grouping_expressions.len() + measures.len();
689 let emit = make_emit(output_mapping, direct_count);
690 let common = RelCommon {
691 emit_kind: Some(emit),
692 ..Default::default()
693 };
694
695 Ok((
696 AggregateRel {
697 input: Some(input),
698 grouping_expressions,
699 groupings,
700 measures,
701 common: Some(common),
702 advanced_extension: None,
703 },
704 output_count,
705 ))
706 }
707}
708
709fn expression_key(expression: &Expression) -> Vec<u8> {
714 expression.encode_to_vec()
715}
716
717fn parse_aggregate_output(
722 extensions: &SimpleExtensions,
723 output_pair: Pair<'_, Rule>,
724 grouping_expressions: &[Expression],
725) -> Result<(Vec<aggregate_rel::Measure>, Vec<i32>), MessageParseError> {
726 assert_eq!(output_pair.as_rule(), Rule::aggregate_output);
727
728 let grouping_positions: HashMap<Vec<u8>, usize> = grouping_expressions
739 .iter()
740 .enumerate()
741 .map(|(index, expression)| (expression_key(expression), index))
742 .collect();
743
744 let mut measures = Vec::new();
745 let mut output_mapping = Vec::new();
746
747 for output_item in output_pair.into_inner() {
748 assert_eq!(output_item.as_rule(), Rule::expression);
749 let span = output_item.as_span();
750 let inner_item = unwrap_single_pair(output_item.clone());
751
752 if inner_item.as_rule() == Rule::function_call {
753 let expression = Expression::parse_pair(extensions, output_item)?;
754 if let Some(&index) = grouping_positions.get(&expression_key(&expression)) {
755 output_mapping.push(index as i32);
756 continue;
757 }
758
759 let measure = aggregate_rel::Measure::parse_pair(extensions, inner_item)?;
760 output_mapping.push(grouping_expressions.len() as i32 + measures.len() as i32);
761 measures.push(measure);
762 continue;
763 }
764
765 let expression = Expression::parse_pair(extensions, output_item)?;
766 match grouping_positions.get(&expression_key(&expression)) {
767 Some(&index) => output_mapping.push(index as i32),
768 None => {
769 return Err(MessageParseError::invalid(
770 "AggregateRel",
771 span,
772 "output expression is not an aggregate measure and does not match any grouping expression",
773 ));
774 }
775 }
776 }
777
778 Ok((measures, output_mapping))
779}
780
781fn parse_grouping_sets(
790 extensions: &SimpleExtensions,
791 inner: Pair<'_, Rule>,
792) -> Result<Vec<Vec<Expression>>, MessageParseError> {
793 assert!(
794 matches!(
795 inner.as_rule(),
796 Rule::expression_list | Rule::grouping_set_list
797 ),
798 "Expected expression_list or grouping_set_list, got {:?}",
799 inner.as_rule()
800 );
801 match inner.as_rule() {
802 Rule::expression_list => Ok(vec![parse_expression_list(extensions, inner)?]),
803 Rule::grouping_set_list => inner
804 .into_inner()
805 .map(|pair| parse_grouping_set(extensions, pair))
806 .collect(),
807 _ => unreachable!(
808 "Unexpected rule in aggregate_group_by: {:?}",
809 inner.as_rule()
810 ),
811 }
812}
813
814fn parse_grouping_set(
818 extensions: &SimpleExtensions,
819 pair: Pair<'_, Rule>,
820) -> Result<Vec<Expression>, MessageParseError> {
821 assert_eq!(pair.as_rule(), Rule::grouping_set);
822 let inner = pair
823 .into_inner()
824 .next()
825 .expect("grouping_set must have one inner item");
826 match inner.as_rule() {
827 Rule::empty => Ok(vec![]),
828 Rule::expression_list => parse_expression_list(extensions, inner),
829 _ => unreachable!("Unexpected item in grouping_set: {:?}", inner.as_rule()),
830 }
831}
832
833pub(crate) fn parse_expression_list(
835 extensions: &SimpleExtensions,
836 pair: Pair<'_, Rule>,
837) -> Result<Vec<Expression>, MessageParseError> {
838 pair.into_inner()
839 .map(|expr_pair| Expression::parse_pair(extensions, expr_pair))
840 .collect()
841}
842
843fn build_grouping_fields(expression_sets: &[Vec<Expression>]) -> (Vec<Grouping>, Vec<Expression>) {
847 let mut expressions: Vec<Expression> = Vec::new();
848 let mut seen: HashMap<Vec<u8>, u32> = HashMap::new();
849
850 let groupings = expression_sets
851 .iter()
852 .map(|set| {
853 let expression_references = set
854 .iter()
855 .map(|exp| {
856 let key = expression_key(exp);
857 let next_idx = expressions.len() as u32;
858 *seen.entry(key).or_insert_with(|| {
859 expressions.push(exp.clone());
860 next_idx
861 })
862 })
863 .collect();
864 Grouping {
865 expression_references,
866 #[allow(deprecated)]
867 grouping_expressions: vec![],
868 }
869 })
870 .collect();
871
872 (groupings, expressions)
873}
874
875impl ScopedParsePair for SortField {
876 fn rule() -> Rule {
877 Rule::sort_field
878 }
879
880 fn message() -> &'static str {
881 "SortField"
882 }
883
884 fn parse_pair(
885 extensions: &SimpleExtensions,
886 pair: Pair<Rule>,
887 ) -> Result<Self, MessageParseError> {
888 assert_eq!(pair.as_rule(), Self::rule());
889 let mut iter = RuleIter::from(pair.into_inner());
890 let expression_pair = iter.pop(Rule::expression);
891 let expression = Expression::parse_pair(extensions, expression_pair)?;
892 let direction_pair = iter.pop(Rule::sort_direction);
893 let direction = sort_direction_from_str(
894 direction_pair.as_str().trim_start_matches('&'),
895 direction_pair.as_span(),
896 )?;
897 iter.done();
898 Ok(SortField {
899 expr: Some(expression),
900 sort_kind: Some(SortKind::Direction(direction as i32)),
902 })
903 }
904}
905
906impl RelationParsePair for SortRel {
907 fn rule() -> Rule {
908 Rule::sort_relation
909 }
910
911 fn message() -> &'static str {
912 "SortRel"
913 }
914
915 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
916 self.advanced_extension = adv_ext;
917 Rel {
918 rel_type: Some(RelType::Sort(Box::new(self))),
919 }
920 }
921
922 fn parse_pair_with_context(
923 extensions: &SimpleExtensions,
924 pair: Pair<Rule>,
925 input_children: Vec<Rel>,
926 input_field_count: usize,
927 ) -> Result<(Self, usize), MessageParseError> {
928 assert_eq!(pair.as_rule(), Self::rule());
929 let input = expect_one_child(Self::message(), &pair, input_children)?;
930 let mut iter = RuleIter::from(pair.into_inner());
931 let sort_field_list_pair = iter.pop(Rule::sort_field_list);
932 let references_pair = iter.pop(Rule::reference_list);
933 let mut sorts = Vec::new();
934 for sort_field_pair in sort_field_list_pair.into_inner() {
935 let sort_field = SortField::parse_pair(extensions, sort_field_pair)?;
936 sorts.push(sort_field);
937 }
938 let (emit, output_count) = parse_emit(references_pair, input_field_count);
939 let common = RelCommon {
940 emit_kind: Some(emit),
941 ..Default::default()
942 };
943 iter.done();
944 Ok((
945 SortRel {
946 input: Some(input),
947 sorts,
948 common: Some(common),
949 advanced_extension: None,
950 },
951 output_count,
952 ))
953 }
954}
955
956impl ScopedParsePair for CountMode {
957 fn rule() -> Rule {
958 Rule::fetch_value
959 }
960 fn message() -> &'static str {
961 "CountMode"
962 }
963 fn parse_pair(
964 extensions: &SimpleExtensions,
965 pair: Pair<Rule>,
966 ) -> Result<Self, MessageParseError> {
967 assert_eq!(pair.as_rule(), Self::rule());
968 let mut arg_inner = RuleIter::from(pair.into_inner());
969 let value_pair = if let Some(int_pair) = arg_inner.try_pop(Rule::integer) {
970 int_pair
971 } else {
972 arg_inner.pop(Rule::expression)
973 };
974 match value_pair.as_rule() {
975 Rule::integer => {
976 let value = value_pair.as_str().parse::<i64>().map_err(|e| {
977 MessageParseError::invalid(
978 Self::message(),
979 value_pair.as_span(),
980 format!("Invalid integer: {e}"),
981 )
982 })?;
983 if value < 0 {
984 return Err(MessageParseError::invalid(
985 Self::message(),
986 value_pair.as_span(),
987 format!("Fetch limit must be non-negative, got: {value}"),
988 ));
989 }
990 Ok(CountMode::CountExpr(i64_literal_expr(value)))
991 }
992 Rule::expression => {
993 let expr = Expression::parse_pair(extensions, value_pair)?;
994 Ok(CountMode::CountExpr(Box::new(expr)))
995 }
996 _ => Err(MessageParseError::invalid(
997 Self::message(),
998 value_pair.as_span(),
999 format!("Unexpected rule for CountMode: {:?}", value_pair.as_rule()),
1000 )),
1001 }
1002 }
1003}
1004
1005fn i64_literal_expr(value: i64) -> Box<Expression> {
1006 Box::new(Expression {
1007 rex_type: Some(RexType::Literal(Literal {
1008 nullable: false,
1009 type_variation_reference: 0,
1010 literal_type: Some(LiteralType::I64(value)),
1011 })),
1012 })
1013}
1014
1015impl ScopedParsePair for OffsetMode {
1016 fn rule() -> Rule {
1017 Rule::fetch_value
1018 }
1019 fn message() -> &'static str {
1020 "OffsetMode"
1021 }
1022 fn parse_pair(
1023 extensions: &SimpleExtensions,
1024 pair: Pair<Rule>,
1025 ) -> Result<Self, MessageParseError> {
1026 assert_eq!(pair.as_rule(), Self::rule());
1027 let mut arg_inner = RuleIter::from(pair.into_inner());
1028 let value_pair = if let Some(int_pair) = arg_inner.try_pop(Rule::integer) {
1029 int_pair
1030 } else {
1031 arg_inner.pop(Rule::expression)
1032 };
1033 match value_pair.as_rule() {
1034 Rule::integer => {
1035 let value = value_pair.as_str().parse::<i64>().map_err(|e| {
1036 MessageParseError::invalid(
1037 Self::message(),
1038 value_pair.as_span(),
1039 format!("Invalid integer: {e}"),
1040 )
1041 })?;
1042 if value < 0 {
1043 return Err(MessageParseError::invalid(
1044 Self::message(),
1045 value_pair.as_span(),
1046 format!("Fetch offset must be non-negative, got: {value}"),
1047 ));
1048 }
1049 Ok(OffsetMode::OffsetExpr(i64_literal_expr(value)))
1050 }
1051 Rule::expression => {
1052 let expr = Expression::parse_pair(extensions, value_pair)?;
1053 Ok(OffsetMode::OffsetExpr(Box::new(expr)))
1054 }
1055 _ => Err(MessageParseError::invalid(
1056 Self::message(),
1057 value_pair.as_span(),
1058 format!("Unexpected rule for OffsetMode: {:?}", value_pair.as_rule()),
1059 )),
1060 }
1061 }
1062}
1063
1064impl RelationParsePair for FetchRel {
1065 fn rule() -> Rule {
1066 Rule::fetch_relation
1067 }
1068
1069 fn message() -> &'static str {
1070 "FetchRel"
1071 }
1072
1073 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
1074 self.advanced_extension = adv_ext;
1075 Rel {
1076 rel_type: Some(RelType::Fetch(Box::new(self))),
1077 }
1078 }
1079
1080 fn parse_pair_with_context(
1081 extensions: &SimpleExtensions,
1082 pair: Pair<Rule>,
1083 input_children: Vec<Rel>,
1084 input_field_count: usize,
1085 ) -> Result<(Self, usize), MessageParseError> {
1086 assert_eq!(pair.as_rule(), Self::rule());
1087 let input = expect_one_child(Self::message(), &pair, input_children)?;
1088 let mut iter = RuleIter::from(pair.into_inner());
1089
1090 let (limit_pair, offset_pair) = match iter.try_pop(Rule::fetch_named_arg_list) {
1094 None => {
1095 iter.pop(Rule::empty);
1096 (None, None)
1097 }
1098 Some(fetch_args_pair) => {
1099 let extractor =
1100 ParsedNamedArgs::new(fetch_args_pair.into_inner(), Rule::fetch_named_arg)?;
1101 let (extractor, limit_pair) = extractor.pop("limit", Rule::fetch_value);
1102 let (extractor, offset_pair) = extractor.pop("offset", Rule::fetch_value);
1103 extractor.done()?;
1104 (limit_pair, offset_pair)
1105 }
1106 };
1107
1108 let references_pair = iter.pop(Rule::reference_list);
1109 let (emit, output_count) = parse_emit(references_pair, input_field_count);
1110 let common = RelCommon {
1111 emit_kind: Some(emit),
1112 ..Default::default()
1113 };
1114 iter.done();
1115
1116 let count_mode = limit_pair
1117 .map(|pair| CountMode::parse_pair(extensions, pair))
1118 .transpose()?;
1119 let offset_mode = offset_pair
1120 .map(|pair| OffsetMode::parse_pair(extensions, pair))
1121 .transpose()?;
1122 Ok((
1123 FetchRel {
1124 input: Some(input),
1125 common: Some(common),
1126 advanced_extension: None,
1127 offset_mode,
1128 count_mode,
1129 },
1130 output_count,
1131 ))
1132 }
1133}
1134
1135impl ParsePair for join_rel::JoinType {
1136 fn rule() -> Rule {
1137 Rule::join_type
1138 }
1139
1140 fn message() -> &'static str {
1141 "JoinType"
1142 }
1143
1144 fn parse_pair(pair: Pair<Rule>) -> Self {
1145 assert_eq!(pair.as_rule(), Self::rule());
1146 let join_type_str = pair.as_str().trim_start_matches('&');
1147 match join_type_str {
1148 "Inner" => join_rel::JoinType::Inner,
1149 "Left" => join_rel::JoinType::Left,
1150 "Right" => join_rel::JoinType::Right,
1151 "Outer" => join_rel::JoinType::Outer,
1152 "LeftSemi" => join_rel::JoinType::LeftSemi,
1153 "RightSemi" => join_rel::JoinType::RightSemi,
1154 "LeftAnti" => join_rel::JoinType::LeftAnti,
1155 "RightAnti" => join_rel::JoinType::RightAnti,
1156 "LeftSingle" => join_rel::JoinType::LeftSingle,
1157 "RightSingle" => join_rel::JoinType::RightSingle,
1158 "LeftMark" => join_rel::JoinType::LeftMark,
1159 "RightMark" => join_rel::JoinType::RightMark,
1160 _ => panic!("Unknown join type: {join_type_str} (this should be caught by grammar)"),
1161 }
1162 }
1163}
1164
1165impl RelationParsePair for JoinRel {
1166 fn rule() -> Rule {
1167 Rule::join_relation
1168 }
1169
1170 fn message() -> &'static str {
1171 "JoinRel"
1172 }
1173
1174 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
1175 self.advanced_extension = adv_ext;
1176 Rel {
1177 rel_type: Some(RelType::Join(Box::new(self))),
1178 }
1179 }
1180
1181 fn parse_pair_with_context(
1182 extensions: &SimpleExtensions,
1183 pair: Pair<Rule>,
1184 input_children: Vec<Rel>,
1185 input_field_count: usize,
1186 ) -> Result<(Self, usize), MessageParseError> {
1187 assert_eq!(pair.as_rule(), Self::rule());
1188
1189 if input_children.len() != 2 {
1190 return Err(MessageParseError::invalid(
1191 Self::message(),
1192 pair.as_span(),
1193 format!(
1194 "JoinRel should have exactly 2 input children, got {}",
1195 input_children.len()
1196 ),
1197 ));
1198 }
1199
1200 let mut children_iter = input_children.into_iter();
1201 let left = Box::new(children_iter.next().unwrap());
1202 let right = Box::new(children_iter.next().unwrap());
1203
1204 let mut iter = RuleIter::from(pair.into_inner());
1205 let join_type = iter.parse_next::<join_rel::JoinType>();
1206 let condition = iter.parse_next_scoped::<Expression>(extensions)?;
1207 let post_join_filter = iter
1208 .try_pop(Rule::join_post_join_filter)
1209 .map(|pair| {
1210 let expression_pair = unwrap_single_pair(pair);
1211 Expression::parse_pair(extensions, expression_pair).map(Box::new)
1212 })
1213 .transpose()?;
1214 let references_pair = iter.pop(Rule::reference_list);
1215 iter.done();
1216
1217 let (emit, output_count) = parse_emit(references_pair, input_field_count);
1221 let common = RelCommon {
1222 emit_kind: Some(emit),
1223 ..Default::default()
1224 };
1225
1226 Ok((
1227 JoinRel {
1228 common: Some(common),
1229 left: Some(left),
1230 right: Some(right),
1231 expression: Some(Box::new(condition)),
1232 post_join_filter,
1233 r#type: join_type as i32,
1234 advanced_extension: None,
1235 },
1236 output_count,
1237 ))
1238 }
1239}
1240
1241impl RelationParsePair for CrossRel {
1242 fn rule() -> Rule {
1243 Rule::cross_relation
1244 }
1245
1246 fn message() -> &'static str {
1247 "CrossRel"
1248 }
1249
1250 fn into_rel(mut self, adv_ext: Option<AdvancedExtension>) -> Rel {
1251 self.advanced_extension = adv_ext;
1252 Rel {
1253 rel_type: Some(RelType::Cross(Box::new(self))),
1254 }
1255 }
1256
1257 fn parse_pair_with_context(
1258 _extensions: &SimpleExtensions,
1259 pair: Pair<Rule>,
1260 input_children: Vec<Rel>,
1261 input_field_count: usize,
1262 ) -> Result<(Self, usize), MessageParseError> {
1263 assert_eq!(pair.as_rule(), Self::rule());
1264
1265 if input_children.len() != 2 {
1266 return Err(MessageParseError::invalid(
1267 Self::message(),
1268 pair.as_span(),
1269 format!(
1270 "CrossRel should have exactly 2 input children, got {}",
1271 input_children.len()
1272 ),
1273 ));
1274 }
1275
1276 let mut children_iter = input_children.into_iter();
1277 let left = Box::new(children_iter.next().unwrap());
1278 let right = Box::new(children_iter.next().unwrap());
1279
1280 let mut iter = RuleIter::from(pair.into_inner());
1281 let reference_list_pair = iter.pop(Rule::reference_list);
1282 iter.done();
1283
1284 let (emit, output_count) = parse_emit(reference_list_pair, input_field_count);
1285 let common = RelCommon {
1286 emit_kind: Some(emit),
1287 ..Default::default()
1288 };
1289
1290 Ok((
1291 CrossRel {
1292 common: Some(common),
1293 left: Some(left),
1294 right: Some(right),
1295 advanced_extension: None,
1296 },
1297 output_count,
1298 ))
1299 }
1300}
1301
1302impl ParsePair for set_rel::SetOp {
1303 fn rule() -> Rule {
1304 Rule::set_op
1305 }
1306
1307 fn message() -> &'static str {
1308 "SetOp"
1309 }
1310
1311 fn parse_pair(pair: Pair<Rule>) -> Self {
1312 assert_eq!(pair.as_rule(), Self::rule());
1313 let set_op_str = pair.as_str().trim_start_matches('&');
1314 match set_op_str {
1315 "MinusPrimary" => set_rel::SetOp::MinusPrimary,
1316 "MinusPrimaryAll" => set_rel::SetOp::MinusPrimaryAll,
1317 "MinusMultiset" => set_rel::SetOp::MinusMultiset,
1318 "IntersectionPrimary" => set_rel::SetOp::IntersectionPrimary,
1319 "IntersectionMultiset" => set_rel::SetOp::IntersectionMultiset,
1320 "IntersectionMultisetAll" => set_rel::SetOp::IntersectionMultisetAll,
1321 "UnionDistinct" => set_rel::SetOp::UnionDistinct,
1322 "UnionAll" => set_rel::SetOp::UnionAll,
1323 _ => panic!("Unknown set op: {set_op_str} (this should be caught by grammar)"),
1324 }
1325 }
1326}
1327
1328pub(crate) fn parse_set_relation_pair(
1331 pair: Pair<Rule>,
1332 input_children: Vec<Rel>,
1333 child_field_counts: &[usize],
1334 advanced_extension: Option<AdvancedExtension>,
1335) -> Result<(Rel, usize), MessageParseError> {
1336 assert_eq!(pair.as_rule(), Rule::set_relation);
1337
1338 if input_children.len() < 2 {
1339 return Err(MessageParseError::invalid(
1340 "SetRel",
1341 pair.as_span(),
1342 format!(
1343 "SetRel should have at least 2 input children, got {}",
1344 input_children.len()
1345 ),
1346 ));
1347 }
1348
1349 let child_width = child_field_counts[0];
1352 if child_field_counts.iter().any(|&w| w != child_width) {
1353 return Err(MessageParseError::invalid(
1354 "SetRel",
1355 pair.as_span(),
1356 format!(
1357 "SetRel inputs must all have the same number of columns, got widths {child_field_counts:?}"
1358 ),
1359 ));
1360 }
1361
1362 let mut iter = RuleIter::from(pair.into_inner());
1363 let op = iter.parse_next::<set_rel::SetOp>();
1364 let reference_list_pair = iter.pop(Rule::reference_list);
1365 iter.done();
1366
1367 let (emit, output_count) = parse_emit(reference_list_pair, child_width);
1368 let common = RelCommon {
1369 emit_kind: Some(emit),
1370 ..Default::default()
1371 };
1372
1373 Ok((
1374 Rel {
1375 rel_type: Some(RelType::Set(SetRel {
1376 common: Some(common),
1377 inputs: input_children,
1378 op: op as i32,
1379 advanced_extension,
1380 })),
1381 },
1382 output_count,
1383 ))
1384}
1385
1386#[cfg(test)]
1387mod tests {
1388 use pest::Parser;
1389
1390 use super::*;
1391 use crate::fixtures::TestContext;
1392 use crate::parser::{ExpressionParser, Rule};
1393
1394 #[test]
1395 fn test_parse_relation() {
1396 }
1398
1399 #[test]
1400 fn test_parse_read_relation() {
1401 let extensions = SimpleExtensions::default();
1402 let read = ReadRel::parse_pair_with_context(
1403 &extensions,
1404 parse_exact(Rule::read_relation, "Read[ab.cd.ef => a:i32, b:string?]"),
1405 vec![],
1406 0,
1407 )
1408 .unwrap()
1409 .0;
1410 let names = match &read.read_type {
1411 Some(read_rel::ReadType::NamedTable(table)) => &table.names,
1412 _ => panic!("Expected NamedTable"),
1413 };
1414 assert_eq!(names, &["ab", "cd", "ef"]);
1415 let columns = &read
1416 .base_schema
1417 .as_ref()
1418 .unwrap()
1419 .r#struct
1420 .as_ref()
1421 .unwrap()
1422 .types;
1423 assert_eq!(columns.len(), 2);
1424 assert_eq!(read.common, Some(direct_common()));
1425 }
1426
1427 #[test]
1428 fn test_parse_read_relation_explicit_emit() {
1429 let extensions = SimpleExtensions::default();
1430 let read = ReadRel::parse_pair_with_context(
1431 &extensions,
1432 parse_exact(
1433 Rule::read_relation,
1434 "Read[ab.cd.ef +> a:i32, b:string?, c:i64 |> $2, $0]",
1435 ),
1436 vec![],
1437 0,
1438 )
1439 .unwrap();
1440 let (read, output_count) = read;
1441 assert_eq!(output_count, 2);
1442 let emit_kind = read.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
1443 match emit_kind {
1444 EmitKind::Emit(emit) => assert_eq!(emit.output_mapping, vec![2, 0]),
1445 other => panic!("Expected EmitKind::Emit, got {other:?}"),
1446 }
1447 }
1448
1449 #[test]
1450 fn test_parse_read_relation_explicit_identity_emit_not_collapsed() {
1451 let extensions = SimpleExtensions::default();
1454 let read = ReadRel::parse_pair_with_context(
1455 &extensions,
1456 parse_exact(
1457 Rule::read_relation,
1458 "Read[ab.cd.ef +> a:i32, b:string? |> $0, $1]",
1459 ),
1460 vec![],
1461 0,
1462 )
1463 .unwrap()
1464 .0;
1465 let emit_kind = read.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
1466 assert!(
1467 matches!(emit_kind, EmitKind::Emit(_)),
1468 "Expected explicit Emit to survive even with an identity mapping, got {emit_kind:?}"
1469 );
1470 }
1471
1472 #[test]
1473 fn test_parse_read_relation_explicit_direct() {
1474 let extensions = SimpleExtensions::default();
1475 let (read, output_count) = ReadRel::parse_pair_with_context(
1476 &extensions,
1477 parse_exact(Rule::read_relation, "Read[ab.cd.ef +> a:i32, b:string?]"),
1478 vec![],
1479 0,
1480 )
1481 .unwrap();
1482 assert_eq!(output_count, 2);
1483 let emit_kind = read.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
1484 assert!(
1485 matches!(emit_kind, EmitKind::Direct(_)),
1486 "Expected +> without |> to produce Direct, got {emit_kind:?}"
1487 );
1488 }
1489
1490 #[test]
1491 fn test_parse_virtual_read_relation_filter() {
1492 let extensions = TestContext::new()
1493 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_comparison.yaml")
1494 .with_function(1, 10, "gt")
1495 .extensions;
1496
1497 let read = VirtualReadRel::parse_pair_with_context(
1498 &extensions,
1499 parse_exact(
1500 Rule::virtual_read_relation,
1501 "Read:Virtual[(1, 'alice'), filter=gt($0, 0:i64):boolean => id:i64, name:string]",
1502 ),
1503 vec![],
1504 0,
1505 )
1506 .unwrap()
1507 .0
1508 .0;
1509
1510 match read.read_type {
1511 Some(read_rel::ReadType::VirtualTable(table)) => {
1512 assert_eq!(table.expressions.len(), 1);
1513 }
1514 other => panic!("Expected VirtualTable, got {other:?}"),
1515 }
1516 assert!(read.filter.is_some());
1517 }
1518
1519 #[test]
1520 fn test_parse_read_relation_rejects_arrow_with_emit() {
1521 let parsed = ExpressionParser::parse(
1522 Rule::read_relation,
1523 "Read[ab.cd.ef => a:i32, b:string? |> $0, $1]",
1524 );
1525 assert!(
1526 parsed.is_err(),
1527 "Read cannot combine legacy => output with explicit |>"
1528 );
1529 }
1530
1531 fn example_read_relation() -> ReadRel {
1533 let extensions = SimpleExtensions::default();
1534 ReadRel::parse_pair_with_context(
1535 &extensions,
1536 parse_exact(
1537 Rule::read_relation,
1538 "Read[ab.cd.ef => a:i32, b:string?, c:i64]",
1539 ),
1540 vec![],
1541 0,
1542 )
1543 .unwrap()
1544 .0
1545 }
1546
1547 #[test]
1548 fn test_parse_filter_relation() {
1549 let extensions = SimpleExtensions::default();
1550 let filter = FilterRel::parse_pair_with_context(
1551 &extensions,
1552 parse_exact(Rule::filter_relation, "Filter[$1 => $0, $1, $2]"),
1553 vec![example_read_relation().into_rel(None)],
1554 3,
1555 )
1556 .unwrap()
1557 .0;
1558 let emit_kind = filter.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
1560 assert!(
1561 matches!(emit_kind, EmitKind::Direct(_)),
1562 "Expected Direct for identity emit, got {emit_kind:?}"
1563 );
1564 }
1565
1566 #[test]
1567 fn test_parse_project_relation() {
1568 let extensions = SimpleExtensions::default();
1569 let project = ProjectRel::parse_pair_with_context(
1570 &extensions,
1571 parse_exact(Rule::project_relation, "Project[$0, $1, 42]"),
1572 vec![example_read_relation().into_rel(None)],
1573 3,
1574 )
1575 .unwrap()
1576 .0;
1577
1578 assert_eq!(project.expressions.len(), 1);
1580
1581 let emit_kind = &project.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
1582 let emit = match emit_kind {
1583 EmitKind::Emit(emit) => &emit.output_mapping,
1584 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
1585 };
1586 assert_eq!(emit, &[0, 1, 3]);
1588 }
1589
1590 #[test]
1591 fn test_parse_project_relation_complex() {
1592 let extensions = SimpleExtensions::default();
1593 let project = ProjectRel::parse_pair_with_context(
1594 &extensions,
1595 parse_exact(Rule::project_relation, "Project[42, $0, 100, $2, $1]"),
1596 vec![example_read_relation().into_rel(None)],
1597 5, )
1599 .unwrap()
1600 .0;
1601
1602 assert_eq!(project.expressions.len(), 2);
1604
1605 let emit_kind = &project.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
1606 let emit = match emit_kind {
1607 EmitKind::Emit(emit) => &emit.output_mapping,
1608 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
1609 };
1610 assert_eq!(emit, &[5, 0, 6, 2, 1]);
1613 }
1614
1615 #[test]
1616 fn test_parse_aggregate_relation() {
1617 let extensions = TestContext::new()
1618 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1619 .with_function(1, 10, "sum")
1620 .with_function(1, 11, "count")
1621 .extensions;
1622
1623 let aggregate = AggregateRel::parse_pair_with_context(
1624 &extensions,
1625 parse_exact(
1626 Rule::aggregate_relation,
1627 "Aggregate[($0, $1), _ => sum($2):i64, $0, count($2):i64]",
1628 ),
1629 vec![example_read_relation().into_rel(None)],
1630 3,
1631 )
1632 .unwrap()
1633 .0;
1634
1635 assert_eq!(aggregate.grouping_expressions.len(), 2);
1637 assert_eq!(aggregate.groupings[0].expression_references.len(), 2);
1638 assert_eq!(aggregate.groupings.len(), 2);
1639 assert_eq!(aggregate.measures.len(), 2);
1640
1641 let emit_kind = &aggregate
1642 .common
1643 .as_ref()
1644 .unwrap()
1645 .emit_kind
1646 .as_ref()
1647 .unwrap();
1648 let emit = match emit_kind {
1649 EmitKind::Emit(emit) => &emit.output_mapping,
1650 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
1651 };
1652 assert_eq!(emit, &[2, 0, 3]);
1655 }
1656
1657 #[test]
1658 fn test_parse_aggregate_relation_maintain_column_order() {
1659 let extensions = TestContext::new()
1660 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1661 .with_function(1, 10, "sum")
1662 .with_function(1, 11, "count")
1663 .extensions;
1664
1665 let aggregate = AggregateRel::parse_pair_with_context(
1666 &extensions,
1667 parse_exact(
1668 Rule::aggregate_relation,
1669 "Aggregate[$0 => sum($1):i64, $0, count($1):i64]",
1670 ),
1671 vec![example_read_relation().into_rel(None)],
1672 3,
1673 )
1674 .unwrap()
1675 .0;
1676
1677 assert_eq!(aggregate.grouping_expressions.len(), 1);
1679 assert_eq!(aggregate.groupings.len(), 1);
1680 assert_eq!(aggregate.measures.len(), 2);
1681
1682 let emit_kind = &aggregate
1683 .common
1684 .as_ref()
1685 .unwrap()
1686 .emit_kind
1687 .as_ref()
1688 .unwrap();
1689 let emit = match emit_kind {
1690 EmitKind::Emit(emit) => &emit.output_mapping,
1691 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
1692 };
1693 assert_eq!(emit, &[1, 0, 2]);
1695 }
1696
1697 #[test]
1698 fn test_parse_aggregate_relation_simple() {
1699 let extensions = TestContext::new()
1700 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1701 .with_function(1, 10, "sum")
1702 .extensions;
1703
1704 let aggregate = AggregateRel::parse_pair_with_context(
1705 &extensions,
1706 parse_exact(Rule::aggregate_relation, "Aggregate[$2, $0 => sum($1):i64]"),
1707 vec![example_read_relation().into_rel(None)],
1708 3,
1709 )
1710 .unwrap()
1711 .0;
1712
1713 assert_eq!(aggregate.grouping_expressions.len(), 2);
1714 assert_eq!(aggregate.groupings.len(), 1);
1715 assert_eq!(aggregate.groupings[0].expression_references, vec![0, 1]);
1717 }
1718
1719 #[test]
1720 fn test_parse_aggregate_relation_output_reference_uses_grouping_position() {
1721 let extensions = TestContext::new()
1722 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1723 .with_function(1, 10, "sum")
1724 .extensions;
1725
1726 let aggregate = AggregateRel::parse_pair_with_context(
1733 &extensions,
1734 parse_exact(
1735 Rule::aggregate_relation,
1736 "Aggregate[$2, $0 => $0, $2, sum($1):i64]",
1737 ),
1738 vec![example_read_relation().into_rel(None)],
1739 3,
1740 )
1741 .unwrap()
1742 .0;
1743
1744 assert_eq!(aggregate.grouping_expressions.len(), 2);
1745 let emit_kind = &aggregate
1746 .common
1747 .as_ref()
1748 .unwrap()
1749 .emit_kind
1750 .as_ref()
1751 .unwrap();
1752 let emit = match emit_kind {
1753 EmitKind::Emit(emit) => &emit.output_mapping,
1754 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
1755 };
1756 assert_eq!(emit, &[1, 0, 2]);
1758 }
1759
1760 #[test]
1761 fn test_parse_aggregate_relation_output_not_in_grouping_expressions_errors() {
1762 let extensions = TestContext::new()
1763 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1764 .with_function(1, 10, "sum")
1765 .extensions;
1766
1767 let result = AggregateRel::parse_pair_with_context(
1770 &extensions,
1771 parse_exact(Rule::aggregate_relation, "Aggregate[$0 => $1, sum($1):i64]"),
1772 vec![example_read_relation().into_rel(None)],
1773 3,
1774 );
1775
1776 let error = result.unwrap_err();
1777 assert!(error.to_string().contains(
1778 "output expression is not an aggregate measure and does not match any grouping expression"
1779 ));
1780 }
1781
1782 #[test]
1783 fn test_parse_aggregate_relation_output_with_literal_expression() {
1784 let extensions = TestContext::new()
1785 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1786 .with_function(1, 10, "sum")
1787 .extensions;
1788
1789 let aggregate = AggregateRel::parse_pair_with_context(
1793 &extensions,
1794 parse_exact(
1795 Rule::aggregate_relation,
1796 "Aggregate[42, $0 => $0, 42, sum($1):i64]",
1797 ),
1798 vec![example_read_relation().into_rel(None)],
1799 3,
1800 )
1801 .unwrap()
1802 .0;
1803
1804 assert_eq!(aggregate.grouping_expressions.len(), 2);
1805 let emit_kind = &aggregate
1806 .common
1807 .as_ref()
1808 .unwrap()
1809 .emit_kind
1810 .as_ref()
1811 .unwrap();
1812 let emit = match emit_kind {
1813 EmitKind::Emit(emit) => &emit.output_mapping,
1814 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
1815 };
1816 assert_eq!(emit, &[1, 0, 2]);
1818 }
1819
1820 #[test]
1821 fn test_parse_aggregate_relation_function_call_is_not_a_measure() {
1822 let extensions = TestContext::new()
1823 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_comparison.yaml")
1824 .with_urn(2, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1825 .with_function(1, 10, "eq")
1826 .with_function(2, 11, "sum")
1827 .extensions;
1828
1829 let aggregate = AggregateRel::parse_pair_with_context(
1834 &extensions,
1835 parse_exact(
1836 Rule::aggregate_relation,
1837 "Aggregate[eq($0, $1):boolean => eq($0, $1):boolean, sum($2):i64]",
1838 ),
1839 vec![example_read_relation().into_rel(None)],
1840 3,
1841 )
1842 .unwrap()
1843 .0;
1844
1845 assert_eq!(aggregate.grouping_expressions.len(), 1);
1846 assert_eq!(aggregate.measures.len(), 1);
1847 let emit_kind = &aggregate
1848 .common
1849 .as_ref()
1850 .unwrap()
1851 .emit_kind
1852 .as_ref()
1853 .unwrap();
1854 assert!(matches!(emit_kind, EmitKind::Direct(_)));
1855 }
1856
1857 #[test]
1858 fn test_parse_aggregate_relation_global_aggregate() {
1859 let extensions = TestContext::new()
1860 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1861 .with_function(1, 10, "sum")
1862 .with_function(1, 11, "count")
1863 .extensions;
1864
1865 let aggregate = AggregateRel::parse_pair_with_context(
1866 &extensions,
1867 parse_exact(
1868 Rule::aggregate_relation,
1869 "Aggregate[_ => sum($0):i64, count($1):i64]",
1870 ),
1871 vec![example_read_relation().into_rel(None)],
1872 3,
1873 )
1874 .unwrap()
1875 .0;
1876
1877 assert_eq!(aggregate.grouping_expressions.len(), 0);
1879 assert_eq!(aggregate.groupings.len(), 1);
1880 assert_eq!(aggregate.groupings[0].expression_references.len(), 0);
1881 assert_eq!(aggregate.measures.len(), 2);
1882
1883 let emit_kind = aggregate
1885 .common
1886 .as_ref()
1887 .unwrap()
1888 .emit_kind
1889 .as_ref()
1890 .unwrap();
1891 assert!(
1892 matches!(emit_kind, EmitKind::Direct(_)),
1893 "Expected Direct for identity emit, got {emit_kind:?}"
1894 );
1895 }
1896
1897 #[test]
1898 fn test_parse_aggregate_relation_grouping_sets() {
1899 let extensions = TestContext::new()
1900 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_aggregate.yaml")
1901 .with_function(1, 11, "count")
1902 .extensions;
1903
1904 let read_rel = ReadRel::parse_pair_with_context(
1905 &extensions,
1906 parse_exact(
1907 Rule::read_relation,
1908 "Read[ab.cd.ef => a:i32, b:string?, c:i64, d:i64]",
1909 ),
1910 vec![],
1911 0,
1912 )
1913 .unwrap()
1914 .0;
1915
1916 let aggregate = AggregateRel::parse_pair_with_context(
1917 &extensions,
1918 parse_exact(
1919 Rule::aggregate_relation,
1920 "Aggregate[($0, $1, $2), ($2, $0), ($1), _ => $0, $1, $2, count($3):i64]",
1921 ),
1922 vec![read_rel.into_rel(None)],
1923 4,
1924 )
1925 .unwrap()
1926 .0;
1927
1928 assert_eq!(aggregate.grouping_expressions.len(), 3);
1929 assert_eq!(aggregate.groupings.len(), 4);
1930 assert_eq!(aggregate.groupings[0].expression_references, vec![0, 1, 2]);
1932 assert_eq!(aggregate.groupings[1].expression_references, vec![2, 0]);
1934 assert_eq!(aggregate.groupings[2].expression_references, vec![1]);
1936 assert!(aggregate.groupings[3].expression_references.is_empty());
1938 assert_eq!(aggregate.measures.len(), 1);
1939 }
1940
1941 #[test]
1942 fn test_fetch_relation_positive_values() {
1943 let extensions = SimpleExtensions::default();
1944
1945 let fetch_rel = FetchRel::parse_pair_with_context(
1947 &extensions,
1948 parse_exact(Rule::fetch_relation, "Fetch[limit=10, offset=5 => $0]"),
1949 vec![example_read_relation().into_rel(None)],
1950 3,
1951 )
1952 .unwrap()
1953 .0;
1954
1955 assert_eq!(
1957 fetch_rel.count_mode,
1958 Some(CountMode::CountExpr(i64_literal_expr(10)))
1959 );
1960 assert_eq!(
1961 fetch_rel.offset_mode,
1962 Some(OffsetMode::OffsetExpr(i64_literal_expr(5)))
1963 );
1964 }
1965
1966 #[test]
1967 fn test_fetch_relation_negative_limit_rejected() {
1968 let extensions = SimpleExtensions::default();
1969
1970 let parsed_result = ExpressionParser::parse(Rule::fetch_relation, "Fetch[limit=-5 => $0]");
1972 if let Ok(mut pairs) = parsed_result {
1973 let pair = pairs.next().unwrap();
1974 if pair.as_str() == "Fetch[limit=-5 => $0]" {
1975 let result = FetchRel::parse_pair_with_context(
1977 &extensions,
1978 pair,
1979 vec![example_read_relation().into_rel(None)],
1980 3,
1981 );
1982 assert!(result.is_err());
1983 let error_msg = result.unwrap_err().to_string();
1984 assert!(error_msg.contains("Fetch limit must be non-negative"));
1985 } else {
1986 println!("Grammar prevents negative limit values at parse time");
1989 }
1990 } else {
1991 println!("Grammar prevents negative limit values at parse time");
1993 }
1994 }
1995
1996 #[test]
1997 fn test_fetch_relation_negative_offset_rejected() {
1998 let extensions = SimpleExtensions::default();
1999
2000 let parsed_result =
2002 ExpressionParser::parse(Rule::fetch_relation, "Fetch[offset=-10 => $0]");
2003 if let Ok(mut pairs) = parsed_result {
2004 let pair = pairs.next().unwrap();
2005 if pair.as_str() == "Fetch[offset=-10 => $0]" {
2006 let result = FetchRel::parse_pair_with_context(
2008 &extensions,
2009 pair,
2010 vec![example_read_relation().into_rel(None)],
2011 3,
2012 );
2013 assert!(result.is_err());
2014 let error_msg = result.unwrap_err().to_string();
2015 assert!(error_msg.contains("Fetch offset must be non-negative"));
2016 } else {
2017 println!("Grammar prevents negative offset values at parse time");
2019 }
2020 } else {
2021 println!("Grammar prevents negative offset values at parse time");
2023 }
2024 }
2025
2026 #[test]
2027 fn test_parse_join_relation() {
2028 let extensions = TestContext::new()
2029 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_comparison.yaml")
2030 .with_function(1, 10, "eq")
2031 .extensions;
2032
2033 let left_rel = example_read_relation().into_rel(None);
2034 let right_rel = example_read_relation().into_rel(None);
2035
2036 let join = JoinRel::parse_pair_with_context(
2037 &extensions,
2038 parse_exact(
2039 Rule::join_relation,
2040 "Join[&Inner, eq($0, $3):boolean => $0, $1, $3, $4]",
2041 ),
2042 vec![left_rel, right_rel],
2043 6, )
2045 .unwrap()
2046 .0;
2047
2048 assert_eq!(join.r#type, join_rel::JoinType::Inner as i32);
2050
2051 assert!(join.left.is_some());
2053 assert!(join.right.is_some());
2054
2055 assert!(join.expression.is_some());
2057 assert!(join.post_join_filter.is_none());
2058
2059 let emit_kind = &join.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
2060 let emit = match emit_kind {
2061 EmitKind::Emit(emit) => &emit.output_mapping,
2062 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
2063 };
2064 assert_eq!(emit, &[0, 1, 3, 4]);
2066 }
2067
2068 #[test]
2069 fn test_parse_join_relation_post_join_filter() {
2070 let extensions = TestContext::new()
2071 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_comparison.yaml")
2072 .with_function(1, 10, "eq")
2073 .with_function(1, 11, "gt")
2074 .extensions;
2075
2076 let left_rel = example_read_relation().into_rel(None);
2077 let right_rel = example_read_relation().into_rel(None);
2078
2079 let join = JoinRel::parse_pair_with_context(
2080 &extensions,
2081 parse_exact(
2082 Rule::join_relation,
2083 "Join[&RightSemi, eq($0, $3):boolean, post_filter=gt($1, 100:i32):boolean => $0, $1]",
2084 ),
2085 vec![left_rel, right_rel],
2086 6,
2087 )
2088 .unwrap()
2089 .0;
2090
2091 assert_eq!(join.r#type, join_rel::JoinType::RightSemi as i32);
2092 assert!(join.expression.is_some());
2093 assert!(join.post_join_filter.is_some());
2094
2095 let emit_kind = &join.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
2096 let emit = match emit_kind {
2097 EmitKind::Emit(emit) => &emit.output_mapping,
2098 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
2099 };
2100 assert_eq!(emit, &[0, 1]);
2101 }
2102
2103 #[test]
2104 fn test_parse_join_relation_left_outer() {
2105 let extensions = TestContext::new()
2106 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_comparison.yaml")
2107 .with_function(1, 10, "eq")
2108 .extensions;
2109
2110 let left_rel = example_read_relation().into_rel(None);
2111 let right_rel = example_read_relation().into_rel(None);
2112
2113 let join = JoinRel::parse_pair_with_context(
2114 &extensions,
2115 parse_exact(
2116 Rule::join_relation,
2117 "Join[&Left, eq($0, $3):boolean => $0, $1, $2]",
2118 ),
2119 vec![left_rel, right_rel],
2120 6,
2121 )
2122 .unwrap()
2123 .0;
2124
2125 assert_eq!(join.r#type, join_rel::JoinType::Left as i32);
2127
2128 let emit_kind = &join.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
2129 let emit = match emit_kind {
2130 EmitKind::Emit(emit) => &emit.output_mapping,
2131 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
2132 };
2133 assert_eq!(emit, &[0, 1, 2]);
2135 }
2136
2137 #[test]
2138 fn test_parse_join_relation_left_semi() {
2139 let extensions = TestContext::new()
2140 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_comparison.yaml")
2141 .with_function(1, 10, "eq")
2142 .extensions;
2143
2144 let left_rel = example_read_relation().into_rel(None);
2145 let right_rel = example_read_relation().into_rel(None);
2146
2147 let join = JoinRel::parse_pair_with_context(
2148 &extensions,
2149 parse_exact(
2150 Rule::join_relation,
2151 "Join[&LeftSemi, eq($0, $3):boolean => $0, $1]",
2152 ),
2153 vec![left_rel, right_rel],
2154 6,
2155 )
2156 .unwrap()
2157 .0;
2158
2159 assert_eq!(join.r#type, join_rel::JoinType::LeftSemi as i32);
2161
2162 let emit_kind = &join.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
2163 let emit = match emit_kind {
2164 EmitKind::Emit(emit) => &emit.output_mapping,
2165 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
2166 };
2167 assert_eq!(emit, &[0, 1]);
2169 }
2170
2171 #[test]
2172 fn test_parse_join_relation_right_semi() {
2173 let extensions = TestContext::new()
2174 .with_urn(1, "https://github.com/substrait-io/substrait/blob/main/extensions/functions_comparison.yaml")
2175 .with_function(1, 10, "eq")
2176 .extensions;
2177
2178 let left_rel = example_read_relation().into_rel(None);
2179 let right_rel = example_read_relation().into_rel(None);
2180
2181 let join = JoinRel::parse_pair_with_context(
2182 &extensions,
2183 parse_exact(
2184 Rule::join_relation,
2185 "Join[&RightSemi, eq($0, $3):boolean => $0, $1]",
2186 ),
2187 vec![left_rel, right_rel],
2188 6,
2189 )
2190 .unwrap()
2191 .0;
2192
2193 assert_eq!(join.r#type, join_rel::JoinType::RightSemi as i32);
2195
2196 let emit_kind = &join.common.as_ref().unwrap().emit_kind.as_ref().unwrap();
2197 let emit = match emit_kind {
2198 EmitKind::Emit(emit) => &emit.output_mapping,
2199 _ => panic!("Expected EmitKind::Emit, got {emit_kind:?}"),
2200 };
2201 assert_eq!(emit, &[0, 1]);
2203 }
2204
2205 #[test]
2206 fn test_parse_join_relation_requires_two_children() {
2207 let extensions = SimpleExtensions::default();
2208
2209 let result = JoinRel::parse_pair_with_context(
2211 &extensions,
2212 parse_exact(
2213 Rule::join_relation,
2214 "Join[&Inner, eq($0, $1):boolean => $0, $1]",
2215 ),
2216 vec![],
2217 0,
2218 );
2219 assert!(result.is_err());
2220
2221 let result = JoinRel::parse_pair_with_context(
2223 &extensions,
2224 parse_exact(
2225 Rule::join_relation,
2226 "Join[&Inner, eq($0, $1):boolean => $0, $1]",
2227 ),
2228 vec![example_read_relation().into_rel(None)],
2229 3,
2230 );
2231 assert!(result.is_err());
2232
2233 let result = JoinRel::parse_pair_with_context(
2235 &extensions,
2236 parse_exact(
2237 Rule::join_relation,
2238 "Join[&Inner, eq($0, $1):boolean => $0, $1]",
2239 ),
2240 vec![
2241 example_read_relation().into_rel(None),
2242 example_read_relation().into_rel(None),
2243 example_read_relation().into_rel(None),
2244 ],
2245 9,
2246 );
2247 assert!(result.is_err());
2248 }
2249
2250 fn parse_exact(rule: Rule, input: &'_ str) -> Pair<'_, Rule> {
2251 let mut pairs = ExpressionParser::parse(rule, input).unwrap();
2252 assert_eq!(pairs.as_str(), input);
2253 let pair = pairs.next().unwrap();
2254 assert_eq!(pairs.next(), None);
2255 pair
2256 }
2257}