apache/seatunnel · error · DatabendConnectorException

SQL_OPERATION_FAILED

SQL_OPERATION_FAILED

Error message

Failed to prepare custom statement: ${e.getMessage()}

What it means

Thrown in the DatabendSinkWriter constructor when preparing the user's custom SQL insert statement fails with a SQLException. This happens in the 'custom SQL' branch where the user supplied their own insertSql instead of the auto-generated one.

Solutions

  1. Run the custom SQL directly in a Databend client to reproduce and fix the syntax error.
  2. Verify every table/column referenced in the custom SQL exists in the target database.
  3. Use Databend-compatible syntax; the statement is prepared with parameters (? placeholders), so parameter count must match the SeaTunnelRowType field count.
  4. Check executeTimeoutSec is a positive integer accepted by the JDBC driver.

Example fix

// before
"insert into db.tbl values (?, ?, ?)" // 3 placeholders but schema has 4 fields
// after
"INSERT INTO db.tbl (id, name, ts, amount) VALUES (?, ?, ?, ?)" // matches row type
Defensive patterns

Strategy: validation

Validate before calling

// validate custom SQL before configuring the job:
// run the SQL (with dummy params) in a Databend client: PREPARE stmt FROM 'INSERT ... VALUES (?, ?, ?)';
// confirm placeholder count == SeaTunnelRowType field count

Prevention

When it happens

Trigger: connection.prepareStatement(customInsertSql) or setQueryTimeout throws: the custom SQL has a syntax error, references non-existent tables/columns, or the query timeout value is invalid (e.g. 0/negative unsupported by the driver).

Common situations: User typo in the custom SQL template; custom SQL written for another dialect (MySQL syntax in Databend); schema renamed so the custom SQL references a dropped column.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-databend/src/main/java/org/apache/seatunnel/connectors/seatunnel/databend/sink/DatabendSinkWriter.java:143

        log.info("DatabendSinkWriter constructor - catalogTable: {}", catalogTable);
        log.info("DatabendSinkWriter constructor - tableSchema: {}", tableSchema);
        log.info(
                "DatabendSinkWriter constructor - rowType: {}", catalogTable.getSeaTunnelRowType());
        log.info("DatabendSinkWriter constructor - target table path: {}", sinkTablePath);
        log.info("DatabendSinkWriter constructor - CDC mode: {}", isCdcMode);

        // if custom SQL is provided, use it directly
        if (customSql != null && !customSql.isEmpty()) {
            this.insertSql = customSql;
            log.info("Using custom SQL: {}", insertSql);
            try {
                this.schemaChangeManager = new SchemaChangeManager(databendSinkConfig);
                this.preparedStatement = connection.prepareStatement(insertSql);
                this.preparedStatement.setQueryTimeout(executeTimeoutSec);
                log.info("PreparedStatement created successfully with custom SQL");
            } catch (SQLException e) {
                throw new DatabendConnectorException(
                        DatabendConnectorErrorCode.SQL_OPERATION_FAILED,
                        "Failed to prepare custom statement: " + e.getMessage(),
                        e);
            }
        } else {
            try {
                if (isCdcMode) {
                    // In CDC mode, we don't create tables here, it's done in AggregatedCommitter
                    // We'll get the raw table and stream names from the committer via prepareCommit
                    log.info(
                            "CDC mode enabled, table creation will be handled by AggregatedCommitter");
                } else {
                    // Traditional mode
                    initTraditionalMode(database, table);
                }
            } catch (SQLException e) {
                throw new DatabendConnectorException(
                        DatabendConnectorErrorCode.SQL_OPERATION_FAILED,

View on GitHub (pinned to cf67b549a7)