diff --git a/docs/changelog/83795.yaml b/docs/changelog/83795.yaml
new file mode 100644
index 0000000000000..af5a670918a7a
--- /dev/null
+++ b/docs/changelog/83795.yaml
@@ -0,0 +1,6 @@
+pr: 83795
+summary: Add leniency option to SQL CLI
+area: SQL
+type: enhancement
+issues:
+ - 67436
diff --git a/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliLenientIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliLenientIT.java
new file mode 100644
index 0000000000000..fc4a04570ff67
--- /dev/null
+++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliLenientIT.java
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.sql.qa.multi_node;
+
+import org.elasticsearch.xpack.sql.qa.cli.LenientTestCase;
+
+public class CliLenientIT extends LenientTestCase {}
diff --git a/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliLenientIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliLenientIT.java
new file mode 100644
index 0000000000000..87e056baa6751
--- /dev/null
+++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliLenientIT.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.sql.qa.security;
+
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.xpack.sql.qa.cli.EmbeddedCli.SecurityConfig;
+import org.elasticsearch.xpack.sql.qa.cli.LenientTestCase;
+
+public class CliLenientIT extends LenientTestCase {
+ @Override
+ protected Settings restClientSettings() {
+ return RestSqlIT.securitySettings();
+ }
+
+ @Override
+ protected String getProtocol() {
+ return RestSqlIT.SSL_ENABLED ? "https" : "http";
+ }
+
+ @Override
+ protected SecurityConfig securityConfig() {
+ return CliSecurityIT.adminSecurityConfig();
+ }
+}
diff --git a/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliLenientIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliLenientIT.java
new file mode 100644
index 0000000000000..afcfca0a01ed2
--- /dev/null
+++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliLenientIT.java
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.sql.qa.single_node;
+
+import org.elasticsearch.xpack.sql.qa.cli.LenientTestCase;
+
+public class CliLenientIT extends LenientTestCase {}
diff --git a/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/LenientTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/LenientTestCase.java
new file mode 100644
index 0000000000000..76f84541e5bb9
--- /dev/null
+++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/LenientTestCase.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.sql.qa.cli;
+
+import org.elasticsearch.test.hamcrest.RegexMatcher;
+
+import java.io.IOException;
+
+import static org.hamcrest.Matchers.containsString;
+
+public abstract class LenientTestCase extends CliIntegrationTestCase {
+
+ public void testLenientCommand() throws IOException {
+ index("test", body -> body.field("name", "foo").field("tags", new String[] { "bar", "bar" }));
+ assertEquals("[?1l>[?1000l[?2004llenient set to [90mtrue[0m", command("lenient = true"));
+ assertThat(command("SELECT * FROM test"), RegexMatcher.matches("\\s*name\\s*\\|\\s*tags\\s*"));
+ assertThat(readLine(), containsString("----------"));
+ assertThat(readLine(), RegexMatcher.matches("\\s*foo\\s*\\|\\s*bar\\s*"));
+ assertEquals("", readLine());
+ }
+
+ public void testDefaultNoLenient() throws IOException {
+ index("test", body -> body.field("name", "foo").field("tags", new String[] { "bar", "bar" }));
+ assertThat(
+ command("SELECT * FROM test"),
+ containsString("Server encountered an error [Arrays (returned by [tags]) are not supported]")
+ );
+ while ("][23;31;1m][0m".equals(readLine()) == false)
+ ; // clean console to avoid failures on shutdown
+ }
+
+ public void testExplicitNoLenient() throws IOException {
+ index("test", body -> body.field("name", "foo").field("tags", new String[] { "bar", "bar" }));
+ assertEquals("[?1l>[?1000l[?2004llenient set to [90mfalse[0m", command("lenient = false"));
+ assertThat(
+ command("SELECT * FROM test"),
+ containsString("Server encountered an error [Arrays (returned by [tags]) are not supported]")
+ );
+ while ("][23;31;1m][0m".equals(readLine()) == false)
+ ; // clean console to avoid failures on shutdown
+ }
+}
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/Cli.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/Cli.java
index 8ccc079860937..97d5bcc3da927 100644
--- a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/Cli.java
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/Cli.java
@@ -19,6 +19,7 @@
import org.elasticsearch.xpack.sql.cli.command.CliSession;
import org.elasticsearch.xpack.sql.cli.command.FetchSeparatorCliCommand;
import org.elasticsearch.xpack.sql.cli.command.FetchSizeCliCommand;
+import org.elasticsearch.xpack.sql.cli.command.LenientCliCommand;
import org.elasticsearch.xpack.sql.cli.command.PrintLogoCommand;
import org.elasticsearch.xpack.sql.cli.command.ServerInfoCliCommand;
import org.elasticsearch.xpack.sql.cli.command.ServerQueryCliCommand;
@@ -128,6 +129,7 @@ private void execute(String uri, boolean debug, boolean binary, String keystoreL
new PrintLogoCommand(),
new ClearScreenCliCommand(),
new FetchSizeCliCommand(),
+ new LenientCliCommand(),
new FetchSeparatorCliCommand(),
new ServerInfoCliCommand(),
new ServerQueryCliCommand()
@@ -136,7 +138,7 @@ private void execute(String uri, boolean debug, boolean binary, String keystoreL
ConnectionBuilder connectionBuilder = new ConnectionBuilder(cliTerminal);
ConnectionConfiguration con = connectionBuilder.buildConnection(uri, keystoreLocation, binary);
CliSession cliSession = new CliSession(new HttpClient(con));
- cliSession.setDebug(debug);
+ cliSession.cfg().setDebug(debug);
if (checkConnection) {
checkConnection(cliSession, cliTerminal, con);
}
@@ -150,7 +152,7 @@ private void checkConnection(CliSession cliSession, CliTerminal cliTerminal, Con
try {
cliSession.checkConnection();
} catch (ClientException ex) {
- if (cliSession.isDebug()) {
+ if (cliSession.cfg().isDebug()) {
cliTerminal.error("Client Exception", ex.getMessage());
cliTerminal.println();
cliTerminal.printStackTrace(ex);
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/AbstractServerCliCommand.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/AbstractServerCliCommand.java
index a3ede76da53a7..89f8a71ca9f5c 100644
--- a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/AbstractServerCliCommand.java
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/AbstractServerCliCommand.java
@@ -34,7 +34,7 @@ protected void handleExceptionWhileCommunicatingWithServer(CliTerminal terminal,
.param(e.getMessage() == null ? e.getClass().getName() : e.getMessage())
.error("]")
.ln();
- if (cliSession.isDebug()) {
+ if (cliSession.cfg().isDebug()) {
terminal.printStackTrace(e);
}
}
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/CliSession.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/CliSession.java
index 34502aab9db3f..b48c4b84cd0cf 100644
--- a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/CliSession.java
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/CliSession.java
@@ -9,7 +9,6 @@
import org.elasticsearch.xpack.sql.client.ClientException;
import org.elasticsearch.xpack.sql.client.ClientVersion;
import org.elasticsearch.xpack.sql.client.HttpClient;
-import org.elasticsearch.xpack.sql.proto.CoreProtocol;
import org.elasticsearch.xpack.sql.proto.MainResponse;
import org.elasticsearch.xpack.sql.proto.SqlVersion;
@@ -20,52 +19,19 @@
*/
public class CliSession {
private final HttpClient httpClient;
- private int fetchSize = CoreProtocol.FETCH_SIZE;
- private String fetchSeparator = "";
- private boolean debug;
- private boolean binary;
+ private final CliSessionConfiguration configuration;
public CliSession(HttpClient httpClient) {
this.httpClient = httpClient;
+ this.configuration = new CliSessionConfiguration();
}
public HttpClient getClient() {
return httpClient;
}
- public void setFetchSize(int fetchSize) {
- if (fetchSize <= 0) {
- throw new IllegalArgumentException("Must be > 0.");
- }
- this.fetchSize = fetchSize;
- }
-
- public int getFetchSize() {
- return fetchSize;
- }
-
- public void setFetchSeparator(String fetchSeparator) {
- this.fetchSeparator = fetchSeparator;
- }
-
- public String getFetchSeparator() {
- return fetchSeparator;
- }
-
- public void setDebug(boolean debug) {
- this.debug = debug;
- }
-
- public boolean isDebug() {
- return debug;
- }
-
- public void setBinary(boolean binary) {
- this.binary = binary;
- }
-
- public boolean isBinary() {
- return binary;
+ public CliSessionConfiguration cfg() {
+ return configuration;
}
public void checkConnection() throws ClientException {
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/CliSessionConfiguration.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/CliSessionConfiguration.java
new file mode 100644
index 0000000000000..4507d36946bde
--- /dev/null
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/CliSessionConfiguration.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.sql.cli.command;
+
+import org.elasticsearch.xpack.sql.proto.CoreProtocol;
+
+/**
+ * Configuration for CLI session
+ */
+public class CliSessionConfiguration {
+ private int fetchSize;
+ private String fetchSeparator = "";
+ private boolean debug;
+ private boolean lenient;
+
+ public CliSessionConfiguration() {
+ this.fetchSize = CoreProtocol.FETCH_SIZE;
+ this.lenient = CoreProtocol.FIELD_MULTI_VALUE_LENIENCY;
+ }
+
+ public void setFetchSize(int fetchSize) {
+ if (fetchSize <= 0) {
+ throw new IllegalArgumentException("Must be > 0.");
+ }
+ this.fetchSize = fetchSize;
+ }
+
+ public int getFetchSize() {
+ return fetchSize;
+ }
+
+ public void setFetchSeparator(String fetchSeparator) {
+ this.fetchSeparator = fetchSeparator;
+ }
+
+ public String getFetchSeparator() {
+ return fetchSeparator;
+ }
+
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ public boolean isDebug() {
+ return debug;
+ }
+
+ public boolean isLenient() {
+ return lenient;
+ }
+
+ public void setLenient(boolean lenient) {
+ this.lenient = lenient;
+ }
+}
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSeparatorCliCommand.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSeparatorCliCommand.java
index bd07a5b9f04e2..efb6c9c054775 100644
--- a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSeparatorCliCommand.java
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSeparatorCliCommand.java
@@ -22,8 +22,8 @@ public FetchSeparatorCliCommand() {
@Override
protected boolean doHandle(CliTerminal terminal, CliSession cliSession, Matcher m, String line) {
- cliSession.setFetchSeparator(m.group(1));
- terminal.line().text("fetch separator set to \"").em(cliSession.getFetchSeparator()).text("\"").end();
+ cliSession.cfg().setFetchSeparator(m.group(1));
+ terminal.line().text("fetch separator set to \"").em(cliSession.cfg().getFetchSeparator()).text("\"").end();
return true;
}
}
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSizeCliCommand.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSizeCliCommand.java
index c4b3f1aeeb0ae..f17b3c469aa2d 100644
--- a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSizeCliCommand.java
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/FetchSizeCliCommand.java
@@ -23,7 +23,7 @@ public FetchSizeCliCommand() {
@Override
protected boolean doHandle(CliTerminal terminal, CliSession cliSession, Matcher m, String line) {
try {
- cliSession.setFetchSize(Integer.parseInt(m.group(1)));
+ cliSession.cfg().setFetchSize(Integer.parseInt(m.group(1)));
} catch (NumberFormatException e) {
terminal.line().error("Invalid fetch size [").param(m.group(1)).error("]").end();
return true;
@@ -31,7 +31,7 @@ protected boolean doHandle(CliTerminal terminal, CliSession cliSession, Matcher
terminal.line().error("Invalid fetch size [").param(m.group(1)).error("]. " + e.getMessage()).end();
return true;
}
- terminal.line().text("fetch size set to ").em(Integer.toString(cliSession.getFetchSize())).end();
+ terminal.line().text("fetch size set to ").em(Integer.toString(cliSession.cfg().getFetchSize())).end();
return true;
}
}
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/LenientCliCommand.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/LenientCliCommand.java
new file mode 100644
index 0000000000000..fd285a35c96e5
--- /dev/null
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/LenientCliCommand.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.sql.cli.command;
+
+import org.elasticsearch.xpack.sql.cli.CliTerminal;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * lenient command, enables/disables fields multi-value leniency.
+ * ie. with lenient = true, in case of array values, return the first value, with no guarantee of consistent results.
+ *
+ */
+public class LenientCliCommand extends AbstractCliCommand {
+
+ public LenientCliCommand() {
+ super(Pattern.compile("lenient *= *(.+)", Pattern.CASE_INSENSITIVE));
+ }
+
+ @Override
+ protected boolean doHandle(CliTerminal terminal, CliSession cliSession, Matcher m, String line) {
+ cliSession.cfg().setLenient(Boolean.parseBoolean(m.group(1)));
+ terminal.line().text("lenient set to ").em(Boolean.toString(cliSession.cfg().isLenient())).end();
+ return true;
+ }
+}
diff --git a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommand.java b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommand.java
index 1d929ed7708b4..ae582837b2e9f 100644
--- a/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommand.java
+++ b/x-pack/plugin/sql/sql-cli/src/main/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommand.java
@@ -26,7 +26,7 @@ protected boolean doHandle(CliTerminal terminal, CliSession cliSession, String l
SimpleFormatter formatter;
String data;
try {
- response = cliClient.basicQuery(line, cliSession.getFetchSize());
+ response = cliClient.basicQuery(line, cliSession.cfg().getFetchSize(), cliSession.cfg().isLenient());
formatter = new SimpleFormatter(response.columns(), response.rows(), CLI);
data = formatter.formatWithHeader(response.columns(), response.rows());
while (true) {
@@ -36,8 +36,8 @@ protected boolean doHandle(CliTerminal terminal, CliSession cliSession, String l
terminal.flush();
return true;
}
- if (false == cliSession.getFetchSeparator().equals("")) {
- terminal.println(cliSession.getFetchSeparator());
+ if (false == cliSession.cfg().getFetchSeparator().equals("")) {
+ terminal.println(cliSession.cfg().getFetchSeparator());
}
response = cliSession.getClient().nextPage(response.cursor());
data = formatter.formatWithoutHeader(response.rows());
diff --git a/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/BuiltinCommandTests.java b/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/BuiltinCommandTests.java
index 6c935885662a4..0d809f940c820 100644
--- a/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/BuiltinCommandTests.java
+++ b/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/BuiltinCommandTests.java
@@ -44,20 +44,20 @@ public void testFetchSeparator() throws Exception {
CliSession cliSession = new CliSession(httpClient);
FetchSeparatorCliCommand cliCommand = new FetchSeparatorCliCommand();
assertFalse(cliCommand.handle(testTerminal, cliSession, "fetch"));
- assertEquals("", cliSession.getFetchSeparator());
+ assertEquals("", cliSession.cfg().getFetchSeparator());
assertTrue(cliCommand.handle(testTerminal, cliSession, "fetch_separator = \"foo\""));
- assertEquals("foo", cliSession.getFetchSeparator());
+ assertEquals("foo", cliSession.cfg().getFetchSeparator());
assertEquals("fetch separator set to \"foo\"", testTerminal.toString());
testTerminal.clear();
assertTrue(cliCommand.handle(testTerminal, cliSession, "fetch_separator=\"bar\""));
- assertEquals("bar", cliSession.getFetchSeparator());
+ assertEquals("bar", cliSession.cfg().getFetchSeparator());
assertEquals("fetch separator set to \"bar\"", testTerminal.toString());
testTerminal.clear();
assertTrue(cliCommand.handle(testTerminal, cliSession, "fetch separator=\"baz\""));
- assertEquals("baz", cliSession.getFetchSeparator());
+ assertEquals("baz", cliSession.cfg().getFetchSeparator());
assertEquals("fetch separator set to \"baz\"", testTerminal.toString());
verifyNoMoreInteractions(httpClient);
}
@@ -68,21 +68,21 @@ public void testFetchSize() throws Exception {
CliSession cliSession = new CliSession(httpClient);
FetchSizeCliCommand cliCommand = new FetchSizeCliCommand();
assertFalse(cliCommand.handle(testTerminal, cliSession, "fetch"));
- assertEquals(1000L, cliSession.getFetchSize());
+ assertEquals(1000L, cliSession.cfg().getFetchSize());
assertTrue(cliCommand.handle(testTerminal, cliSession, "fetch_size = \"foo\""));
- assertEquals(1000L, cliSession.getFetchSize());
+ assertEquals(1000L, cliSession.cfg().getFetchSize());
assertEquals("Invalid fetch size [\"foo\"]", testTerminal.toString());
testTerminal.clear();
assertTrue(cliCommand.handle(testTerminal, cliSession, "fetch_size = 10"));
- assertEquals(10L, cliSession.getFetchSize());
+ assertEquals(10L, cliSession.cfg().getFetchSize());
assertEquals("fetch size set to 10", testTerminal.toString());
testTerminal.clear();
assertTrue(cliCommand.handle(testTerminal, cliSession, "fetch_size = -10"));
- assertEquals(10L, cliSession.getFetchSize());
+ assertEquals(10L, cliSession.cfg().getFetchSize());
assertEquals("Invalid fetch size [-10]. Must be > 0.", testTerminal.toString());
verifyNoMoreInteractions(httpClient);
}
@@ -98,4 +98,21 @@ public void testPrintLogo() throws Exception {
verifyNoMoreInteractions(httpClient);
}
+ public void testLenient() {
+ TestTerminal testTerminal = new TestTerminal();
+ HttpClient httpClient = mock(HttpClient.class);
+ CliSession cliSession = new CliSession(httpClient);
+ LenientCliCommand cliCommand = new LenientCliCommand();
+ assertFalse(cliCommand.handle(testTerminal, cliSession, "lenient"));
+ assertEquals(false, cliSession.cfg().isLenient());
+ assertTrue(cliCommand.handle(testTerminal, cliSession, "lenient = true"));
+ assertEquals(true, cliSession.cfg().isLenient());
+ assertEquals("lenient set to true", testTerminal.toString());
+ testTerminal.clear();
+ assertTrue(cliCommand.handle(testTerminal, cliSession, "lenient = false"));
+ assertEquals(false, cliSession.cfg().isLenient());
+ assertEquals("lenient set to false", testTerminal.toString());
+ testTerminal.clear();
+ }
+
}
diff --git a/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommandTests.java b/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommandTests.java
index e005e9f668ff9..bc1eb75bd9a76 100644
--- a/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommandTests.java
+++ b/x-pack/plugin/sql/sql-cli/src/test/java/org/elasticsearch/xpack/sql/cli/command/ServerQueryCliCommandTests.java
@@ -32,11 +32,11 @@ public void testExceptionHandling() throws Exception {
TestTerminal testTerminal = new TestTerminal();
HttpClient client = mock(HttpClient.class);
CliSession cliSession = new CliSession(client);
- when(client.basicQuery("blah", 1000)).thenThrow(new SQLException("test exception"));
+ when(client.basicQuery("blah", 1000, false)).thenThrow(new SQLException("test exception"));
ServerQueryCliCommand cliCommand = new ServerQueryCliCommand();
assertTrue(cliCommand.handle(testTerminal, cliSession, "blah"));
assertEquals("Bad request [test exception]\n", testTerminal.toString());
- verify(client, times(1)).basicQuery(eq("blah"), eq(1000));
+ verify(client, times(1)).basicQuery(eq("blah"), eq(1000), eq(false));
verifyNoMoreInteractions(client);
}
@@ -44,8 +44,8 @@ public void testOnePageQuery() throws Exception {
TestTerminal testTerminal = new TestTerminal();
HttpClient client = mock(HttpClient.class);
CliSession cliSession = new CliSession(client);
- cliSession.setFetchSize(10);
- when(client.basicQuery("test query", 10)).thenReturn(fakeResponse("", true, "foo"));
+ cliSession.cfg().setFetchSize(10);
+ when(client.basicQuery("test query", 10, false)).thenReturn(fakeResponse("", true, "foo"));
ServerQueryCliCommand cliCommand = new ServerQueryCliCommand();
assertTrue(cliCommand.handle(testTerminal, cliSession, "test query"));
assertEquals("""
@@ -53,7 +53,7 @@ public void testOnePageQuery() throws Exception {
---------------
foo \s
""", testTerminal.toString());
- verify(client, times(1)).basicQuery(eq("test query"), eq(10));
+ verify(client, times(1)).basicQuery(eq("test query"), eq(10), eq(false));
verifyNoMoreInteractions(client);
}
@@ -61,8 +61,8 @@ public void testThreePageQuery() throws Exception {
TestTerminal testTerminal = new TestTerminal();
HttpClient client = mock(HttpClient.class);
CliSession cliSession = new CliSession(client);
- cliSession.setFetchSize(10);
- when(client.basicQuery("test query", 10)).thenReturn(fakeResponse("my_cursor1", true, "first"));
+ cliSession.cfg().setFetchSize(10);
+ when(client.basicQuery("test query", 10, false)).thenReturn(fakeResponse("my_cursor1", true, "first"));
when(client.nextPage("my_cursor1")).thenReturn(fakeResponse("my_cursor2", false, "second"));
when(client.nextPage("my_cursor2")).thenReturn(fakeResponse("", false, "third"));
ServerQueryCliCommand cliCommand = new ServerQueryCliCommand();
@@ -74,7 +74,7 @@ public void testThreePageQuery() throws Exception {
second \s
third \s
""", testTerminal.toString());
- verify(client, times(1)).basicQuery(eq("test query"), eq(10));
+ verify(client, times(1)).basicQuery(eq("test query"), eq(10), eq(false));
verify(client, times(2)).nextPage(any());
verifyNoMoreInteractions(client);
}
@@ -83,10 +83,10 @@ public void testTwoPageQueryWithSeparator() throws Exception {
TestTerminal testTerminal = new TestTerminal();
HttpClient client = mock(HttpClient.class);
CliSession cliSession = new CliSession(client);
- cliSession.setFetchSize(15);
+ cliSession.cfg().setFetchSize(15);
// Set a separator
- cliSession.setFetchSeparator("-----");
- when(client.basicQuery("test query", 15)).thenReturn(fakeResponse("my_cursor1", true, "first"));
+ cliSession.cfg().setFetchSeparator("-----");
+ when(client.basicQuery("test query", 15, false)).thenReturn(fakeResponse("my_cursor1", true, "first"));
when(client.nextPage("my_cursor1")).thenReturn(fakeResponse("", false, "second"));
ServerQueryCliCommand cliCommand = new ServerQueryCliCommand();
assertTrue(cliCommand.handle(testTerminal, cliSession, "test query"));
@@ -97,7 +97,7 @@ public void testTwoPageQueryWithSeparator() throws Exception {
-----
second \s
""", testTerminal.toString());
- verify(client, times(1)).basicQuery(eq("test query"), eq(15));
+ verify(client, times(1)).basicQuery(eq("test query"), eq(15), eq(false));
verify(client, times(1)).nextPage(any());
verifyNoMoreInteractions(client);
}
@@ -106,8 +106,8 @@ public void testCursorCleanupOnError() throws Exception {
TestTerminal testTerminal = new TestTerminal();
HttpClient client = mock(HttpClient.class);
CliSession cliSession = new CliSession(client);
- cliSession.setFetchSize(15);
- when(client.basicQuery("test query", 15)).thenReturn(fakeResponse("my_cursor1", true, "first"));
+ cliSession.cfg().setFetchSize(15);
+ when(client.basicQuery("test query", 15, false)).thenReturn(fakeResponse("my_cursor1", true, "first"));
when(client.nextPage("my_cursor1")).thenThrow(new SQLException("test exception"));
when(client.queryClose("my_cursor1", Mode.CLI)).thenReturn(true);
ServerQueryCliCommand cliCommand = new ServerQueryCliCommand();
@@ -118,7 +118,7 @@ public void testCursorCleanupOnError() throws Exception {
first \s
Bad request [test exception]
""", testTerminal.toString());
- verify(client, times(1)).basicQuery(eq("test query"), eq(15));
+ verify(client, times(1)).basicQuery(eq("test query"), eq(15), eq(false));
verify(client, times(1)).nextPage(any());
verify(client, times(1)).queryClose(eq("my_cursor1"), eq(Mode.CLI));
verifyNoMoreInteractions(client);
diff --git a/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java b/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java
index 8c14a8008540c..d3784b70a00e2 100644
--- a/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java
+++ b/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java
@@ -61,6 +61,10 @@ public MainResponse serverInfo() throws SQLException {
}
public SqlQueryResponse basicQuery(String query, int fetchSize) throws SQLException {
+ return basicQuery(query, fetchSize, CoreProtocol.FIELD_MULTI_VALUE_LENIENCY);
+ }
+
+ public SqlQueryResponse basicQuery(String query, int fetchSize, boolean fieldMultiValueLeniency) throws SQLException {
// TODO allow customizing the time zone - this is what session set/reset/get should be about
// method called only from CLI
SqlQueryRequest sqlRequest = new SqlQueryRequest(
@@ -74,7 +78,7 @@ public SqlQueryResponse basicQuery(String query, int fetchSize) throws SQLExcept
Boolean.FALSE,
null,
new RequestInfo(Mode.CLI, ClientVersion.CURRENT),
- false,
+ fieldMultiValueLeniency,
false,
cfg.binaryCommunication()
);
diff --git a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/HttpClientRequestTests.java b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/HttpClientRequestTests.java
index 6b4648702fb0f..6ff8fc6946856 100644
--- a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/HttpClientRequestTests.java
+++ b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/HttpClientRequestTests.java
@@ -106,7 +106,7 @@ private void assertBinaryRequestForCLI(XContentType xContentType) throws URISynt
prepareMockResponse();
try {
- httpClient.basicQuery(query, fetchSize);
+ httpClient.basicQuery(query, fetchSize, randomBoolean());
} catch (SQLException e) {
logger.info("Ignored SQLException", e);
}