1use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime};
2use substrait::proto::aggregate_rel::Measure;
3use substrait::proto::expression::field_reference::{ReferenceType, RootReference, RootType};
4use substrait::proto::expression::if_then::IfClause;
5use substrait::proto::expression::literal::{
6 LiteralType, PrecisionTime as LitPrecisionTime, PrecisionTimestamp as LitPrecisionTimestamp,
7};
8use substrait::proto::expression::{
9 Cast, FieldReference, IfThen, Literal, ReferenceSegment, RexType, ScalarFunction, cast,
10 reference_segment,
11};
12use substrait::proto::function_argument::ArgType;
13use substrait::proto::r#type::{Fp64, I64, Kind, Nullability};
14use substrait::proto::{AggregateFunction, Expression, FunctionArgument, Type};
15
16use super::types::get_and_validate_anchor;
17use super::{
18 MessageParseError, ParsePair, Rule, RuleIter, ScopedParsePair, unescape_string,
19 unwrap_single_pair,
20};
21use crate::extensions::SimpleExtensions;
22use crate::extensions::simple::{CompoundName, ExtensionKind};
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub struct FieldIndex(pub i32);
27
28impl FieldIndex {
29 pub fn to_field_reference(self) -> FieldReference {
31 FieldReference {
34 reference_type: Some(ReferenceType::DirectReference(ReferenceSegment {
35 reference_type: Some(reference_segment::ReferenceType::StructField(Box::new(
36 reference_segment::StructField {
37 field: self.0,
38 child: None,
39 },
40 ))),
41 })),
42 root_type: Some(RootType::RootReference(RootReference {})),
43 }
44 }
45}
46
47impl ParsePair for FieldIndex {
48 fn rule() -> Rule {
49 Rule::reference
50 }
51
52 fn message() -> &'static str {
53 "FieldIndex"
54 }
55
56 fn parse_pair(pair: pest::iterators::Pair<Rule>) -> Self {
57 assert_eq!(pair.as_rule(), Self::rule());
58 let inner = unwrap_single_pair(pair);
59 let index: i32 = inner.as_str().parse().unwrap();
60 FieldIndex(index)
61 }
62}
63
64impl ParsePair for FieldReference {
65 fn rule() -> Rule {
66 Rule::reference
67 }
68
69 fn message() -> &'static str {
70 "FieldReference"
71 }
72
73 fn parse_pair(pair: pest::iterators::Pair<Rule>) -> Self {
74 assert_eq!(pair.as_rule(), Self::rule());
75
76 FieldIndex::parse_pair(pair).to_field_reference()
78 }
79}
80
81fn to_int_literal(
82 value: pest::iterators::Pair<Rule>,
83 typ: Option<Type>,
84) -> Result<Literal, MessageParseError> {
85 assert_eq!(value.as_rule(), Rule::integer);
86 let parsed_value: i64 = value.as_str().parse().unwrap();
87
88 const DEFAULT_KIND: Kind = Kind::I64(I64 {
89 type_variation_reference: 0,
90 nullability: Nullability::Required as i32,
91 });
92
93 let kind = typ.and_then(|t| t.kind).unwrap_or(DEFAULT_KIND);
95
96 let (lit, nullability, tvar) = match &kind {
97 Kind::I8(i) => (
99 LiteralType::I8(parsed_value as i32),
100 i.nullability,
101 i.type_variation_reference,
102 ),
103 Kind::I16(i) => (
104 LiteralType::I16(parsed_value as i32),
105 i.nullability,
106 i.type_variation_reference,
107 ),
108 Kind::I32(i) => (
109 LiteralType::I32(parsed_value as i32),
110 i.nullability,
111 i.type_variation_reference,
112 ),
113 Kind::I64(i) => (
114 LiteralType::I64(parsed_value),
115 i.nullability,
116 i.type_variation_reference,
117 ),
118 k => {
119 return Err(MessageParseError::invalid(
120 "int_literal_type",
121 value.as_span(),
122 format!("Invalid type for integer literal: {k:?}"),
123 ));
124 }
125 };
126
127 Ok(Literal {
128 literal_type: Some(lit),
129 nullable: nullability != Nullability::Required as i32,
130 type_variation_reference: tvar,
131 })
132}
133
134fn to_float_literal(
135 value: pest::iterators::Pair<Rule>,
136 typ: Option<Type>,
137) -> Result<Literal, MessageParseError> {
138 assert_eq!(value.as_rule(), Rule::float);
139 let parsed_value: f64 = value.as_str().parse().unwrap();
140
141 const DEFAULT_KIND: Kind = Kind::Fp64(Fp64 {
142 type_variation_reference: 0,
143 nullability: Nullability::Required as i32,
144 });
145
146 let kind = typ.and_then(|t| t.kind).unwrap_or(DEFAULT_KIND);
148
149 let (lit, nullability, tvar) = match &kind {
150 Kind::Fp32(f) => (
151 LiteralType::Fp32(parsed_value as f32),
152 f.nullability,
153 f.type_variation_reference,
154 ),
155 Kind::Fp64(f) => (
156 LiteralType::Fp64(parsed_value),
157 f.nullability,
158 f.type_variation_reference,
159 ),
160 k => {
161 return Err(MessageParseError::invalid(
162 "float_literal_type",
163 value.as_span(),
164 format!("Invalid type for float literal: {k:?}"),
165 ));
166 }
167 };
168
169 Ok(Literal {
170 literal_type: Some(lit),
171 nullable: nullability != Nullability::Required as i32,
172 type_variation_reference: tvar,
173 })
174}
175
176fn to_boolean_literal(
177 value: pest::iterators::Pair<Rule>,
178 typ: Option<Type>,
179) -> Result<Literal, MessageParseError> {
180 assert_eq!(value.as_rule(), Rule::boolean);
181 let parsed_value: bool = value.as_str().parse().unwrap();
182
183 let (nullable, tvar) = match typ.and_then(|t| t.kind) {
184 Some(Kind::Bool(b)) => (
185 b.nullability != Nullability::Required as i32,
186 b.type_variation_reference,
187 ),
188 None => (false, 0),
189 Some(k) => {
190 return Err(MessageParseError::invalid(
191 "bool_literal_type",
192 value.as_span(),
193 format!("Invalid type for boolean literal: {k:?}"),
194 ));
195 }
196 };
197
198 Ok(Literal {
199 literal_type: Some(LiteralType::Boolean(parsed_value)),
200 nullable,
201 type_variation_reference: tvar,
202 })
203}
204
205fn to_string_literal(
206 value: pest::iterators::Pair<Rule>,
207 typ: Option<Type>,
208) -> Result<Literal, MessageParseError> {
209 assert_eq!(value.as_rule(), Rule::string_literal);
210 let string_value = unescape_string(value.clone());
211
212 let Some(typ) = typ else {
214 return Ok(Literal {
215 literal_type: Some(LiteralType::String(string_value)),
216 nullable: false,
217 type_variation_reference: 0,
218 });
219 };
220
221 let Some(kind) = typ.kind else {
222 return Ok(Literal {
223 literal_type: Some(LiteralType::String(string_value)),
224 nullable: false,
225 type_variation_reference: 0,
226 });
227 };
228
229 match &kind {
230 Kind::Date(d) => {
231 let date_days = parse_date_to_days(&string_value, value.as_span())?;
233 Ok(Literal {
234 literal_type: Some(LiteralType::Date(date_days)),
235 nullable: d.nullability != Nullability::Required as i32,
236 type_variation_reference: d.type_variation_reference,
237 })
238 }
239 #[allow(deprecated)]
240 Kind::Time(t) => {
241 let time_microseconds = parse_time_to_microseconds(&string_value, value.as_span())?;
243 Ok(Literal {
244 literal_type: Some(LiteralType::Time(time_microseconds)),
245 nullable: t.nullability != Nullability::Required as i32,
246 type_variation_reference: t.type_variation_reference,
247 })
248 }
249 #[allow(deprecated)]
250 Kind::Timestamp(ts) => {
251 let timestamp_microseconds =
253 parse_timestamp_to_microseconds(&string_value, value.as_span())?;
254 Ok(Literal {
255 literal_type: Some(LiteralType::Timestamp(timestamp_microseconds)),
256 nullable: ts.nullability != Nullability::Required as i32,
257 type_variation_reference: ts.type_variation_reference,
258 })
259 }
260 Kind::PrecisionTimestamp(pt) => {
261 let precision = pt.precision;
262 let timestamp_value = parse_timestamp_to_precision_units(
263 &string_value,
264 precision,
265 "precisiontimestamp",
266 value.as_span(),
267 )?;
268 Ok(Literal {
269 literal_type: Some(LiteralType::PrecisionTimestamp(LitPrecisionTimestamp {
270 precision,
271 value: timestamp_value,
272 })),
273 nullable: pt.nullability != Nullability::Required as i32,
274 type_variation_reference: pt.type_variation_reference,
275 })
276 }
277 Kind::PrecisionTimestampTz(pt) => {
278 let precision = pt.precision;
279 let timestamp_value = parse_timestamp_to_precision_units(
280 &string_value,
281 precision,
282 "precisiontimestamptz",
283 value.as_span(),
284 )?;
285 Ok(Literal {
286 literal_type: Some(LiteralType::PrecisionTimestampTz(LitPrecisionTimestamp {
287 precision,
288 value: timestamp_value,
289 })),
290 nullable: pt.nullability != Nullability::Required as i32,
291 type_variation_reference: pt.type_variation_reference,
292 })
293 }
294 Kind::PrecisionTime(pt) => {
295 let precision = pt.precision;
296 let time_value = parse_time_to_precision_units(
297 &string_value,
298 precision,
299 "precisiontime",
300 value.as_span(),
301 )?;
302 Ok(Literal {
303 literal_type: Some(LiteralType::PrecisionTime(LitPrecisionTime {
304 precision,
305 value: time_value,
306 })),
307 nullable: pt.nullability != Nullability::Required as i32,
308 type_variation_reference: pt.type_variation_reference,
309 })
310 }
311 _ => {
312 Ok(Literal {
314 literal_type: Some(LiteralType::String(string_value)),
315 nullable: false,
316 type_variation_reference: 0,
317 })
318 }
319 }
320}
321
322fn to_null_literal(
323 value: pest::iterators::Pair<Rule>,
324 typ: Option<Type>,
325) -> Result<Literal, MessageParseError> {
326 assert_eq!(value.as_rule(), Rule::null);
327 let typ = typ.ok_or_else(|| {
328 MessageParseError::invalid(
329 "null_literal_type",
330 value.as_span(),
331 "Null literals require an explicit type annotation, e.g. null:i64?",
332 )
333 })?;
334
335 Ok(Literal {
336 literal_type: Some(LiteralType::Null(typ)),
337 nullable: false,
338 type_variation_reference: 0,
339 })
340}
341
342fn parse_date_to_days(date_str: &str, span: pest::Span) -> Result<i32, MessageParseError> {
344 let formats = ["%Y-%m-%d", "%Y/%m/%d"];
346
347 for format in &formats {
348 if let Ok(date) = NaiveDate::parse_from_str(date_str, format) {
349 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
351 let days = date.signed_duration_since(epoch).num_days();
352 return Ok(days as i32);
353 }
354 }
355
356 Err(MessageParseError::invalid(
357 "date_parse_format",
358 span,
359 format!("Invalid date format: '{date_str}'. Expected YYYY-MM-DD or YYYY/MM/DD"),
360 ))
361}
362
363fn parse_time_to_microseconds(time_str: &str, span: pest::Span) -> Result<i64, MessageParseError> {
365 parse_time_to_precision_units(time_str, 6, "time", span)
366}
367
368fn parse_timestamp_to_microseconds(
370 timestamp_str: &str,
371 span: pest::Span,
372) -> Result<i64, MessageParseError> {
373 parse_timestamp_to_precision_units(timestamp_str, 6, "timestamp", span)
374}
375
376#[derive(Debug, Clone, Copy)]
377enum SupportedPrecision {
378 Seconds, Milliseconds, Microseconds, Nanoseconds, }
383
384impl SupportedPrecision {
385 fn units(self) -> i32 {
387 match self {
388 SupportedPrecision::Seconds => 0,
389 SupportedPrecision::Milliseconds => 3,
390 SupportedPrecision::Microseconds => 6,
391 SupportedPrecision::Nanoseconds => 9,
392 }
393 }
394}
395
396fn duration_to_precision_units(
401 duration: chrono::Duration,
402 precision: SupportedPrecision,
403 literal_kind: &'static str,
404 span: pest::Span,
405) -> Result<i64, MessageParseError> {
406 let out_of_range = || {
407 MessageParseError::invalid(
408 "precision_literal_out_of_range",
409 span,
410 format!(
411 "value is out of range for a {literal_kind} literal at precision {}",
412 precision.units()
413 ),
414 )
415 };
416 let fractional_truncated = || {
417 MessageParseError::invalid(
418 "precision_literal_fractional_truncated",
419 span,
420 format!(
421 "value has a fractional component finer than precision {} can represent for a {literal_kind} literal",
422 precision.units()
423 ),
424 )
425 };
426
427 match precision {
428 SupportedPrecision::Seconds => {
429 let value = duration.num_seconds();
430 if chrono::Duration::seconds(value) != duration {
431 return Err(fractional_truncated());
432 }
433 Ok(value)
434 }
435 SupportedPrecision::Milliseconds => {
436 let value = duration.num_milliseconds();
437 if chrono::Duration::milliseconds(value) != duration {
438 return Err(fractional_truncated());
439 }
440 Ok(value)
441 }
442 SupportedPrecision::Microseconds => {
443 let value = duration.num_microseconds().ok_or_else(out_of_range)?;
444 if chrono::Duration::microseconds(value) != duration {
445 return Err(fractional_truncated());
446 }
447 Ok(value)
448 }
449 SupportedPrecision::Nanoseconds => duration.num_nanoseconds().ok_or_else(out_of_range),
452 }
453}
454
455fn check_supported_precision(
456 precision: i32,
457 literal_kind: &'static str,
458 span: pest::Span,
459) -> Result<SupportedPrecision, MessageParseError> {
460 match precision {
461 0 => return Ok(SupportedPrecision::Seconds),
462 3 => return Ok(SupportedPrecision::Milliseconds),
463 6 => return Ok(SupportedPrecision::Microseconds),
464 9 => return Ok(SupportedPrecision::Nanoseconds),
465 _ => {}
466 }
467 if precision == 12 {
468 return Err(MessageParseError::invalid(
469 "precision_literal_unsupported_precision",
470 span,
471 format!(
472 "precision 12 (picoseconds) is not supported for {literal_kind} literals; chrono only supports nanosecond (precision 9) resolution"
473 ),
474 ));
475 }
476 Err(MessageParseError::invalid(
477 "precision_literal_invalid_precision",
478 span,
479 format!(
480 "Invalid precision {precision} for a {literal_kind} literal; expected one of 0 (seconds), 3 (milliseconds), 6 (microseconds), or 9 (nanoseconds)"
481 ),
482 ))
483}
484
485fn parse_timestamp_to_precision_units(
487 timestamp_str: &str,
488 precision: i32,
489 literal_kind: &'static str,
490 span: pest::Span,
491) -> Result<i64, MessageParseError> {
492 let precision = check_supported_precision(precision, literal_kind, span)?;
493
494 let formats = [
496 "%Y-%m-%dT%H:%M:%S%.f", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S%.f", "%Y-%m-%d %H:%M:%S", "%Y/%m/%dT%H:%M:%S%.f", "%Y/%m/%dT%H:%M:%S", "%Y/%m/%d %H:%M:%S%.f", "%Y/%m/%d %H:%M:%S", ];
505
506 for format in &formats {
507 if let Ok(datetime) = NaiveDateTime::parse_from_str(timestamp_str, format) {
508 let epoch = DateTime::from_timestamp(0, 0).unwrap().naive_utc();
509 let duration = datetime.signed_duration_since(epoch);
510 return duration_to_precision_units(duration, precision, literal_kind, span);
511 }
512 }
513
514 Err(MessageParseError::invalid(
515 "timestamp_parse_format",
516 span,
517 format!(
518 "Invalid timestamp format: '{timestamp_str}'. Expected YYYY-MM-DDTHH:MM:SS or YYYY-MM-DD HH:MM:SS"
519 ),
520 ))
521}
522
523fn parse_time_to_precision_units(
525 time_str: &str,
526 precision: i32,
527 literal_kind: &'static str,
528 span: pest::Span,
529) -> Result<i64, MessageParseError> {
530 let precision = check_supported_precision(precision, literal_kind, span)?;
531
532 let formats = ["%H:%M:%S%.f", "%H:%M:%S"];
534
535 for format in &formats {
536 if let Ok(time) = NaiveTime::parse_from_str(time_str, format) {
537 let midnight = NaiveTime::from_hms_opt(0, 0, 0).unwrap();
538 let duration = time.signed_duration_since(midnight);
539 return duration_to_precision_units(duration, precision, literal_kind, span);
540 }
541 }
542
543 Err(MessageParseError::invalid(
544 "time_parse_format",
545 span,
546 format!("Invalid time format: '{time_str}'. Expected HH:MM:SS or HH:MM:SS.fff"),
547 ))
548}
549
550impl ScopedParsePair for Literal {
551 fn rule() -> Rule {
552 Rule::literal
553 }
554
555 fn message() -> &'static str {
556 "Literal"
557 }
558
559 fn parse_pair(
560 extensions: &SimpleExtensions,
561 pair: pest::iterators::Pair<Rule>,
562 ) -> Result<Self, MessageParseError> {
563 assert_eq!(pair.as_rule(), Self::rule());
564 let mut pairs = pair.into_inner();
565 let value = pairs.next().unwrap(); let typ = pairs.next(); assert!(pairs.next().is_none());
568 let typ = match typ {
569 Some(t) => Some(Type::parse_pair(extensions, t)?),
570 None => None,
571 };
572 match value.as_rule() {
573 Rule::integer => to_int_literal(value, typ),
574 Rule::float => to_float_literal(value, typ),
575 Rule::boolean => to_boolean_literal(value, typ),
576 Rule::string_literal => to_string_literal(value, typ),
577 Rule::null => to_null_literal(value, typ),
578 _ => unreachable!("Literal unexpected rule: {:?}", value.as_rule()),
579 }
580 }
581}
582
583impl ScopedParsePair for ScalarFunction {
584 fn rule() -> Rule {
585 Rule::function_call
586 }
587
588 fn message() -> &'static str {
589 "ScalarFunction"
590 }
591
592 fn parse_pair(
593 extensions: &SimpleExtensions,
594 pair: pest::iterators::Pair<Rule>,
595 ) -> Result<Self, MessageParseError> {
596 assert_eq!(pair.as_rule(), Self::rule());
597 let span = pair.as_span();
598 let mut iter = RuleIter::from(pair.into_inner());
599
600 let name = iter.parse_next::<CompoundName>();
602
603 let anchor = iter
605 .try_pop(Rule::anchor)
606 .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
607
608 let _urn_anchor = iter
610 .try_pop(Rule::urn_anchor)
611 .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
612
613 let argument_list = iter.pop(Rule::argument_list);
615 let mut arguments = Vec::new();
616 for e in argument_list.into_inner() {
617 arguments.push(FunctionArgument {
618 arg_type: Some(ArgType::Value(Expression::parse_pair(extensions, e)?)),
619 });
620 }
621
622 let output_type = Some(Type::parse_pair(extensions, iter.pop(Rule::r#type))?);
625
626 iter.done();
627 let anchor = get_and_validate_anchor(
628 extensions,
629 ExtensionKind::Function,
630 anchor,
631 name.full(),
632 span,
633 )?;
634 Ok(ScalarFunction {
635 function_reference: anchor,
636 arguments,
637 options: vec![], output_type,
639 #[allow(deprecated)]
640 args: vec![],
641 })
642 }
643}
644
645impl ScopedParsePair for Cast {
646 fn rule() -> Rule {
647 Rule::cast_expression
648 }
649
650 fn message() -> &'static str {
651 "Cast"
652 }
653
654 fn parse_pair(
655 extensions: &SimpleExtensions,
656 pair: pest::iterators::Pair<Rule>,
657 ) -> Result<Self, MessageParseError> {
658 assert_eq!(pair.as_rule(), Self::rule());
659 let mut pairs = pair.into_inner();
660
661 let expr_pair = pairs.next().unwrap();
662
663 let next = pairs.next().unwrap();
665 let (failure_behavior, type_pair) = if next.as_rule() == Rule::cast_failure_behavior {
666 let fb = match next.as_str() {
667 "?" => cast::FailureBehavior::ReturnNull as i32,
668 "!" => cast::FailureBehavior::ThrowException as i32,
669 _ => unreachable!("Grammar guarantees cast_failure_behavior is ? or !"),
670 };
671 (fb, pairs.next().unwrap())
672 } else {
673 (cast::FailureBehavior::Unspecified as i32, next)
674 };
675
676 assert!(pairs.next().is_none());
677
678 let input = Expression::parse_pair(extensions, expr_pair)?;
679 let target_type = Type::parse_pair(extensions, type_pair)?;
680
681 Ok(Cast {
682 r#type: Some(target_type),
683 input: Some(Box::new(input)),
684 failure_behavior,
685 })
686 }
687}
688
689impl ScopedParsePair for Expression {
690 fn rule() -> Rule {
691 Rule::expression
692 }
693
694 fn message() -> &'static str {
695 "Expression"
696 }
697
698 fn parse_pair(
699 extensions: &SimpleExtensions,
700 pair: pest::iterators::Pair<Rule>,
701 ) -> Result<Self, MessageParseError> {
702 assert_eq!(pair.as_rule(), Self::rule());
703 let inner = unwrap_single_pair(pair);
704 match inner.as_rule() {
705 Rule::literal => Ok(Expression {
706 rex_type: Some(RexType::Literal(Literal::parse_pair(extensions, inner)?)),
707 }),
708 Rule::function_call => Ok(Expression {
709 rex_type: Some(RexType::ScalarFunction(ScalarFunction::parse_pair(
710 extensions, inner,
711 )?)),
712 }),
713 Rule::reference => Ok(Expression {
714 rex_type: Some(RexType::Selection(Box::new(FieldReference::parse_pair(
715 inner,
716 )))),
717 }),
718 Rule::if_then => Ok(Expression {
719 rex_type: Some(RexType::IfThen(Box::new(IfThen::parse_pair(
720 extensions, inner,
721 )?))),
722 }),
723 Rule::cast_expression => Ok(Expression {
724 rex_type: Some(RexType::Cast(Box::new(Cast::parse_pair(
725 extensions, inner,
726 )?))),
727 }),
728 _ => unreachable!(
729 "Grammar guarantees expression can only be literal, function_call, reference, if_then, or cast_expression, got: {:?}",
730 inner.as_rule()
731 ),
732 }
733 }
734}
735
736impl ScopedParsePair for IfClause {
737 fn rule() -> Rule {
738 Rule::if_clause
739 }
740
741 fn message() -> &'static str {
742 "IfClause"
743 }
744
745 fn parse_pair(
746 extensions: &SimpleExtensions,
747 pair: pest::iterators::Pair<Rule>,
748 ) -> Result<Self, MessageParseError> {
749 assert_eq!(pair.as_rule(), Self::rule());
750 let mut pairs = pair.into_inner(); let condition = pairs.next().unwrap();
753 let result = pairs.next().unwrap();
754 assert!(pairs.next().is_none());
755
756 let ex1 = Some(Expression::parse_pair(extensions, condition)?);
757 let ex2 = Some(Expression::parse_pair(extensions, result)?);
758
759 Ok(IfClause {
760 r#if: ex1,
761 then: ex2,
762 })
763 }
764}
765
766impl ScopedParsePair for IfThen {
767 fn rule() -> Rule {
768 Rule::if_then
769 }
770 fn message() -> &'static str {
771 "IfThen"
772 }
773
774 fn parse_pair(
775 extensions: &SimpleExtensions,
776 pair: pest::iterators::Pair<Rule>,
777 ) -> Result<Self, MessageParseError> {
778 assert_eq!(pair.as_rule(), Self::rule());
779
780 let mut iter = RuleIter::from(pair.into_inner()); let mut ifs: Vec<IfClause> = Vec::new();
783
784 while let Some(p) = iter.try_pop(Rule::if_clause) {
786 let if_clause = IfClause::parse_pair(extensions, p)?;
787 ifs.push(if_clause);
788 }
789
790 let pair = iter.try_pop(Rule::expression).unwrap(); iter.done();
792 let else_clause = Some(Box::new(Expression::parse_pair(extensions, pair)?));
793
794 Ok(IfThen {
795 ifs,
796 r#else: else_clause,
797 })
798 }
799}
800pub struct Name(pub String);
801
802impl ParsePair for Name {
803 fn rule() -> Rule {
804 Rule::name
805 }
806
807 fn message() -> &'static str {
808 "Name"
809 }
810
811 fn parse_pair(pair: pest::iterators::Pair<Rule>) -> Self {
812 assert_eq!(pair.as_rule(), Self::rule());
813 let inner = unwrap_single_pair(pair);
814 match inner.as_rule() {
815 Rule::identifier => Name(inner.as_str().to_string()),
816 Rule::quoted_name => Name(unescape_string(inner)),
817 _ => unreachable!("Name unexpected rule: {:?}", inner.as_rule()),
818 }
819 }
820}
821
822impl ParsePair for CompoundName {
823 fn rule() -> Rule {
824 Rule::function_signature
825 }
826
827 fn message() -> &'static str {
828 "CompoundName"
829 }
830
831 fn parse_pair(pair: pest::iterators::Pair<Rule>) -> Self {
832 assert_eq!(pair.as_rule(), Self::rule());
833 CompoundName::new(pair.as_str())
834 }
835}
836
837impl ScopedParsePair for Measure {
838 fn rule() -> Rule {
839 Rule::function_call
840 }
841
842 fn message() -> &'static str {
843 "Measure"
844 }
845
846 fn parse_pair(
847 extensions: &SimpleExtensions,
848 pair: pest::iterators::Pair<Rule>,
849 ) -> Result<Self, MessageParseError> {
850 assert_eq!(pair.as_rule(), Self::rule());
851
852 let scalar = ScalarFunction::parse_pair(extensions, pair)?;
854 Ok(Measure {
855 measure: Some(AggregateFunction {
856 function_reference: scalar.function_reference,
857 arguments: scalar.arguments,
858 options: scalar.options,
859 output_type: scalar.output_type,
860 invocation: 0, phase: 0, sorts: vec![], #[allow(deprecated)]
864 args: scalar.args,
865 }),
866 filter: None, })
868 }
869}
870
871#[cfg(test)]
872mod tests {
873 use pest::Parser as PestParser;
874
875 use super::*;
876 use crate::parser::ExpressionParser;
877
878 fn parse_exact(rule: Rule, input: &'_ str) -> pest::iterators::Pair<'_, Rule> {
879 let mut pairs = ExpressionParser::parse(rule, input).unwrap();
880 assert_eq!(pairs.as_str(), input);
881 let pair = pairs.next().unwrap();
882 assert_eq!(pairs.next(), None);
883 pair
884 }
885
886 fn assert_parses_to<T: ParsePair + PartialEq + std::fmt::Debug>(input: &str, expected: T) {
887 let pair = parse_exact(T::rule(), input);
888 let actual = T::parse_pair(pair);
889 assert_eq!(actual, expected);
890 }
891
892 fn assert_parses_with<T: ScopedParsePair + PartialEq + std::fmt::Debug>(
893 ext: &SimpleExtensions,
894 input: &str,
895 expected: T,
896 ) {
897 let pair = parse_exact(T::rule(), input);
898 let actual = T::parse_pair(ext, pair).unwrap();
899 assert_eq!(actual, expected);
900 }
901
902 #[test]
903 fn test_parse_field_reference() {
904 assert_parses_to("$1", FieldIndex(1).to_field_reference());
905 }
906
907 #[test]
908 fn test_parse_integer_literal() {
909 let extensions = SimpleExtensions::default();
910 let expected = Literal {
911 literal_type: Some(LiteralType::I64(1)),
912 nullable: false,
913 type_variation_reference: 0,
914 };
915 assert_parses_with(&extensions, "1", expected);
916 }
917
918 #[test]
919 fn test_parse_float_literal() {
920 let pairs = ExpressionParser::parse(Rule::float, "3.82").unwrap();
922 let parsed_text = pairs.as_str();
923 assert_eq!(parsed_text, "3.82");
924
925 let extensions = SimpleExtensions::default();
926 let expected = Literal {
927 literal_type: Some(LiteralType::Fp64(3.82)),
928 nullable: false,
929 type_variation_reference: 0,
930 };
931 assert_parses_with(&extensions, "3.82", expected);
932 }
933
934 #[test]
935 fn test_parse_negative_float_literal() {
936 let extensions = SimpleExtensions::default();
937 let expected = Literal {
938 literal_type: Some(LiteralType::Fp64(-2.5)),
939 nullable: false,
940 type_variation_reference: 0,
941 };
942 assert_parses_with(&extensions, "-2.5", expected);
943 }
944
945 #[test]
946 fn test_parse_boolean_true_literal() {
947 let extensions = SimpleExtensions::default();
948 let expected = Literal {
949 literal_type: Some(LiteralType::Boolean(true)),
950 nullable: false,
951 type_variation_reference: 0,
952 };
953 assert_parses_with(&extensions, "true", expected);
954 }
955
956 #[test]
957 fn test_parse_boolean_false_literal() {
958 let extensions = SimpleExtensions::default();
959 let expected = Literal {
960 literal_type: Some(LiteralType::Boolean(false)),
961 nullable: false,
962 type_variation_reference: 0,
963 };
964 assert_parses_with(&extensions, "false", expected);
965 }
966
967 #[test]
968 fn test_parse_nullable_boolean_literal() {
969 let extensions = SimpleExtensions::default();
970 let expected_true = Literal {
971 literal_type: Some(LiteralType::Boolean(true)),
972 nullable: true,
973 type_variation_reference: 0,
974 };
975 let expected_false = Literal {
976 literal_type: Some(LiteralType::Boolean(false)),
977 nullable: true,
978 type_variation_reference: 0,
979 };
980 assert_parses_with(&extensions, "true:boolean?", expected_true);
981 assert_parses_with(&extensions, "false:boolean?", expected_false);
982 }
983
984 #[test]
985 fn test_parse_nullable_integer_literal() {
986 let extensions = SimpleExtensions::default();
987 let expected_i32 = Literal {
988 literal_type: Some(LiteralType::I32(78)),
989 nullable: true,
990 type_variation_reference: 0,
991 };
992 let expected_i64 = Literal {
993 literal_type: Some(LiteralType::I64(42)),
994 nullable: true,
995 type_variation_reference: 0,
996 };
997 assert_parses_with(&extensions, "78:i32?", expected_i32);
998 assert_parses_with(&extensions, "42:i64?", expected_i64);
999 }
1000
1001 #[test]
1002 fn test_parse_nullable_float_literal() {
1003 let extensions = SimpleExtensions::default();
1004 let expected_fp64 = Literal {
1005 literal_type: Some(LiteralType::Fp64(3.19)),
1006 nullable: true,
1007 type_variation_reference: 0,
1008 };
1009 assert_parses_with(&extensions, "3.19:fp64?", expected_fp64);
1010 }
1011
1012 #[test]
1013 fn test_parse_float_literal_with_fp32_type() {
1014 let extensions = SimpleExtensions::default();
1015 let pair = parse_exact(Rule::literal, "3.82:fp32");
1016 let result = Literal::parse_pair(&extensions, pair).unwrap();
1017
1018 match result.literal_type {
1019 Some(LiteralType::Fp32(val)) => assert!((val - 3.82).abs() < f32::EPSILON),
1020 _ => panic!("Expected Fp32 literal type"),
1021 }
1022 }
1023
1024 #[test]
1025 fn test_parse_date_literal() {
1026 let extensions = SimpleExtensions::default();
1027 let pair = parse_exact(Rule::literal, "'2023-12-25':date");
1028 let result = Literal::parse_pair(&extensions, pair).unwrap();
1029
1030 match result.literal_type {
1031 Some(LiteralType::Date(days)) => {
1032 assert!(
1034 days > 0,
1035 "Expected positive days since epoch, got: {}",
1036 days
1037 );
1038 }
1039 _ => panic!("Expected Date literal type, got: {:?}", result.literal_type),
1040 }
1041 }
1042
1043 #[test]
1044 fn test_parse_time_literal() {
1045 let extensions = SimpleExtensions::default();
1046 let pair = parse_exact(Rule::literal, "'14:30:45':time");
1047 let result = Literal::parse_pair(&extensions, pair).unwrap();
1048
1049 match result.literal_type {
1050 #[allow(deprecated)]
1051 Some(LiteralType::Time(microseconds)) => {
1052 let expected = (14 * 3600 + 30 * 60 + 45) * 1_000_000;
1054 assert_eq!(microseconds, expected);
1055 }
1056 _ => panic!("Expected Time literal type, got: {:?}", result.literal_type),
1057 }
1058 }
1059
1060 #[test]
1061 fn test_parse_timestamp_literal_with_t() {
1062 let extensions = SimpleExtensions::default();
1063 let pair = parse_exact(Rule::literal, "'2023-01-01T12:00:00':timestamp");
1064 let result = Literal::parse_pair(&extensions, pair).unwrap();
1065
1066 match result.literal_type {
1067 #[allow(deprecated)]
1068 Some(LiteralType::Timestamp(microseconds)) => {
1069 assert!(
1070 microseconds > 0,
1071 "Expected positive microseconds since epoch"
1072 );
1073 }
1074 _ => panic!(
1075 "Expected Timestamp literal type, got: {:?}",
1076 result.literal_type
1077 ),
1078 }
1079 }
1080
1081 #[test]
1082 fn test_parse_timestamp_literal_with_space() {
1083 let extensions = SimpleExtensions::default();
1084 let pair = parse_exact(Rule::literal, "'2023-01-01 12:00:00':timestamp");
1085 let result = Literal::parse_pair(&extensions, pair).unwrap();
1086
1087 match result.literal_type {
1088 #[allow(deprecated)]
1089 Some(LiteralType::Timestamp(microseconds)) => {
1090 assert!(
1091 microseconds > 0,
1092 "Expected positive microseconds since epoch"
1093 );
1094 }
1095 _ => panic!(
1096 "Expected Timestamp literal type, got: {:?}",
1097 result.literal_type
1098 ),
1099 }
1100 }
1101
1102 #[test]
1103 fn test_parse_precision_timestamp_literal() {
1104 let extensions = SimpleExtensions::default();
1105 let pair = parse_exact(
1106 Rule::literal,
1107 "'2023-01-01T12:00:00.123456789':precisiontimestamp<9>",
1108 );
1109 let result = Literal::parse_pair(&extensions, pair).unwrap();
1110
1111 match result.literal_type {
1112 Some(LiteralType::PrecisionTimestamp(p)) => {
1113 assert_eq!(p.precision, 9);
1114 assert!(p.value > 0, "Expected positive value since epoch");
1115 assert_eq!(p.value % 1_000_000_000, 123_456_789);
1118 }
1119 _ => panic!(
1120 "Expected PrecisionTimestamp literal type, got: {:?}",
1121 result.literal_type
1122 ),
1123 }
1124 assert!(!result.nullable);
1125 }
1126
1127 #[test]
1128 fn test_parse_precision_timestamp_tz_literal_nullable() {
1129 let extensions = SimpleExtensions::default();
1130 let pair = parse_exact(
1131 Rule::literal,
1132 "'2023-01-01T12:00:00.123':precisiontimestamptz?<3>",
1133 );
1134 let result = Literal::parse_pair(&extensions, pair).unwrap();
1135
1136 match result.literal_type {
1137 Some(LiteralType::PrecisionTimestampTz(p)) => {
1138 assert_eq!(p.precision, 3);
1139 assert_eq!(p.value % 1000, 123);
1140 }
1141 _ => panic!(
1142 "Expected PrecisionTimestampTz literal type, got: {:?}",
1143 result.literal_type
1144 ),
1145 }
1146 assert!(result.nullable);
1147 }
1148
1149 #[test]
1150 fn test_parse_precision_time_literal() {
1151 let extensions = SimpleExtensions::default();
1152 let pair = parse_exact(Rule::literal, "'14:30:45.123456':precisiontime<6>");
1153 let result = Literal::parse_pair(&extensions, pair).unwrap();
1154
1155 match result.literal_type {
1156 Some(LiteralType::PrecisionTime(p)) => {
1157 assert_eq!(p.precision, 6);
1158 let expected = (14 * 3600 + 30 * 60 + 45) * 1_000_000 + 123_456;
1159 assert_eq!(p.value, expected);
1160 }
1161 _ => panic!(
1162 "Expected PrecisionTime literal type, got: {:?}",
1163 result.literal_type
1164 ),
1165 }
1166 }
1167
1168 #[test]
1169 fn test_parse_precision_timestamp_literal_precision_12_unsupported() {
1170 let extensions = SimpleExtensions::default();
1171 let pair = parse_exact(
1172 Rule::literal,
1173 "'2023-01-01T12:00:00':precisiontimestamp<12>",
1174 );
1175 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1176 assert!(err.to_string().contains("picoseconds"));
1177 }
1178
1179 #[test]
1180 fn test_parse_precision_timestamp_literal_invalid_precision() {
1181 let extensions = SimpleExtensions::default();
1182 let pair = parse_exact(Rule::literal, "'2023-01-01T12:00:00':precisiontimestamp<5>");
1184 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1185 assert!(err.to_string().contains("Invalid precision 5"));
1186 }
1187
1188 #[test]
1189 fn test_parse_precision_timestamp_literal_nullable() {
1190 let extensions = SimpleExtensions::default();
1191 let pair = parse_exact(
1192 Rule::literal,
1193 "'2023-01-01T12:00:00.123456789':precisiontimestamp?<9>",
1194 );
1195 let result = Literal::parse_pair(&extensions, pair).unwrap();
1196 assert!(result.nullable);
1197 }
1198
1199 #[test]
1200 fn test_parse_precision_time_literal_nullable() {
1201 let extensions = SimpleExtensions::default();
1202 let pair = parse_exact(Rule::literal, "'14:30:45.123456':precisiontime?<6>");
1203 let result = Literal::parse_pair(&extensions, pair).unwrap();
1204 assert!(result.nullable);
1205 }
1206
1207 #[test]
1208 fn test_parse_precision_timestamp_literal_fractional_truncated() {
1209 let extensions = SimpleExtensions::default();
1210 let pair = parse_exact(
1213 Rule::literal,
1214 "'2023-01-01T12:00:00.999':precisiontimestamp<0>",
1215 );
1216 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1217 assert!(err.to_string().contains("fractional"));
1218 }
1219
1220 #[test]
1221 fn test_parse_precision_time_literal_fractional_truncated() {
1222 let extensions = SimpleExtensions::default();
1223 let pair = parse_exact(Rule::literal, "'14:30:45.123456':precisiontime<3>");
1226 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1227 assert!(err.to_string().contains("fractional"));
1228 }
1229
1230 #[test]
1231 fn test_parse_precision_timestamp_literal_nanosecond_overflow() {
1232 let extensions = SimpleExtensions::default();
1233 let pair = parse_exact(Rule::literal, "'2300-01-01T00:00:00':precisiontimestamp<9>");
1236 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1237 assert!(err.to_string().contains("out of range"));
1238 }
1239
1240 fn make_literal_bool(value: bool) -> Expression {
1242 Expression {
1243 rex_type: Some(RexType::Literal(Literal {
1244 literal_type: Some(LiteralType::Boolean(value)),
1245 nullable: false,
1246 type_variation_reference: 0,
1247 })),
1248 }
1249 }
1250
1251 #[test]
1252 fn test_parse_if_then_single_clause() {
1253 let extensions = SimpleExtensions::default();
1254 let input = "if_then(true -> 42, _ -> 0)";
1255 let pair = parse_exact(Rule::if_then, input);
1256 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1257
1258 assert_eq!(result.ifs.len(), 1);
1259 assert!(result.r#else.is_some());
1260 }
1261
1262 #[test]
1263 fn test_parse_if_then_with_typed_literals() {
1264 let extensions = SimpleExtensions::default();
1265 let input = "if_then(true -> 100:i32, _ -> -100:i32)";
1266 let pair = parse_exact(Rule::if_then, input);
1267 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1268
1269 assert_eq!(result.ifs.len(), 1);
1270 assert!(result.r#else.is_some());
1271 }
1272
1273 #[test]
1274 fn test_parse_if_then_with_date_literals() {
1275 let extensions = SimpleExtensions::default();
1276 let input = "if_then(true -> '2023-12-25':date, _ -> '1970-01-01':date)";
1277 let pair = parse_exact(Rule::if_then, input);
1278 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1279
1280 assert_eq!(result.ifs.len(), 1);
1281 assert!(result.r#else.is_some());
1282 }
1283
1284 #[test]
1285 fn test_parse_if_then_with_time_literals() {
1286 let extensions = SimpleExtensions::default();
1287 let input = "if_then(true -> '14:30:45':time, _ -> '00:00:00':time)";
1288 let pair = parse_exact(Rule::if_then, input);
1289 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1290
1291 assert_eq!(result.ifs.len(), 1);
1292 assert!(result.r#else.is_some());
1293 }
1294
1295 #[test]
1296 fn test_parse_if_then_with_timestamp_literals() {
1297 let extensions = SimpleExtensions::default();
1298 let input = "if_then(true -> '2023-01-01T12:00:00':timestamp, _ -> '1970-01-01T00:00:00':timestamp)";
1299 let pair = parse_exact(Rule::if_then, input);
1300 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1301
1302 assert_eq!(result.ifs.len(), 1);
1303 assert!(result.r#else.is_some());
1304 }
1305
1306 #[test]
1307 fn test_parse_if_clause_with_whitespace_variations() {
1308 let extensions = SimpleExtensions::default();
1309
1310 let inputs = vec!["true->false", "true -> false", "true -> false"];
1312
1313 for input in inputs {
1314 let pair = parse_exact(Rule::if_clause, input);
1315 let result = IfClause::parse_pair(&extensions, pair).unwrap();
1316 assert!(result.r#if.is_some());
1317 assert!(result.then.is_some());
1318 }
1319 }
1320
1321 #[test]
1322 fn test_if_clause_structure() {
1323 let extensions = SimpleExtensions::default();
1324 let pair = parse_exact(Rule::if_clause, "42 -> 100");
1325 let result = IfClause::parse_pair(&extensions, pair).unwrap();
1326
1327 let if_expr = result.r#if.as_ref().unwrap();
1329 let then_expr = result.then.as_ref().unwrap();
1330
1331 match (&if_expr.rex_type, &then_expr.rex_type) {
1333 (Some(RexType::Literal(_)), Some(RexType::Literal(_))) => {
1334 }
1336 _ => panic!("Expected both if and then to be literals"),
1337 }
1338 }
1339
1340 #[test]
1341 fn test_if_then_structure() {
1342 let extensions = SimpleExtensions::default();
1343 let input = "if_then(true -> 1, false -> 2, _ -> 0)";
1344 let pair = parse_exact(Rule::if_then, input);
1345 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1346
1347 assert_eq!(result.ifs.len(), 2);
1349
1350 for clause in &result.ifs {
1352 assert!(clause.r#if.is_some(), "If clause condition should exist");
1353 assert!(clause.then.is_some(), "If clause result should exist");
1354 }
1355
1356 assert!(result.r#else.is_some(), "Else clause should exist");
1358 }
1359
1360 #[test]
1361 fn test_parse_if_then_mixed_types_in_conditions() {
1362 let extensions = SimpleExtensions::default();
1363 let input = "if_then(true -> 1, true -> 'yes', 'yes' -> true, 42 -> 2, $0 -> 3, _ -> 0)";
1365 let pair = parse_exact(Rule::if_then, input);
1366 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1367
1368 assert_eq!(result.ifs.len(), 5);
1369 assert!(result.r#else.is_some());
1370 }
1371
1372 #[test]
1373 fn test_if_then_preserves_clause_order() {
1374 let extensions = SimpleExtensions::default();
1375 let input = "if_then(1 -> 10, 2 -> 20, 3 -> 30, _ -> 0)";
1376 let pair = parse_exact(Rule::if_then, input);
1377 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1378
1379 assert_eq!(result.ifs.len(), 3);
1380
1381 for (i, clause) in result.ifs.iter().enumerate() {
1383 if let Some(Expression {
1384 rex_type: Some(RexType::Literal(lit)),
1385 }) = &clause.r#if
1386 && let Some(LiteralType::I64(val)) = &lit.literal_type
1387 {
1388 assert_eq!(*val, (i as i64) + 1);
1389 }
1390 }
1391 }
1392
1393 #[test]
1394 fn test_parse_if_then() {
1395 let extensions = SimpleExtensions::default();
1396
1397 let c1 = IfClause {
1398 r#if: Some(make_literal_bool(true)),
1399 then: Some(make_literal_bool(true)),
1400 };
1401
1402 let c2 = IfClause {
1403 r#if: Some(make_literal_bool(false)),
1404 then: Some(make_literal_bool(false)),
1405 };
1406
1407 let if_clause = IfThen {
1408 ifs: vec![c1, c2],
1409 r#else: Some(Box::new(make_literal_bool(false))),
1410 };
1411 assert_parses_with(
1412 &extensions,
1413 "if_then(true -> true , false -> false, _ -> false)",
1414 if_clause,
1415 );
1416 }
1417
1418 fn parse_function_signature(input: &str) -> CompoundName {
1421 let pair = parse_exact(Rule::function_signature, input);
1422 CompoundName::parse_pair(pair)
1423 }
1424
1425 #[test]
1426 fn test_compound_name_plain() {
1427 assert_eq!(parse_function_signature("add").full(), "add");
1428 }
1429
1430 #[test]
1431 fn test_compound_name_full_zero_arg_type_signature() {
1432 let n = parse_function_signature("add:");
1434 assert_eq!(n.full(), "add:");
1435 assert_eq!(n.base(), "add");
1436 assert!(n.matches("add:"));
1437 assert!(!n.matches("add:i64_i64"));
1438 assert!(n.matches("add"));
1439 }
1440
1441 #[test]
1442 fn test_compound_name_with_signature() {
1443 assert_eq!(
1444 parse_function_signature("equal:any_any").full(),
1445 "equal:any_any"
1446 );
1447 assert_eq!(
1448 parse_function_signature("regexp_match_substring:str_str_i64").full(),
1449 "regexp_match_substring:str_str_i64"
1450 );
1451 assert_eq!(
1452 parse_function_signature("add:i64_i64").full(),
1453 "add:i64_i64"
1454 );
1455 }
1456
1457 #[test]
1458 fn test_compound_name_trailing_colon_grammar() {
1459 let name = parse_function_signature("count:");
1462 assert_eq!(name.base(), "count");
1463 assert_eq!(name.full(), "count:");
1464 assert!(
1465 name.has_signature(),
1466 "trailing colon must set has_signature"
1467 );
1468 }
1469
1470 #[test]
1471 fn test_compound_name_stops_at_opening_paren() {
1472 let pairs = ExpressionParser::parse(Rule::function_signature, "equal:any_any").unwrap();
1474 assert_eq!(pairs.as_str(), "equal:any_any");
1475 }
1476
1477 fn make_extensions_for_fn_tests() -> SimpleExtensions {
1480 let mut exts = SimpleExtensions::default();
1481 exts.add_extension_urn("urn".to_string(), 1).unwrap();
1482 exts.add_extension(
1483 crate::extensions::simple::ExtensionKind::Function,
1484 1,
1485 1,
1486 "equal:any_any".to_string(),
1487 )
1488 .unwrap();
1489 exts.add_extension(
1490 crate::extensions::simple::ExtensionKind::Function,
1491 1,
1492 2,
1493 "equal:str_str".to_string(),
1494 )
1495 .unwrap();
1496 exts.add_extension(
1497 crate::extensions::simple::ExtensionKind::Function,
1498 1,
1499 3,
1500 "add:i64_i64".to_string(),
1501 )
1502 .unwrap();
1503 exts
1504 }
1505
1506 #[test]
1507 fn test_scalar_function_full_compound_name() {
1508 let exts = make_extensions_for_fn_tests();
1510 let pair = parse_exact(Rule::function_call, "equal:any_any($0, $1):boolean");
1511 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1512 assert_eq!(f.function_reference, 1);
1513 assert_eq!(f.arguments.len(), 2);
1514 assert!(
1515 f.output_type.is_some(),
1516 "output_type must be set after parsing"
1517 );
1518 }
1519
1520 #[test]
1521 fn test_scalar_function_second_overload() {
1522 let exts = make_extensions_for_fn_tests();
1523 let pair = parse_exact(Rule::function_call, "equal:str_str($0, $1):boolean");
1524 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1525
1526 assert_eq!(f.arguments.len(), 2);
1527 assert_eq!(f.function_reference, 2);
1528 }
1529
1530 #[test]
1531 fn test_scalar_function_base_name_unique_overload() {
1532 let exts = make_extensions_for_fn_tests();
1534 let pair = parse_exact(Rule::function_call, "add($0, $1):i64");
1535 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1536
1537 assert_eq!(f.arguments.len(), 2);
1538 assert_eq!(f.function_reference, 3);
1539 assert!(
1540 f.output_type.is_some(),
1541 "output_type must be set after parsing"
1542 );
1543 }
1544
1545 #[test]
1546 fn test_scalar_function_base_name_ambiguous_fails() {
1547 let exts = make_extensions_for_fn_tests();
1549 let pair = parse_exact(Rule::function_call, "equal($0, $1):boolean");
1550 let result = ScalarFunction::parse_pair(&exts, pair);
1551 assert!(result.is_err(), "ambiguous base name should fail");
1552 }
1553
1554 #[test]
1555 fn test_scalar_function_compound_name_with_anchor() {
1556 let exts = make_extensions_for_fn_tests();
1557 let pair = parse_exact(Rule::function_call, "equal:any_any#1($0, $1):boolean");
1558 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1559 assert_eq!(f.function_reference, 1);
1560 assert_eq!(f.arguments.len(), 2);
1561 }
1562
1563 #[test]
1564 fn test_scalar_function_base_name_with_anchor() {
1565 let exts = make_extensions_for_fn_tests();
1567 let pair = parse_exact(Rule::function_call, "equal#1($0, $1):boolean");
1568 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1569 assert_eq!(f.function_reference, 1);
1570 assert_eq!(f.arguments.len(), 2);
1571 }
1572
1573 #[test]
1574 fn test_scalar_function_wrong_name_for_anchor_fails() {
1575 let exts = make_extensions_for_fn_tests();
1576 let pair = parse_exact(Rule::function_call, "like#1($0):boolean");
1577 let result = ScalarFunction::parse_pair(&exts, pair);
1578 assert!(result.is_err(), "mismatched name/anchor should fail");
1579 }
1580
1581 #[test]
1582 fn test_scalar_function_user_defined_type_in_signature() {
1583 let mut exts = SimpleExtensions::default();
1585 exts.add_extension_urn("urn".to_string(), 1).unwrap();
1586 exts.add_extension(
1587 crate::extensions::simple::ExtensionKind::Function,
1588 1,
1589 10,
1590 "json_extract_path:u!json_str".to_string(),
1591 )
1592 .unwrap();
1593
1594 let pair = parse_exact(
1595 Rule::function_call,
1596 "json_extract_path:u!json_str($0, $1):string",
1597 );
1598 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1599 assert_eq!(f.function_reference, 10);
1600 assert_eq!(f.arguments.len(), 2);
1601 }
1602
1603 #[test]
1604 fn test_scalar_function_missing_type_fails_to_parse() {
1605 let result = ExpressionParser::parse(Rule::function_call, "add($0, $1)");
1607 assert!(
1608 result.is_err(),
1609 "function call without type annotation should fail to parse"
1610 );
1611 }
1612
1613 #[test]
1614 fn test_parse_cast_expression_basic() {
1615 let extensions = SimpleExtensions::default();
1616 let pair = parse_exact(Rule::cast_expression, "(78:i32)::i16");
1617 let result = Cast::parse_pair(&extensions, pair).unwrap();
1618
1619 let input = result.input.as_ref().unwrap();
1621 match &input.rex_type {
1622 Some(RexType::Literal(lit)) => match &lit.literal_type {
1623 Some(LiteralType::I32(v)) => assert_eq!(*v, 78),
1624 other => panic!("Expected I32 literal, got: {:?}", other),
1625 },
1626 other => panic!("Expected literal, got: {:?}", other),
1627 }
1628
1629 let target = result.r#type.as_ref().unwrap();
1631 match &target.kind {
1632 Some(substrait::proto::r#type::Kind::I16(_)) => {}
1633 other => panic!("Expected i16 type, got: {:?}", other),
1634 }
1635
1636 assert_eq!(result.failure_behavior, 0);
1637 }
1638
1639 #[test]
1640 fn test_parse_cast_expression_via_expression_rule() {
1641 let extensions = SimpleExtensions::default();
1642 let pair = parse_exact(Rule::expression, "(78:i32)::i16");
1643 let result = Expression::parse_pair(&extensions, pair).unwrap();
1644
1645 match result.rex_type {
1646 Some(RexType::Cast(_)) => {}
1647 other => panic!("Expected Cast rex type, got: {:?}", other),
1648 }
1649 }
1650
1651 #[test]
1652 fn test_parse_cast_expression_nested() {
1653 let extensions = SimpleExtensions::default();
1654 let pair = parse_exact(Rule::cast_expression, "((78:i32)::i16)::i32");
1655 let result = Cast::parse_pair(&extensions, pair).unwrap();
1656
1657 let input = result.input.as_ref().unwrap();
1659 match &input.rex_type {
1660 Some(RexType::Cast(inner)) => {
1661 let inner_input = inner.input.as_ref().unwrap();
1662 match &inner_input.rex_type {
1663 Some(RexType::Literal(lit)) => match &lit.literal_type {
1664 Some(LiteralType::I32(v)) => assert_eq!(*v, 78),
1665 other => panic!("Expected I32 literal, got: {:?}", other),
1666 },
1667 other => panic!("Expected literal, got: {:?}", other),
1668 }
1669 }
1670 other => panic!("Expected inner Cast, got: {:?}", other),
1671 }
1672
1673 match &result.r#type.as_ref().unwrap().kind {
1674 Some(substrait::proto::r#type::Kind::I32(_)) => {}
1675 other => panic!("Expected i32 outer type, got: {:?}", other),
1676 }
1677 }
1678
1679 #[test]
1680 fn test_parse_cast_expression_with_boolean() {
1681 let extensions = SimpleExtensions::default();
1682 let pair = parse_exact(Rule::cast_expression, "(true)::i32");
1683 let result = Cast::parse_pair(&extensions, pair).unwrap();
1684
1685 let input = result.input.as_ref().unwrap();
1686 match &input.rex_type {
1687 Some(RexType::Literal(lit)) => match &lit.literal_type {
1688 Some(LiteralType::Boolean(v)) => assert!(*v),
1689 other => panic!("Expected Boolean literal, got: {:?}", other),
1690 },
1691 other => panic!("Expected literal, got: {:?}", other),
1692 }
1693 }
1694
1695 #[test]
1696 fn test_parse_cast_expression_with_whitespace() {
1697 let extensions = SimpleExtensions::default();
1698 let pair = parse_exact(Rule::cast_expression, "( 78:i32 ) :: i16");
1700 let result = Cast::parse_pair(&extensions, pair).unwrap();
1701 assert!(result.input.is_some());
1702 assert!(result.r#type.is_some());
1703 }
1704
1705 #[test]
1706 fn test_parse_cast_unspecified_failure_behavior() {
1707 let extensions = SimpleExtensions::default();
1708 let pair = parse_exact(Rule::cast_expression, "(78:i32)::i16");
1709 let result = Cast::parse_pair(&extensions, pair).unwrap();
1710 assert_eq!(
1711 result.failure_behavior,
1712 cast::FailureBehavior::Unspecified as i32
1713 );
1714 }
1715
1716 #[test]
1717 fn test_parse_cast_return_null_failure_behavior() {
1718 let extensions = SimpleExtensions::default();
1719 let pair = parse_exact(Rule::cast_expression, "(78:i32)::?i16");
1720 let result = Cast::parse_pair(&extensions, pair).unwrap();
1721 assert_eq!(
1722 result.failure_behavior,
1723 cast::FailureBehavior::ReturnNull as i32
1724 );
1725 }
1726
1727 #[test]
1728 fn test_parse_cast_throw_exception_failure_behavior() {
1729 let extensions = SimpleExtensions::default();
1730 let pair = parse_exact(Rule::cast_expression, "(78:i32)::!i16");
1731 let result = Cast::parse_pair(&extensions, pair).unwrap();
1732 assert_eq!(
1733 result.failure_behavior,
1734 cast::FailureBehavior::ThrowException as i32
1735 );
1736 }
1737
1738 #[test]
1739 fn test_parse_cast_to_user_defined_type_with_u_prefix() {
1740 let mut extensions = SimpleExtensions::default();
1742 extensions.add_extension_urn("urn".to_string(), 1).unwrap();
1743 extensions
1744 .add_extension(
1745 crate::extensions::simple::ExtensionKind::Type,
1746 1,
1747 5,
1748 "u!json".to_string(),
1749 )
1750 .unwrap();
1751
1752 let pair = parse_exact(Rule::cast_expression, "($0)::u!json");
1753 let result = Cast::parse_pair(&extensions, pair).unwrap();
1754 match result.r#type.as_ref().unwrap().kind.as_ref().unwrap() {
1755 substrait::proto::r#type::Kind::UserDefined(u) => {
1756 assert_eq!(u.type_reference, 5);
1757 }
1758 other => panic!("expected UserDefined, got {other:?}"),
1759 }
1760 }
1761
1762 #[test]
1763 fn test_function_call_u_prefix_base_name_rejected() {
1764 assert!(
1767 ExpressionParser::parse(Rule::function_call, "u!json_get($0)").is_err(),
1768 "u! prefix in function call base name must be rejected by the grammar"
1769 );
1770 }
1771}