VisitTemporalOperator visits a parse tree produced by MangleParser#temporalOperator. Returns an *ast.TemporalOperator.
(ctx *gen.TemporalOperatorContext)
| 851 | // VisitTemporalOperator visits a parse tree produced by MangleParser#temporalOperator. |
| 852 | // Returns an *ast.TemporalOperator. |
| 853 | func (p Parser) VisitTemporalOperator(ctx *gen.TemporalOperatorContext) any { |
| 854 | bounds := ctx.AllTemporalBound() |
| 855 | if len(bounds) != 2 { |
| 856 | p.errors.Add("temporal operator requires exactly two bounds", ctx.GetStart().GetLine(), ctx.GetStart().GetColumn()) |
| 857 | return nil |
| 858 | } |
| 859 | |
| 860 | // Check for negative durations in temporal operator bounds. |
| 861 | // The temporal operator determines direction (past/future), not the duration sign. |
| 862 | // Negative durations are rejected to avoid confusion. |
| 863 | for _, boundCtx := range bounds { |
| 864 | if dur := boundCtx.(*gen.TemporalBoundContext).DURATION(); dur != nil { |
| 865 | text := dur.GetText() |
| 866 | if strings.HasPrefix(text, "-") { |
| 867 | p.errors.Add( |
| 868 | fmt.Sprintf("negative duration %q not allowed in temporal operator; use the operator type to indicate direction (e.g., <-[...] for past, <+[...] for future)", text), |
| 869 | boundCtx.GetStart().GetLine(), boundCtx.GetStart().GetColumn()) |
| 870 | } |
| 871 | } |
| 872 | } |
| 873 | |
| 874 | start := p.Visit(bounds[0]).(ast.TemporalBound) |
| 875 | end := p.Visit(bounds[1]).(ast.TemporalBound) |
| 876 | interval := ast.NewInterval(start, end) |
| 877 | |
| 878 | var opType ast.TemporalOperatorType |
| 879 | if ctx.DIAMONDMINUS() != nil { |
| 880 | opType = ast.DiamondMinus |
| 881 | } else if ctx.BOXMINUS() != nil { |
| 882 | opType = ast.BoxMinus |
| 883 | } else if ctx.DIAMONDPLUS() != nil { |
| 884 | opType = ast.DiamondPlus |
| 885 | } else if ctx.BOXPLUS() != nil { |
| 886 | opType = ast.BoxPlus |
| 887 | } else { |
| 888 | p.errors.Add("unknown temporal operator", ctx.GetStart().GetLine(), ctx.GetStart().GetColumn()) |
| 889 | return nil |
| 890 | } |
| 891 | |
| 892 | return &ast.TemporalOperator{ |
| 893 | Type: opType, |
| 894 | Interval: interval, |
| 895 | } |
| 896 | } |
| 897 | |
| 898 | // parseTimestamp parses a timestamp string in ISO 8601 format. |
| 899 | func parseTimestamp(s string) (time.Time, error) { |
no test coverage detected