1use std::fmt::{self, Display, Formatter};
2use std::mem::size_of;
3use std::str::FromStr;
4
5use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime};
6use pest::Parser as PestParser;
7use pest::iterators::Pair;
8use substrait::proto::aggregate_rel::Measure;
9use substrait::proto::expression::field_reference::{ReferenceType, RootReference, RootType};
10use substrait::proto::expression::if_then::IfClause;
11use substrait::proto::expression::literal::interval_day_to_second::PrecisionMode;
12use substrait::proto::expression::literal::{
13 IntervalDayToSecond, LiteralType, PrecisionTime as LitPrecisionTime,
14 PrecisionTimestamp as LitPrecisionTimestamp,
15};
16use substrait::proto::expression::{
17 Cast, FieldReference, IfThen, Literal, ReferenceSegment, RexType, ScalarFunction, cast,
18 reference_segment,
19};
20use substrait::proto::function_argument::ArgType;
21use substrait::proto::r#type::{Fp64, I64, Kind, Nullability};
22use substrait::proto::{AggregateFunction, Expression, FunctionArgument, Type};
23
24use super::types::get_and_validate_anchor;
25use super::{
26 ExpressionParser, MessageParseError, ParsePair, Rule, RuleIter, ScopedParsePair,
27 unescape_string, unwrap_single_pair,
28};
29use crate::extensions::SimpleExtensions;
30use crate::extensions::simple::{CompoundName, ExtensionKind};
31use crate::precision::SupportedPrecision;
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub struct FieldIndex(pub i32);
36
37impl FieldIndex {
38 pub fn to_field_reference(self) -> FieldReference {
40 FieldReference {
43 reference_type: Some(ReferenceType::DirectReference(ReferenceSegment {
44 reference_type: Some(reference_segment::ReferenceType::StructField(Box::new(
45 reference_segment::StructField {
46 field: self.0,
47 child: None,
48 },
49 ))),
50 })),
51 root_type: Some(RootType::RootReference(RootReference {})),
52 }
53 }
54}
55
56impl ParsePair for FieldIndex {
57 fn rule() -> Rule {
58 Rule::reference
59 }
60
61 fn message() -> &'static str {
62 "FieldIndex"
63 }
64
65 fn parse_pair(pair: Pair<Rule>) -> Self {
66 assert_eq!(pair.as_rule(), Self::rule());
67 let inner = unwrap_single_pair(pair);
68 let index: i32 = inner.as_str().parse().unwrap();
69 FieldIndex(index)
70 }
71}
72
73impl ParsePair for FieldReference {
74 fn rule() -> Rule {
75 Rule::reference
76 }
77
78 fn message() -> &'static str {
79 "FieldReference"
80 }
81
82 fn parse_pair(pair: Pair<Rule>) -> Self {
83 assert_eq!(pair.as_rule(), Self::rule());
84
85 FieldIndex::parse_pair(pair).to_field_reference()
87 }
88}
89
90const UNSIGNED_INT_KIND: Kind = Kind::I64(I64 {
91 type_variation_reference: 0,
92 nullability: Nullability::Required as i32,
93});
94
95fn to_int_literal(value: Pair<Rule>, typ: Option<Type>) -> Result<Literal, MessageParseError> {
96 assert_eq!(value.as_rule(), Rule::integer);
97 let parsed_value: i64 = value.as_str().parse().unwrap();
98
99 let kind = typ.and_then(|t| t.kind).unwrap_or(UNSIGNED_INT_KIND);
101
102 let (lit, nullability, tvar) = match &kind {
103 Kind::I8(i) => (
105 LiteralType::I8(parsed_value as i32),
106 i.nullability,
107 i.type_variation_reference,
108 ),
109 Kind::I16(i) => (
110 LiteralType::I16(parsed_value as i32),
111 i.nullability,
112 i.type_variation_reference,
113 ),
114 Kind::I32(i) => (
115 LiteralType::I32(parsed_value as i32),
116 i.nullability,
117 i.type_variation_reference,
118 ),
119 Kind::I64(i) => (
120 LiteralType::I64(parsed_value),
121 i.nullability,
122 i.type_variation_reference,
123 ),
124 k => {
125 return Err(MessageParseError::invalid(
126 "int_literal_type",
127 value.as_span(),
128 format!("Invalid type for integer literal: {k:?}"),
129 ));
130 }
131 };
132
133 Ok(Literal {
134 literal_type: Some(lit),
135 nullable: nullability != Nullability::Required as i32,
136 type_variation_reference: tvar,
137 })
138}
139
140const UNSIGNED_FLOAT_KIND: Kind = Kind::Fp64(Fp64 {
141 type_variation_reference: 0,
142 nullability: Nullability::Required as i32,
143});
144
145fn to_float_literal(value: Pair<Rule>, typ: Option<Type>) -> Result<Literal, MessageParseError> {
146 assert_eq!(value.as_rule(), Rule::float);
147 let parsed_value: f64 = value.as_str().parse().unwrap();
148
149 let kind = typ.and_then(|t| t.kind).unwrap_or(UNSIGNED_FLOAT_KIND);
151
152 let (lit, nullability, tvar) = match &kind {
153 Kind::Fp32(f) => (
154 LiteralType::Fp32(parsed_value as f32),
155 f.nullability,
156 f.type_variation_reference,
157 ),
158 Kind::Fp64(f) => (
159 LiteralType::Fp64(parsed_value),
160 f.nullability,
161 f.type_variation_reference,
162 ),
163 k => {
164 return Err(MessageParseError::invalid(
165 "float_literal_type",
166 value.as_span(),
167 format!("Invalid type for float literal: {k:?}"),
168 ));
169 }
170 };
171
172 Ok(Literal {
173 literal_type: Some(lit),
174 nullable: nullability != Nullability::Required as i32,
175 type_variation_reference: tvar,
176 })
177}
178
179fn to_boolean_literal(value: Pair<Rule>, typ: Option<Type>) -> 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(value: Pair<Rule>, typ: Option<Type>) -> Result<Literal, MessageParseError> {
206 assert_eq!(value.as_rule(), Rule::string_literal);
207 let string_value = unescape_string(value.clone());
208
209 let Some(typ) = typ else {
211 return Ok(Literal {
212 literal_type: Some(LiteralType::String(string_value)),
213 nullable: false,
214 type_variation_reference: 0,
215 });
216 };
217
218 let Some(kind) = typ.kind else {
219 return Ok(Literal {
220 literal_type: Some(LiteralType::String(string_value)),
221 nullable: false,
222 type_variation_reference: 0,
223 });
224 };
225
226 match &kind {
227 Kind::Date(d) => {
228 let date_days = parse_date_to_days(&string_value, value.as_span())?;
230 Ok(Literal {
231 literal_type: Some(LiteralType::Date(date_days)),
232 nullable: d.nullability != Nullability::Required as i32,
233 type_variation_reference: d.type_variation_reference,
234 })
235 }
236 Kind::IntervalDay(i) => {
237 let precision = i
245 .precision
246 .and_then(SupportedPrecision::from_units)
247 .ok_or_else(|| {
248 MessageParseError::invalid(
249 "interval_day_literal_type",
250 value.as_span(),
251 format!(
252 "Invalid precision {} for an interval_day literal; expected one of 0 (seconds), 3 (milliseconds), 6 (microseconds), 9 (nanoseconds), or 12 (picoseconds)",
253 i.precision.map_or("<unset>".to_string(), |p| p.to_string())
254 ),
255 )
256 })?;
257 let interval = parse_interval_day_duration(&string_value, precision, value.as_span())?;
258 Ok(Literal {
259 literal_type: Some(LiteralType::IntervalDayToSecond(interval)),
260 nullable: i.nullability != Nullability::Required as i32,
261 type_variation_reference: i.type_variation_reference,
262 })
263 }
264 #[allow(deprecated)]
265 Kind::Time(t) => {
266 let time_microseconds = parse_time_to_microseconds(&string_value, value.as_span())?;
268 Ok(Literal {
269 literal_type: Some(LiteralType::Time(time_microseconds)),
270 nullable: t.nullability != Nullability::Required as i32,
271 type_variation_reference: t.type_variation_reference,
272 })
273 }
274 #[allow(deprecated)]
275 Kind::Timestamp(ts) => {
276 let timestamp_microseconds =
278 parse_timestamp_to_microseconds(&string_value, value.as_span())?;
279 Ok(Literal {
280 literal_type: Some(LiteralType::Timestamp(timestamp_microseconds)),
281 nullable: ts.nullability != Nullability::Required as i32,
282 type_variation_reference: ts.type_variation_reference,
283 })
284 }
285 Kind::PrecisionTimestamp(pt) => {
286 let precision = pt.precision;
287 let timestamp_value = parse_timestamp_to_precision_units(
288 &string_value,
289 precision,
290 "precisiontimestamp",
291 value.as_span(),
292 )?;
293 Ok(Literal {
294 literal_type: Some(LiteralType::PrecisionTimestamp(LitPrecisionTimestamp {
295 precision,
296 value: timestamp_value,
297 })),
298 nullable: pt.nullability != Nullability::Required as i32,
299 type_variation_reference: pt.type_variation_reference,
300 })
301 }
302 Kind::PrecisionTimestampTz(pt) => {
303 let precision = pt.precision;
304 let timestamp_value = parse_timestamp_to_precision_units(
305 &string_value,
306 precision,
307 "precisiontimestamptz",
308 value.as_span(),
309 )?;
310 Ok(Literal {
311 literal_type: Some(LiteralType::PrecisionTimestampTz(LitPrecisionTimestamp {
312 precision,
313 value: timestamp_value,
314 })),
315 nullable: pt.nullability != Nullability::Required as i32,
316 type_variation_reference: pt.type_variation_reference,
317 })
318 }
319 Kind::PrecisionTime(pt) => {
320 let precision = pt.precision;
321 let time_value = parse_time_to_precision_units(
322 &string_value,
323 precision,
324 "precisiontime",
325 value.as_span(),
326 )?;
327 Ok(Literal {
328 literal_type: Some(LiteralType::PrecisionTime(LitPrecisionTime {
329 precision,
330 value: time_value,
331 })),
332 nullable: pt.nullability != Nullability::Required as i32,
333 type_variation_reference: pt.type_variation_reference,
334 })
335 }
336 _ => {
337 Ok(Literal {
339 literal_type: Some(LiteralType::String(string_value)),
340 nullable: false,
341 type_variation_reference: 0,
342 })
343 }
344 }
345}
346
347fn to_null_literal(value: Pair<Rule>, typ: Option<Type>) -> Result<Literal, MessageParseError> {
348 assert_eq!(value.as_rule(), Rule::null);
349 let typ = typ.ok_or_else(|| {
350 MessageParseError::invalid(
351 "null_literal_type",
352 value.as_span(),
353 "Null literals require an explicit type annotation, e.g. null:i64?",
354 )
355 })?;
356
357 Ok(Literal {
358 literal_type: Some(LiteralType::Null(typ)),
359 nullable: false,
360 type_variation_reference: 0,
361 })
362}
363
364fn parse_date_to_days(date_str: &str, span: pest::Span) -> Result<i32, MessageParseError> {
366 let formats = ["%Y-%m-%d", "%Y/%m/%d"];
368
369 for format in &formats {
370 if let Ok(date) = NaiveDate::parse_from_str(date_str, format) {
371 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
373 let days = date.signed_duration_since(epoch).num_days();
374 return Ok(days as i32);
375 }
376 }
377
378 Err(MessageParseError::invalid(
379 "date_parse_format",
380 span,
381 format!("Invalid date format: '{date_str}'. Expected YYYY-MM-DD or YYYY/MM/DD"),
382 ))
383}
384
385fn parse_time_to_microseconds(time_str: &str, span: pest::Span) -> Result<i64, MessageParseError> {
387 parse_time_to_precision_units(time_str, 6, "time", span)
388}
389
390fn parse_timestamp_to_microseconds(
392 timestamp_str: &str,
393 span: pest::Span,
394) -> Result<i64, MessageParseError> {
395 parse_timestamp_to_precision_units(timestamp_str, 6, "timestamp", span)
396}
397
398fn duration_to_precision_units(
403 duration: chrono::Duration,
404 precision: SupportedPrecision,
405 literal_kind: &'static str,
406 span: pest::Span,
407) -> Result<i64, MessageParseError> {
408 let out_of_range = || {
409 MessageParseError::invalid(
410 "precision_literal_out_of_range",
411 span,
412 format!(
413 "value is out of range for a {literal_kind} literal at precision {}",
414 precision.units()
415 ),
416 )
417 };
418 let fractional_truncated = || {
419 MessageParseError::invalid(
420 "precision_literal_fractional_truncated",
421 span,
422 format!(
423 "value has a fractional component finer than precision {} can represent for a {literal_kind} literal",
424 precision.units()
425 ),
426 )
427 };
428
429 match precision {
430 SupportedPrecision::Seconds => {
431 let value = duration.num_seconds();
432 if chrono::Duration::seconds(value) != duration {
433 return Err(fractional_truncated());
434 }
435 Ok(value)
436 }
437 SupportedPrecision::Milliseconds => {
438 let value = duration.num_milliseconds();
439 if chrono::Duration::milliseconds(value) != duration {
440 return Err(fractional_truncated());
441 }
442 Ok(value)
443 }
444 SupportedPrecision::Microseconds => {
445 let value = duration.num_microseconds().ok_or_else(out_of_range)?;
446 if chrono::Duration::microseconds(value) != duration {
447 return Err(fractional_truncated());
448 }
449 Ok(value)
450 }
451 SupportedPrecision::Nanoseconds => duration.num_nanoseconds().ok_or_else(out_of_range),
454 SupportedPrecision::Picoseconds => Err(MessageParseError::invalid(
457 "precision_literal_unsupported_precision",
458 span,
459 format!(
460 "precision 12 (picoseconds) is not supported for {literal_kind} literals; chrono only supports nanosecond (precision 9) resolution"
461 ),
462 )),
463 }
464}
465
466fn check_supported_precision(
467 precision: i32,
468 literal_kind: &'static str,
469 span: pest::Span,
470) -> Result<SupportedPrecision, MessageParseError> {
471 match SupportedPrecision::from_units(precision) {
472 Some(SupportedPrecision::Picoseconds) => Err(MessageParseError::invalid(
475 "precision_literal_unsupported_precision",
476 span,
477 format!(
478 "precision 12 (picoseconds) is not supported for {literal_kind} literals; chrono only supports nanosecond (precision 9) resolution"
479 ),
480 )),
481 Some(precision) => Ok(precision),
482 None => Err(MessageParseError::invalid(
483 "precision_literal_invalid_precision",
484 span,
485 format!(
486 "Invalid precision {precision} for a {literal_kind} literal; expected one of 0 (seconds), 3 (milliseconds), 6 (microseconds), or 9 (nanoseconds)"
487 ),
488 )),
489 }
490}
491
492fn parse_timestamp_to_precision_units(
494 timestamp_str: &str,
495 precision: i32,
496 literal_kind: &'static str,
497 span: pest::Span,
498) -> Result<i64, MessageParseError> {
499 let precision = check_supported_precision(precision, literal_kind, span)?;
500
501 let formats = [
503 "%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", ];
512
513 for format in &formats {
514 if let Ok(datetime) = NaiveDateTime::parse_from_str(timestamp_str, format) {
515 let epoch = DateTime::from_timestamp(0, 0).unwrap().naive_utc();
516 let duration = datetime.signed_duration_since(epoch);
517 return duration_to_precision_units(duration, precision, literal_kind, span);
518 }
519 }
520
521 Err(MessageParseError::invalid(
522 "timestamp_parse_format",
523 span,
524 format!(
525 "Invalid timestamp format: '{timestamp_str}'. Expected YYYY-MM-DDTHH:MM:SS or YYYY-MM-DD HH:MM:SS"
526 ),
527 ))
528}
529
530fn parse_time_to_precision_units(
532 time_str: &str,
533 precision: i32,
534 literal_kind: &'static str,
535 span: pest::Span,
536) -> Result<i64, MessageParseError> {
537 let precision = check_supported_precision(precision, literal_kind, span)?;
538
539 let formats = ["%H:%M:%S%.f", "%H:%M:%S"];
541
542 for format in &formats {
543 if let Ok(time) = NaiveTime::parse_from_str(time_str, format) {
544 let midnight = NaiveTime::from_hms_opt(0, 0, 0).unwrap();
545 let duration = time.signed_duration_since(midnight);
546 return duration_to_precision_units(duration, precision, literal_kind, span);
547 }
548 }
549
550 Err(MessageParseError::invalid(
551 "time_parse_format",
552 span,
553 format!("Invalid time format: '{time_str}'. Expected HH:MM:SS or HH:MM:SS.fff"),
554 ))
555}
556
557#[derive(Debug, Clone, PartialEq, Eq)]
558enum IntervalDayError {
559 TermOverflow {
562 unit: &'static str,
563 number: String,
564 bits: usize,
565 },
566 UnitPrecisionMismatch {
568 unit: &'static str,
569 unit_precision: SupportedPrecision,
570 precision: SupportedPrecision,
571 },
572}
573
574impl Display for IntervalDayError {
575 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
576 match self {
577 IntervalDayError::TermOverflow { unit, number, bits } => write!(
578 f,
579 "the '{unit}' term {number} does not fit in a {bits}-bit integer"
580 ),
581 IntervalDayError::UnitPrecisionMismatch {
582 unit,
583 unit_precision,
584 precision,
585 } => write!(
586 f,
587 "the sub-second unit '{unit}' means precision {unit_precision}, but the type is interval_day<{precision}>"
588 ),
589 }
590 }
591}
592
593fn parse_duration_number<T: FromStr>(
598 number: &str,
599 unit: &'static str,
600) -> Result<T, IntervalDayError> {
601 number.parse().map_err(|_| IntervalDayError::TermOverflow {
602 unit,
603 number: number.to_string(),
604 bits: size_of::<T>() * 8,
605 })
606}
607
608fn parse_interval_day_duration(
612 duration_str: &str,
613 precision: SupportedPrecision,
614 span: pest::Span,
615) -> Result<IntervalDayToSecond, MessageParseError> {
616 let mut pairs = ExpressionParser::parse(Rule::interval_day_duration, duration_str).map_err(
617 |e| {
618 MessageParseError::invalid(
619 "interval_day_duration",
620 span,
621 format!(
622 "Invalid duration '{duration_str}': {}. Expected one to three terms, separated by single spaces, in the order days ('d'), seconds ('s'), sub-seconds ('ms', 'us', 'ns', or 'ps'); e.g. '5d', '4d 5s', '5d 3s 100ns'",
623 e.variant.message()
624 ),
625 )
626 },
627 )?;
628 let pair = pairs.next().expect("interval_day_duration matched");
629
630 interval_day_from_pair(pair, precision).map_err(|e| {
631 MessageParseError::invalid(
632 "interval_day_duration",
633 span,
634 format!("Invalid duration '{duration_str}': {e}"),
635 )
636 })
637}
638
639fn interval_day_from_pair(
642 pair: Pair<Rule>,
643 precision: SupportedPrecision,
644) -> Result<IntervalDayToSecond, IntervalDayError> {
645 assert_eq!(pair.as_rule(), Rule::interval_day_duration);
646
647 let mut interval = IntervalDayToSecond {
648 days: 0,
649 seconds: 0,
650 subseconds: 0,
651 precision_mode: Some(PrecisionMode::Precision(precision.units())),
652 };
653
654 for term in pair.into_inner() {
655 match term.as_rule() {
656 Rule::duration_days => {
657 let number = unwrap_single_pair(term);
658 interval.days = parse_duration_number(number.as_str(), "d")?;
659 }
660 Rule::duration_seconds => {
661 let number = unwrap_single_pair(term);
662 interval.seconds = parse_duration_number(number.as_str(), "s")?;
663 }
664 Rule::duration_subseconds => {
665 let mut iter = RuleIter::from(term.into_inner());
666 let number = iter.pop(Rule::integer);
667 let unit = iter.pop(Rule::subsecond_unit);
668 iter.done();
669
670 let unit_precision = SupportedPrecision::from_subsecond_unit(unit.as_str())
671 .expect("the grammar restricts sub-second units to ms/us/ns/ps");
672 let unit = unit_precision
673 .subsecond_unit()
674 .expect("a sub-second precision has a sub-second unit");
675 if unit_precision != precision {
678 return Err(IntervalDayError::UnitPrecisionMismatch {
679 unit,
680 unit_precision,
681 precision,
682 });
683 }
684 interval.subseconds = parse_duration_number(number.as_str(), unit)?;
685 }
686 Rule::EOI => {}
689 rule => unreachable!("unexpected rule in interval_day_duration: {rule:?}"),
690 }
691 }
692
693 Ok(interval)
700}
701
702impl ScopedParsePair for Literal {
703 fn rule() -> Rule {
704 Rule::expression_literal
705 }
706
707 fn message() -> &'static str {
708 "Literal"
709 }
710
711 fn parse_pair(
712 extensions: &SimpleExtensions,
713 pair: Pair<Rule>,
714 ) -> Result<Self, MessageParseError> {
715 assert_eq!(pair.as_rule(), Self::rule());
716 let mut pairs = pair.into_inner();
717 let value = pairs.next().unwrap(); let typ = pairs.next(); assert!(pairs.next().is_none());
720 let typ = match typ {
721 Some(t) => Some(Type::parse_pair(extensions, t)?),
722 None => None,
723 };
724 match value.as_rule() {
725 Rule::integer => to_int_literal(value, typ),
726 Rule::float => to_float_literal(value, typ),
727 Rule::boolean => to_boolean_literal(value, typ),
728 Rule::string_literal => to_string_literal(value, typ),
729 Rule::null => to_null_literal(value, typ),
730 _ => unreachable!("Literal unexpected rule: {:?}", value.as_rule()),
731 }
732 }
733}
734
735struct FunctionReference {
737 name: CompoundName,
738 anchor: Option<u32>,
739}
740
741impl ParsePair for FunctionReference {
742 fn rule() -> Rule {
743 Rule::function_reference
744 }
745
746 fn message() -> &'static str {
747 "FunctionReference"
748 }
749
750 fn parse_pair(pair: Pair<Rule>) -> Self {
751 assert_eq!(pair.as_rule(), Self::rule());
752 let mut iter = RuleIter::from(pair.into_inner());
753
754 let name = iter.parse_next::<CompoundName>();
756
757 let anchor = iter
759 .try_pop(Rule::anchor)
760 .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
761
762 let _urn_anchor = iter
764 .try_pop(Rule::urn_anchor)
765 .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
766
767 iter.done();
768 FunctionReference { name, anchor }
769 }
770}
771
772impl FunctionReference {
773 fn resolve(
776 &self,
777 extensions: &SimpleExtensions,
778 span: pest::Span,
779 ) -> Result<u32, MessageParseError> {
780 get_and_validate_anchor(
781 extensions,
782 ExtensionKind::Function,
783 self.anchor,
784 self.name.full(),
785 span,
786 )
787 }
788}
789
790struct FunctionArguments(Vec<FunctionArgument>);
793
794impl ScopedParsePair for FunctionArguments {
795 fn rule() -> Rule {
796 Rule::argument_list
797 }
798
799 fn message() -> &'static str {
800 "FunctionArguments"
801 }
802
803 fn parse_pair(
804 extensions: &SimpleExtensions,
805 pair: Pair<Rule>,
806 ) -> Result<Self, MessageParseError> {
807 assert_eq!(pair.as_rule(), Self::rule());
808 let mut arguments = Vec::new();
809 for e in pair.into_inner() {
810 arguments.push(FunctionArgument {
811 arg_type: Some(ArgType::Value(Expression::parse_pair(extensions, e)?)),
812 });
813 }
814 Ok(Self(arguments))
815 }
816}
817
818impl ScopedParsePair for ScalarFunction {
819 fn rule() -> Rule {
820 Rule::function_call
821 }
822
823 fn message() -> &'static str {
824 "ScalarFunction"
825 }
826
827 fn parse_pair(
828 extensions: &SimpleExtensions,
829 pair: Pair<Rule>,
830 ) -> Result<Self, MessageParseError> {
831 assert_eq!(pair.as_rule(), Self::rule());
832 let span = pair.as_span();
833 let mut iter = RuleIter::from(pair.into_inner());
834
835 let reference_pair = iter.pop(Rule::function_reference);
839 let args_pair = iter.pop(Rule::argument_list);
840 let type_pair = iter.pop(Rule::r#type);
841 iter.done();
842
843 let reference = FunctionReference::parse_pair(reference_pair);
844 let FunctionArguments(arguments) = FunctionArguments::parse_pair(extensions, args_pair)?;
845 let output_type = Type::parse_pair(extensions, type_pair)?;
847
848 let function_reference = reference.resolve(extensions, span)?;
851 Ok(ScalarFunction {
852 function_reference,
853 arguments,
854 options: vec![], output_type: Some(output_type),
856 #[allow(deprecated)]
857 args: vec![],
858 })
859 }
860}
861
862impl ScopedParsePair for Cast {
863 fn rule() -> Rule {
864 Rule::cast_expression
865 }
866
867 fn message() -> &'static str {
868 "Cast"
869 }
870
871 fn parse_pair(
872 extensions: &SimpleExtensions,
873 pair: Pair<Rule>,
874 ) -> Result<Self, MessageParseError> {
875 assert_eq!(pair.as_rule(), Self::rule());
876 let mut pairs = pair.into_inner();
877
878 let expr_pair = pairs.next().unwrap();
879
880 let next = pairs.next().unwrap();
882 let (failure_behavior, type_pair) = if next.as_rule() == Rule::cast_failure_behavior {
883 let fb = match next.as_str() {
884 "?" => cast::FailureBehavior::ReturnNull as i32,
885 "!" => cast::FailureBehavior::ThrowException as i32,
886 _ => unreachable!("Grammar guarantees cast_failure_behavior is ? or !"),
887 };
888 (fb, pairs.next().unwrap())
889 } else {
890 (cast::FailureBehavior::Unspecified as i32, next)
891 };
892
893 assert!(pairs.next().is_none());
894
895 let input = Expression::parse_pair(extensions, expr_pair)?;
896 let target_type = Type::parse_pair(extensions, type_pair)?;
897
898 Ok(Cast {
899 r#type: Some(target_type),
900 input: Some(Box::new(input)),
901 failure_behavior,
902 })
903 }
904}
905
906impl ScopedParsePair for Expression {
907 fn rule() -> Rule {
908 Rule::expression
909 }
910
911 fn message() -> &'static str {
912 "Expression"
913 }
914
915 fn parse_pair(
916 extensions: &SimpleExtensions,
917 pair: Pair<Rule>,
918 ) -> Result<Self, MessageParseError> {
919 assert_eq!(pair.as_rule(), Self::rule());
920 let inner = unwrap_single_pair(pair);
921 match inner.as_rule() {
922 Rule::expression_literal => Ok(Expression {
923 rex_type: Some(RexType::Literal(Literal::parse_pair(extensions, inner)?)),
924 }),
925 Rule::function_call => Ok(Expression {
926 rex_type: Some(RexType::ScalarFunction(ScalarFunction::parse_pair(
927 extensions, inner,
928 )?)),
929 }),
930 Rule::reference => Ok(Expression {
931 rex_type: Some(RexType::Selection(Box::new(FieldReference::parse_pair(
932 inner,
933 )))),
934 }),
935 Rule::if_then => Ok(Expression {
936 rex_type: Some(RexType::IfThen(Box::new(IfThen::parse_pair(
937 extensions, inner,
938 )?))),
939 }),
940 Rule::cast_expression => Ok(Expression {
941 rex_type: Some(RexType::Cast(Box::new(Cast::parse_pair(
942 extensions, inner,
943 )?))),
944 }),
945 _ => unreachable!(
946 "Grammar guarantees expression can only be expression_literal, function_call, reference, if_then, or cast_expression, got: {:?}",
947 inner.as_rule()
948 ),
949 }
950 }
951}
952
953impl ScopedParsePair for IfClause {
954 fn rule() -> Rule {
955 Rule::if_clause
956 }
957
958 fn message() -> &'static str {
959 "IfClause"
960 }
961
962 fn parse_pair(
963 extensions: &SimpleExtensions,
964 pair: Pair<Rule>,
965 ) -> Result<Self, MessageParseError> {
966 assert_eq!(pair.as_rule(), Self::rule());
967 let mut pairs = pair.into_inner(); let condition = pairs.next().unwrap();
970 let result = pairs.next().unwrap();
971 assert!(pairs.next().is_none());
972
973 let ex1 = Some(Expression::parse_pair(extensions, condition)?);
974 let ex2 = Some(Expression::parse_pair(extensions, result)?);
975
976 Ok(IfClause {
977 r#if: ex1,
978 then: ex2,
979 })
980 }
981}
982
983impl ScopedParsePair for IfThen {
984 fn rule() -> Rule {
985 Rule::if_then
986 }
987 fn message() -> &'static str {
988 "IfThen"
989 }
990
991 fn parse_pair(
992 extensions: &SimpleExtensions,
993 pair: Pair<Rule>,
994 ) -> Result<Self, MessageParseError> {
995 assert_eq!(pair.as_rule(), Self::rule());
996
997 let mut iter = RuleIter::from(pair.into_inner()); let mut ifs: Vec<IfClause> = Vec::new();
1000
1001 while let Some(p) = iter.try_pop(Rule::if_clause) {
1003 let if_clause = IfClause::parse_pair(extensions, p)?;
1004 ifs.push(if_clause);
1005 }
1006
1007 let pair = iter.try_pop(Rule::expression).unwrap(); iter.done();
1009 let else_clause = Some(Box::new(Expression::parse_pair(extensions, pair)?));
1010
1011 Ok(IfThen {
1012 ifs,
1013 r#else: else_clause,
1014 })
1015 }
1016}
1017pub struct Name(pub String);
1018
1019impl ParsePair for Name {
1020 fn rule() -> Rule {
1021 Rule::name
1022 }
1023
1024 fn message() -> &'static str {
1025 "Name"
1026 }
1027
1028 fn parse_pair(pair: Pair<Rule>) -> Self {
1029 assert_eq!(pair.as_rule(), Self::rule());
1030 let inner = unwrap_single_pair(pair);
1031 match inner.as_rule() {
1032 Rule::identifier => Name(inner.as_str().to_string()),
1033 Rule::quoted_name => Name(unescape_string(inner)),
1034 _ => unreachable!("Name unexpected rule: {:?}", inner.as_rule()),
1035 }
1036 }
1037}
1038
1039impl ParsePair for CompoundName {
1040 fn rule() -> Rule {
1041 Rule::function_signature
1042 }
1043
1044 fn message() -> &'static str {
1045 "CompoundName"
1046 }
1047
1048 fn parse_pair(pair: Pair<Rule>) -> Self {
1049 assert_eq!(pair.as_rule(), Self::rule());
1050 CompoundName::new(pair.as_str())
1051 }
1052}
1053
1054impl ScopedParsePair for Measure {
1055 fn rule() -> Rule {
1056 Rule::function_call
1057 }
1058
1059 fn message() -> &'static str {
1060 "Measure"
1061 }
1062
1063 fn parse_pair(
1064 extensions: &SimpleExtensions,
1065 pair: Pair<Rule>,
1066 ) -> Result<Self, MessageParseError> {
1067 assert_eq!(pair.as_rule(), Self::rule());
1068
1069 let scalar = ScalarFunction::parse_pair(extensions, pair)?;
1071 Ok(Measure {
1072 measure: Some(AggregateFunction {
1073 function_reference: scalar.function_reference,
1074 arguments: scalar.arguments,
1075 options: scalar.options,
1076 output_type: scalar.output_type,
1077 invocation: 0, phase: 0, sorts: vec![], #[allow(deprecated)]
1081 args: scalar.args,
1082 }),
1083 filter: None, })
1085 }
1086}
1087
1088#[cfg(test)]
1089mod tests {
1090 use std::fmt::Debug;
1091
1092 use pest::Parser as PestParser;
1093
1094 use super::*;
1095 use crate::parser::ExpressionParser;
1096
1097 fn parse_exact(rule: Rule, input: &'_ str) -> Pair<'_, Rule> {
1098 let mut pairs = ExpressionParser::parse(rule, input).unwrap();
1099 assert_eq!(pairs.as_str(), input);
1100 let pair = pairs.next().unwrap();
1101 assert_eq!(pairs.next(), None);
1102 pair
1103 }
1104
1105 fn assert_parses_to<T: ParsePair + PartialEq + Debug>(input: &str, expected: T) {
1106 let pair = parse_exact(T::rule(), input);
1107 let actual = T::parse_pair(pair);
1108 assert_eq!(actual, expected);
1109 }
1110
1111 fn assert_parses_with<T: ScopedParsePair + PartialEq + Debug>(
1112 ext: &SimpleExtensions,
1113 input: &str,
1114 expected: T,
1115 ) {
1116 let pair = parse_exact(T::rule(), input);
1117 let actual = T::parse_pair(ext, pair).unwrap();
1118 assert_eq!(actual, expected);
1119 }
1120
1121 #[test]
1122 fn test_parse_field_reference() {
1123 assert_parses_to("$1", FieldIndex(1).to_field_reference());
1124 }
1125
1126 #[test]
1127 fn test_parse_integer_literal() {
1128 let extensions = SimpleExtensions::default();
1129 let expected = Literal {
1130 literal_type: Some(LiteralType::I64(1)),
1131 nullable: false,
1132 type_variation_reference: 0,
1133 };
1134 assert_parses_with(&extensions, "1", expected);
1135 }
1136
1137 #[test]
1138 fn test_parse_float_literal() {
1139 let pairs = ExpressionParser::parse(Rule::float, "3.82").unwrap();
1141 let parsed_text = pairs.as_str();
1142 assert_eq!(parsed_text, "3.82");
1143
1144 let extensions = SimpleExtensions::default();
1145 let expected = Literal {
1146 literal_type: Some(LiteralType::Fp64(3.82)),
1147 nullable: false,
1148 type_variation_reference: 0,
1149 };
1150 assert_parses_with(&extensions, "3.82", expected);
1151 }
1152
1153 #[test]
1154 fn test_parse_negative_float_literal() {
1155 let extensions = SimpleExtensions::default();
1156 let expected = Literal {
1157 literal_type: Some(LiteralType::Fp64(-2.5)),
1158 nullable: false,
1159 type_variation_reference: 0,
1160 };
1161 assert_parses_with(&extensions, "-2.5", expected);
1162 }
1163
1164 #[test]
1165 fn test_parse_boolean_true_literal() {
1166 let extensions = SimpleExtensions::default();
1167 let expected = Literal {
1168 literal_type: Some(LiteralType::Boolean(true)),
1169 nullable: false,
1170 type_variation_reference: 0,
1171 };
1172 assert_parses_with(&extensions, "true", expected);
1173 }
1174
1175 #[test]
1176 fn test_parse_boolean_false_literal() {
1177 let extensions = SimpleExtensions::default();
1178 let expected = Literal {
1179 literal_type: Some(LiteralType::Boolean(false)),
1180 nullable: false,
1181 type_variation_reference: 0,
1182 };
1183 assert_parses_with(&extensions, "false", expected);
1184 }
1185
1186 #[test]
1187 fn test_parse_nullable_boolean_literal() {
1188 let extensions = SimpleExtensions::default();
1189 let expected_true = Literal {
1190 literal_type: Some(LiteralType::Boolean(true)),
1191 nullable: true,
1192 type_variation_reference: 0,
1193 };
1194 let expected_false = Literal {
1195 literal_type: Some(LiteralType::Boolean(false)),
1196 nullable: true,
1197 type_variation_reference: 0,
1198 };
1199 assert_parses_with(&extensions, "true:boolean?", expected_true);
1200 assert_parses_with(&extensions, "false:boolean?", expected_false);
1201 }
1202
1203 #[test]
1204 fn test_parse_nullable_integer_literal() {
1205 let extensions = SimpleExtensions::default();
1206 let expected_i32 = Literal {
1207 literal_type: Some(LiteralType::I32(78)),
1208 nullable: true,
1209 type_variation_reference: 0,
1210 };
1211 let expected_i64 = Literal {
1212 literal_type: Some(LiteralType::I64(42)),
1213 nullable: true,
1214 type_variation_reference: 0,
1215 };
1216 assert_parses_with(&extensions, "78:i32?", expected_i32);
1217 assert_parses_with(&extensions, "42:i64?", expected_i64);
1218 }
1219
1220 #[test]
1221 fn test_parse_nullable_float_literal() {
1222 let extensions = SimpleExtensions::default();
1223 let expected_fp64 = Literal {
1224 literal_type: Some(LiteralType::Fp64(3.19)),
1225 nullable: true,
1226 type_variation_reference: 0,
1227 };
1228 assert_parses_with(&extensions, "3.19:fp64?", expected_fp64);
1229 }
1230
1231 #[test]
1232 fn test_parse_float_literal_with_fp32_type() {
1233 let extensions = SimpleExtensions::default();
1234 let pair = parse_exact(Rule::expression_literal, "3.82:fp32");
1235 let result = Literal::parse_pair(&extensions, pair).unwrap();
1236
1237 match result.literal_type {
1238 Some(LiteralType::Fp32(val)) => assert!((val - 3.82).abs() < f32::EPSILON),
1239 _ => panic!("Expected Fp32 literal type"),
1240 }
1241 }
1242
1243 #[test]
1244 fn test_parse_date_literal() {
1245 let extensions = SimpleExtensions::default();
1246 let pair = parse_exact(Rule::expression_literal, "'2023-12-25':date");
1247 let result = Literal::parse_pair(&extensions, pair).unwrap();
1248
1249 match result.literal_type {
1250 Some(LiteralType::Date(days)) => {
1251 assert!(
1253 days > 0,
1254 "Expected positive days since epoch, got: {}",
1255 days
1256 );
1257 }
1258 _ => panic!("Expected Date literal type, got: {:?}", result.literal_type),
1259 }
1260 }
1261
1262 #[test]
1263 fn test_parse_time_literal() {
1264 let extensions = SimpleExtensions::default();
1265 let pair = parse_exact(Rule::expression_literal, "'14:30:45':time");
1266 let result = Literal::parse_pair(&extensions, pair).unwrap();
1267
1268 match result.literal_type {
1269 #[allow(deprecated)]
1270 Some(LiteralType::Time(microseconds)) => {
1271 let expected = (14 * 3600 + 30 * 60 + 45) * 1_000_000;
1273 assert_eq!(microseconds, expected);
1274 }
1275 _ => panic!("Expected Time literal type, got: {:?}", result.literal_type),
1276 }
1277 }
1278
1279 #[test]
1280 fn test_parse_timestamp_literal_with_t() {
1281 let extensions = SimpleExtensions::default();
1282 let pair = parse_exact(Rule::expression_literal, "'2023-01-01T12:00:00':timestamp");
1283 let result = Literal::parse_pair(&extensions, pair).unwrap();
1284
1285 match result.literal_type {
1286 #[allow(deprecated)]
1287 Some(LiteralType::Timestamp(microseconds)) => {
1288 assert!(
1289 microseconds > 0,
1290 "Expected positive microseconds since epoch"
1291 );
1292 }
1293 _ => panic!(
1294 "Expected Timestamp literal type, got: {:?}",
1295 result.literal_type
1296 ),
1297 }
1298 }
1299
1300 #[test]
1301 fn test_parse_timestamp_literal_with_space() {
1302 let extensions = SimpleExtensions::default();
1303 let pair = parse_exact(Rule::expression_literal, "'2023-01-01 12:00:00':timestamp");
1304 let result = Literal::parse_pair(&extensions, pair).unwrap();
1305
1306 match result.literal_type {
1307 #[allow(deprecated)]
1308 Some(LiteralType::Timestamp(microseconds)) => {
1309 assert!(
1310 microseconds > 0,
1311 "Expected positive microseconds since epoch"
1312 );
1313 }
1314 _ => panic!(
1315 "Expected Timestamp literal type, got: {:?}",
1316 result.literal_type
1317 ),
1318 }
1319 }
1320
1321 #[test]
1322 fn test_parse_precision_timestamp_literal() {
1323 let extensions = SimpleExtensions::default();
1324 let pair = parse_exact(
1325 Rule::expression_literal,
1326 "'2023-01-01T12:00:00.123456789':precisiontimestamp<9>",
1327 );
1328 let result = Literal::parse_pair(&extensions, pair).unwrap();
1329
1330 match result.literal_type {
1331 Some(LiteralType::PrecisionTimestamp(p)) => {
1332 assert_eq!(p.precision, 9);
1333 assert!(p.value > 0, "Expected positive value since epoch");
1334 assert_eq!(p.value % 1_000_000_000, 123_456_789);
1337 }
1338 _ => panic!(
1339 "Expected PrecisionTimestamp literal type, got: {:?}",
1340 result.literal_type
1341 ),
1342 }
1343 assert!(!result.nullable);
1344 }
1345
1346 #[test]
1347 fn test_parse_precision_timestamp_tz_literal_nullable() {
1348 let extensions = SimpleExtensions::default();
1349 let pair = parse_exact(
1350 Rule::expression_literal,
1351 "'2023-01-01T12:00:00.123':precisiontimestamptz?<3>",
1352 );
1353 let result = Literal::parse_pair(&extensions, pair).unwrap();
1354
1355 match result.literal_type {
1356 Some(LiteralType::PrecisionTimestampTz(p)) => {
1357 assert_eq!(p.precision, 3);
1358 assert_eq!(p.value % 1000, 123);
1359 }
1360 _ => panic!(
1361 "Expected PrecisionTimestampTz literal type, got: {:?}",
1362 result.literal_type
1363 ),
1364 }
1365 assert!(result.nullable);
1366 }
1367
1368 #[test]
1369 fn test_parse_precision_time_literal() {
1370 let extensions = SimpleExtensions::default();
1371 let pair = parse_exact(
1372 Rule::expression_literal,
1373 "'14:30:45.123456':precisiontime<6>",
1374 );
1375 let result = Literal::parse_pair(&extensions, pair).unwrap();
1376
1377 match result.literal_type {
1378 Some(LiteralType::PrecisionTime(p)) => {
1379 assert_eq!(p.precision, 6);
1380 let expected = (14 * 3600 + 30 * 60 + 45) * 1_000_000 + 123_456;
1381 assert_eq!(p.value, expected);
1382 }
1383 _ => panic!(
1384 "Expected PrecisionTime literal type, got: {:?}",
1385 result.literal_type
1386 ),
1387 }
1388 }
1389
1390 #[test]
1391 fn test_parse_precision_timestamp_literal_precision_12_unsupported() {
1392 let extensions = SimpleExtensions::default();
1393 let pair = parse_exact(
1394 Rule::expression_literal,
1395 "'2023-01-01T12:00:00':precisiontimestamp<12>",
1396 );
1397 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1398 assert!(err.to_string().contains("picoseconds"));
1399 }
1400
1401 #[test]
1402 fn test_parse_precision_timestamp_literal_invalid_precision() {
1403 let extensions = SimpleExtensions::default();
1404 let pair = parse_exact(
1406 Rule::expression_literal,
1407 "'2023-01-01T12:00:00':precisiontimestamp<5>",
1408 );
1409 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1410 assert!(err.to_string().contains("Invalid precision 5"));
1411 }
1412
1413 #[test]
1414 fn test_parse_precision_timestamp_literal_nullable() {
1415 let extensions = SimpleExtensions::default();
1416 let pair = parse_exact(
1417 Rule::expression_literal,
1418 "'2023-01-01T12:00:00.123456789':precisiontimestamp?<9>",
1419 );
1420 let result = Literal::parse_pair(&extensions, pair).unwrap();
1421 assert!(result.nullable);
1422 }
1423
1424 #[test]
1425 fn test_parse_precision_time_literal_nullable() {
1426 let extensions = SimpleExtensions::default();
1427 let pair = parse_exact(
1428 Rule::expression_literal,
1429 "'14:30:45.123456':precisiontime?<6>",
1430 );
1431 let result = Literal::parse_pair(&extensions, pair).unwrap();
1432 assert!(result.nullable);
1433 }
1434
1435 #[test]
1436 fn test_parse_precision_timestamp_literal_fractional_truncated() {
1437 let extensions = SimpleExtensions::default();
1438 let pair = parse_exact(
1441 Rule::expression_literal,
1442 "'2023-01-01T12:00:00.999':precisiontimestamp<0>",
1443 );
1444 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1445 assert!(err.to_string().contains("fractional"));
1446 }
1447
1448 #[test]
1449 fn test_parse_precision_time_literal_fractional_truncated() {
1450 let extensions = SimpleExtensions::default();
1451 let pair = parse_exact(
1454 Rule::expression_literal,
1455 "'14:30:45.123456':precisiontime<3>",
1456 );
1457 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1458 assert!(err.to_string().contains("fractional"));
1459 }
1460
1461 #[test]
1462 fn test_parse_precision_timestamp_literal_nanosecond_overflow() {
1463 let extensions = SimpleExtensions::default();
1464 let pair = parse_exact(
1467 Rule::expression_literal,
1468 "'2300-01-01T00:00:00':precisiontimestamp<9>",
1469 );
1470 let err = Literal::parse_pair(&extensions, pair).unwrap_err();
1471 assert!(err.to_string().contains("out of range"));
1472 }
1473
1474 fn parse_interval_day_literal(input: &str) -> Result<IntervalDayToSecond, MessageParseError> {
1475 let extensions = SimpleExtensions::default();
1476 let pair = parse_exact(Rule::expression_literal, input);
1477 let result = Literal::parse_pair(&extensions, pair)?;
1478 match result.literal_type {
1479 Some(LiteralType::IntervalDayToSecond(interval)) => Ok(interval),
1480 other => panic!("Expected IntervalDayToSecond literal type, got: {other:?}"),
1481 }
1482 }
1483
1484 fn assert_interval_day(input: &str, days: i32, seconds: i32, subseconds: i64, precision: i32) {
1485 let interval = parse_interval_day_literal(input).unwrap();
1486 assert_eq!(
1487 interval,
1488 IntervalDayToSecond {
1489 days,
1490 seconds,
1491 subseconds,
1492 precision_mode: Some(PrecisionMode::Precision(precision)),
1493 },
1494 "input: {input}"
1495 );
1496 }
1497
1498 #[test]
1499 fn test_parse_interval_day_literals() {
1500 for (input, days, seconds, subseconds, precision) in [
1501 ("'5d':interval_day<0>", 5, 0, 0, 0),
1504 ("'5d':interval_day<9>", 5, 0, 0, 9),
1505 ("'4d 5s':interval_day<0>", 4, 5, 0, 0),
1506 ("'123ms':interval_day<3>", 0, 0, 123, 3),
1507 ("'123456us':interval_day<6>", 0, 0, 123_456, 6),
1508 ("'123456789ns':interval_day<9>", 0, 0, 123_456_789, 9),
1509 ("'5d 3s 100ns':interval_day<9>", 5, 3, 100, 9),
1510 ("'-5d 3s':interval_day<0>", -5, 3, 0, 0),
1512 ("'-500000000ns':interval_day<9>", 0, 0, -500_000_000, 9),
1513 ("'5d':interval_day?<6>", 5, 0, 0, 6),
1515 ("'3650001d':interval_day<0>", 3_650_001, 0, 0, 0),
1518 ("'1000000000ns':interval_day<9>", 0, 0, 1_000_000_000, 9),
1519 ] {
1520 assert_interval_day(input, days, seconds, subseconds, precision);
1521 }
1522 }
1523
1524 #[test]
1525 fn test_parse_interval_day_literal_errors() {
1526 for input in [
1527 "'':interval_day<0>",
1529 "'5x':interval_day<0>",
1530 "'5':interval_day<0>",
1531 "'5d 3d':interval_day<0>",
1533 "'5s 3s':interval_day<0>",
1534 "'3ms 5us':interval_day<3>",
1535 "'3s 5d':interval_day<0>",
1537 "'100ns 5d 3s':interval_day<9>",
1538 "'5d 3s':interval_day<0>",
1540 "' 5d 3s ':interval_day<0>",
1541 "'5d\t3s':interval_day<0>",
1542 "'100ns':interval_day<6>",
1544 "'5d 3s':interval_day<4>",
1547 "'5d':interval_day<13>",
1548 "'5d':interval_day<-1>",
1549 "'2200000000s':interval_day<0>",
1551 "'99999999999d':interval_day<0>",
1552 "'99999999999999999999ns':interval_day<9>",
1553 ] {
1554 assert!(
1555 parse_interval_day_literal(input).is_err(),
1556 "expected {input} to fail"
1557 );
1558 }
1559 }
1560
1561 #[test]
1562 fn test_parse_interval_day_literal_requires_precision() {
1563 let err = parse_interval_day_literal("'5d':interval_day")
1566 .expect_err("bare interval_day should not be a known type");
1567 assert!(
1568 err.to_string().contains("interval_day"),
1569 "unexpected error: {err}"
1570 );
1571 }
1572
1573 #[test]
1574 fn test_parse_interval_day_literal_unit_precision_mismatch_message() {
1575 let err = parse_interval_day_literal("'100ns':interval_day<6>")
1576 .expect_err("a sub-second unit that disagrees with the type should fail");
1577 assert!(
1578 err.to_string().contains("means precision 9"),
1579 "unexpected error: {err}"
1580 );
1581 }
1582
1583 fn make_literal_bool(value: bool) -> Expression {
1585 Expression {
1586 rex_type: Some(RexType::Literal(Literal {
1587 literal_type: Some(LiteralType::Boolean(value)),
1588 nullable: false,
1589 type_variation_reference: 0,
1590 })),
1591 }
1592 }
1593
1594 #[test]
1595 fn test_parse_if_then_single_clause() {
1596 let extensions = SimpleExtensions::default();
1597 let input = "if_then(true -> 42, _ -> 0)";
1598 let pair = parse_exact(Rule::if_then, input);
1599 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1600
1601 assert_eq!(result.ifs.len(), 1);
1602 assert!(result.r#else.is_some());
1603 }
1604
1605 #[test]
1606 fn test_parse_if_then_with_typed_literals() {
1607 let extensions = SimpleExtensions::default();
1608 let input = "if_then(true -> 100:i32, _ -> -100:i32)";
1609 let pair = parse_exact(Rule::if_then, input);
1610 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1611
1612 assert_eq!(result.ifs.len(), 1);
1613 assert!(result.r#else.is_some());
1614 }
1615
1616 #[test]
1617 fn test_parse_if_then_with_date_literals() {
1618 let extensions = SimpleExtensions::default();
1619 let input = "if_then(true -> '2023-12-25':date, _ -> '1970-01-01':date)";
1620 let pair = parse_exact(Rule::if_then, input);
1621 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1622
1623 assert_eq!(result.ifs.len(), 1);
1624 assert!(result.r#else.is_some());
1625 }
1626
1627 #[test]
1628 fn test_parse_if_then_with_time_literals() {
1629 let extensions = SimpleExtensions::default();
1630 let input = "if_then(true -> '14:30:45':time, _ -> '00:00:00':time)";
1631 let pair = parse_exact(Rule::if_then, input);
1632 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1633
1634 assert_eq!(result.ifs.len(), 1);
1635 assert!(result.r#else.is_some());
1636 }
1637
1638 #[test]
1639 fn test_parse_if_then_with_timestamp_literals() {
1640 let extensions = SimpleExtensions::default();
1641 let input = "if_then(true -> '2023-01-01T12:00:00':timestamp, _ -> '1970-01-01T00:00:00':timestamp)";
1642 let pair = parse_exact(Rule::if_then, input);
1643 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1644
1645 assert_eq!(result.ifs.len(), 1);
1646 assert!(result.r#else.is_some());
1647 }
1648
1649 #[test]
1650 fn test_parse_if_clause_with_whitespace_variations() {
1651 let extensions = SimpleExtensions::default();
1652
1653 let inputs = vec!["true->false", "true -> false", "true -> false"];
1655
1656 for input in inputs {
1657 let pair = parse_exact(Rule::if_clause, input);
1658 let result = IfClause::parse_pair(&extensions, pair).unwrap();
1659 assert!(result.r#if.is_some());
1660 assert!(result.then.is_some());
1661 }
1662 }
1663
1664 #[test]
1665 fn test_if_clause_structure() {
1666 let extensions = SimpleExtensions::default();
1667 let pair = parse_exact(Rule::if_clause, "42 -> 100");
1668 let result = IfClause::parse_pair(&extensions, pair).unwrap();
1669
1670 let if_expr = result.r#if.as_ref().unwrap();
1672 let then_expr = result.then.as_ref().unwrap();
1673
1674 match (&if_expr.rex_type, &then_expr.rex_type) {
1676 (Some(RexType::Literal(_)), Some(RexType::Literal(_))) => {
1677 }
1679 _ => panic!("Expected both if and then to be literals"),
1680 }
1681 }
1682
1683 #[test]
1684 fn test_if_then_structure() {
1685 let extensions = SimpleExtensions::default();
1686 let input = "if_then(true -> 1, false -> 2, _ -> 0)";
1687 let pair = parse_exact(Rule::if_then, input);
1688 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1689
1690 assert_eq!(result.ifs.len(), 2);
1692
1693 for clause in &result.ifs {
1695 assert!(clause.r#if.is_some(), "If clause condition should exist");
1696 assert!(clause.then.is_some(), "If clause result should exist");
1697 }
1698
1699 assert!(result.r#else.is_some(), "Else clause should exist");
1701 }
1702
1703 #[test]
1704 fn test_parse_if_then_mixed_types_in_conditions() {
1705 let extensions = SimpleExtensions::default();
1706 let input = "if_then(true -> 1, true -> 'yes', 'yes' -> true, 42 -> 2, $0 -> 3, _ -> 0)";
1708 let pair = parse_exact(Rule::if_then, input);
1709 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1710
1711 assert_eq!(result.ifs.len(), 5);
1712 assert!(result.r#else.is_some());
1713 }
1714
1715 #[test]
1716 fn test_if_then_preserves_clause_order() {
1717 let extensions = SimpleExtensions::default();
1718 let input = "if_then(1 -> 10, 2 -> 20, 3 -> 30, _ -> 0)";
1719 let pair = parse_exact(Rule::if_then, input);
1720 let result = IfThen::parse_pair(&extensions, pair).unwrap();
1721
1722 assert_eq!(result.ifs.len(), 3);
1723
1724 for (i, clause) in result.ifs.iter().enumerate() {
1726 if let Some(Expression {
1727 rex_type: Some(RexType::Literal(lit)),
1728 }) = &clause.r#if
1729 && let Some(LiteralType::I64(val)) = &lit.literal_type
1730 {
1731 assert_eq!(*val, (i as i64) + 1);
1732 }
1733 }
1734 }
1735
1736 #[test]
1737 fn test_parse_if_then() {
1738 let extensions = SimpleExtensions::default();
1739
1740 let c1 = IfClause {
1741 r#if: Some(make_literal_bool(true)),
1742 then: Some(make_literal_bool(true)),
1743 };
1744
1745 let c2 = IfClause {
1746 r#if: Some(make_literal_bool(false)),
1747 then: Some(make_literal_bool(false)),
1748 };
1749
1750 let if_clause = IfThen {
1751 ifs: vec![c1, c2],
1752 r#else: Some(Box::new(make_literal_bool(false))),
1753 };
1754 assert_parses_with(
1755 &extensions,
1756 "if_then(true -> true , false -> false, _ -> false)",
1757 if_clause,
1758 );
1759 }
1760
1761 fn parse_function_signature(input: &str) -> CompoundName {
1764 let pair = parse_exact(Rule::function_signature, input);
1765 CompoundName::parse_pair(pair)
1766 }
1767
1768 #[test]
1769 fn test_compound_name_plain() {
1770 assert_eq!(parse_function_signature("add").full(), "add");
1771 }
1772
1773 #[test]
1774 fn test_compound_name_full_zero_arg_type_signature() {
1775 let n = parse_function_signature("add:");
1777 assert_eq!(n.full(), "add:");
1778 assert_eq!(n.base(), "add");
1779 assert!(n.matches("add:"));
1780 assert!(!n.matches("add:i64_i64"));
1781 assert!(n.matches("add"));
1782 }
1783
1784 #[test]
1785 fn test_compound_name_with_signature() {
1786 assert_eq!(
1787 parse_function_signature("equal:any_any").full(),
1788 "equal:any_any"
1789 );
1790 assert_eq!(
1791 parse_function_signature("regexp_match_substring:str_str_i64").full(),
1792 "regexp_match_substring:str_str_i64"
1793 );
1794 assert_eq!(
1795 parse_function_signature("add:i64_i64").full(),
1796 "add:i64_i64"
1797 );
1798 }
1799
1800 #[test]
1801 fn test_compound_name_trailing_colon_grammar() {
1802 let name = parse_function_signature("count:");
1805 assert_eq!(name.base(), "count");
1806 assert_eq!(name.full(), "count:");
1807 assert!(
1808 name.has_signature(),
1809 "trailing colon must set has_signature"
1810 );
1811 }
1812
1813 #[test]
1814 fn test_compound_name_stops_at_opening_paren() {
1815 let pairs = ExpressionParser::parse(Rule::function_signature, "equal:any_any").unwrap();
1817 assert_eq!(pairs.as_str(), "equal:any_any");
1818 }
1819
1820 #[test]
1821 fn test_parse_function_arguments() {
1822 let exts = SimpleExtensions::default();
1824
1825 let pair = parse_exact(Rule::argument_list, "()");
1826 let FunctionArguments(args) = FunctionArguments::parse_pair(&exts, pair).unwrap();
1827 assert!(args.is_empty());
1828
1829 let pair = parse_exact(Rule::argument_list, "($0, 1)");
1830 let FunctionArguments(args) = FunctionArguments::parse_pair(&exts, pair).unwrap();
1831 assert_eq!(
1832 args,
1833 vec![
1834 FunctionArgument {
1835 arg_type: Some(ArgType::Value(Expression {
1836 rex_type: Some(RexType::Selection(Box::new(
1837 FieldIndex(0).to_field_reference()
1838 ))),
1839 })),
1840 },
1841 FunctionArgument {
1842 arg_type: Some(ArgType::Value(Expression {
1843 rex_type: Some(RexType::Literal(Literal {
1844 literal_type: Some(LiteralType::I64(1)),
1845 nullable: false,
1846 type_variation_reference: 0,
1847 })),
1848 })),
1849 },
1850 ]
1851 );
1852 }
1853
1854 fn make_extensions_for_fn_tests() -> SimpleExtensions {
1855 let mut exts = SimpleExtensions::default();
1856 exts.add_extension_urn("urn".to_string(), 1).unwrap();
1857 exts.add_extension(ExtensionKind::Function, 1, 1, "equal:any_any".to_string())
1858 .unwrap();
1859 exts.add_extension(ExtensionKind::Function, 1, 2, "equal:str_str".to_string())
1860 .unwrap();
1861 exts.add_extension(ExtensionKind::Function, 1, 3, "add:i64_i64".to_string())
1862 .unwrap();
1863 exts
1864 }
1865
1866 #[test]
1867 fn test_scalar_function_full_compound_name() {
1868 let exts = make_extensions_for_fn_tests();
1870 let pair = parse_exact(Rule::function_call, "equal:any_any($0, $1):boolean");
1871 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1872 assert_eq!(f.function_reference, 1);
1873 assert_eq!(f.arguments.len(), 2);
1874 assert!(
1875 f.output_type.is_some(),
1876 "output_type must be set after parsing"
1877 );
1878 }
1879
1880 #[test]
1881 fn test_scalar_function_second_overload() {
1882 let exts = make_extensions_for_fn_tests();
1883 let pair = parse_exact(Rule::function_call, "equal:str_str($0, $1):boolean");
1884 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1885
1886 assert_eq!(f.arguments.len(), 2);
1887 assert_eq!(f.function_reference, 2);
1888 }
1889
1890 #[test]
1891 fn test_scalar_function_base_name_unique_overload() {
1892 let exts = make_extensions_for_fn_tests();
1894 let pair = parse_exact(Rule::function_call, "add($0, $1):i64");
1895 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1896
1897 assert_eq!(f.arguments.len(), 2);
1898 assert_eq!(f.function_reference, 3);
1899 assert!(
1900 f.output_type.is_some(),
1901 "output_type must be set after parsing"
1902 );
1903 }
1904
1905 #[test]
1906 fn test_scalar_function_base_name_ambiguous_fails() {
1907 let exts = make_extensions_for_fn_tests();
1909 let pair = parse_exact(Rule::function_call, "equal($0, $1):boolean");
1910 let result = ScalarFunction::parse_pair(&exts, pair);
1911 assert!(result.is_err(), "ambiguous base name should fail");
1912 }
1913
1914 #[test]
1915 fn test_scalar_function_compound_name_with_anchor() {
1916 let exts = make_extensions_for_fn_tests();
1917 let pair = parse_exact(Rule::function_call, "equal:any_any#1($0, $1):boolean");
1918 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1919 assert_eq!(f.function_reference, 1);
1920 assert_eq!(f.arguments.len(), 2);
1921 }
1922
1923 #[test]
1924 fn test_scalar_function_base_name_with_anchor() {
1925 let exts = make_extensions_for_fn_tests();
1927 let pair = parse_exact(Rule::function_call, "equal#1($0, $1):boolean");
1928 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1929 assert_eq!(f.function_reference, 1);
1930 assert_eq!(f.arguments.len(), 2);
1931 }
1932
1933 #[test]
1934 fn test_scalar_function_wrong_name_for_anchor_fails() {
1935 let exts = make_extensions_for_fn_tests();
1936 let pair = parse_exact(Rule::function_call, "like#1($0):boolean");
1937 let result = ScalarFunction::parse_pair(&exts, pair);
1938 assert!(result.is_err(), "mismatched name/anchor should fail");
1939 }
1940
1941 #[test]
1942 fn test_scalar_function_user_defined_type_in_signature() {
1943 let mut exts = SimpleExtensions::default();
1945 exts.add_extension_urn("urn".to_string(), 1).unwrap();
1946 exts.add_extension(
1947 ExtensionKind::Function,
1948 1,
1949 10,
1950 "json_extract_path:u!json_str".to_string(),
1951 )
1952 .unwrap();
1953
1954 let pair = parse_exact(
1955 Rule::function_call,
1956 "json_extract_path:u!json_str($0, $1):string",
1957 );
1958 let f = ScalarFunction::parse_pair(&exts, pair).unwrap();
1959 assert_eq!(f.function_reference, 10);
1960 assert_eq!(f.arguments.len(), 2);
1961 }
1962
1963 #[test]
1964 fn test_scalar_function_missing_type_fails_to_parse() {
1965 let result = ExpressionParser::parse(Rule::function_call, "add($0, $1)");
1967 assert!(
1968 result.is_err(),
1969 "function call without type annotation should fail to parse"
1970 );
1971 }
1972
1973 #[test]
1974 fn test_parse_cast_expression_basic() {
1975 let extensions = SimpleExtensions::default();
1976 let pair = parse_exact(Rule::cast_expression, "(78:i32)::i16");
1977 let result = Cast::parse_pair(&extensions, pair).unwrap();
1978
1979 let input = result.input.as_ref().unwrap();
1981 match &input.rex_type {
1982 Some(RexType::Literal(lit)) => match &lit.literal_type {
1983 Some(LiteralType::I32(v)) => assert_eq!(*v, 78),
1984 other => panic!("Expected I32 literal, got: {:?}", other),
1985 },
1986 other => panic!("Expected literal, got: {:?}", other),
1987 }
1988
1989 let target = result.r#type.as_ref().unwrap();
1991 match &target.kind {
1992 Some(Kind::I16(_)) => {}
1993 other => panic!("Expected i16 type, got: {:?}", other),
1994 }
1995
1996 assert_eq!(result.failure_behavior, 0);
1997 }
1998
1999 #[test]
2000 fn test_parse_cast_expression_via_expression_rule() {
2001 let extensions = SimpleExtensions::default();
2002 let pair = parse_exact(Rule::expression, "(78:i32)::i16");
2003 let result = Expression::parse_pair(&extensions, pair).unwrap();
2004
2005 match result.rex_type {
2006 Some(RexType::Cast(_)) => {}
2007 other => panic!("Expected Cast rex type, got: {:?}", other),
2008 }
2009 }
2010
2011 #[test]
2012 fn test_parse_cast_expression_nested() {
2013 let extensions = SimpleExtensions::default();
2014 let pair = parse_exact(Rule::cast_expression, "((78:i32)::i16)::i32");
2015 let result = Cast::parse_pair(&extensions, pair).unwrap();
2016
2017 let input = result.input.as_ref().unwrap();
2019 match &input.rex_type {
2020 Some(RexType::Cast(inner)) => {
2021 let inner_input = inner.input.as_ref().unwrap();
2022 match &inner_input.rex_type {
2023 Some(RexType::Literal(lit)) => match &lit.literal_type {
2024 Some(LiteralType::I32(v)) => assert_eq!(*v, 78),
2025 other => panic!("Expected I32 literal, got: {:?}", other),
2026 },
2027 other => panic!("Expected literal, got: {:?}", other),
2028 }
2029 }
2030 other => panic!("Expected inner Cast, got: {:?}", other),
2031 }
2032
2033 match &result.r#type.as_ref().unwrap().kind {
2034 Some(Kind::I32(_)) => {}
2035 other => panic!("Expected i32 outer type, got: {:?}", other),
2036 }
2037 }
2038
2039 #[test]
2040 fn test_parse_cast_expression_with_boolean() {
2041 let extensions = SimpleExtensions::default();
2042 let pair = parse_exact(Rule::cast_expression, "(true)::i32");
2043 let result = Cast::parse_pair(&extensions, pair).unwrap();
2044
2045 let input = result.input.as_ref().unwrap();
2046 match &input.rex_type {
2047 Some(RexType::Literal(lit)) => match &lit.literal_type {
2048 Some(LiteralType::Boolean(v)) => assert!(*v),
2049 other => panic!("Expected Boolean literal, got: {:?}", other),
2050 },
2051 other => panic!("Expected literal, got: {:?}", other),
2052 }
2053 }
2054
2055 #[test]
2056 fn test_parse_cast_expression_with_whitespace() {
2057 let extensions = SimpleExtensions::default();
2058 let pair = parse_exact(Rule::cast_expression, "( 78:i32 ) :: i16");
2060 let result = Cast::parse_pair(&extensions, pair).unwrap();
2061 assert!(result.input.is_some());
2062 assert!(result.r#type.is_some());
2063 }
2064
2065 #[test]
2066 fn test_parse_cast_unspecified_failure_behavior() {
2067 let extensions = SimpleExtensions::default();
2068 let pair = parse_exact(Rule::cast_expression, "(78:i32)::i16");
2069 let result = Cast::parse_pair(&extensions, pair).unwrap();
2070 assert_eq!(
2071 result.failure_behavior,
2072 cast::FailureBehavior::Unspecified as i32
2073 );
2074 }
2075
2076 #[test]
2077 fn test_parse_cast_return_null_failure_behavior() {
2078 let extensions = SimpleExtensions::default();
2079 let pair = parse_exact(Rule::cast_expression, "(78:i32)::?i16");
2080 let result = Cast::parse_pair(&extensions, pair).unwrap();
2081 assert_eq!(
2082 result.failure_behavior,
2083 cast::FailureBehavior::ReturnNull as i32
2084 );
2085 }
2086
2087 #[test]
2088 fn test_parse_cast_throw_exception_failure_behavior() {
2089 let extensions = SimpleExtensions::default();
2090 let pair = parse_exact(Rule::cast_expression, "(78:i32)::!i16");
2091 let result = Cast::parse_pair(&extensions, pair).unwrap();
2092 assert_eq!(
2093 result.failure_behavior,
2094 cast::FailureBehavior::ThrowException as i32
2095 );
2096 }
2097
2098 #[test]
2099 fn test_parse_cast_to_user_defined_type_with_u_prefix() {
2100 let mut extensions = SimpleExtensions::default();
2102 extensions.add_extension_urn("urn".to_string(), 1).unwrap();
2103 extensions
2104 .add_extension(ExtensionKind::Type, 1, 5, "u!json".to_string())
2105 .unwrap();
2106
2107 let pair = parse_exact(Rule::cast_expression, "($0)::u!json");
2108 let result = Cast::parse_pair(&extensions, pair).unwrap();
2109 match result.r#type.as_ref().unwrap().kind.as_ref().unwrap() {
2110 Kind::UserDefined(u) => {
2111 assert_eq!(u.type_reference, 5);
2112 }
2113 other => panic!("expected UserDefined, got {other:?}"),
2114 }
2115 }
2116
2117 #[test]
2118 fn test_function_call_u_prefix_base_name_rejected() {
2119 assert!(
2122 ExpressionParser::parse(Rule::function_call, "u!json_get($0)").is_err(),
2123 "u! prefix in function call base name must be rejected by the grammar"
2124 );
2125 }
2126}