apache/seatunnel · warning · CatalogException

Custom SQL execution interrupted

Error message

Custom SQL execution interrupted

What it means

Thrown by BigQueryCatalog.executeSql when bigquery.query(queryConfig) throws InterruptedException while executing a user-supplied custom SQL statement. The interrupt flag is restored and the interruption is wrapped in a CatalogException. It indicates the custom SQL job was cancelled because the calling thread was interrupted, not a SQL syntax or data problem.

Source

Thrown at seatunnel-connectors-v2/connector-bigquery/src/main/java/org/apache/seatunnel/connectors/bigquery/catalog/BigQueryCatalog.java:415

            TableId tableId = TableId.of(getDatasetName(tablePath), tablePath.getTableName());
            Table table = bigquery.getTable(tableId);
            return table != null && table.getNumRows().longValue() > 0;
        }
    }

    @Override
    public void executeSql(TablePath tablePath, String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            log.warn("No custom SQL query provided for table {}, skipping execution.", tablePath);
            return;
        }
        log.info("Executing custom SQL in dataset {}: {}", getDatasetName(tablePath), sql);
        QueryJobConfiguration queryConfig = QueryJobConfiguration.newBuilder(sql).build();
        try {
            bigquery.query(queryConfig);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new CatalogException("Custom SQL execution interrupted", e);
        } catch (Exception e) {
            throw new CatalogException("Failed to execute custom SQL", e);
        }
    }

    private Field convertColumn(Column column) {
        StandardSQLTypeName bqType = mapToBigQueryType(column.getDataType().getSqlType());
        Field.Builder fieldBuilder = Field.newBuilder(column.getName(), bqType);

        if (column.isNullable()) {
            fieldBuilder.setMode(Field.Mode.NULLABLE);
        } else {
            fieldBuilder.setMode(Field.Mode.REQUIRED);
        }

        if (column.getDataType().getSqlType() == SqlType.ROW) {
            SeaTunnelRowType rowType = (SeaTunnelRowType) column.getDataType();
            List<Field> subFields = new ArrayList<>();

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Determine whether the interrupt was intentional (job cancel) — if so, handle at the orchestration level
  2. Re-run the SQL after confirming job state; the statement may have partially executed, so verify results in BigQuery
  3. Move long-running SQL to an async pattern if interruption-prone threads must issue it
Defensive patterns

Strategy: try-catch

Try / catch

try {
    catalog.executeSql(tablePath, sql);
} catch (CatalogException e) {
    if (Thread.interrupted()) {
        LOG.warn("Custom SQL cancelled by interruption");
        return;
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling executeSql(tablePath, sql) when the thread waiting on the synchronous BigQuery query job is interrupted — e.g. SeaTunnel job cancellation, engine shutdown, or a watchdog interrupt during schema-save-mode SQL execution.

Common situations: Job stopped by the user while a save-mode auto-create/DDL SQL ran; Zeta worker task termination; pipeline failover interrupting catalog calls.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/92e41e0b1bcd88cd. Report an issue: GitHub.