This is an automated email from the ASF dual-hosted git repository.
sk0x50 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new eb4f324245 IGNITE-17090 Show user-friendly message in sql command.
Fixes #1024
eb4f324245 is described below
commit eb4f324245054187b562baba5e3e5f7ed17ce90f
Author: Aleksandr Pakhomov <[email protected]>
AuthorDate: Fri Sep 9 19:57:43 2022 +0300
IGNITE-17090 Show user-friendly message in sql command. Fixes #1024
Signed-off-by: Slava Koptilin <[email protected]>
---
.../ignite/cli/commands/sql/ItSqlCommandTest.java | 56 ++++++++++++++--
.../exception/handler/SqlExceptionHandler.java | 77 +++++++++++++++++++++-
.../ignite/cli/core/style/AnsiStringSupport.java | 16 ++---
.../cli/core/style/component/CommonMessages.java | 4 +-
.../cli/core/style/element/MarkedUiElement.java | 4 +-
.../ignite/cli/core/style/element/UiElement.java | 4 +-
.../ignite/cli/core/style/element/UiElements.java | 4 +-
.../ignite/cli/core/style/element/UiString.java | 4 +-
.../client/handler/JdbcQueryEventHandlerImpl.java | 4 +-
.../apache/ignite/internal/jdbc/JdbcStatement.java | 13 +---
.../java/org/apache/ignite/lang/ErrorGroup.java | 4 +-
.../org/apache/ignite/lang/ErrorGroupTest.java | 31 +++++++++
.../ignite/internal/sql/engine/util/Commons.java | 8 ++-
13 files changed, 180 insertions(+), 49 deletions(-)
diff --git
a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java
b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java
index 034a4d2b5f..ecf746b239 100644
---
a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java
+++
b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java
@@ -31,7 +31,6 @@ import org.junit.jupiter.api.TestInfo;
* Tests for {@link SqlCommand}.
*/
class ItSqlCommandTest extends CliCommandTestInitializedIntegrationBase {
-
@BeforeEach
@Override
public void setUp(TestInfo testInfo) throws Exception {
@@ -64,8 +63,7 @@ class ItSqlCommandTest extends
CliCommandTestInitializedIntegrationBase {
assertAll(
() -> assertExitCodeIs(1),
this::assertOutputIsEmpty,
- // TODO: https://issues.apache.org/jira/browse/IGNITE-17090
- () -> assertErrOutputIs(CLIENT_CONNECTION_FAILED_MESSAGE +
System.lineSeparator())
+ () -> assertErrOutputContains(CLIENT_CONNECTION_FAILED_MESSAGE)
);
}
@@ -77,9 +75,55 @@ class ItSqlCommandTest extends
CliCommandTestInitializedIntegrationBase {
assertAll(
() -> assertExitCodeIs(1),
this::assertOutputIsEmpty,
- // TODO: https://issues.apache.org/jira/browse/IGNITE-17090
- () -> assertErrOutputIs("SQL query parsing error" +
System.lineSeparator()
- + "Sql query execution failed." +
System.lineSeparator())
+ () -> assertErrOutputContains("Failed to parse query:
Encountered \"\" at line 1, column 6")
+ );
+ }
+
+ @Test
+ @DisplayName("Should display readable error when wrong engine is given on
CREATE TABLE")
+ void incorrectEngineOnCreate() {
+ execute("sql", "create table mytable1(i int, j int, primary key (i))
with engine='nusuch'", "--jdbc-url", JDBC_URL);
+
+ assertAll(
+ () -> assertExitCodeIs(1),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("Unexpected table option
[option=ENGINE")
+ );
+ }
+
+ @Test
+ @DisplayName("Should display readable error when not SQL expression given")
+ void notSqlExpression() {
+ execute("sql", "asdf", "--jdbc-url", JDBC_URL);
+
+ assertAll(
+ () -> assertExitCodeIs(1),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("Failed to parse query:
Non-query expression encountered in illegal context")
+ );
+ }
+
+ @Test
+ @DisplayName("Should display readable error when select from non existent
table")
+ void noSuchTableSelect() {
+ execute("sql", "select * from nosuchtable", "--jdbc-url", JDBC_URL);
+
+ assertAll(
+ () -> assertExitCodeIs(1),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("From line 1, column 15 to line
1, column 25: Object 'NOSUCHTABLE' not found")
+ );
+ }
+
+ @Test
+ @DisplayName("Should display readable error when create table without PK")
+ void createTableWithoutPk() {
+ execute("sql", "create table mytable(i int)", "--jdbc-url", JDBC_URL);
+
+ assertAll(
+ () -> assertExitCodeIs(1),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("Table without PRIMARY KEY is
not supported")
);
}
}
diff --git
a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java
b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java
index d3d62e87b7..7d498b8aac 100644
---
a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java
+++
b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java
@@ -18,12 +18,24 @@
package org.apache.ignite.cli.core.exception.handler;
import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.Function;
import org.apache.ignite.cli.core.exception.ExceptionHandler;
import org.apache.ignite.cli.core.exception.ExceptionWriter;
import org.apache.ignite.cli.core.style.component.ErrorUiComponent;
+import
org.apache.ignite.cli.core.style.component.ErrorUiComponent.ErrorComponentBuilder;
+import org.apache.ignite.client.IgniteClientConnectionException;
import org.apache.ignite.internal.jdbc.proto.SqlStateCode;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.util.ExceptionUtils;
+import org.apache.ignite.lang.ErrorGroup;
+import org.apache.ignite.lang.ErrorGroups.Client;
+import org.apache.ignite.lang.ErrorGroups.Sql;
+import org.apache.ignite.lang.IgniteCheckedException;
+import org.apache.ignite.lang.IgniteException;
/**
* Exception handler for {@link SQLException}.
@@ -38,9 +50,52 @@ public class SqlExceptionHandler implements
ExceptionHandler<SQLException> {
public static final String CLIENT_CONNECTION_FAILED_MESSAGE = "Connection
failed";
public static final String CONNECTION_BROKE_MESSAGE = "Connection error";
+ public static final String UNRECOGNIZED_ERROR_MESSAGE = "Unrecognized
error while processing SQL query ";
+
+ private final Map<Integer, Function<IgniteException,
ErrorComponentBuilder>> sqlExceptionMappers = new HashMap<>();
+
+ /** Default constructor. */
+ public SqlExceptionHandler() {
+ sqlExceptionMappers.put(Client.CONNECTION_ERR,
this::connectionErrUiComponent);
+ sqlExceptionMappers.put(Sql.QUERY_INVALID_ERR,
this::invalidQueryErrUiComponent);
+ }
+
+ private ErrorComponentBuilder invalidQueryErrUiComponent(IgniteException
e) {
+ return fromExWithHeader(PARSING_ERROR_MESSAGE, e.errorCode(),
e.traceId(), e.getMessage());
+ }
+
+ private ErrorComponentBuilder unrecognizedErrComponent(IgniteException e) {
+ return fromExWithHeader(UNRECOGNIZED_ERROR_MESSAGE, e.errorCode(),
e.traceId(), e.getMessage());
+ }
+
+ private ErrorComponentBuilder connectionErrUiComponent(IgniteException e) {
+ if (e.getCause() instanceof IgniteClientConnectionException) {
+ IgniteClientConnectionException cause =
(IgniteClientConnectionException) e.getCause();
+ return fromExWithHeader(CLIENT_CONNECTION_FAILED_MESSAGE,
cause.errorCode(), cause.traceId(), cause.getMessage());
+ }
+
+ return fromExWithHeader(CLIENT_CONNECTION_FAILED_MESSAGE,
e.errorCode(), e.traceId(), e.getMessage());
+ }
+
+ private static ErrorComponentBuilder fromExWithHeader(String header, int
errorCode, UUID traceId, String message) {
+ return ErrorUiComponent.builder()
+ .header(header)
+ .errorCode(String.valueOf(errorCode))
+ .traceId(traceId)
+ .details(ErrorGroup.extractCauseMessage(message));
+ }
@Override
public int handle(ExceptionWriter err, SQLException e) {
+ Throwable unwrappedCause = ExceptionUtils.unwrapCause(e.getCause());
+ if (unwrappedCause instanceof IgniteException) {
+ return handleIgniteException(err, (IgniteException)
unwrappedCause);
+ }
+
+ if (unwrappedCause instanceof IgniteCheckedException) {
+ return handleIgniteCheckedException(err, (IgniteCheckedException)
unwrappedCause);
+ }
+
var errorComponentBuilder = ErrorUiComponent.builder();
switch (e.getSQLState()) {
@@ -50,7 +105,7 @@ public class SqlExceptionHandler implements
ExceptionHandler<SQLException> {
errorComponentBuilder.header(CONNECTION_BROKE_MESSAGE);
break;
case SqlStateCode.PARSING_EXCEPTION:
-
errorComponentBuilder.header(PARSING_ERROR_MESSAGE).details(e.getMessage());
+
errorComponentBuilder.header(PARSING_ERROR_MESSAGE).details(ErrorGroup.extractCauseMessage(e.getMessage()));
break;
case SqlStateCode.INVALID_PARAMETER_VALUE:
errorComponentBuilder.header(INVALID_PARAMETER_MESSAGE);
@@ -60,13 +115,31 @@ public class SqlExceptionHandler implements
ExceptionHandler<SQLException> {
break;
default:
LOG.error("Unrecognized error", e);
- errorComponentBuilder.header("Unrecognized error while process
SQL query");
+ errorComponentBuilder.header("SQL query execution
error").details(e.getMessage());
}
err.write(errorComponentBuilder.build().render());
return 1;
}
+ /** Handles IgniteException that has more information like error code and
trace id. */
+ private int handleIgniteException(ExceptionWriter err, IgniteException e) {
+ var errorComponentBuilder = sqlExceptionMappers.getOrDefault(e.code(),
this::unrecognizedErrComponent);
+
+ String renderedError = errorComponentBuilder.apply(e).build().render();
+ err.write(renderedError);
+
+ return 1;
+ }
+
+ private int handleIgniteCheckedException(ExceptionWriter err,
IgniteCheckedException e) {
+ String renderedError = fromExWithHeader(UNRECOGNIZED_ERROR_MESSAGE,
e.errorCode(), e.traceId(), e.getMessage())
+ .build().render();
+ err.write(renderedError);
+
+ return 1;
+ }
+
@Override
public Class<SQLException> applicableException() {
return SQLException.class;
diff --git
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/AnsiStringSupport.java
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/AnsiStringSupport.java
index e9e20a6e62..d69f7e07d5 100644
---
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/AnsiStringSupport.java
+++
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/AnsiStringSupport.java
@@ -33,9 +33,7 @@ public final class AnsiStringSupport {
return new Fg(color);
}
- /**
- * Can mark the string as a ANSI string.
- */
+ /** Can mark the string as a ANSI string. */
public interface Marker {
String mark(String content);
}
@@ -45,6 +43,7 @@ public final class AnsiStringSupport {
*/
public static class Fg implements Marker {
private final Color color;
+
private Style style;
private Fg(Color color) {
@@ -56,9 +55,7 @@ public final class AnsiStringSupport {
return this;
}
- /**
- * Marks given text with the configured before style.
- */
+ /** Marks given text with the configured before style. */
public String mark(String textToMark) {
if (style == Style.BOLD) {
return String.format("@|fg(%d),bold %s|@", color.code,
textToMark);
@@ -67,12 +64,9 @@ public final class AnsiStringSupport {
}
}
- /**
- * Represents the text style.
- */
+ /** Represents the text style. */
public enum Style implements Marker {
- BOLD("bold"),
- UNDERLINE("underline");
+ BOLD("bold"), UNDERLINE("underline");
private final String value;
diff --git
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/component/CommonMessages.java
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/component/CommonMessages.java
index 7bbf3f3518..dae4fe5bfb 100644
---
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/component/CommonMessages.java
+++
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/component/CommonMessages.java
@@ -19,9 +19,7 @@ package org.apache.ignite.cli.core.style.component;
import org.apache.ignite.cli.core.style.element.UiElements;
-/**
- * Common UI messages.
- */
+/** Common UI messages. */
public class CommonMessages {
public static MessageUiComponent CONNECT_OR_USE_CLUSTER_URL_MESSAGE =
MessageUiComponent.builder()
.message("You are not connected to node")
diff --git
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/MarkedUiElement.java
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/MarkedUiElement.java
index 56522c1f3b..24c50dc9dc 100644
---
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/MarkedUiElement.java
+++
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/MarkedUiElement.java
@@ -19,9 +19,7 @@ package org.apache.ignite.cli.core.style.element;
import org.apache.ignite.cli.core.style.AnsiStringSupport.Marker;
-/**
- * IU element that is marked with provided ANSI marker.
- */
+/** IU element that is marked with provided ANSI marker. */
public class MarkedUiElement implements UiElement {
private final String content;
diff --git
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElement.java
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElement.java
index a808770e69..941d5bd2a9 100644
---
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElement.java
+++
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElement.java
@@ -17,9 +17,7 @@
package org.apache.ignite.cli.core.style.element;
-/**
- * Can represent UI Element as an ANSI string.
- */
+/** Can represent UI Element as an ANSI string. */
public interface UiElement {
/** Represents the UI Element as ansi String. For example '@|fg(1) text
|@'. */
String represent();
diff --git
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElements.java
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElements.java
index 224130bb7a..240c1314d9 100644
---
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElements.java
+++
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiElements.java
@@ -22,9 +22,7 @@ import static
org.apache.ignite.cli.core.style.AnsiStringSupport.fg;
import org.apache.ignite.cli.core.style.AnsiStringSupport.Color;
import org.apache.ignite.cli.core.style.AnsiStringSupport.Style;
-/**
- * Defines all UI Elements that are used in the CLI.
- */
+/** Defines all UI Elements that are used in the CLI. */
public class UiElements {
public static UiElement url(String content) {
return new MarkedUiElement(content, Style.UNDERLINE);
diff --git
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiString.java
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiString.java
index ee92072444..c7aed9f84a 100644
---
a/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiString.java
+++
b/modules/cli/src/main/java/org/apache/ignite/cli/core/style/element/UiString.java
@@ -19,9 +19,7 @@ package org.apache.ignite.cli.core.style.element;
import java.util.Arrays;
-/**
- * Can format the string with UI Elements.
- */
+/** Can format the string with UI Elements. */
public class UiString {
/** Accepts the String template with UI Elements. */
public static String format(String template, UiElement... elements) {
diff --git
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/JdbcQueryEventHandlerImpl.java
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/JdbcQueryEventHandlerImpl.java
index 53596c2a60..79f67525a8 100644
---
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/JdbcQueryEventHandlerImpl.java
+++
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/JdbcQueryEventHandlerImpl.java
@@ -57,6 +57,7 @@ import org.apache.ignite.internal.sql.engine.QueryValidator;
import org.apache.ignite.internal.sql.engine.exec.QueryValidationException;
import org.apache.ignite.internal.sql.engine.prepare.QueryPlan;
import org.apache.ignite.internal.sql.engine.prepare.QueryPlan.Type;
+import org.apache.ignite.internal.util.ExceptionUtils;
import org.apache.ignite.lang.IgniteInternalCheckedException;
import org.apache.ignite.lang.IgniteInternalException;
import org.apache.ignite.sql.ResultSetMetadata;
@@ -272,10 +273,11 @@ public class JdbcQueryEventHandlerImpl implements
JdbcQueryEventHandler {
* @return StringWriter filled with exception.
*/
private StringWriter getWriterWithStackTrace(Throwable t) {
+ String message = ExceptionUtils.unwrapCause(t).getMessage();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
+ pw.print(message);
return sw;
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/jdbc/JdbcStatement.java
b/modules/client/src/main/java/org/apache/ignite/internal/jdbc/JdbcStatement.java
index 3ad1a8b8f8..b9c1906880 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/jdbc/JdbcStatement.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/jdbc/JdbcStatement.java
@@ -46,7 +46,6 @@ import
org.apache.ignite.internal.jdbc.proto.event.JdbcQuerySingleResult;
import org.apache.ignite.internal.jdbc.proto.event.Response;
import org.apache.ignite.internal.util.ArrayUtils;
import org.apache.ignite.internal.util.CollectionUtils;
-import org.apache.ignite.lang.IgniteException;
/**
* Jdbc statement implementation.
@@ -734,16 +733,6 @@ public class JdbcStatement implements Statement {
}
private static SQLException toSqlException(CompletionException e) {
- if (e.getCause() instanceof IgniteException) {
- IgniteException cause = (IgniteException) e.getCause();
- String message = cause.getMessage();
-
- if (message != null) {
- if (message.contains("Failed to parse query")) {
- return new SQLException("Sql query execution failed.",
SqlStateCode.PARSING_EXCEPTION, e);
- }
- }
- }
- return new SQLException("Internal server error.",
SqlStateCode.INTERNAL_ERROR, e);
+ return new SQLException(e);
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroup.java
b/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroup.java
index 3f18678b13..88c6b2d7a1 100755
--- a/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroup.java
+++ b/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroup.java
@@ -17,6 +17,8 @@
package org.apache.ignite.lang;
+import static java.util.regex.Pattern.DOTALL;
+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
@@ -36,7 +38,7 @@ public class ErrorGroup {
/** Error message pattern. */
private static final Pattern EXCEPTION_MESSAGE_PATTERN =
-
Pattern.compile("(.*)(IGN)-([A-Z]+)-(\\d+)\\s(TraceId:)([a-f0-9]{8}(?:-[a-f0-9]{4}){4}[a-f0-9]{8})(\\s?)(.*)");
+
Pattern.compile("(.*)(IGN)-([A-Z]+)-(\\d+)\\s(TraceId:)([a-f0-9]{8}(?:-[a-f0-9]{4}){4}[a-f0-9]{8})(\\s?)(.*)",
DOTALL);
/** List of all registered error groups. */
private static final Int2ObjectMap<ErrorGroup> registeredGroups = new
Int2ObjectOpenHashMap<>();
diff --git
a/modules/core/src/test/java/org/apache/ignite/lang/ErrorGroupTest.java
b/modules/core/src/test/java/org/apache/ignite/lang/ErrorGroupTest.java
index 65e95429f5..3063d33398 100644
--- a/modules/core/src/test/java/org/apache/ignite/lang/ErrorGroupTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/lang/ErrorGroupTest.java
@@ -20,6 +20,8 @@ package org.apache.ignite.lang;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
+import java.util.UUID;
+import org.apache.ignite.lang.ErrorGroups.Common;
import org.junit.jupiter.api.Test;
class ErrorGroupTest {
@@ -46,4 +48,33 @@ class ErrorGroupTest {
// Then
assertThat(extractedMessage, equalTo(""));
}
+
+ @Test
+ void createsErrorMassage() {
+ // Given
+ UUID traceId = UUID.fromString("24103638-d079-4a19-a8f6-ca9c23662908");
+ int code = Common.UNEXPECTED_ERR;
+ String reason = "I'm the reason";
+
+ // When
+ String errorMessage = ErrorGroup.errorMessage(traceId, code, reason);
+
+ // Then
+ assertThat(errorMessage, equalTo("IGN-CMN-1
TraceId:24103638-d079-4a19-a8f6-ca9c23662908 I'm the reason"));
+ }
+
+ @Test
+ void doesNotDuplicateErrorCodeAndTraceId() {
+ // Given
+ UUID traceId = UUID.fromString("24103638-d079-4a19-a8f6-ca9c23662908");
+ int code = Common.UNEXPECTED_ERR;
+ IgniteInternalException cause = new IgniteInternalException(traceId,
code, "I'm the\n reason\n");
+ IgniteInternalException origin = new IgniteInternalException(traceId,
code, cause);
+
+ // When
+ String errorMessage = origin.getMessage();
+
+ // Then error code and traceId are not duplicated
+ assertThat(errorMessage, equalTo("IGN-CMN-1
TraceId:24103638-d079-4a19-a8f6-ca9c23662908 I'm the\n reason\n"));
+ }
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
index 0ae238066d..ebaebbc4cf 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.sql.engine.util;
import static
org.apache.ignite.internal.sql.engine.util.BaseQueryContext.CLUSTER;
import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
+import static org.apache.ignite.internal.util.ExceptionUtils.withCauseAndCode;
+import static org.apache.ignite.lang.ErrorGroup.extractCauseMessage;
import static org.apache.ignite.lang.ErrorGroups.Sql.QUERY_INVALID_ERR;
import it.unimi.dsi.fastutil.ints.IntArrayList;
@@ -815,7 +817,11 @@ public final class Commons {
try {
return parse(new SourceStringReader(qry), parserCfg);
} catch (SqlParseException e) {
- throw new SqlException(QUERY_INVALID_ERR, "Failed to parse query",
e);
+ throw withCauseAndCode(
+ SqlException::new,
+ QUERY_INVALID_ERR,
+ "Failed to parse query: " +
extractCauseMessage(e.getMessage()),
+ e);
}
}