Skip to content
Draft
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f95c2a8
Add capability and YAML tests for request and SET time_zone parameters
ivancea Oct 17, 2025
569d9e5
Add SET CSV tests, and adapted CsvTests to work with SET statements
ivancea Oct 17, 2025
cc15c9f
Escape ; in csv tests with backslash
ivancea Oct 17, 2025
449abe6
Randomize configuration in function tests, and make it static for the…
ivancea Oct 17, 2025
5dec7c3
[CI] Auto commit changes from spotless
Oct 17, 2025
fedbf4f
Merge branch 'main' into esql-time-zone-tests
ivancea Oct 27, 2025
b088abf
Moved custom config cases to another method
ivancea Oct 27, 2025
ee1316c
Add comment on function with config dserialization randomization
ivancea Oct 27, 2025
13d8b4b
Fix multi cluster tests to accept SET statements
ivancea Oct 27, 2025
d794329
Merge branch 'main' into esql-time-zone-tests
ivancea Oct 27, 2025
2713280
Fix configuration and source matching in random tests
ivancea Oct 28, 2025
f76f5ec
Added function tests for timezones
ivancea Oct 28, 2025
9005c78
Fix typo
ivancea Oct 28, 2025
fad189f
Fixed capability requirement
ivancea Oct 28, 2025
4f62f23
Fix ScalbTests
ivancea Oct 28, 2025
4c5adc0
[CI] Auto commit changes from spotless
Oct 28, 2025
3f233bf
Add configuration to DATE_TRUNC and related functions
ivancea Oct 28, 2025
d81729b
Merge branch 'main' into esql-time-zone-tests
ivancea Oct 29, 2025
8b8a115
Merge branch 'esql-time-zone-tests' into esql-datetrunc-timezone
ivancea Oct 29, 2025
a11d4b8
Merge branch 'main' into esql-datetrunc-timezone
ivancea Oct 29, 2025
ebd00dd
Added a ConfigurationFUnction interface and fixed tests with static c…
ivancea Oct 29, 2025
de30da7
WIP: Initial DateTrunc unit tests
ivancea Oct 29, 2025
dcce704
Reuse DateTrunc tests in Bucket and TBucket
ivancea Oct 30, 2025
24e99c1
Added unit tests for timezones
ivancea Oct 31, 2025
dd523d5
Extracted matchers
ivancea Oct 31, 2025
ad32a98
Moved matchers to a common place
ivancea Oct 31, 2025
539b7a7
Extracted date_trunc csv tests to date
ivancea Oct 31, 2025
5053983
Update docs/changelog/137450.yaml
ivancea Oct 31, 2025
a75301c
Fix benchmark
ivancea Oct 31, 2025
7e5c01d
Added CSV tests for timezones on affected functions
ivancea Oct 31, 2025
544c4cf
Fixed Rounding builders being reused
ivancea Oct 31, 2025
e499df4
Use DateTrunc zoneId instead of configuration in rule
ivancea Oct 31, 2025
205a15c
Undo roundings test
ivancea Oct 31, 2025
46debec
Fix tests
ivancea Oct 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,12 @@ private static EvalOperator.ExpressionEvaluator evaluator(String operation) {
);
yield EvalMapper.toEvaluator(
FOLD_CONTEXT,
new DateTrunc(Source.EMPTY, new Literal(Source.EMPTY, Duration.ofHours(24), DataType.TIME_DURATION), timestamp),
new DateTrunc(
Source.EMPTY,
new Literal(Source.EMPTY, Duration.ofHours(24), DataType.TIME_DURATION),
timestamp,
configuration()
),
layout(timestamp)
).get(driverContext);
}
Expand Down
5 changes: 5 additions & 0 deletions docs/changelog/137450.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 137450
summary: "Timezone support in DATE_TRUNC, BUCKET and TBUCKET"
area: ES|QL
type: feature
issues: []
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this class for testing purposes, as working with random configurations "with just a single fixed field" was a bit painful. I'm listening for opinions here!

Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.esql;

import org.elasticsearch.xpack.esql.plugin.QueryPragmas;
import org.elasticsearch.xpack.esql.session.Configuration;

import java.time.ZoneId;
import java.util.Locale;
import java.util.Map;

/**
* Builder to modify configurations on tests.
* <p>
* The {@link Configuration#now()} field is actually modified, so built configurations will also differ there.
* </p>
*/
public class ConfigurationBuilder {

private String clusterName;
private String username;
private ZoneId zoneId;

private QueryPragmas pragmas;

private int resultTruncationMaxSizeRegular;
private int resultTruncationDefaultSizeRegular;
private int resultTruncationMaxSizeTimeseries;
private int resultTruncationDefaultSizeTimeseries;

private Locale locale;

private String query;

private boolean profile;
private boolean allowPartialResults;

private Map<String, Map<String, Column>> tables;
private long queryStartTimeNanos;

public ConfigurationBuilder(Configuration configuration) {
clusterName = configuration.clusterName();
username = configuration.username();
zoneId = configuration.zoneId();
pragmas = configuration.pragmas();
resultTruncationMaxSizeRegular = configuration.resultTruncationMaxSize(false);
resultTruncationDefaultSizeRegular = configuration.resultTruncationDefaultSize(false);
resultTruncationMaxSizeTimeseries = configuration.resultTruncationMaxSize(true);
resultTruncationDefaultSizeTimeseries = configuration.resultTruncationDefaultSize(true);
locale = configuration.locale();
query = configuration.query();
profile = configuration.profile();
allowPartialResults = configuration.allowPartialResults();
tables = configuration.tables();
queryStartTimeNanos = configuration.queryStartTimeNanos();
}

public ConfigurationBuilder clusterName(String clusterName) {
this.clusterName = clusterName;
return this;
}

public ConfigurationBuilder username(String username) {
this.username = username;
return this;
}

public ConfigurationBuilder zoneId(ZoneId zoneId) {
this.zoneId = zoneId;
return this;
}

public ConfigurationBuilder pragmas(QueryPragmas pragmas) {
this.pragmas = pragmas;
return this;
}

public ConfigurationBuilder resultTruncationMaxSizeRegular(int resultTruncationMaxSizeRegular) {
this.resultTruncationMaxSizeRegular = resultTruncationMaxSizeRegular;
return this;
}

public ConfigurationBuilder resultTruncationDefaultSizeRegular(int resultTruncationDefaultSizeRegular) {
this.resultTruncationDefaultSizeRegular = resultTruncationDefaultSizeRegular;
return this;
}

public ConfigurationBuilder resultTruncationMaxSizeTimeseries(int resultTruncationMaxSizeTimeseries) {
this.resultTruncationMaxSizeTimeseries = resultTruncationMaxSizeTimeseries;
return this;
}

public ConfigurationBuilder resultTruncationDefaultSizeTimeseries(int resultTruncationDefaultSizeTimeseries) {
this.resultTruncationDefaultSizeTimeseries = resultTruncationDefaultSizeTimeseries;
return this;
}

public ConfigurationBuilder locale(Locale locale) {
this.locale = locale;
return this;
}

public ConfigurationBuilder query(String query) {
this.query = query;
return this;
}

public ConfigurationBuilder profile(boolean profile) {
this.profile = profile;
return this;
}

public ConfigurationBuilder allowPartialResults(boolean allowPartialResults) {
this.allowPartialResults = allowPartialResults;
return this;
}

public ConfigurationBuilder tables(Map<String, Map<String, Column>> tables) {
this.tables = tables;
return this;
}

public ConfigurationBuilder queryStartTimeNanos(long queryStartTimeNanos) {
this.queryStartTimeNanos = queryStartTimeNanos;
return this;
}

public Configuration build() {
return new Configuration(
zoneId,
locale,
username,
clusterName,
pragmas,
resultTruncationMaxSizeRegular,
resultTruncationDefaultSizeRegular,
query,
profile,
tables,
queryStartTimeNanos,
allowPartialResults,
resultTruncationMaxSizeTimeseries,
resultTruncationDefaultSizeTimeseries
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import static org.elasticsearch.test.ESTestCase.randomRealisticUnicodeOfLength;
import static org.elasticsearch.test.ESTestCase.randomZone;
import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral;
import static org.elasticsearch.xpack.esql.EsqlTestUtils.tables;
import static org.elasticsearch.xpack.esql.session.Configuration.QUERY_COMPRESS_THRESHOLD_CHARS;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -988,3 +988,22 @@ COUNT(*):long | bucket:datetime
1 | 1986-07-09T00:00:00.000Z
1 | 1986-09-17T00:00:00.000Z
;

bucketWithTimezone
required_capability: date_trunc_timezone_support

SET time_zone = "+05:00"\;
FROM employees
| WHERE hire_date >= "1980-01-01T00:00:00Z"
| STATS by hire_date, bucketHours = BUCKET(hire_date, 3 hours), bucketDay = BUCKET(hire_date, 1 day)
| SORT hire_date
| LIMIT 5
;

hire_date:date | bucketHours:date | bucketDay:date
1985-02-18T00:00:00.000Z | 1985-02-17T22:00:00.000Z | 1985-02-17T19:00:00.000Z
1985-02-24T00:00:00.000Z | 1985-02-23T22:00:00.000Z | 1985-02-23T19:00:00.000Z
1985-05-13T00:00:00.000Z | 1985-05-12T22:00:00.000Z | 1985-05-12T19:00:00.000Z
1985-07-09T00:00:00.000Z | 1985-07-08T22:00:00.000Z | 1985-07-08T19:00:00.000Z
1985-09-17T00:00:00.000Z | 1985-09-16T22:00:00.000Z | 1985-09-16T19:00:00.000Z
;
Loading