Skip to content

Commit 2cd0e85

Browse files
matthewryanwellsMitchellGale
authored andcommitted
Added support of timestamp/date/time using curly brackets (opensearch-project#1894)
* Added support of timestamp/date/time using curly brackets (#297) * added bracketed time/date/timestamp input, tests, and documentation Signed-off-by: Matthew Wells <[email protected]> * improved failing tests Signed-off-by: Matthew Wells <[email protected]> * simplified tests for checking for failure Signed-off-by: Matthew Wells <[email protected]> * fixed redundant tests and improved tests that should fail Signed-off-by: Matthew Wells <[email protected]> --------- Signed-off-by: Matthew Wells <[email protected]> Signed-off-by: Mitchell Gale <[email protected]>
1 parent 4b353ee commit 2cd0e85

File tree

6 files changed

+142
-4
lines changed

6 files changed

+142
-4
lines changed

docs/user/dql/expressions.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ A literal is a symbol that represents a value. The most common literal values in
2525
1. Numeric literals: specify numeric values such as integer and floating-point numbers.
2626
2. String literals: specify a string enclosed by single or double quotes.
2727
3. Boolean literals: ``true`` or ``false``.
28-
4. Date and Time literals: DATE 'YYYY-MM-DD' represent the date, TIME 'hh:mm:ss' represent the time, TIMESTAMP 'YYYY-MM-DD hh:mm:ss' represent the timestamp.
28+
4. Date and Time literals: DATE 'YYYY-MM-DD' represent the date, TIME 'hh:mm:ss' represent the time, TIMESTAMP 'YYYY-MM-DD hh:mm:ss' represent the timestamp. You can also surround the literals with curly brackets, if you do, you can replace date with d, time with t, and timestamp with ts
2929

3030
Examples
3131
--------
@@ -49,6 +49,15 @@ Here is an example for different type of literals::
4949
| Hello | Hello | It"s | It's | It's | "Its" | It's | It\'s | \I\t\s |
5050
+-----------+-----------+-----------+-----------+----------+-----------+-----------+-------------+------------+
5151

52+
53+
os> SELECT {DATE '2020-07-07'}, {D '2020-07-07'}, {TIME '01:01:01'}, {T '01:01:01'}, {TIMESTAMP '2020-07-07 01:01:01'}, {TS '2020-07-07 01:01:01'}
54+
fetched rows / total rows = 1/1
55+
+-----------------------+--------------------+---------------------+------------------+-------------------------------------+------------------------------+
56+
| {DATE '2020-07-07'} | {D '2020-07-07'} | {TIME '01:01:01'} | {T '01:01:01'} | {TIMESTAMP '2020-07-07 01:01:01'} | {TS '2020-07-07 01:01:01'} |
57+
|-----------------------+--------------------+---------------------+------------------+-------------------------------------+------------------------------|
58+
| 2020-07-07 | 2020-07-07 | 01:01:01 | 01:01:01 | 2020-07-07 01:01:01 | 2020-07-07 01:01:01 |
59+
+-----------------------+--------------------+---------------------+------------------+-------------------------------------+------------------------------+
60+
5261
Limitations
5362
-----------
5463

integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.opensearch.client.Request;
3030
import org.opensearch.client.RequestOptions;
3131
import org.opensearch.client.Response;
32+
import org.opensearch.client.ResponseException;
3233
import org.opensearch.sql.common.utils.StringUtils;
3334
import org.opensearch.sql.legacy.SQLIntegTestCase;
3435

@@ -1288,4 +1289,85 @@ protected JSONObject executeQuery(String query) throws IOException {
12881289
Response response = client().performRequest(request);
12891290
return new JSONObject(getResponseBody(response));
12901291
}
1292+
1293+
@Test
1294+
public void testTimestampBracket() throws IOException {
1295+
JSONObject result = executeQuery("select {timestamp '2020-09-16 17:30:00'}");
1296+
verifySchema(result, schema("{timestamp '2020-09-16 17:30:00'}", null, "timestamp"));
1297+
verifyDataRows(result, rows("2020-09-16 17:30:00"));
1298+
1299+
result = executeQuery("select {ts '2020-09-16 17:30:00'}");
1300+
verifySchema(result, schema("{ts '2020-09-16 17:30:00'}", null, "timestamp"));
1301+
verifyDataRows(result, rows("2020-09-16 17:30:00"));
1302+
1303+
result = executeQuery("select {timestamp '2020-09-16 17:30:00.123'}");
1304+
verifySchema(result, schema("{timestamp '2020-09-16 17:30:00.123'}", null, "timestamp"));
1305+
verifyDataRows(result, rows("2020-09-16 17:30:00.123"));
1306+
1307+
result = executeQuery("select {ts '2020-09-16 17:30:00.123'}");
1308+
verifySchema(result, schema("{ts '2020-09-16 17:30:00.123'}", null, "timestamp"));
1309+
verifyDataRows(result, rows("2020-09-16 17:30:00.123"));
1310+
}
1311+
1312+
@Test
1313+
public void testTimeBracket() throws IOException {
1314+
JSONObject result = executeQuery("select {time '17:30:00'}");
1315+
verifySchema(result, schema("{time '17:30:00'}", null, "time"));
1316+
verifyDataRows(result, rows("17:30:00"));
1317+
1318+
result = executeQuery("select {t '17:30:00'}");
1319+
verifySchema(result, schema("{t '17:30:00'}", null, "time"));
1320+
verifyDataRows(result, rows("17:30:00"));
1321+
1322+
result = executeQuery("select {time '17:30:00.123'}");
1323+
verifySchema(result, schema("{time '17:30:00.123'}", null, "time"));
1324+
verifyDataRows(result, rows("17:30:00.123"));
1325+
1326+
result = executeQuery("select {t '17:30:00.123'}");
1327+
verifySchema(result, schema("{t '17:30:00.123'}", null, "time"));
1328+
verifyDataRows(result, rows("17:30:00.123"));
1329+
}
1330+
1331+
@Test
1332+
public void testDateBracket() throws IOException {
1333+
JSONObject result = executeQuery("select {date '2020-09-16'}");
1334+
verifySchema(result, schema("{date '2020-09-16'}", null, "date"));
1335+
verifyDataRows(result, rows("2020-09-16"));
1336+
1337+
result = executeQuery("select {d '2020-09-16'}");
1338+
verifySchema(result, schema("{d '2020-09-16'}", null, "date"));
1339+
verifyDataRows(result, rows("2020-09-16"));
1340+
}
1341+
1342+
private void compareBrackets(String query1, String query2, String datetime) throws IOException {
1343+
JSONObject result1 = executeQuery("select " + query1 + " '" + datetime + "'");
1344+
JSONObject result2 = executeQuery("select {" + query2 + " '" + datetime + "'}");
1345+
1346+
verifyDataRows(result1, rows(datetime));
1347+
verifyDataRows(result2, rows(datetime));
1348+
}
1349+
1350+
@Test
1351+
public void testBracketedEquivalent() throws IOException {
1352+
compareBrackets("timestamp", "timestamp", "2020-09-16 17:30:00");
1353+
compareBrackets("timestamp", "ts", "2020-09-16 17:30:00");
1354+
compareBrackets("timestamp", "timestamp", "2020-09-16 17:30:00.123");
1355+
compareBrackets("timestamp", "ts", "2020-09-16 17:30:00.123");
1356+
compareBrackets("date", "date", "2020-09-16");
1357+
compareBrackets("date", "d", "2020-09-16");
1358+
compareBrackets("time", "time", "17:30:00");
1359+
compareBrackets("time", "t", "17:30:00");
1360+
}
1361+
1362+
@Test
1363+
public void testBracketFails() {
1364+
assertThrows(ResponseException.class, ()->executeQuery("select {time '2020-09-16'}"));
1365+
assertThrows(ResponseException.class, ()->executeQuery("select {t '2020-09-16'}"));
1366+
assertThrows(ResponseException.class, ()->executeQuery("select {date '17:30:00'}"));
1367+
assertThrows(ResponseException.class, ()->executeQuery("select {d '17:30:00'}"));
1368+
assertThrows(ResponseException.class, ()->executeQuery("select {timestamp '2020-09-16'}"));
1369+
assertThrows(ResponseException.class, ()->executeQuery("select {ts '2020-09-16'}"));
1370+
assertThrows(ResponseException.class, ()->executeQuery("select {timestamp '17:30:00'}"));
1371+
assertThrows(ResponseException.class, ()->executeQuery("select {ts '17:30:00'}"));
1372+
}
12911373
}

sql/src/main/antlr/OpenSearchSQLParser.g4

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ constant
185185
// Doesn't support the following types for now
186186
//| BIT_STRING
187187
//| NOT? nullLiteral=(NULL_LITERAL | NULL_SPEC_LITERAL)
188-
//| LEFT_BRACE dateType=(D | T | TS | DATE | TIME | TIMESTAMP) stringLiteral RIGHT_BRACE
189188
;
190189

191190
decimalLiteral
@@ -227,14 +226,17 @@ datetimeLiteral
227226

228227
dateLiteral
229228
: DATE date=stringLiteral
229+
| LEFT_BRACE (DATE | D) date=stringLiteral RIGHT_BRACE
230230
;
231231

232232
timeLiteral
233233
: TIME time=stringLiteral
234+
| LEFT_BRACE (TIME | T) time=stringLiteral RIGHT_BRACE
234235
;
235236

236237
timestampLiteral
237238
: TIMESTAMP timestamp=stringLiteral
239+
| LEFT_BRACE (TIMESTAMP | TS) timestamp=stringLiteral RIGHT_BRACE
238240
;
239241

240242
// Actually, these constants are shortcuts to the corresponding functions

sql/src/test/java/org/opensearch/sql/common/antlr/SyntaxParserTestBase.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package org.opensearch.sql.common.antlr;
22

33
import static org.junit.jupiter.api.Assertions.assertNotNull;
4-
import static org.junit.jupiter.api.Assertions.assertNull;
54
import static org.junit.jupiter.api.Assertions.assertThrows;
65

76
import lombok.AccessLevel;
87
import lombok.Getter;
98
import lombok.RequiredArgsConstructor;
10-
import org.opensearch.sql.sql.antlr.SQLSyntaxParser;
119

1210
/**
1311
* A base class for tests for SQL or PPL parser.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
7+
package org.opensearch.sql.sql.antlr;
8+
9+
import org.junit.jupiter.api.Test;
10+
11+
public class BracketedTimestampTest extends SQLParserTest {
12+
@Test
13+
void date_shortened_test() {
14+
acceptQuery("SELECT {d '2001-05-07'}");
15+
}
16+
17+
@Test
18+
void date_test() {
19+
acceptQuery("SELECT {date '2001-05-07'}");
20+
}
21+
22+
@Test
23+
void time_shortened_test() {
24+
acceptQuery("SELECT {t '10:11:12'}");
25+
}
26+
27+
@Test
28+
void time_test() {
29+
acceptQuery("SELECT {time '10:11:12'}");
30+
}
31+
32+
@Test
33+
void timestamp_shortened_test() {
34+
acceptQuery("SELECT {ts '2001-05-07 10:11:12'}");
35+
}
36+
37+
@Test
38+
void timestamp_test() {
39+
acceptQuery("SELECT {timestamp '2001-05-07 10:11:12'}");
40+
}
41+
}

sql/src/test/java/org/opensearch/sql/sql/antlr/SQLParserTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
17
package org.opensearch.sql.sql.antlr;
28

39
import org.opensearch.sql.common.antlr.SyntaxParserTestBase;

0 commit comments

Comments
 (0)