From 6f14f039aad8fb6f0b8210071df56009a7677e41 Mon Sep 17 00:00:00 2001 From: lbrdnk <lbrdnk@users.noreply.github.com> Date: Wed, 17 Apr 2024 20:53:42 +0200 Subject: [PATCH] Cancel statement on completion of `execute-reducible-query` (#41470) * Cancel statement on completion of execute-reducible-query * Address review remarks --- src/metabase/driver/sql_jdbc/execute.clj | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/metabase/driver/sql_jdbc/execute.clj b/src/metabase/driver/sql_jdbc/execute.clj index 10d02abe8e6..f96f0152c3e 100644 --- a/src/metabase/driver/sql_jdbc/execute.clj +++ b/src/metabase/driver/sql_jdbc/execute.clj @@ -32,7 +32,8 @@ [metabase.util.malli :as mu] [potemkin :as p]) (:import - (java.sql Connection JDBCType PreparedStatement ResultSet ResultSetMetaData Statement Types) + (java.sql Connection JDBCType PreparedStatement ResultSet ResultSetMetaData SQLFeatureNotSupportedException + Statement Types) (java.time Instant LocalDate LocalDateTime LocalTime OffsetDateTime OffsetTime ZonedDateTime) (javax.sql DataSource))) @@ -713,7 +714,18 @@ e))))] (let [rsmeta (.getMetaData rs) results-metadata {:cols (column-metadata driver rsmeta)}] - (respond results-metadata (reducible-rows driver rs rsmeta qp.pipeline/*canceled-chan*)))))))) + (try (respond results-metadata (reducible-rows driver rs rsmeta qp.pipeline/*canceled-chan*)) + ;; Following cancels the statment on the dbms side. + ;; It avoids blocking `.close` call, in case we reduced the results subset eg. by means of + ;; [[metabase.query-processor.middleware.limit/limit-xform]] middleware, while statment is still + ;; in progress. This problem was encountered on Redshift. For details see the issue #39018. + ;; It also handles situation where query is canceled through [[qp.pipeline/*canceled-chan*]] (#41448). + (finally (try (.cancel stmt) + (catch SQLFeatureNotSupportedException _ + (log/warnf "Statemet's `.cancel` method is not supported by the `%s` driver." + (name driver))) + (catch Throwable _ + (log/warn "Statement cancelation failed."))))))))))) (defn reducible-query "Returns a reducible collection of rows as maps from `db` and a given SQL query. This is similar to [[jdbc/reducible-query]] but reuses the -- GitLab