Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support of timestamp/date/time using curly brackets #1894

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 10 additions & 1 deletion docs/user/dql/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ A literal is a symbol that represents a value. The most common literal values in
1. Numeric literals: specify numeric values such as integer and floating-point numbers.
2. String literals: specify a string enclosed by single or double quotes.
3. Boolean literals: ``true`` or ``false``.
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.
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

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


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'}
fetched rows / total rows = 1/1
+-----------------------+--------------------+---------------------+------------------+-------------------------------------+------------------------------+
| {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'} |
|-----------------------+--------------------+---------------------+------------------+-------------------------------------+------------------------------|
| 2020-07-07 | 2020-07-07 | 01:01:01 | 01:01:01 | 2020-07-07 01:01:01 | 2020-07-07 01:01:01 |
+-----------------------+--------------------+---------------------+------------------+-------------------------------------+------------------------------+

Limitations
-----------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.opensearch.client.Request;
import org.opensearch.client.RequestOptions;
import org.opensearch.client.Response;
import org.opensearch.client.ResponseException;
import org.opensearch.sql.common.utils.StringUtils;
import org.opensearch.sql.legacy.SQLIntegTestCase;

Expand Down Expand Up @@ -1288,4 +1289,85 @@ protected JSONObject executeQuery(String query) throws IOException {
Response response = client().performRequest(request);
return new JSONObject(getResponseBody(response));
}

@Test
public void testTimestampBracket() throws IOException {
JSONObject result = executeQuery("select {timestamp '2020-09-16 17:30:00'}");
verifySchema(result, schema("{timestamp '2020-09-16 17:30:00'}", null, "timestamp"));
verifyDataRows(result, rows("2020-09-16 17:30:00"));

result = executeQuery("select {ts '2020-09-16 17:30:00'}");
verifySchema(result, schema("{ts '2020-09-16 17:30:00'}", null, "timestamp"));
verifyDataRows(result, rows("2020-09-16 17:30:00"));

result = executeQuery("select {timestamp '2020-09-16 17:30:00.123'}");
verifySchema(result, schema("{timestamp '2020-09-16 17:30:00.123'}", null, "timestamp"));
verifyDataRows(result, rows("2020-09-16 17:30:00.123"));

result = executeQuery("select {ts '2020-09-16 17:30:00.123'}");
verifySchema(result, schema("{ts '2020-09-16 17:30:00.123'}", null, "timestamp"));
verifyDataRows(result, rows("2020-09-16 17:30:00.123"));
}

@Test
public void testTimeBracket() throws IOException {
JSONObject result = executeQuery("select {time '17:30:00'}");
verifySchema(result, schema("{time '17:30:00'}", null, "time"));
verifyDataRows(result, rows("17:30:00"));

result = executeQuery("select {t '17:30:00'}");
verifySchema(result, schema("{t '17:30:00'}", null, "time"));
verifyDataRows(result, rows("17:30:00"));

result = executeQuery("select {time '17:30:00.123'}");
verifySchema(result, schema("{time '17:30:00.123'}", null, "time"));
verifyDataRows(result, rows("17:30:00.123"));

result = executeQuery("select {t '17:30:00.123'}");
verifySchema(result, schema("{t '17:30:00.123'}", null, "time"));
verifyDataRows(result, rows("17:30:00.123"));
}

@Test
public void testDateBracket() throws IOException {
JSONObject result = executeQuery("select {date '2020-09-16'}");
verifySchema(result, schema("{date '2020-09-16'}", null, "date"));
verifyDataRows(result, rows("2020-09-16"));

result = executeQuery("select {d '2020-09-16'}");
verifySchema(result, schema("{d '2020-09-16'}", null, "date"));
verifyDataRows(result, rows("2020-09-16"));
}

private void compareBrackets(String query1, String query2, String datetime) throws IOException {
JSONObject result1 = executeQuery("select " + query1 + " '" + datetime + "'");
JSONObject result2 = executeQuery("select {" + query2 + " '" + datetime + "'}");

verifyDataRows(result1, rows(datetime));
verifyDataRows(result2, rows(datetime));
}

@Test
public void testBracketedEquivalent() throws IOException {
compareBrackets("timestamp", "timestamp", "2020-09-16 17:30:00");
compareBrackets("timestamp", "ts", "2020-09-16 17:30:00");
compareBrackets("timestamp", "timestamp", "2020-09-16 17:30:00.123");
compareBrackets("timestamp", "ts", "2020-09-16 17:30:00.123");
compareBrackets("date", "date", "2020-09-16");
compareBrackets("date", "d", "2020-09-16");
compareBrackets("time", "time", "17:30:00");
compareBrackets("time", "t", "17:30:00");
}

@Test
public void testBracketFails() {
assertThrows(ResponseException.class, ()->executeQuery("select {time '2020-09-16'}"));
assertThrows(ResponseException.class, ()->executeQuery("select {t '2020-09-16'}"));
assertThrows(ResponseException.class, ()->executeQuery("select {date '17:30:00'}"));
assertThrows(ResponseException.class, ()->executeQuery("select {d '17:30:00'}"));
assertThrows(ResponseException.class, ()->executeQuery("select {timestamp '2020-09-16'}"));
assertThrows(ResponseException.class, ()->executeQuery("select {ts '2020-09-16'}"));
assertThrows(ResponseException.class, ()->executeQuery("select {timestamp '17:30:00'}"));
assertThrows(ResponseException.class, ()->executeQuery("select {ts '17:30:00'}"));
}
}
4 changes: 3 additions & 1 deletion sql/src/main/antlr/OpenSearchSQLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ constant
// Doesn't support the following types for now
//| BIT_STRING
//| NOT? nullLiteral=(NULL_LITERAL | NULL_SPEC_LITERAL)
//| LEFT_BRACE dateType=(D | T | TS | DATE | TIME | TIMESTAMP) stringLiteral RIGHT_BRACE
;

decimalLiteral
Expand Down Expand Up @@ -227,14 +226,17 @@ datetimeLiteral

dateLiteral
: DATE date=stringLiteral
| LEFT_BRACE (DATE | D) date=stringLiteral RIGHT_BRACE
;

timeLiteral
: TIME time=stringLiteral
| LEFT_BRACE (TIME | T) time=stringLiteral RIGHT_BRACE
;

timestampLiteral
: TIMESTAMP timestamp=stringLiteral
| LEFT_BRACE (TIMESTAMP | TS) timestamp=stringLiteral RIGHT_BRACE
;

// Actually, these constants are shortcuts to the corresponding functions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package org.opensearch.sql.common.antlr;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.opensearch.sql.sql.antlr.SQLSyntaxParser;

/**
* A base class for tests for SQL or PPL parser.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/


package org.opensearch.sql.sql.antlr;

import org.junit.jupiter.api.Test;

public class BracketedTimestampTest extends SQLParserTest {
@Test
void date_shortened_test() {
acceptQuery("SELECT {d '2001-05-07'}");
}

@Test
void date_test() {
acceptQuery("SELECT {date '2001-05-07'}");
}

@Test
void time_shortened_test() {
acceptQuery("SELECT {t '10:11:12'}");
}

@Test
void time_test() {
acceptQuery("SELECT {time '10:11:12'}");
}

@Test
void timestamp_shortened_test() {
acceptQuery("SELECT {ts '2001-05-07 10:11:12'}");
}

@Test
void timestamp_test() {
acceptQuery("SELECT {timestamp '2001-05-07 10:11:12'}");
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/


package org.opensearch.sql.sql.antlr;

import org.opensearch.sql.common.antlr.SyntaxParserTestBase;
Expand Down