|
@@ -9,6 +9,7 @@ package org.elasticsearch.xpack.sql.action;
|
|
|
import org.elasticsearch.common.unit.TimeValue;
|
|
|
import org.elasticsearch.common.xcontent.DeprecationHandler;
|
|
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
|
|
+import org.elasticsearch.common.xcontent.XContentParseException;
|
|
|
import org.elasticsearch.common.xcontent.XContentParser;
|
|
|
import org.elasticsearch.common.xcontent.XContentType;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
@@ -21,7 +22,7 @@ import java.util.List;
|
|
|
import java.util.function.Consumer;
|
|
|
import java.util.function.Function;
|
|
|
|
|
|
-import static org.hamcrest.Matchers.containsString;
|
|
|
+import static org.hamcrest.CoreMatchers.containsString;
|
|
|
|
|
|
public class SqlRequestParsersTests extends ESTestCase {
|
|
|
|
|
@@ -105,23 +106,139 @@ public class SqlRequestParsersTests extends ESTestCase {
|
|
|
SqlQueryRequest::fromXContent);
|
|
|
|
|
|
Mode randomMode = randomFrom(Mode.values());
|
|
|
+ String params;
|
|
|
+ List<SqlTypedParamValue> list = new ArrayList<>(1);
|
|
|
+
|
|
|
+ if (Mode.isDriver(randomMode)) {
|
|
|
+ params = "{\"value\":123, \"type\":\"whatever\"}";
|
|
|
+ list.add(new SqlTypedParamValue("whatever", 123, true));
|
|
|
+ } else {
|
|
|
+ params = "123";
|
|
|
+ list.add(new SqlTypedParamValue("integer", 123, false));
|
|
|
+ }
|
|
|
+
|
|
|
SqlQueryRequest request = generateRequest("{\"cursor\" : \"whatever\", \"mode\" : \""
|
|
|
+ randomMode.toString() + "\", \"client_id\" : \"bla\","
|
|
|
- + "\"query\":\"select\",\"params\":[{\"value\":123, \"type\":\"whatever\"}], \"time_zone\":\"UTC\","
|
|
|
+ + "\"query\":\"select\","
|
|
|
+ + "\"params\":[" + params + "],"
|
|
|
+ + " \"time_zone\":\"UTC\","
|
|
|
+ "\"request_timeout\":\"5s\",\"page_timeout\":\"10s\"}", SqlQueryRequest::fromXContent);
|
|
|
assertNull(request.clientId());
|
|
|
assertEquals(randomMode, request.mode());
|
|
|
assertEquals("whatever", request.cursor());
|
|
|
assertEquals("select", request.query());
|
|
|
-
|
|
|
- List<SqlTypedParamValue> list = new ArrayList<>(1);
|
|
|
- list.add(new SqlTypedParamValue("whatever", 123));
|
|
|
+
|
|
|
assertEquals(list, request.params());
|
|
|
assertEquals("UTC", request.zoneId().getId());
|
|
|
assertEquals(TimeValue.parseTimeValue("5s", "request_timeout"), request.requestTimeout());
|
|
|
assertEquals(TimeValue.parseTimeValue("10s", "page_timeout"), request.pageTimeout());
|
|
|
}
|
|
|
|
|
|
+ public void testParamsSuccessfulParsingInDriverMode() throws IOException {
|
|
|
+ Mode driverMode = randomValueOtherThanMany((m) -> Mode.isDriver(m) == false, () -> randomFrom(Mode.values()));
|
|
|
+ String json = "{" +
|
|
|
+ " \"params\":[{\"type\":\"integer\",\"value\":35000},"
|
|
|
+ + " {\"type\":\"date\",\"value\":\"1960-01-01\"},"
|
|
|
+ + " {\"type\":\"boolean\",\"value\":false},"
|
|
|
+ + " {\"type\":\"keyword\",\"value\":\"foo\"}]," +
|
|
|
+ " \"mode\": \"" + driverMode.toString() + "\"" +
|
|
|
+ "}";
|
|
|
+ SqlQueryRequest request = generateRequest(json, SqlQueryRequest::fromXContent);
|
|
|
+ List<SqlTypedParamValue> params = request.params();
|
|
|
+ assertEquals(4, params.size());
|
|
|
+
|
|
|
+ assertEquals(35000, params.get(0).value);
|
|
|
+ assertEquals("integer", params.get(0).type);
|
|
|
+ assertTrue(params.get(0).hasExplicitType());
|
|
|
+
|
|
|
+ assertEquals("1960-01-01", params.get(1).value);
|
|
|
+ assertEquals("date", params.get(1).type);
|
|
|
+ assertTrue(params.get(1).hasExplicitType());
|
|
|
+
|
|
|
+ assertEquals(false, params.get(2).value);
|
|
|
+ assertEquals("boolean", params.get(2).type);
|
|
|
+ assertTrue(params.get(2).hasExplicitType());
|
|
|
+
|
|
|
+ assertEquals("foo", params.get(3).value);
|
|
|
+ assertEquals("keyword", params.get(3).type);
|
|
|
+ assertTrue(params.get(3).hasExplicitType());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParamsSuccessfulParsingInNonDriverMode() throws IOException {
|
|
|
+ Mode nonDriverMode = randomValueOtherThanMany(Mode::isDriver, () -> randomFrom(Mode.values()));
|
|
|
+ String json = "{" +
|
|
|
+ " \"params\":[35000,\"1960-01-01\",false,\"foo\"]," +
|
|
|
+ " \"mode\": \"" + nonDriverMode.toString() + "\"" +
|
|
|
+ "}";
|
|
|
+ SqlQueryRequest request = generateRequest(json, SqlQueryRequest::fromXContent);
|
|
|
+ List<SqlTypedParamValue> params = request.params();
|
|
|
+ assertEquals(4, params.size());
|
|
|
+
|
|
|
+ assertEquals(35000, params.get(0).value);
|
|
|
+ assertEquals("integer", params.get(0).type);
|
|
|
+ assertFalse(params.get(0).hasExplicitType());
|
|
|
+
|
|
|
+ assertEquals("1960-01-01", params.get(1).value);
|
|
|
+ assertEquals("keyword", params.get(1).type);
|
|
|
+ assertFalse(params.get(1).hasExplicitType());
|
|
|
+
|
|
|
+ assertEquals(false, params.get(2).value);
|
|
|
+ assertEquals("boolean", params.get(2).type);
|
|
|
+ assertFalse(params.get(2).hasExplicitType());
|
|
|
+
|
|
|
+ assertEquals("foo", params.get(3).value);
|
|
|
+ assertEquals("keyword", params.get(3).type);
|
|
|
+ assertFalse(params.get(3).hasExplicitType());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParamsParsingFailure_QueryRequest_NonDriver() throws IOException {
|
|
|
+ Mode m = randomValueOtherThanMany(Mode::isDriver, () -> randomFrom(Mode.values()));
|
|
|
+ assertXContentParsingErrorMessage("{\"params\":[{\"whatever\":35000},\"1960-01-01\",false,\"foo\"],\"mode\": \""
|
|
|
+ + m.toString() + "\"}",
|
|
|
+ "[sql/query] failed to parse field [params]",
|
|
|
+ SqlQueryRequest::fromXContent);
|
|
|
+ assertXContentParsingErrorMessage("{\"params\":[350.123,\"1960-01-01\",{\"foobar\":false},\"foo\"],\"mode\": \"}"
|
|
|
+ + m.toString() + "\"}",
|
|
|
+ "[sql/query] failed to parse field [params]",
|
|
|
+ SqlQueryRequest::fromXContent);
|
|
|
+ assertXContentParsingErrorMessage("{\"mode\": \"" + m.toString() + "\",\"params\":[350.123,\"1960-01-01\",false,"
|
|
|
+ + "{\"type\":\"keyword\",\"value\":\"foo\"}]}",
|
|
|
+ "[params] must be an array where each entry is a single field (no objects supported)",
|
|
|
+ SqlQueryRequest::fromXContent);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParamsParsingFailure_TranslateRequest_NonDriver() throws IOException {
|
|
|
+ Mode m = randomValueOtherThanMany(Mode::isDriver, () -> randomFrom(Mode.values()));
|
|
|
+ assertXContentParsingErrorMessage("{\"params\":[{\"whatever\":35000},\"1960-01-01\",false,\"foo\"],\"mode\": \""
|
|
|
+ + m.toString() + "\"}",
|
|
|
+ "[sql/query] failed to parse field [params]",
|
|
|
+ SqlTranslateRequest::fromXContent);
|
|
|
+ assertXContentParsingErrorMessage("{\"params\":[350.123,\"1960-01-01\",{\"foobar\":false},\"foo\"],\"mode\": \"}"
|
|
|
+ + m.toString() + "\"}",
|
|
|
+ "[sql/query] failed to parse field [params]",
|
|
|
+ SqlTranslateRequest::fromXContent);
|
|
|
+ assertXContentParsingErrorMessage("{\"mode\": \"" + m.toString() + "\",\"params\":[350.123,\"1960-01-01\",false,"
|
|
|
+ + "{\"type\":\"keyword\",\"value\":\"foo\"}]}",
|
|
|
+ "[params] must be an array where each entry is a single field (no objects supported)",
|
|
|
+ SqlTranslateRequest::fromXContent);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParamsParsingFailure_Driver() throws IOException {
|
|
|
+ Mode m = randomValueOtherThanMany((t) -> Mode.isDriver(t) == false, () -> randomFrom(Mode.values()));
|
|
|
+ assertXContentParsingErrorMessage("{\"params\":[35000,{\"value\":\"1960-01-01\",\"type\":\"date\"},{\"value\":\"foo\","
|
|
|
+ + "\"type\":\"keyword\"}],\"mode\": \"" + m.toString() + "\"}",
|
|
|
+ "[params] must be an array where each entry is an object with a value/type pair",
|
|
|
+ SqlQueryRequest::fromXContent);
|
|
|
+ assertXContentParsingErrorMessage("{\"params\":[{\"value\":10,\"type\":\"integer\"},{\"value\":\"1960-01-01\",\"type\":\"date\"},"
|
|
|
+ + "false,\"foo\"],\"mode\": \"" + m.toString() + "\"}",
|
|
|
+ "[params] must be an array where each entry is an object with a value/type pair",
|
|
|
+ SqlQueryRequest::fromXContent);
|
|
|
+ assertXContentParsingErrorMessage("{\"mode\": \"" + m.toString() + "\",\"params\":[{\"value\":10,\"type\":\"integer\"},"
|
|
|
+ + "{\"value\":\"1960-01-01\",\"type\":\"date\"},{\"foo\":\"bar\"}]}",
|
|
|
+ "[sql/query] failed to parse field [params]",
|
|
|
+ SqlQueryRequest::fromXContent);
|
|
|
+ }
|
|
|
+
|
|
|
private <R extends AbstractSqlRequest> R generateRequest(String json, Function<XContentParser, R> fromXContent)
|
|
|
throws IOException {
|
|
|
XContentParser parser = parser(json);
|
|
@@ -140,6 +257,12 @@ public class SqlRequestParsersTests extends ESTestCase {
|
|
|
assertThat(e.getCause().getMessage(), containsString(errorMessage));
|
|
|
}
|
|
|
|
|
|
+ private void assertXContentParsingErrorMessage(String json, String errorMessage, Consumer<XContentParser> consumer) throws IOException {
|
|
|
+ XContentParser parser = parser(json);
|
|
|
+ Exception e = expectThrows(XContentParseException.class, () -> consumer.accept(parser));
|
|
|
+ assertThat(e.getMessage(), containsString(errorMessage));
|
|
|
+ }
|
|
|
+
|
|
|
private XContentParser parser(String content) throws IOException {
|
|
|
XContentType xContentType = XContentType.JSON;
|
|
|
return xContentType.xContent().createParser(
|