substrait_explain/parser/
expressions.rs

1use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime};
2use substrait::proto::aggregate_rel::Measure;
3use substrait::proto::expression::field_reference::ReferenceType;
4use substrait::proto::expression::literal::LiteralType;
5use substrait::proto::expression::{
6    FieldReference, Literal, ReferenceSegment, RexType, ScalarFunction, reference_segment,
7};
8use substrait::proto::function_argument::ArgType;
9use substrait::proto::r#type::{Fp64, I64, Kind, Nullability};
10use substrait::proto::{AggregateFunction, Expression, FunctionArgument, Type};
11
12use super::types::get_and_validate_anchor;
13use super::{
14    MessageParseError, ParsePair, Rule, RuleIter, ScopedParsePair, unescape_string,
15    unwrap_single_pair,
16};
17use crate::extensions::SimpleExtensions;
18use crate::extensions::simple::ExtensionKind;
19use crate::parser::ErrorKind;
20
21/// A field index (e.g., parsed from "$0" -> 0).
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub struct FieldIndex(pub i32);
24
25impl FieldIndex {
26    /// Convert this field index to a FieldReference for use in expressions.
27    pub fn to_field_reference(self) -> FieldReference {
28        // XXX: Why is it so many layers to make a struct field reference? This is
29        // surprisingly complex
30        FieldReference {
31            reference_type: Some(ReferenceType::DirectReference(ReferenceSegment {
32                reference_type: Some(reference_segment::ReferenceType::StructField(Box::new(
33                    reference_segment::StructField {
34                        field: self.0,
35                        child: None,
36                    },
37                ))),
38            })),
39            root_type: None,
40        }
41    }
42}
43
44impl ParsePair for FieldIndex {
45    fn rule() -> Rule {
46        Rule::reference
47    }
48
49    fn message() -> &'static str {
50        "FieldIndex"
51    }
52
53    fn parse_pair(pair: pest::iterators::Pair<Rule>) -> Self {
54        assert_eq!(pair.as_rule(), Self::rule());
55        let inner = unwrap_single_pair(pair);
56        let index: i32 = inner.as_str().parse().unwrap();
57        FieldIndex(index)
58    }
59}
60
61impl ParsePair for FieldReference {
62    fn rule() -> Rule {
63        Rule::reference
64    }
65
66    fn message() -> &'static str {
67        "FieldReference"
68    }
69
70    fn parse_pair(pair: pest::iterators::Pair<Rule>) -> Self {
71        assert_eq!(pair.as_rule(), Self::rule());
72
73        // TODO: Other types of references.
74        FieldIndex::parse_pair(pair).to_field_reference()
75    }
76}
77
78fn to_int_literal(
79    value: pest::iterators::Pair<Rule>,
80    typ: Option<Type>,
81) -> Result<Literal, MessageParseError> {
82    assert_eq!(value.as_rule(), Rule::integer);
83    let parsed_value: i64 = value.as_str().parse().unwrap();
84
85    const DEFAULT_KIND: Kind = Kind::I64(I64 {
86        type_variation_reference: 0,
87        nullability: Nullability::Required as i32,
88    });
89
90    // If no type is provided, we assume i64, Nullability::Required.
91    let kind = typ.and_then(|t| t.kind).unwrap_or(DEFAULT_KIND);
92
93    let (lit, nullability, tvar) = match &kind {
94        // If no type is provided, we assume i64, Nullability::Required.
95        Kind::I8(i) => (
96            LiteralType::I8(parsed_value as i32),
97            i.nullability,
98            i.type_variation_reference,
99        ),
100        Kind::I16(i) => (
101            LiteralType::I16(parsed_value as i32),
102            i.nullability,
103            i.type_variation_reference,
104        ),
105        Kind::I32(i) => (
106            LiteralType::I32(parsed_value as i32),
107            i.nullability,
108            i.type_variation_reference,
109        ),
110        Kind::I64(i) => (
111            LiteralType::I64(parsed_value),
112            i.nullability,
113            i.type_variation_reference,
114        ),
115        k => {
116            let pest_error = pest::error::Error::new_from_span(
117                pest::error::ErrorVariant::CustomError {
118                    message: format!("Invalid type for integer literal: {k:?}"),
119                },
120                value.as_span(),
121            );
122            let error = MessageParseError {
123                message: "int_literal_type",
124                kind: ErrorKind::InvalidValue,
125                error: Box::new(pest_error),
126            };
127            return Err(error);
128        }
129    };
130
131    Ok(Literal {
132        literal_type: Some(lit),
133        nullable: nullability != Nullability::Required as i32,
134        type_variation_reference: tvar,
135    })
136}
137
138fn to_float_literal(
139    value: pest::iterators::Pair<Rule>,
140    typ: Option<Type>,
141) -> Result<Literal, MessageParseError> {
142    assert_eq!(value.as_rule(), Rule::float);
143    let parsed_value: f64 = value.as_str().parse().unwrap();
144
145    const DEFAULT_KIND: Kind = Kind::Fp64(Fp64 {
146        type_variation_reference: 0,
147        nullability: Nullability::Required as i32,
148    });
149
150    // If no type is provided, we assume fp64, Nullability::Required.
151    let kind = typ.and_then(|t| t.kind).unwrap_or(DEFAULT_KIND);
152
153    let (lit, nullability, tvar) = match &kind {
154        Kind::Fp32(f) => (
155            LiteralType::Fp32(parsed_value as f32),
156            f.nullability,
157            f.type_variation_reference,
158        ),
159        Kind::Fp64(f) => (
160            LiteralType::Fp64(parsed_value),
161            f.nullability,
162            f.type_variation_reference,
163        ),
164        k => {
165            let pest_error = pest::error::Error::new_from_span(
166                pest::error::ErrorVariant::CustomError {
167                    message: format!("Invalid type for float literal: {k:?}"),
168                },
169                value.as_span(),
170            );
171            let error = MessageParseError {
172                message: "float_literal_type",
173                kind: ErrorKind::InvalidValue,
174                error: Box::new(pest_error),
175            };
176            return Err(error);
177        }
178    };
179
180    Ok(Literal {
181        literal_type: Some(lit),
182        nullable: nullability != Nullability::Required as i32,
183        type_variation_reference: tvar,
184    })
185}
186
187fn to_boolean_literal(value: pest::iterators::Pair<Rule>) -> Result<Literal, MessageParseError> {
188    assert_eq!(value.as_rule(), Rule::boolean);
189    let parsed_value: bool = value.as_str().parse().unwrap();
190
191    Ok(Literal {
192        literal_type: Some(LiteralType::Boolean(parsed_value)),
193        nullable: false,
194        type_variation_reference: 0,
195    })
196}
197
198fn to_string_literal(
199    value: pest::iterators::Pair<Rule>,
200    typ: Option<Type>,
201) -> Result<Literal, MessageParseError> {
202    assert_eq!(value.as_rule(), Rule::string_literal);
203    let string_value = unescape_string(value.clone());
204
205    // If no type is provided, default to string
206    let Some(typ) = typ else {
207        return Ok(Literal {
208            literal_type: Some(LiteralType::String(string_value)),
209            nullable: false,
210            type_variation_reference: 0,
211        });
212    };
213
214    let Some(kind) = typ.kind else {
215        return Ok(Literal {
216            literal_type: Some(LiteralType::String(string_value)),
217            nullable: false,
218            type_variation_reference: 0,
219        });
220    };
221
222    match &kind {
223        Kind::Date(d) => {
224            // Parse date in ISO 8601 format: YYYY-MM-DD
225            let date_days = parse_date_to_days(&string_value, value.as_span())?;
226            Ok(Literal {
227                literal_type: Some(LiteralType::Date(date_days)),
228                nullable: d.nullability != Nullability::Required as i32,
229                type_variation_reference: d.type_variation_reference,
230            })
231        }
232        Kind::Time(t) => {
233            // Parse time in ISO 8601 format: HH:MM:SS[.fff]
234            let time_microseconds = parse_time_to_microseconds(&string_value, value.as_span())?;
235            Ok(Literal {
236                literal_type: Some(LiteralType::Time(time_microseconds)),
237                nullable: t.nullability != Nullability::Required as i32,
238                type_variation_reference: t.type_variation_reference,
239            })
240        }
241        #[allow(deprecated)]
242        Kind::Timestamp(ts) => {
243            // Parse timestamp in ISO 8601 format: YYYY-MM-DDTHH:MM:SS[.fff] or YYYY-MM-DD HH:MM:SS[.fff]
244            let timestamp_microseconds =
245                parse_timestamp_to_microseconds(&string_value, value.as_span())?;
246            Ok(Literal {
247                literal_type: Some(LiteralType::Timestamp(timestamp_microseconds)),
248                nullable: ts.nullability != Nullability::Required as i32,
249                type_variation_reference: ts.type_variation_reference,
250            })
251        }
252        _ => {
253            // For other types, treat as string
254            Ok(Literal {
255                literal_type: Some(LiteralType::String(string_value)),
256                nullable: false,
257                type_variation_reference: 0,
258            })
259        }
260    }
261}
262
263/// Parse a date string using chrono to days since Unix epoch
264fn parse_date_to_days(date_str: &str, span: pest::Span) -> Result<i32, MessageParseError> {
265    // Try multiple date formats for flexibility
266    let formats = ["%Y-%m-%d", "%Y/%m/%d"];
267
268    for format in &formats {
269        if let Ok(date) = NaiveDate::parse_from_str(date_str, format) {
270            // Calculate days since Unix epoch (1970-01-01)
271            let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
272            let days = date.signed_duration_since(epoch).num_days();
273            return Ok(days as i32);
274        }
275    }
276
277    Err(MessageParseError {
278        message: "date_parse_format",
279        kind: ErrorKind::InvalidValue,
280        error: Box::new(pest::error::Error::new_from_span(
281            pest::error::ErrorVariant::CustomError {
282                message: format!(
283                    "Invalid date format: '{date_str}'. Expected YYYY-MM-DD or YYYY/MM/DD"
284                ),
285            },
286            span,
287        )),
288    })
289}
290
291/// Parse a time string using chrono to microseconds since midnight
292fn parse_time_to_microseconds(time_str: &str, span: pest::Span) -> Result<i64, MessageParseError> {
293    // Try multiple time formats for flexibility
294    let formats = ["%H:%M:%S%.f", "%H:%M:%S"];
295
296    for format in &formats {
297        if let Ok(time) = NaiveTime::parse_from_str(time_str, format) {
298            // Convert to microseconds since midnight
299            let midnight = NaiveTime::from_hms_opt(0, 0, 0).unwrap();
300            let duration = time.signed_duration_since(midnight);
301            return Ok(duration.num_microseconds().unwrap_or(0));
302        }
303    }
304
305    Err(MessageParseError {
306        message: "time_parse_format",
307        kind: ErrorKind::InvalidValue,
308        error: Box::new(pest::error::Error::new_from_span(
309            pest::error::ErrorVariant::CustomError {
310                message: format!(
311                    "Invalid time format: '{time_str}'. Expected HH:MM:SS or HH:MM:SS.fff"
312                ),
313            },
314            span,
315        )),
316    })
317}
318
319/// Parse a timestamp string using chrono to microseconds since Unix epoch
320fn parse_timestamp_to_microseconds(
321    timestamp_str: &str,
322    span: pest::Span,
323) -> Result<i64, MessageParseError> {
324    // Try multiple timestamp formats for flexibility
325    let formats = [
326        "%Y-%m-%dT%H:%M:%S%.f", // ISO 8601 with T and fractional seconds
327        "%Y-%m-%dT%H:%M:%S",    // ISO 8601 with T
328        "%Y-%m-%d %H:%M:%S%.f", // Space separator with fractional seconds
329        "%Y-%m-%d %H:%M:%S",    // Space separator
330        "%Y/%m/%dT%H:%M:%S%.f", // Alternative date format with T
331        "%Y/%m/%dT%H:%M:%S",    // Alternative date format with T
332        "%Y/%m/%d %H:%M:%S%.f", // Alternative date format with space
333        "%Y/%m/%d %H:%M:%S",    // Alternative date format with space
334    ];
335
336    for format in &formats {
337        if let Ok(datetime) = NaiveDateTime::parse_from_str(timestamp_str, format) {
338            // Calculate microseconds since Unix epoch (1970-01-01 00:00:00)
339            let epoch = DateTime::from_timestamp(0, 0).unwrap().naive_utc();
340            let duration = datetime.signed_duration_since(epoch);
341            return Ok(duration.num_microseconds().unwrap_or(0));
342        }
343    }
344
345    Err(MessageParseError {
346        message: "timestamp_parse_format",
347        kind: ErrorKind::InvalidValue,
348        error: Box::new(pest::error::Error::new_from_span(
349            pest::error::ErrorVariant::CustomError {
350                message: format!(
351                    "Invalid timestamp format: '{timestamp_str}'. Expected YYYY-MM-DDTHH:MM:SS or YYYY-MM-DD HH:MM:SS"
352                ),
353            },
354            span,
355        )),
356    })
357}
358
359impl ScopedParsePair for Literal {
360    fn rule() -> Rule {
361        Rule::literal
362    }
363
364    fn message() -> &'static str {
365        "Literal"
366    }
367
368    fn parse_pair(
369        extensions: &SimpleExtensions,
370        pair: pest::iterators::Pair<Rule>,
371    ) -> Result<Self, MessageParseError> {
372        assert_eq!(pair.as_rule(), Self::rule());
373        let mut pairs = pair.into_inner();
374        let value = pairs.next().unwrap(); // First item is always the value
375        let typ = pairs.next(); // Second item is optional type
376        assert!(pairs.next().is_none());
377        let typ = match typ {
378            Some(t) => Some(Type::parse_pair(extensions, t)?),
379            None => None,
380        };
381        match value.as_rule() {
382            Rule::integer => to_int_literal(value, typ),
383            Rule::float => to_float_literal(value, typ),
384            Rule::boolean => to_boolean_literal(value),
385            Rule::string_literal => to_string_literal(value, typ),
386            _ => unreachable!("Literal unexpected rule: {:?}", value.as_rule()),
387        }
388    }
389}
390
391impl ScopedParsePair for ScalarFunction {
392    fn rule() -> Rule {
393        Rule::function_call
394    }
395
396    fn message() -> &'static str {
397        "ScalarFunction"
398    }
399
400    fn parse_pair(
401        extensions: &SimpleExtensions,
402        pair: pest::iterators::Pair<Rule>,
403    ) -> Result<Self, MessageParseError> {
404        assert_eq!(pair.as_rule(), Self::rule());
405        let span = pair.as_span();
406        let mut iter = RuleIter::from(pair.into_inner());
407
408        // Parse function name (required)
409        let name = iter.parse_next::<Name>();
410
411        // Parse optional URN anchor (e.g., #1)
412        let anchor = iter
413            .try_pop(Rule::anchor)
414            .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
415
416        // Parse optional URN anchor (e.g., @1)
417        let _urn_anchor = iter
418            .try_pop(Rule::urn_anchor)
419            .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
420
421        // Parse argument list (required)
422        let argument_list = iter.pop(Rule::argument_list);
423        let mut arguments = Vec::new();
424        for e in argument_list.into_inner() {
425            arguments.push(FunctionArgument {
426                arg_type: Some(ArgType::Value(Expression::parse_pair(extensions, e)?)),
427            });
428        }
429
430        // Parse optional output type (e.g., :i64)
431        let output_type = match iter.try_pop(Rule::r#type) {
432            Some(t) => Some(Type::parse_pair(extensions, t)?),
433            None => None,
434        };
435
436        iter.done();
437        let anchor =
438            get_and_validate_anchor(extensions, ExtensionKind::Function, anchor, &name.0, span)?;
439        Ok(ScalarFunction {
440            function_reference: anchor,
441            arguments,
442            options: vec![], // TODO: Function Options
443            output_type,
444            #[allow(deprecated)]
445            args: vec![],
446        })
447    }
448}
449
450impl ScopedParsePair for Expression {
451    fn rule() -> Rule {
452        Rule::expression
453    }
454
455    fn message() -> &'static str {
456        "Expression"
457    }
458
459    fn parse_pair(
460        extensions: &SimpleExtensions,
461        pair: pest::iterators::Pair<Rule>,
462    ) -> Result<Self, MessageParseError> {
463        assert_eq!(pair.as_rule(), Self::rule());
464        let inner = unwrap_single_pair(pair);
465
466        match inner.as_rule() {
467            Rule::literal => Ok(Expression {
468                rex_type: Some(RexType::Literal(Literal::parse_pair(extensions, inner)?)),
469            }),
470            Rule::function_call => Ok(Expression {
471                rex_type: Some(RexType::ScalarFunction(ScalarFunction::parse_pair(
472                    extensions, inner,
473                )?)),
474            }),
475            Rule::reference => Ok(Expression {
476                rex_type: Some(RexType::Selection(Box::new(FieldReference::parse_pair(
477                    inner,
478                )))),
479            }),
480            _ => unimplemented!("Expression unexpected rule: {:?}", inner.as_rule()),
481        }
482    }
483}
484
485pub struct Name(pub String);
486
487impl ParsePair for Name {
488    fn rule() -> Rule {
489        Rule::name
490    }
491
492    fn message() -> &'static str {
493        "Name"
494    }
495
496    fn parse_pair(pair: pest::iterators::Pair<Rule>) -> Self {
497        assert_eq!(pair.as_rule(), Self::rule());
498        let inner = unwrap_single_pair(pair);
499        match inner.as_rule() {
500            Rule::identifier => Name(inner.as_str().to_string()),
501            Rule::quoted_name => Name(unescape_string(inner)),
502            _ => unreachable!("Name unexpected rule: {:?}", inner.as_rule()),
503        }
504    }
505}
506
507impl ScopedParsePair for Measure {
508    fn rule() -> Rule {
509        Rule::aggregate_measure
510    }
511
512    fn message() -> &'static str {
513        "Measure"
514    }
515
516    fn parse_pair(
517        extensions: &SimpleExtensions,
518        pair: pest::iterators::Pair<Rule>,
519    ) -> Result<Self, MessageParseError> {
520        assert_eq!(pair.as_rule(), Self::rule());
521
522        // Extract the inner function_call from aggregate_measure
523        let function_call_pair = unwrap_single_pair(pair);
524        assert_eq!(function_call_pair.as_rule(), Rule::function_call);
525
526        // Parse as ScalarFunction, then convert to AggregateFunction
527        let scalar = ScalarFunction::parse_pair(extensions, function_call_pair)?;
528        Ok(Measure {
529            measure: Some(AggregateFunction {
530                function_reference: scalar.function_reference,
531                arguments: scalar.arguments,
532                options: scalar.options,
533                output_type: scalar.output_type,
534                invocation: 0, // TODO: support invocation (ALL, DISTINCT, etc.)
535                phase: 0, // TODO: support phase (INITIAL_TO_RESULT, PARTIAL_TO_INTERMEDIATE, etc.)
536                sorts: vec![], // TODO: support sorts for ordered aggregates
537                #[allow(deprecated)]
538                args: scalar.args,
539            }),
540            filter: None, // TODO: support filter conditions on aggregate measures
541        })
542    }
543}
544
545#[cfg(test)]
546mod tests {
547    use pest::Parser as PestParser;
548
549    use super::*;
550    use crate::parser::ExpressionParser;
551
552    fn parse_exact(rule: Rule, input: &str) -> pest::iterators::Pair<Rule> {
553        let mut pairs = ExpressionParser::parse(rule, input).unwrap();
554        assert_eq!(pairs.as_str(), input);
555        let pair = pairs.next().unwrap();
556        assert_eq!(pairs.next(), None);
557        pair
558    }
559
560    fn assert_parses_to<T: ParsePair + PartialEq + std::fmt::Debug>(input: &str, expected: T) {
561        let pair = parse_exact(T::rule(), input);
562        let actual = T::parse_pair(pair);
563        assert_eq!(actual, expected);
564    }
565
566    fn assert_parses_with<T: ScopedParsePair + PartialEq + std::fmt::Debug>(
567        ext: &SimpleExtensions,
568        input: &str,
569        expected: T,
570    ) {
571        let pair = parse_exact(T::rule(), input);
572        let actual = T::parse_pair(ext, pair).unwrap();
573        assert_eq!(actual, expected);
574    }
575
576    #[test]
577    fn test_parse_field_reference() {
578        assert_parses_to("$1", FieldIndex(1).to_field_reference());
579    }
580
581    #[test]
582    fn test_parse_integer_literal() {
583        let extensions = SimpleExtensions::default();
584        let expected = Literal {
585            literal_type: Some(LiteralType::I64(1)),
586            nullable: false,
587            type_variation_reference: 0,
588        };
589        assert_parses_with(&extensions, "1", expected);
590    }
591
592    #[test]
593    fn test_parse_float_literal() {
594        // First test that the grammar can parse floats
595        let pairs = ExpressionParser::parse(Rule::float, "3.82").unwrap();
596        let parsed_text = pairs.as_str();
597        assert_eq!(parsed_text, "3.82");
598
599        let extensions = SimpleExtensions::default();
600        let expected = Literal {
601            literal_type: Some(LiteralType::Fp64(3.82)),
602            nullable: false,
603            type_variation_reference: 0,
604        };
605        assert_parses_with(&extensions, "3.82", expected);
606    }
607
608    #[test]
609    fn test_parse_negative_float_literal() {
610        let extensions = SimpleExtensions::default();
611        let expected = Literal {
612            literal_type: Some(LiteralType::Fp64(-2.5)),
613            nullable: false,
614            type_variation_reference: 0,
615        };
616        assert_parses_with(&extensions, "-2.5", expected);
617    }
618
619    #[test]
620    fn test_parse_boolean_true_literal() {
621        let extensions = SimpleExtensions::default();
622        let expected = Literal {
623            literal_type: Some(LiteralType::Boolean(true)),
624            nullable: false,
625            type_variation_reference: 0,
626        };
627        assert_parses_with(&extensions, "true", expected);
628    }
629
630    #[test]
631    fn test_parse_boolean_false_literal() {
632        let extensions = SimpleExtensions::default();
633        let expected = Literal {
634            literal_type: Some(LiteralType::Boolean(false)),
635            nullable: false,
636            type_variation_reference: 0,
637        };
638        assert_parses_with(&extensions, "false", expected);
639    }
640
641    #[test]
642    fn test_parse_float_literal_with_fp32_type() {
643        let extensions = SimpleExtensions::default();
644        let pair = parse_exact(Rule::literal, "3.82:fp32");
645        let result = Literal::parse_pair(&extensions, pair).unwrap();
646
647        match result.literal_type {
648            Some(LiteralType::Fp32(val)) => assert!((val - 3.82).abs() < f32::EPSILON),
649            _ => panic!("Expected Fp32 literal type"),
650        }
651    }
652
653    #[test]
654    fn test_parse_date_literal() {
655        let extensions = SimpleExtensions::default();
656        let pair = parse_exact(Rule::literal, "'2023-12-25':date");
657        let result = Literal::parse_pair(&extensions, pair).unwrap();
658
659        match result.literal_type {
660            Some(LiteralType::Date(days)) => {
661                // 2023-12-25 should be a positive number of days since 1970-01-01
662                assert!(
663                    days > 0,
664                    "Expected positive days since epoch, got: {}",
665                    days
666                );
667            }
668            _ => panic!("Expected Date literal type, got: {:?}", result.literal_type),
669        }
670    }
671
672    #[test]
673    fn test_parse_time_literal() {
674        let extensions = SimpleExtensions::default();
675        let pair = parse_exact(Rule::literal, "'14:30:45':time");
676        let result = Literal::parse_pair(&extensions, pair).unwrap();
677
678        match result.literal_type {
679            Some(LiteralType::Time(microseconds)) => {
680                // 14:30:45 = (14*3600 + 30*60 + 45) * 1_000_000 microseconds
681                let expected = (14 * 3600 + 30 * 60 + 45) * 1_000_000;
682                assert_eq!(microseconds, expected);
683            }
684            _ => panic!("Expected Time literal type, got: {:?}", result.literal_type),
685        }
686    }
687
688    #[test]
689    fn test_parse_timestamp_literal_with_t() {
690        let extensions = SimpleExtensions::default();
691        let pair = parse_exact(Rule::literal, "'2023-01-01T12:00:00':timestamp");
692        let result = Literal::parse_pair(&extensions, pair).unwrap();
693
694        match result.literal_type {
695            #[allow(deprecated)]
696            Some(LiteralType::Timestamp(microseconds)) => {
697                assert!(
698                    microseconds > 0,
699                    "Expected positive microseconds since epoch"
700                );
701            }
702            _ => panic!(
703                "Expected Timestamp literal type, got: {:?}",
704                result.literal_type
705            ),
706        }
707    }
708
709    #[test]
710    fn test_parse_timestamp_literal_with_space() {
711        let extensions = SimpleExtensions::default();
712        let pair = parse_exact(Rule::literal, "'2023-01-01 12:00:00':timestamp");
713        let result = Literal::parse_pair(&extensions, pair).unwrap();
714
715        match result.literal_type {
716            #[allow(deprecated)]
717            Some(LiteralType::Timestamp(microseconds)) => {
718                assert!(
719                    microseconds > 0,
720                    "Expected positive microseconds since epoch"
721                );
722            }
723            _ => panic!(
724                "Expected Timestamp literal type, got: {:?}",
725                result.literal_type
726            ),
727        }
728    }
729
730    // #[test]
731    // fn test_parse_string_literal() {
732    //     assert_parses_to("'hello'", Literal::String("hello".to_string()));
733    // }
734
735    // #[test]
736    // fn test_parse_function_call_simple() {
737    //     assert_parses_to(
738    //         "add()",
739    //         FunctionCall {
740    //             name: "add".to_string(),
741    //             parameters: None,
742    //             anchor: None,
743    //             urn_anchor: None,
744    //             arguments: vec![],
745    //         },
746    //     );
747    // }
748
749    // #[test]
750    // fn test_parse_function_call_with_parameters() {
751    //     assert_parses_to(
752    //         "add<param1, param2>()",
753    //         FunctionCall {
754    //             name: "add".to_string(),
755    //             parameters: Some(vec!["param1".to_string(), "param2".to_string()]),
756    //             anchor: None,
757    //             urn_anchor: None,
758    //             arguments: vec![],
759    //         },
760    //     );
761    // }
762
763    // #[test]
764    // fn test_parse_function_call_with_anchor() {
765    //     assert_parses_to(
766    //         "add#1()",
767    //         FunctionCall {
768    //             name: "add".to_string(),
769    //             parameters: None,
770    //             anchor: Some(1),
771    //             urn_anchor: None,
772    //             arguments: vec![],
773    //         },
774    //     );
775    // }
776
777    // #[test]
778    // fn test_parse_function_call_with_urn_anchor() {
779    //     assert_parses_to(
780    //         "add@1()",
781    //         FunctionCall {
782    //             name: "add".to_string(),
783    //             parameters: None,
784    //             anchor: None,
785    //             urn_anchor: Some(1),
786    //             arguments: vec![],
787    //         },
788    //     );
789    // }
790
791    // #[test]
792    // fn test_parse_function_call_all_optionals() {
793    //     assert_parses_to(
794    //         "add<param1, param2>#1@2()",
795    //         FunctionCall {
796    //             name: "add".to_string(),
797    //             parameters: Some(vec!["param1".to_string(), "param2".to_string()]),
798    //             anchor: Some(1),
799    //             urn_anchor: Some(2),
800    //             arguments: vec![],
801    //         },
802    //     );
803    // }
804
805    // #[test]
806    // fn test_parse_function_call_with_simple_arguments() {
807    //     assert_parses_to(
808    //         "add(1, 2)",
809    //         FunctionCall {
810    //             name: "add".to_string(),
811    //             parameters: None,
812    //             anchor: None,
813    //             urn_anchor: None,
814    //             arguments: vec![
815    //                 Expression::Literal(Literal::Integer(1)),
816    //                 Expression::Literal(Literal::Integer(2)),
817    //             ],
818    //         },
819    //     );
820    // }
821
822    // #[test]
823    // fn test_parse_function_call_with_nested_function() {
824    //     assert_parses_to(
825    //         "outer_func(inner_func(), $1)",
826    //         Expression::FunctionCall(Box::new(FunctionCall {
827    //             name: "outer_func".to_string(),
828    //             parameters: None,
829    //             anchor: None,
830    //             urn_anchor: None,
831    //             arguments: vec![
832    //                 Expression::FunctionCall(Box::new(FunctionCall {
833    //                     name: "inner_func".to_string(),
834    //                     parameters: None,
835    //                     anchor: None,
836    //                     urn_anchor: None,
837    //                     arguments: vec![],
838    //                 })),
839    //                 Expression::Reference(Reference(1)),
840    //             ],
841    //         })),
842    //     );
843    // }
844
845    // #[test]
846    // fn test_parse_function_call_funny_names() {
847    //     assert_parses_to(
848    //         "'funny name'<param1, param2>#1@2()",
849    //         FunctionCall {
850    //             name: "funny name".to_string(),
851    //             parameters: Some(vec!["param1".to_string(), "param2".to_string()]),
852    //             anchor: Some(1),
853    //             urn_anchor: Some(2),
854    //             arguments: vec![],
855    //         },
856    //     );
857    // }
858
859    // #[test]
860    // fn test_parse_empty_string_literal() {
861    //     assert_parses_to("''", Literal::String("".to_string()));
862    // }
863}