From f77b5fc9237412b331f44636b1f7821f0f65b793 Mon Sep 17 00:00:00 2001 From: Dominik Przybysz Date: Fri, 11 Oct 2024 12:23:57 +0200 Subject: [PATCH] SNOW-1732777: Log cancel query reason --- .../client/core/CancellationReason.java | 11 +++++++++++ .../snowflake/client/core/SFBaseStatement.java | 14 ++++++++++++++ .../net/snowflake/client/core/SFStatement.java | 15 +++++++++++---- .../net/snowflake/client/core/StmtUtil.java | 17 ++++++++++++++++- .../client/jdbc/SnowflakeStatementV1.java | 3 ++- 5 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/main/java/net/snowflake/client/core/CancellationReason.java diff --git a/src/main/java/net/snowflake/client/core/CancellationReason.java b/src/main/java/net/snowflake/client/core/CancellationReason.java new file mode 100644 index 000000000..e3ae4e308 --- /dev/null +++ b/src/main/java/net/snowflake/client/core/CancellationReason.java @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ +package net.snowflake.client.core; + +@SnowflakeJdbcInternalApi +public enum CancellationReason { + UNKNOWN, + CLIENT_REQUESTED, + TIMEOUT +} diff --git a/src/main/java/net/snowflake/client/core/SFBaseStatement.java b/src/main/java/net/snowflake/client/core/SFBaseStatement.java index 17b2fd1b6..8a6136434 100644 --- a/src/main/java/net/snowflake/client/core/SFBaseStatement.java +++ b/src/main/java/net/snowflake/client/core/SFBaseStatement.java @@ -116,9 +116,23 @@ public abstract SFBaseResultSet asyncExecute( * * @throws SFException if the statement is already closed. * @throws SQLException if there are server-side errors from trying to abort. + * @deprecated use {@link #cancel(CancellationReason)} instead */ + @Deprecated public abstract void cancel() throws SFException, SQLException; + /** + * Aborts the statement. + * + * @param cancellationReason reason for the cancellation + * @throws SFException if the statement is already closed. + * @throws SQLException if there are server-side errors from trying to abort. + */ + @SnowflakeJdbcInternalApi + public void cancel(CancellationReason cancellationReason) throws SFException, SQLException { + cancel(); // default cancel is called to keep interface backward compatibility + } + /** * Sets a property within session properties, i.e., if the sql is using set-sf-property * diff --git a/src/main/java/net/snowflake/client/core/SFStatement.java b/src/main/java/net/snowflake/client/core/SFStatement.java index 6142b8eb9..f3a0f8a09 100644 --- a/src/main/java/net/snowflake/client/core/SFStatement.java +++ b/src/main/java/net/snowflake/client/core/SFStatement.java @@ -298,7 +298,7 @@ private TimeBombTask(SFStatement statement) { @Override public Void call() throws SQLException { try { - statement.cancel(); + statement.cancel(CancellationReason.TIMEOUT); } catch (SFException ex) { throw new SnowflakeSQLLoggedException( session, ex.getSqlState(), ex.getVendorCode(), ex, ex.getParams()); @@ -711,10 +711,11 @@ private void reauthenticate() throws SFException, SnowflakeSQLException { * * @param sql sql statement * @param mediaType media type + * @param cancellationReason reason for the cancellation * @throws SnowflakeSQLException if failed to cancel the statement * @throws SFException if statement is already closed */ - private void cancelHelper(String sql, String mediaType) + private void cancelHelper(String sql, String mediaType, CancellationReason cancellationReason) throws SnowflakeSQLException, SFException { synchronized (this) { if (isClosed) { @@ -734,7 +735,7 @@ private void cancelHelper(String sql, String mediaType) .setMaxRetries(session.getMaxHttpRetries()) .setHttpClientSettingsKey(session.getHttpClientKey()); - StmtUtil.cancel(stmtInput); + StmtUtil.cancel(stmtInput, cancellationReason); synchronized (this) { /* @@ -842,6 +843,12 @@ public void close() { @Override public void cancel() throws SFException, SQLException { logger.trace("void cancel()", false); + cancel(CancellationReason.UNKNOWN); + } + + @Override + public void cancel(CancellationReason cancellationReason) throws SFException, SQLException { + logger.trace("void cancel(CancellationReason)", false); if (canceling.get()) { logger.debug("Query is already cancelled", false); @@ -866,7 +873,7 @@ public void cancel() throws SFException, SQLException { } // cancel the query on the server side if it has been issued - cancelHelper(this.sqlText, StmtUtil.SF_MEDIA_TYPE); + cancelHelper(this.sqlText, StmtUtil.SF_MEDIA_TYPE, cancellationReason); } } diff --git a/src/main/java/net/snowflake/client/core/StmtUtil.java b/src/main/java/net/snowflake/client/core/StmtUtil.java index 96fefe5dc..3d8055d1f 100644 --- a/src/main/java/net/snowflake/client/core/StmtUtil.java +++ b/src/main/java/net/snowflake/client/core/StmtUtil.java @@ -681,8 +681,23 @@ protected static JsonNode getQueryResultJSON(String queryId, SFSession session) * @param stmtInput input statement * @throws SFException if there is an internal exception * @throws SnowflakeSQLException if failed to cancel the statement + * @deprecated use {@link #cancel(StmtInput, CancellationReason)} instead */ + @Deprecated public static void cancel(StmtInput stmtInput) throws SFException, SnowflakeSQLException { + cancel(stmtInput, CancellationReason.UNKNOWN); + } + + /** + * Cancel a statement identifiable by a request id + * + * @param stmtInput input statement + * @param cancellationReason reason for the cancellation + * @throws SFException if there is an internal exception + * @throws SnowflakeSQLException if failed to cancel the statement + */ + public static void cancel(StmtInput stmtInput, CancellationReason cancellationReason) + throws SFException, SnowflakeSQLException { HttpPost httpRequest = null; AssertUtil.assertTrue( @@ -701,7 +716,7 @@ public static void cancel(StmtInput stmtInput) throws SFException, SnowflakeSQLE try { URIBuilder uriBuilder = new URIBuilder(stmtInput.serverUrl); - + logger.warn("Cancelling query {} with reason {}", stmtInput.requestId, cancellationReason); logger.debug("Aborting query: {}", stmtInput.sql); uriBuilder.setPath(SF_PATH_ABORT_REQUEST_V1); diff --git a/src/main/java/net/snowflake/client/jdbc/SnowflakeStatementV1.java b/src/main/java/net/snowflake/client/jdbc/SnowflakeStatementV1.java index 5016c175b..08cb3fac7 100644 --- a/src/main/java/net/snowflake/client/jdbc/SnowflakeStatementV1.java +++ b/src/main/java/net/snowflake/client/jdbc/SnowflakeStatementV1.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import net.snowflake.client.core.CancellationReason; import net.snowflake.client.core.ExecTimeTelemetryData; import net.snowflake.client.core.ParameterBindingDTO; import net.snowflake.client.core.ResultUtil; @@ -952,7 +953,7 @@ public void cancel() throws SQLException { raiseSQLExceptionIfStatementIsClosed(); try { - sfBaseStatement.cancel(); + sfBaseStatement.cancel(CancellationReason.CLIENT_REQUESTED); } catch (SFException ex) { throw new SnowflakeSQLException(ex, ex.getSqlState(), ex.getVendorCode(), ex.getParams()); }