Skip to content

Commit 048f2e6

Browse files
authored
chore: improve legacy iso parsing (#8581)
* chore: improve legacy iso parsing * Add parser for legacy TimeRange * self review
1 parent 9797b6b commit 048f2e6

File tree

3 files changed

+337
-174
lines changed

3 files changed

+337
-174
lines changed

runtime/metricsview/executor/executor_rewrite_time.go

Lines changed: 22 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"time"
88

99
"github.com/rilldata/rill/runtime/metricsview"
10-
"github.com/rilldata/rill/runtime/pkg/duration"
1110
"github.com/rilldata/rill/runtime/pkg/rilltime"
1211
"github.com/rilldata/rill/runtime/pkg/timeutil"
1312
)
@@ -113,9 +112,12 @@ func (e *Executor) resolveTimeRange(ctx context.Context, tr *metricsview.TimeRan
113112

114113
// resolveISOTimeRange resolves the given time range where either only start/end is specified along with ISO duration/offset, ensuring only its Start and End properties are populated.
115114
func (e *Executor) resolveISOTimeRange(ctx context.Context, tr *metricsview.TimeRange, tz *time.Location, executionTime *time.Time) error {
115+
var ts metricsview.TimestampsResult
116+
var err error
117+
116118
if tr.Start.IsZero() && tr.End.IsZero() {
117119
if executionTime == nil {
118-
ts, err := e.Timestamps(ctx, tr.TimeDimension)
120+
ts, err = e.Timestamps(ctx, tr.TimeDimension)
119121
if err != nil {
120122
return fmt.Errorf("failed to fetch timestamps: %w", err)
121123
}
@@ -125,65 +127,30 @@ func (e *Executor) resolveISOTimeRange(ctx context.Context, tr *metricsview.Time
125127
tr.End = *executionTime
126128
}
127129

128-
var isISO bool
129130
if tr.IsoDuration != "" {
130-
d, err := duration.ParseISO8601(tr.IsoDuration)
131-
if err != nil {
132-
return fmt.Errorf("invalid iso_duration %q: %w", tr.IsoDuration, err)
133-
}
134-
135-
if !tr.Start.IsZero() && !tr.End.IsZero() {
136-
return errors.New(`cannot resolve "iso_duration" for a time range with fixed "start" and "end" timestamps`)
137-
} else if !tr.Start.IsZero() {
138-
tr.End = d.Add(tr.Start)
139-
} else if !tr.End.IsZero() {
140-
tr.Start = d.Sub(tr.End)
141-
} else {
142-
// In practice, this shouldn't happen since we resolve a time anchor dynamically if both start and end are zero.
143-
return errors.New(`cannot resolve "iso_duration" for a time range without "start" and "end" timestamps`)
144-
}
145-
146-
isISO = true
147-
}
148-
149-
if tr.IsoOffset != "" {
150-
d, err := duration.ParseISO8601(tr.IsoOffset)
131+
rt, err := rilltime.ParseLegacy(tr.IsoDuration, tr.IsoOffset, tr.RoundToGrain.ToTimeutil(), rilltime.ParseOptions{
132+
DefaultTimeZone: tz,
133+
SmallestGrain: timeutil.TimeGrainFromAPI(e.metricsView.SmallestTimeGrain),
134+
})
151135
if err != nil {
152-
return fmt.Errorf("invalid iso_offset %q: %w", tr.IsoOffset, err)
153-
}
154-
155-
if !tr.Start.IsZero() {
156-
tr.Start = d.Sub(tr.Start)
136+
return err
157137
}
158-
if !tr.End.IsZero() {
159-
tr.End = d.Sub(tr.End)
160-
}
161-
162-
isISO = true
163-
}
164138

165-
// Only modify the start and end if ISO duration or offset was sent.
166-
// This is to maintain backwards compatibility for calls from the UI.
167-
if isISO {
168-
fdow := int(e.metricsView.FirstDayOfWeek)
169-
if fdow > 7 || fdow <= 0 {
170-
fdow = 1
171-
}
172-
fmoy := int(e.metricsView.FirstMonthOfYear)
173-
if fmoy > 12 || fmoy <= 0 {
174-
fmoy = 1
175-
}
176-
if !tr.RoundToGrain.Valid() {
177-
return fmt.Errorf("invalid time grain %q", tr.RoundToGrain)
178-
}
179-
if tr.RoundToGrain != metricsview.TimeGrainUnspecified {
180-
if !tr.Start.IsZero() {
181-
tr.Start = timeutil.TruncateTime(tr.Start, tr.RoundToGrain.ToTimeutil(), tz, fdow, fmoy)
182-
}
183-
if !tr.End.IsZero() {
184-
tr.End = timeutil.TruncateTime(tr.End, tr.RoundToGrain.ToTimeutil(), tz, fdow, fmoy)
139+
if ts.Now.IsZero() {
140+
ts, err = e.Timestamps(ctx, tr.TimeDimension)
141+
if err != nil {
142+
return fmt.Errorf("failed to fetch timestamps: %w", err)
185143
}
186144
}
145+
146+
tr.Start, tr.End, _ = rt.Eval(rilltime.EvalOptions{
147+
Now: ts.Now,
148+
MinTime: ts.Min,
149+
MaxTime: ts.Max,
150+
Watermark: tr.End,
151+
FirstDay: int(e.metricsView.FirstDayOfWeek),
152+
FirstMonth: int(e.metricsView.FirstMonthOfYear),
153+
})
187154
}
188155

189156
// Clear all other fields than Start and End

0 commit comments

Comments
 (0)