apache/seatunnel · error · IllegalArgumentException

Unsupported clause merge format:

Error message

Unsupported clause merge format: 

What it means

SqlTableClauseMerger.merge() merges table options (e.g. 'with' clauses) into a SQL DDL string according to a ClauseMergeFormat enum. Currently only DOUBLE_QUOTED_PROPERTIES is supported; any other enum constant hits the default branch and throws this IllegalArgumentException.

Source

Thrown at seatunnel-connectors-v2/connector-common/src/main/java/org/apache/seatunnel/connectors/seatunnel/common/sql/SqlTableClauseMerger.java:42

/** Utility for merging key-value table options into SQL CREATE TABLE property clauses. */
public final class SqlTableClauseMerger {

    private static final Pattern DOUBLE_QUOTED_ENTRY_PATTERN =
            Pattern.compile("\"((?:[^\"\\\\]|\\\\.)*)\"\\s*=\\s*\"((?:[^\"\\\\]|\\\\.)*)\"");

    private SqlTableClauseMerger() {}

    public static String merge(
            String sql, ClauseMergeFormat format, Map<String, String> tableOptions) {
        if (tableOptions == null || tableOptions.isEmpty()) {
            return sql;
        }
        switch (format) {
            case DOUBLE_QUOTED_PROPERTIES:
                return mergeDoubleQuotedProperties(sql, format.getKeyword(), tableOptions);
            default:
                throw new IllegalArgumentException("Unsupported clause merge format: " + format);
        }
    }

    private static String mergeDoubleQuotedProperties(
            String sql, String keyword, Map<String, String> tableOptions) {
        int keywordStart = findLastKeywordPosition(sql, keyword);
        if (keywordStart >= 0) {
            int openParen = indexOfNonWhitespace(sql, keywordStart + keyword.length());
            if (openParen >= 0 && sql.charAt(openParen) == '(') {
                int closeParen = findMatchingCloseParen(sql, openParen);
                if (closeParen > openParen) {
                    String clauseBody = sql.substring(openParen + 1, closeParen);
                    Map<String, String> merged = parseDoubleQuotedEntries(clauseBody);
                    merged.putAll(tableOptions);
                    String newClause = renderDoubleQuotedProperties(keyword, merged);
                    return sql.substring(0, keywordStart)
                            + newClause
                            + sql.substring(closeParen + 1);

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Use ClauseMergeFormat.DOUBLE_QUOTED_PROPERTIES, the only currently supported format
  2. Align connector-common dependency version with the connector that supplies the format enum (rebuild/shade correctly)
  3. If you added a new enum constant, implement a corresponding mergeXxx method and switch case in SqlTableClauseMerger
  4. Check for duplicate/old connector-common jars on the classpath shadowing the newer version

Example fix

// before
merger.merge(sql, ClauseMergeFormat.SINGLE_QUOTED_PROPERTIES, options); // unsupported
// after
merger.merge(sql, ClauseMergeFormat.DOUBLE_QUOTED_PROPERTIES, options);
Defensive patterns

Strategy: validation

Validate before calling

// check supported formats before calling merge
if (format != ClauseMergeFormat.DOUBLE_QUOTED_PROPERTIES) {
    throw new UnsupportedOperationException("only DOUBLE_QUOTED_PROPERTIES supported");
}

Type guard

boolean isSupportedFormat(ClauseMergeFormat f) {
    return f == ClauseMergeFormat.DOUBLE_QUOTED_PROPERTIES;
}

Try / catch

try {
    merged = SqlTableClauseMerger.merge(sql, format, tableOptions);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unsupported clause merge format")) {
        merged = sql; // fall back to unmerged SQL
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Invoking merge(sql, format, tableOptions) with any ClauseMergeFormat value other than DOUBLE_QUOTED_PROPERTIES (and non-null sql), e.g. future/new enum constants added by upgrades or callers passing a different format constant.

Common situations: SeaTunnel version mismatch where a connector requests a newly added merge format but the connector-common jar on the classpath is older; custom connector code choosing a format the merger doesn't implement.

Related errors


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