Skip to content

Commit

Permalink
Merge branch 'main' into integ/sl_endWithNewLine
Browse files Browse the repository at this point in the history
Signed-off-by: Mitchell Gale <[email protected]>
  • Loading branch information
MitchellGale authored Jul 26, 2023
2 parents ccce743 + 1a7134b commit b9e63c7
Show file tree
Hide file tree
Showing 19 changed files with 274 additions and 164 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ spotless {
// licenseHeader("/*\n" +
// " * Copyright OpenSearch Contributors\n" +
// " * SPDX-License-Identifier: Apache-2.0\n" +
// " */\n\n\n")
// " */\n\n")
// removeUnusedImports()
// trimTrailingWhitespace()
endWithNewline()
Expand Down
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 @@ -7,22 +7,28 @@

package org.opensearch.sql.ppl;

import static org.opensearch.sql.prometheus.data.constants.PrometheusFieldConstants.LABELS;
import static org.opensearch.sql.prometheus.data.constants.PrometheusFieldConstants.TIMESTAMP;
import static org.opensearch.sql.prometheus.data.constants.PrometheusFieldConstants.VALUE;
import static org.opensearch.sql.util.MatcherUtils.assertJsonEquals;
import static org.opensearch.sql.util.MatcherUtils.schema;
import static org.opensearch.sql.util.MatcherUtils.verifySchema;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -218,4 +224,33 @@ public void testMetricSumAggregationCommand() {
}
}


@Test
@SneakyThrows
public void testQueryRange() {
long currentTimestamp = new Date().getTime();
JSONObject response =
executeQuery("source=my_prometheus.query_range('prometheus_http_requests_total',"
+ ((currentTimestamp/1000)-3600) + "," + currentTimestamp/1000 + ", " + 14 + ")" );
verifySchema(response,
schema(VALUE, "array"),
schema(TIMESTAMP, "array"),
schema(LABELS, "struct"));
Assertions.assertTrue(response.getInt("size") > 0);
}

@Test
public void explainQueryRange() throws Exception {
String expected = loadFromFile("expectedOutput/ppl/explain_query_range.json");
assertJsonEquals(
expected,
explainQueryToString("source = my_prometheus"
+ ".query_range('prometheus_http_requests_total',1689281439,1689291439,14)")
);
}

String loadFromFile(String filename) throws Exception {
URI uri = Resources.getResource(filename).toURI();
return new String(Files.readAllBytes(Paths.get(uri)));
}
}
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'}"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"root": {
"name": "QueryRangeFunctionTableScanOperator",
"description": {
"request": "query_range(prometheus_http_requests_total, 1689281439, 1689291439, 14)"
},
"children": []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public void extendTypeMapping(Map<String, OpenSearchDataType> typeMapping) {

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

private final Map<ExprType, BiFunction<Content, ExprType, ExprValue>> typeActionMap =
private static final Map<ExprType, BiFunction<Content, ExprType, ExprValue>> typeActionMap =
new ImmutableMap.Builder<ExprType, BiFunction<Content, ExprType, ExprValue>>()
.put(OpenSearchDataType.of(OpenSearchDataType.MappingType.Integer),
(c, dt) -> new ExprIntegerValue(c.intValue()))
Expand All @@ -126,10 +126,12 @@ public void extendTypeMapping(Map<String, OpenSearchDataType> typeMapping) {
.put(OpenSearchDataType.of(OpenSearchDataType.MappingType.Boolean),
(c, dt) -> ExprBooleanValue.of(c.booleanValue()))
//Handles the creation of DATE, TIME & DATETIME
.put(OpenSearchDateType.of(TIME), this::createOpenSearchDateType)
.put(OpenSearchDateType.of(DATE), this::createOpenSearchDateType)
.put(OpenSearchDateType.of(TIMESTAMP), this::createOpenSearchDateType)
.put(OpenSearchDateType.of(DATETIME), this::createOpenSearchDateType)
.put(OpenSearchDateType.of(TIME), OpenSearchExprValueFactory::createOpenSearchDateType)
.put(OpenSearchDateType.of(DATE), OpenSearchExprValueFactory::createOpenSearchDateType)
.put(OpenSearchDateType.of(TIMESTAMP),
OpenSearchExprValueFactory::createOpenSearchDateType)
.put(OpenSearchDateType.of(DATETIME),
OpenSearchExprValueFactory::createOpenSearchDateType)
.put(OpenSearchDataType.of(OpenSearchDataType.MappingType.Ip),
(c, dt) -> new OpenSearchExprIpValue(c.stringValue()))
.put(OpenSearchDataType.of(OpenSearchDataType.MappingType.GeoPoint),
Expand Down Expand Up @@ -222,7 +224,7 @@ private Optional<ExprType> type(String field) {
* @param dataType - field data type
* @return Parsed value
*/
private ExprValue parseDateTimeString(String value, OpenSearchDateType dataType) {
private static ExprValue parseDateTimeString(String value, OpenSearchDateType dataType) {
List<DateFormatter> formatters = dataType.getAllNamedFormatters();
formatters.addAll(dataType.getAllCustomFormatters());
ExprCoreType returnFormat = (ExprCoreType) dataType.getExprType();
Expand Down Expand Up @@ -262,7 +264,7 @@ private ExprValue parseDateTimeString(String value, OpenSearchDateType dataType)
"Construct %s from \"%s\" failed, unsupported format.", returnFormat, value));
}

private ExprValue createOpenSearchDateType(Content value, ExprType type) {
private static ExprValue createOpenSearchDateType(Content value, ExprType type) {
OpenSearchDateType dt = (OpenSearchDateType) type;
ExprType returnFormat = dt.getExprType();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.opensearch.core.xcontent.MediaTypeParserRegistry.setDefaultMediaType;
import static org.opensearch.sql.opensearch.client.OpenSearchClient.META_CLUSTER_NAME;
import static org.opensearch.sql.opensearch.data.type.OpenSearchDataType.MappingType;

Expand All @@ -34,6 +35,7 @@
import lombok.SneakyThrows;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.lucene.search.TotalHits;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
Expand Down Expand Up @@ -101,6 +103,11 @@ void setUp() {
client = new OpenSearchRestClient(restClient);
}

@BeforeAll
static void setUpJSON() {
setDefaultMediaType(XContentType.JSON);
}

@Test
void is_index_exist() throws IOException {
when(restClient.indices()
Expand Down Expand Up @@ -142,7 +149,6 @@ void create_index() throws IOException {
@Test
void create_index_with_IOException() throws IOException {
when(restClient.indices().create(any(), any())).thenThrow(IOException.class);

assertThrows(IllegalStateException.class,
() -> client.createIndex("test", ImmutableMap.of()));
}
Expand Down
Loading

0 comments on commit b9e63c7

Please sign in to comment.