77
88import static org .opensearch .sql .legacy .TestsConstants .TEST_INDEX_DATATYPE_NONNUMERIC ;
99import static org .opensearch .sql .legacy .TestsConstants .TEST_INDEX_DATATYPE_NUMERIC ;
10+ import static org .opensearch .sql .legacy .TestsConstants .TEST_INDEX_DATE_FORMATS ;
1011import static org .opensearch .sql .legacy .TestsConstants .TEST_INDEX_STATE_COUNTRY ;
1112import static org .opensearch .sql .legacy .TestsConstants .TEST_INDEX_STATE_COUNTRY_WITH_NULL ;
12- import static org .opensearch .sql .util .MatcherUtils .assertJsonEquals ;
1313import static org .opensearch .sql .util .MatcherUtils .rows ;
1414import static org .opensearch .sql .util .MatcherUtils .schema ;
1515import static org .opensearch .sql .util .MatcherUtils .verifyDataRows ;
16+ import static org .opensearch .sql .util .MatcherUtils .verifyErrorMessageContains ;
1617import static org .opensearch .sql .util .MatcherUtils .verifySchema ;
1718
1819import java .io .IOException ;
1920import org .json .JSONObject ;
2021import org .junit .Test ;
2122import org .opensearch .sql .common .antlr .SyntaxCheckException ;
23+ import org .opensearch .sql .exception .SemanticCheckException ;
2224import org .opensearch .sql .ppl .PPLIntegTestCase ;
2325
2426public 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