Skip to content

Commit 4797347

Browse files
committed
SQL: [Tests] Add integ tests for timezone and pagination (#52101)
Cherry pick and adapt tests to validate correct behaviour regarding processing of results that involve the use of the client configured timezone by the HitExtractors when paginating over the results of the query (use of cursors). (cherry picked from commit 8f7afbd)
1 parent 3976770 commit 4797347

File tree

2 files changed

+129
-1
lines changed

2 files changed

+129
-1
lines changed

x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java

+55
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@
99
import org.elasticsearch.common.Strings;
1010
import org.elasticsearch.common.xcontent.XContentBuilder;
1111
import org.elasticsearch.common.xcontent.json.JsonXContent;
12+
import org.elasticsearch.xpack.sql.proto.StringUtils;
1213
import org.junit.Before;
1314

1415
import java.io.IOException;
1516
import java.sql.Connection;
1617
import java.sql.ResultSet;
1718
import java.sql.SQLException;
1819
import java.sql.Statement;
20+
import java.time.Instant;
21+
import java.time.ZoneId;
22+
import java.time.ZonedDateTime;
23+
import java.util.Properties;
1924

25+
import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.JDBC_TIMEZONE;
2026
import static org.elasticsearch.xpack.sql.qa.rest.RestSqlTestCase.assertNoSearchContexts;
2127

2228
/**
@@ -106,6 +112,55 @@ public void testIncompleteScroll() throws Exception {
106112
assertNoSearchContexts();
107113
}
108114

115+
public void testScrollWithDatetimeAndTimezoneParam() throws IOException, SQLException {
116+
Request request = new Request("PUT", "/test_date_timezone");
117+
XContentBuilder createIndex = JsonXContent.contentBuilder().startObject();
118+
createIndex.startObject("mappings");
119+
{
120+
createIndex.startObject("_doc");
121+
{
122+
createIndex.startObject("properties");
123+
{
124+
createIndex.startObject("date").field("type", "date").field("format", "epoch_millis");
125+
createIndex.endObject();
126+
}
127+
createIndex.endObject();
128+
}
129+
createIndex.endObject();
130+
}
131+
createIndex.endObject().endObject();
132+
request.setJsonEntity(Strings.toString(createIndex));
133+
client().performRequest(request);
134+
135+
request = new Request("PUT", "/test_date_timezone/_doc/_bulk");
136+
request.addParameter("refresh", "true");
137+
StringBuilder bulk = new StringBuilder();
138+
long[] datetimes = new long[] { 1_000, 10_000, 100_000, 1_000_000, 10_000_000 };
139+
for (long datetime : datetimes) {
140+
bulk.append("{\"index\":{}}\n");
141+
bulk.append("{\"date\":").append(datetime).append("}\n");
142+
}
143+
request.setJsonEntity(bulk.toString());
144+
assertEquals(200, client().performRequest(request).getStatusLine().getStatusCode());
145+
146+
ZoneId zoneId = randomZone();
147+
Properties connectionProperties = connectionProperties();
148+
connectionProperties.put(JDBC_TIMEZONE, zoneId.toString());
149+
try (Connection c = esJdbc(connectionProperties);
150+
Statement s = c.createStatement()) {
151+
s.setFetchSize(2);
152+
try (ResultSet rs =
153+
s.executeQuery("SELECT CAST(date AS string) AS date FROM test_date_timezone ORDER BY date")) {
154+
for (int i = 0; i < datetimes.length; i++) {
155+
assertEquals(2, rs.getFetchSize());
156+
assertTrue("No more entries left at " + i, rs.next());
157+
assertEquals(StringUtils.toString(ZonedDateTime.ofInstant(Instant.ofEpochMilli(datetimes[i]), zoneId)),
158+
rs.getString(1));
159+
}
160+
assertFalse(rs.next());
161+
}
162+
}
163+
}
109164

110165
/**
111166
* Test for {@code SELECT} that is implemented as an aggregation.

x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java

+74-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.elasticsearch.common.Strings;
1818
import org.elasticsearch.common.collect.Tuple;
1919
import org.elasticsearch.common.io.Streams;
20+
import org.elasticsearch.common.xcontent.XContentBuilder;
2021
import org.elasticsearch.common.xcontent.XContentHelper;
2122
import org.elasticsearch.common.xcontent.json.JsonXContent;
2223
import org.elasticsearch.test.NotEqualMessageBuilder;
@@ -30,6 +31,9 @@
3031
import java.io.InputStreamReader;
3132
import java.nio.charset.StandardCharsets;
3233
import java.sql.JDBCType;
34+
import java.time.Instant;
35+
import java.time.ZoneId;
36+
import java.time.ZonedDateTime;
3337
import java.util.ArrayList;
3438
import java.util.Arrays;
3539
import java.util.Collections;
@@ -126,7 +130,76 @@ public void testNextPage() throws IOException {
126130
ContentType.APPLICATION_JSON), StringUtils.EMPTY));
127131
}
128132

129-
@AwaitsFix(bugUrl = "https://github.com/elastic/x-pack-elasticsearch/issues/2074")
133+
public void testNextPageWithDatetimeAndTimezoneParam() throws IOException {
134+
Request request = new Request("PUT", "/test_date_timezone");
135+
XContentBuilder createIndex = JsonXContent.contentBuilder().startObject();
136+
createIndex.startObject("mappings");
137+
{
138+
createIndex.startObject("_doc");
139+
{
140+
createIndex.startObject("properties");
141+
{
142+
createIndex.startObject("date").field("type", "date").field("format", "epoch_millis");
143+
createIndex.endObject();
144+
}
145+
createIndex.endObject();
146+
}
147+
createIndex.endObject();
148+
}
149+
createIndex.endObject().endObject();
150+
request.setJsonEntity(Strings.toString(createIndex));
151+
client().performRequest(request);
152+
153+
request = new Request("PUT", "/test_date_timezone/_doc/_bulk");
154+
request.addParameter("refresh", "true");
155+
StringBuilder bulk = new StringBuilder();
156+
long[] datetimes = new long[] { 1_000, 10_000, 100_000, 1_000_000, 10_000_000 };
157+
for (long datetime : datetimes) {
158+
bulk.append("{\"index\":{}}\n");
159+
bulk.append("{\"date\":").append(datetime).append("}\n");
160+
}
161+
request.setJsonEntity(bulk.toString());
162+
assertEquals(200, client().performRequest(request).getStatusLine().getStatusCode());
163+
164+
ZoneId zoneId = randomZone();
165+
String mode = randomMode();
166+
String sqlRequest =
167+
"{\"query\":\"SELECT CAST(date AS string) AS date FROM test_date_timezone ORDER BY date\","
168+
+ "\"time_zone\":\"" + zoneId.getId() + "\", "
169+
+ "\"mode\":\"" + mode + "\", "
170+
+ "\"fetch_size\":2}";
171+
172+
String cursor = null;
173+
for (int i = 0; i <= datetimes.length; i += 2) {
174+
Map<String, Object> expected = new HashMap<>();
175+
Map<String, Object> response;
176+
177+
if (i == 0) {
178+
expected.put("columns", singletonList(columnInfo(mode, "date", "keyword", JDBCType.VARCHAR,
179+
Integer.MAX_VALUE)));
180+
response = runSql(new StringEntity(sqlRequest, ContentType.APPLICATION_JSON), "");
181+
} else {
182+
response = runSql(new StringEntity("{\"cursor\":\"" + cursor + "\"" + mode(mode) + "}",
183+
ContentType.APPLICATION_JSON), StringUtils.EMPTY);
184+
}
185+
186+
List<Object> values = new ArrayList<>(2);
187+
for (int j = 0; j < (i < datetimes.length - 1 ? 2 : 1); j++) {
188+
values.add(singletonList(StringUtils.toString(
189+
ZonedDateTime.ofInstant(Instant.ofEpochMilli(datetimes[i + j]), zoneId))));
190+
}
191+
expected.put("rows", values);
192+
cursor = (String) response.remove("cursor");
193+
assertResponse(expected, response);
194+
assertNotNull(cursor);
195+
}
196+
Map<String, Object> expected = new HashMap<>();
197+
expected.put("rows", emptyList());
198+
assertResponse(expected, runSql(new StringEntity("{ \"cursor\":\"" + cursor + "\"" + mode(mode) + "}",
199+
ContentType.APPLICATION_JSON), StringUtils.EMPTY));
200+
}
201+
202+
@AwaitsFix(bugUrl = "Unclear status, https://github.com/elastic/x-pack-elasticsearch/issues/2074")
130203
public void testTimeZone() throws IOException {
131204
String mode = randomMode();
132205
index("{\"test\":\"2017-07-27 00:00:00\"}",

0 commit comments

Comments
 (0)