apache/seatunnel · warning

Failed to alter table change column, SQL:

Error message

Failed to alter table change column, SQL:

What it means

This WARN is logged when the ALTER TABLE ... CHANGE COLUMN (rename/redefine column) SQL generated for a Doris table fails to execute — SchemaChangeManager.execute() returned false. The event is silently swallowed at WARN level, so the SeaTunnel job keeps running but the Doris table schema no longer matches the upstream source, which typically surfaces later as write errors (unknown column).

Source

Thrown at seatunnel-connectors-v2/connector-doris/src/main/java/org/apache/seatunnel/connectors/doris/schema/SchemaChangeManager.java:179

                        .append(" ")
                        .append(quoteIdentifier(event.getOldColumn()))
                        .append(" ")
                        .append(quoteIdentifier(event.getColumn().getName()));
        if (event.getColumn().getComment() != null) {
            sqlBuilder
                    .append(" ")
                    .append("COMMENT ")
                    .append("'")
                    .append(event.getColumn().getComment())
                    .append("'");
        }
        if (event.getAfterColumn() != null) {
            sqlBuilder.append(" ").append("AFTER ").append(quoteIdentifier(event.getAfterColumn()));
        }

        String changeColumnSQL = sqlBuilder.toString();
        if (!execute(changeColumnSQL, tablePath.getDatabaseName())) {
            log.warn("Failed to alter table change column, SQL:" + changeColumnSQL);
        }
    }

    public void applySchemaChange(TablePath tablePath, AlterTableModifyColumnEvent event)
            throws IOException {
        BasicTypeDefine typeDefine = DorisTypeConverterV2.INSTANCE.reconvert(event.getColumn());
        StringBuilder sqlBuilder =
                new StringBuilder()
                        .append("ALTER TABLE")
                        .append(" ")
                        .append(tablePath.getFullName())
                        .append(" ")
                        .append("MODIFY COLUMN")
                        .append(" ")
                        .append(quoteIdentifier(event.getColumn().getName()))
                        .append(" ")
                        .append(typeDefine.getColumnType());
        if (event.getColumn().getComment() != null) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Inspect the full SQL in the log message and run it manually against Doris to see the real FE error (the WARN itself omits the root cause).
  2. Check Doris FE logs (fe.log / fe.audit.log) for the rejected ALTER and its reason (type not supported, conflict, privilege).
  3. Verify the sink user has ALTER privileges on the database: GRANT ALTER ON db.* TO user.
  4. Apply the column change manually (ALTER TABLE ... CHANGE COLUMN ...) to align Doris with the source, then restart the pipeline from the latest checkpoint.
  5. If the type conversion is unsupported, adjust the upstream type or pin the Doris column type so DorisTypeConverterV2 produces a valid mapping.

Example fix

// before: failure swallowed, root cause hidden
String changeColumnSQL = sqlBuilder.toString();
if (!execute(changeColumnSQL, tablePath.getDatabaseName())) {
    log.warn("Failed to alter table change column, SQL:" + changeColumnSQL);
}
// after: surface the root cause and fail fast
if (!execute(changeColumnSQL, tablePath.getDatabaseName())) {
    throw new IOException("Failed to alter table change column, SQL: " + changeColumnSQL);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before enabling schema evolution, verify privileges and FE reachability
SHOW GRANTS FOR 'seatunnel_user';  -- must include ALTER_PRIV on the target db
-- and test the FE HTTP endpoint used by execute():
curl http://<fe-host>:<http-port>/api/bootstrap

Try / catch

// Fail fast on failed DDL instead of silently diverging schemas
try {
    schemaManager.applySchemaChange(tablePath, changeColumnEvent);
} catch (Exception e) {
    LOG.error("Doris schema change failed for table " + tablePath + ", SQL: " + changeColumnSQL, e);
    throw e; // let the pipeline restart/retry from checkpoint
}

Prevention

When it happens

Trigger: execute(changeColumnSQL, database) returns false — the DDL was rejected by Doris FE: invalid target type per DorisTypeConverterV2.reconvert, type change not supported by Doris (e.g. shrinking a type), the old column doesn't exist, AFTER column doesn't exist, connection/HTTP failure to the FE, or insufficient user privileges on the database.

Common situations: Upstream changed a column type in a way Doris cannot convert (varchar->int, unsupported type mapping); Doris user lacks ALTER privilege; FE is unreachable or returns a non-success HTTP code; concurrent schema operations make the DDL conflict (table under another alter/schema change job); light_schema_change settings interplay.

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/60bcd2924a0b0f11. Report an issue: GitHub.