Skip to content

Commit

Permalink
Support timezone offsets for queries
Browse files Browse the repository at this point in the history
The timezone for a query can now be added to the end with something like
`TZ("America/Los_Angeles")` and it will localize the results of the
query to be in that timezone. The offset will automatically be set to
the offset for that timezone and offsets will automatically adjust for
daylight savings time so grouping by a day will result in a 25 hour day
once a year and a 23 hour day another day of the year.

The automatic adjustment of intervals for timezone offsets changing will
only happen if the group by period is greater than the timezone offset
would be. That means grouping by an hour or less will not be affected by
daylight savings time, but a 2 hour or 1 day interval will be.

The default timezone is UTC and existing queries are unaffected by this
change.

When times are returned as strings (when `epoch=1` is not used), the
results will be returned using the requested timezone format in RFC3339
format.
  • Loading branch information
jsternberg committed Mar 20, 2017
1 parent 4b5b47d commit 4f3d241
Show file tree
Hide file tree
Showing 15 changed files with 705 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [#7856](https://github.com/influxdata/influxdb/issues/7856): Failed points during an import now result in a non-zero exit code.
- [#7821](https://github.com/influxdata/influxdb/issues/7821): Expose some configuration settings via SHOW DIAGNOSTICS
- [#8025](https://github.com/influxdata/influxdb/issues/8025): Support single and multiline comments in InfluxQL.
- [#6541](https://github.com/influxdata/influxdb/issues/6541): Support timezone offsets for queries.

### Bugfixes

Expand Down
3 changes: 3 additions & 0 deletions coordinator/statement_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,9 @@ func (e *StatementExecutor) executeSelectStatement(stmt *influxql.SelectStatemen
// Generate a row emitter from the iterator set.
em := influxql.NewEmitter(itrs, stmt.TimeAscending(), ctx.ChunkSize)
em.Columns = stmt.ColumnNames()
if stmt.Location != nil {
em.Location = stmt.Location
}
em.OmitTime = stmt.OmitTime
defer em.Close()

Expand Down
8 changes: 7 additions & 1 deletion influxql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,8 @@ REVOKE READ ON "mydb" FROM "jdoe"
```
select_stmt = "SELECT" fields from_clause [ into_clause ] [ where_clause ]
[ group_by_clause ] [ order_by_clause ] [ limit_clause ]
[ offset_clause ] [ slimit_clause ] [ soffset_clause ] .
[ offset_clause ] [ slimit_clause ] [ soffset_clause ]
[ timezone_clause ] .
```

#### Examples:
Expand All @@ -798,6 +799,9 @@ SELECT mean("value") FROM "cpu" WHERE "region" = 'uswest' GROUP BY time(10m) fil

-- select from all measurements beginning with cpu into the same measurement name in the cpu_1h retention policy
SELECT mean("value") INTO "cpu_1h".:MEASUREMENT FROM /cpu.*/

-- select from measurements grouped by the day with a timezone
SELECT mean("value") FROM "cpu" GROUP BY region, time(1d) fill(0) tz("America/Chicago")
```

## Clauses
Expand All @@ -817,6 +821,8 @@ slimit_clause = "SLIMIT" int_lit .
soffset_clause = "SOFFSET" int_lit .
timezone_clause = tz(identifier) .
on_clause = "ON" db_name .
order_by_clause = "ORDER BY" sort_fields .
Expand Down
6 changes: 6 additions & 0 deletions influxql/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,9 @@ type SelectStatement struct {
// The value to fill empty aggregate buckets with, if any.
FillValue interface{}

// The timezone for the query, if any.
Location *time.Location

// Renames the implicit time field name.
TimeAlias string

Expand Down Expand Up @@ -1650,6 +1653,9 @@ func (s *SelectStatement) String() string {
if s.SOffset > 0 {
_, _ = fmt.Fprintf(&buf, " SOFFSET %d", s.SOffset)
}
if s.Location != nil {
_, _ = fmt.Fprintf(&buf, ` TZ("%s")`, s.Location)
}
return buf.String()
}

Expand Down
6 changes: 5 additions & 1 deletion influxql/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type Emitter struct {
// The columns to attach to each row.
Columns []string

// The time zone location.
Location *time.Location

// Removes the "time" column from output.
// Used for meta queries where time does not apply.
OmitTime bool
Expand All @@ -32,6 +35,7 @@ func NewEmitter(itrs []Iterator, ascending bool, chunkSize int) *Emitter {
itrs: itrs,
ascending: ascending,
chunkSize: chunkSize,
Location: time.UTC,
}
}

Expand Down Expand Up @@ -154,7 +158,7 @@ func (e *Emitter) readAt(t int64, name string, tags Tags) []interface{} {

values := make([]interface{}, len(e.itrs)+offset)
if !e.OmitTime {
values[0] = time.Unix(0, t).UTC()
values[0] = time.Unix(0, t).In(e.Location)
}
e.readInto(t, name, tags, values[offset:])
return values
Expand Down
94 changes: 55 additions & 39 deletions influxql/internal/internal.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions influxql/internal/internal.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ message IteratorOptions {
optional string Condition = 8;
optional int64 StartTime = 9;
optional int64 EndTime = 10;
optional string Location = 21;
optional bool Ascending = 11;
optional int64 Limit = 12;
optional int64 Offset = 13;
Expand Down
Loading

0 comments on commit 4f3d241

Please sign in to comment.