{"record":{"id":"ecfae977659906ac","repo":"apache/iceberg","slug":"interrupted-in-sql-query-ecfae9","errorCode":null,"errorMessage":"Interrupted in SQL query","messagePattern":"Interrupted in SQL query","errorType":"exception","errorClass":"UncheckedInterruptedException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/jdbc/JdbcUtil.java","lineNumber":832,"sourceCode":"            try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {\n              for (int pos = 0; pos < args.length; pos += 1) {\n                preparedStatement.setString(pos + 1, args[pos]);\n              }\n\n              try (ResultSet rs = preparedStatement.executeQuery()) {\n                if (rs.next()) {\n                  return true;\n                }\n              }\n            }\n\n            return false;\n          });\n    } catch (SQLException e) {\n      throw new UncheckedSQLException(e, \"Failed to execute exists query: %s\", sql);\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new UncheckedInterruptedException(e, \"Interrupted in SQL query\");\n    }\n  }\n}\n","sourceCodeStart":814,"sourceCodeEnd":836,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/jdbc/JdbcUtil.java#L814-L836","documentation":"Thrown by JdbcUtil's exists-query helper when the thread waiting on the JDBC connection pool is interrupted. The code re-interrupts the thread (preserving the interrupt flag) and wraps the InterruptedException in UncheckedInterruptedException so callers see a runtime exception. It signals the existence check for a table/view/namespace was aborted mid-query, not that the entity is absent.","triggerScenarios":"Calling JdbcCatalog.tableExists/viewExists/namespaceExists (which call the exists helper) while the current thread's interrupt flag is set or set during pool acquisition/query execution; typically task cancellation in Spark/Flink executors or executor shutdown.","commonSituations":"Query timeouts that cancel the running task, killing a Spark/Flink job mid-scan, application shutdown during catalog operations, or a thread pool being closed while catalog checks are still in flight.","solutions":["Retry the existence check in a fresh, non-interrupted thread after shutdown/cancellation completes","Check whether your framework is cancelling the task (job kill, timeout) and avoid catalog calls during shutdown","Increase connection pool / query timeout settings if long waits lead to cancellation","Preserve and handle the interrupt: catch UncheckedInterruptedException at a higher level and stop work gracefully"],"exampleFix":"// before\nboolean exists = catalog.tableExists(ident);\n// after\ntry {\n  boolean exists = catalog.tableExists(ident);\n} catch (UncheckedInterruptedException e) {\n  // thread was cancelled; re-check or propagate after executor settles\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Java: check interrupt status before catalog calls\nif (Thread.currentThread().isInterrupted()) {\n  throw new IllegalStateException(\"Thread interrupted before existence check\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  boolean exists = catalog.tableExists(ident);\n} catch (UncheckedInterruptedException e) {\n  Thread.currentThread().interrupt();\n  // abort or reschedule the work\n}","preventionTips":["Avoid running catalog calls in threads that may be cancelled mid-flight","Handle cancellation at task boundaries, not inside catalog operations","Keep connection pool timeouts short so waits don't trigger cancellation"],"tags":["jdbc","interruption","threading"],"backgroundTag":"thread-interrupted","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}