Skip to content

Commit bc2c9e2

Browse files
committed
Test cast to date/time/timestamp
Signed-off-by: Yuanchun Shen <yuanchu@amazon.com>
1 parent 0e98650 commit bc2c9e2

1 file changed

Lines changed: 130 additions & 95 deletions

File tree

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLCastFunctionIT.java

Lines changed: 130 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77

88
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_DATATYPE_NONNUMERIC;
99
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_DATATYPE_NUMERIC;
10+
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_DATE_FORMATS;
1011
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_STATE_COUNTRY;
1112
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_STATE_COUNTRY_WITH_NULL;
12-
import static org.opensearch.sql.util.MatcherUtils.assertJsonEquals;
1313
import static org.opensearch.sql.util.MatcherUtils.rows;
1414
import static org.opensearch.sql.util.MatcherUtils.schema;
1515
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
16+
import static org.opensearch.sql.util.MatcherUtils.verifyErrorMessageContains;
1617
import static org.opensearch.sql.util.MatcherUtils.verifySchema;
1718

1819
import java.io.IOException;
1920
import org.json.JSONObject;
2021
import org.junit.Test;
2122
import org.opensearch.sql.common.antlr.SyntaxCheckException;
23+
import org.opensearch.sql.exception.SemanticCheckException;
2224
import org.opensearch.sql.ppl.PPLIntegTestCase;
2325

2426
public class CalcitePPLCastFunctionIT extends PPLIntegTestCase {
@@ -32,6 +34,7 @@ public void init() throws Exception {
3234
loadIndex(Index.STATE_COUNTRY_WITH_NULL);
3335
loadIndex(Index.DATA_TYPE_NUMERIC);
3436
loadIndex(Index.DATA_TYPE_NONNUMERIC);
37+
loadIndex(Index.DATE_FORMATS);
3538
}
3639

3740
@Test
@@ -92,38 +95,15 @@ public void testCastNullValues() throws IOException {
9295
"source=%s | eval a = cast(state as string) | fields a",
9396
TEST_INDEX_STATE_COUNTRY_WITH_NULL));
9497

95-
assertJsonEquals(
96-
"{\n"
97-
+ " \"schema\": [\n"
98-
+ " {\n"
99-
+ " \"name\": \"a\",\n"
100-
+ " \"type\": \"string\"\n"
101-
+ " }\n"
102-
+ " ],\n"
103-
+ " \"datarows\": [\n"
104-
+ " [\n"
105-
+ " \"California\"\n"
106-
+ " ],\n"
107-
+ " [\n"
108-
+ " \"New York\"\n"
109-
+ " ],\n"
110-
+ " [\n"
111-
+ " \"Ontario\"\n"
112-
+ " ],\n"
113-
+ " [\n"
114-
+ " \"Quebec\"\n"
115-
+ " ],\n"
116-
+ " [\n"
117-
+ " null\n"
118-
+ " ],\n"
119-
+ " [\n"
120-
+ " null\n"
121-
+ " ]\n"
122-
+ " ],\n"
123-
+ " \"total\": 6,\n"
124-
+ " \"size\": 6\n"
125-
+ "}",
126-
actual.toString());
98+
verifySchema(actual, schema("a", "string"));
99+
verifyDataRows(
100+
actual,
101+
rows("California"),
102+
rows("New York"),
103+
rows("Ontario"),
104+
rows("Quebec"),
105+
rows((Object) null),
106+
rows((Object) null));
127107
}
128108

129109
@Test
@@ -133,32 +113,9 @@ public void testCastToUnsupportedType() throws IOException {
133113
String.format(
134114
"source=%s | eval a = cast(name as boolean) | fields a", TEST_INDEX_STATE_COUNTRY));
135115

136-
assertJsonEquals(
137-
"{\n"
138-
+ " \"schema\": [\n"
139-
+ " {\n"
140-
+ " \"name\": \"a\",\n"
141-
+ " \"type\": \"boolean\"\n"
142-
+ " }\n"
143-
+ " ],\n"
144-
+ " \"datarows\": [\n"
145-
+ " [\n"
146-
+ " null\n"
147-
+ " ],\n"
148-
+ " [\n"
149-
+ " null\n"
150-
+ " ],\n"
151-
+ " [\n"
152-
+ " null\n"
153-
+ " ],\n"
154-
+ " [\n"
155-
+ " null\n"
156-
+ " ]\n"
157-
+ " ],\n"
158-
+ " \"total\": 4,\n"
159-
+ " \"size\": 4\n"
160-
+ "}",
161-
actual.toString());
116+
verifySchema(actual, schema("a", "boolean"));
117+
verifyDataRows(
118+
actual, rows((Object) null), rows((Object) null), rows((Object) null), rows((Object) null));
162119
}
163120

164121
@Test
@@ -220,24 +177,8 @@ public void testCastLiteralToBoolean() throws IOException {
220177
String.format(
221178
"source=%s | eval a = cast('2' as boolean) | fields a | head 1",
222179
TEST_INDEX_DATATYPE_NUMERIC));
223-
assertJsonEquals(
224-
""
225-
+ "{\n"
226-
+ " \"schema\": [\n"
227-
+ " {\n"
228-
+ " \"name\": \"a\",\n"
229-
+ " \"type\": \"boolean\"\n"
230-
+ " }\n"
231-
+ " ],\n"
232-
+ " \"datarows\": [\n"
233-
+ " [\n"
234-
+ " null\n"
235-
+ " ]\n"
236-
+ " ],\n"
237-
+ " \"total\": 1,\n"
238-
+ " \"size\": 1\n"
239-
+ "}",
240-
actual.toString());
180+
verifySchema(actual, schema("a", "boolean"));
181+
verifyDataRows(actual, rows((Object) null));
241182

242183
actual =
243184
executeQuery(
@@ -251,24 +192,8 @@ public void testCastLiteralToBoolean() throws IOException {
251192
String.format(
252193
"source=%s | eval a = cast('aa' as boolean) | fields a | head 1",
253194
TEST_INDEX_DATATYPE_NUMERIC));
254-
assertJsonEquals(
255-
""
256-
+ "{\n"
257-
+ " \"schema\": [\n"
258-
+ " {\n"
259-
+ " \"name\": \"a\",\n"
260-
+ " \"type\": \"boolean\"\n"
261-
+ " }\n"
262-
+ " ],\n"
263-
+ " \"datarows\": [\n"
264-
+ " [\n"
265-
+ " null\n"
266-
+ " ]\n"
267-
+ " ],\n"
268-
+ " \"total\": 1,\n"
269-
+ " \"size\": 1\n"
270-
+ "}",
271-
actual.toString());
195+
verifySchema(actual, schema("a", "boolean"));
196+
verifyDataRows(actual, rows((Object) null));
272197
}
273198

274199
@Test
@@ -485,4 +410,114 @@ public void testCastNumericSTRING() throws IOException {
485410
TEST_INDEX_DATATYPE_NONNUMERIC));
486411
verifyDataRows(actual, rows(true));
487412
}
413+
414+
@Test
415+
public void testCastDate() throws IOException {
416+
JSONObject actual =
417+
executeQuery(
418+
String.format(
419+
"source=%s | eval a = cast('1984-04-12' as DATE) | fields a",
420+
TEST_INDEX_DATE_FORMATS));
421+
verifySchema(actual, schema("a", "date"));
422+
verifyDataRows(actual, rows("1984-04-12"), rows("1984-04-12"));
423+
424+
actual =
425+
executeQuery(
426+
String.format(
427+
"source=%s | head 1 | eval a = cast('2023-10-01 12:00:00' as date) | fields a",
428+
TEST_INDEX_DATE_FORMATS));
429+
verifySchema(actual, schema("a", "date"));
430+
verifyDataRows(actual, rows("2023-10-01"));
431+
432+
Throwable t =
433+
assertThrowsWithReplace(
434+
SemanticCheckException.class,
435+
() ->
436+
executeQuery(
437+
String.format(
438+
"source=%s | eval a = cast('09:07:42' as DATE) | fields a",
439+
TEST_INDEX_DATE_FORMATS)));
440+
441+
verifyErrorMessageContains(t, "date:09:07:42 in unsupported format, please use 'yyyy-MM-dd'");
442+
}
443+
444+
@Test
445+
public void testCastTime() throws IOException {
446+
JSONObject actual =
447+
executeQuery(
448+
String.format(
449+
"source=%s | eval a = cast('09:07:42' as TIME) | fields a",
450+
TEST_INDEX_DATE_FORMATS));
451+
verifySchema(actual, schema("a", "time"));
452+
verifyDataRows(actual, rows("09:07:42"), rows("09:07:42"));
453+
454+
actual =
455+
executeQuery(
456+
String.format(
457+
"source=%s | head 1 | eval a = cast('09:07:42.12345' as TIME) | fields a",
458+
TEST_INDEX_DATE_FORMATS));
459+
verifySchema(actual, schema("a", "time"));
460+
verifyDataRows(actual, rows("09:07:42.12345"));
461+
462+
actual =
463+
executeQuery(
464+
String.format(
465+
"source=%s | head 1 | eval a = cast('1985-10-09 12:00:00' as time) | fields a",
466+
TEST_INDEX_DATE_FORMATS));
467+
verifySchema(actual, schema("a", "time"));
468+
verifyDataRows(actual, rows("12:00:00"));
469+
470+
Throwable t =
471+
assertThrowsWithReplace(
472+
SemanticCheckException.class,
473+
() ->
474+
executeQuery(
475+
String.format(
476+
"source=%s | eval a = cast('1984-04-12' as TIME) | fields a",
477+
TEST_INDEX_DATE_FORMATS)));
478+
479+
verifyErrorMessageContains(
480+
t, "time:1984-04-12 in unsupported format, please use 'HH:mm:ss[.SSSSSSSSS]'");
481+
}
482+
483+
@Test
484+
public void testCastTimestamp() throws IOException {
485+
JSONObject actual =
486+
executeQuery(
487+
String.format(
488+
"source=%s | eval a = cast('1984-04-12 09:07:42' as TIMESTAMP) | fields a",
489+
TEST_INDEX_DATE_FORMATS));
490+
verifySchema(actual, schema("a", "timestamp"));
491+
verifyDataRows(actual, rows("1984-04-12 09:07:42"), rows("1984-04-12 09:07:42"));
492+
493+
actual =
494+
executeQuery(
495+
String.format(
496+
"source=%s | head 1 | eval a = cast('2023-10-01 12:00:00.123456' as timestamp) |"
497+
+ " fields a",
498+
TEST_INDEX_DATE_FORMATS));
499+
verifySchema(actual, schema("a", "timestamp"));
500+
verifyDataRows(actual, rows("2023-10-01 12:00:00.123456"));
501+
502+
actual =
503+
executeQuery(
504+
String.format(
505+
"source=%s | eval a = cast('1984-04-12' as TIMESTAMP) | fields a",
506+
TEST_INDEX_DATE_FORMATS));
507+
verifySchema(actual, schema("a", "timestamp"));
508+
verifyDataRows(actual, rows("1984-04-12 00:00:00"), rows("1984-04-12 00:00:00"));
509+
510+
Throwable t =
511+
assertThrowsWithReplace(
512+
SemanticCheckException.class,
513+
() ->
514+
executeQuery(
515+
String.format(
516+
"source=%s | eval a = cast('09:07:42' as TIMESTAMP) | fields a",
517+
TEST_INDEX_DATE_FORMATS)));
518+
519+
verifyErrorMessageContains(
520+
t,
521+
"timestamp:09:07:42 in unsupported format, please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'");
522+
}
488523
}

0 commit comments

Comments
 (0)