apache/seatunnel · error · ParserException

Unsupported syntax

Error message

Unsupported syntax: %s

What it means

Thrown by parseCreateAsSql when a CREATE TABLE statement does not contain a SELECT body (the AS SELECT part is missing or is not a plain SELECT). The SQL config builder only supports CREATE TABLE ... AS SELECT as the transform form of DDL.

Solutions

  1. Append 'AS SELECT ...' to the CREATE TABLE statement
  2. Define schema-only tables via a SELECT from an existing source instead of column lists
  3. Rewrite CTE/UNION queries into a plain single SELECT

Example fix

// before
CREATE TABLE t2 (id INT)
// after
CREATE TABLE t2 AS SELECT id FROM t1
Defensive patterns

Strategy: validation

Validate before calling

// verify every CREATE TABLE has an AS SELECT plain query
if (!sql.matches("(?s).*CREATE\\s+TABLE\\s+\\w+\\s+AS\\s+SELECT\\s+.*")) {
    throw new IllegalArgumentException("CREATE TABLE statements must be of form CREATE TABLE t AS SELECT ... (single plain SELECT)");
}

Try / catch

try {
    SeaTunnelConfig c = SqlConfigBuilder.of(sql);
} catch (ParserException e) {
    if (e.getMessage().startsWith("Unsupported syntax:")) {
        // rewrite DDL as CTAS with a plain SELECT
    }
}

Prevention

When it happens

Trigger: Writing plain CREATE TABLE without 'AS SELECT ...' but expecting SQL-style config; using a non-PlainSelect body (e.g. UNION, WITH/CTE) that the parser cannot handle here.

Common situations: Users translating Flink/Spark DDL directly; defining a sink schema with CREATE TABLE (columns) without AS SELECT; using CTE syntax in the CTAS.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-config/seatunnel-config-sql/src/main/java/org/apache/seatunnel/config/sql/SqlConfigBuilder.java:354

                throw new ParserException(
                        String.format("The source table[%s] is not found", pluginInputIdentifier));
            }

            String pluginOutputIdentifier = createTable.getTable().getName();
            if (sqlTables.containsKey(pluginOutputIdentifier)) {
                throw new ParserException(
                        String.format("Table name duplicate: %s", pluginOutputIdentifier));
            }
            sqlTables.put(pluginOutputIdentifier, transformConfig);

            String query = select.toString();
            transformConfig.setPluginInputIdentifier(pluginInputIdentifier);
            transformConfig.setPluginOutputIdentifier(pluginOutputIdentifier);
            transformConfig.setQuery(query);

            return transformConfig;
        } else {
            throw new ParserException(String.format("Unsupported syntax: %s", createTable));
        }
    }

    private static void parseInsertSql(
            Insert insertSql,
            Map<String, BaseConfig> sqlTables,
            SeaTunnelConfig seaTunnelConfig,
            AtomicInteger tempTableIndex) {
        if (insertSql.getColumns() != null && !insertSql.getColumns().isEmpty()) {
            throw new ParserException("Insert sql must not have columns");
        }
        TransformConfig transformConfig = new TransformConfig();
        Select select = insertSql.getSelect();
        if (select == null
                || select.getSelectBody() == null
                || !(select.getSelectBody() instanceof PlainSelect)) {
            throw new ParserException("Insert sql must have select statement");
        }

View on GitHub (pinned to cf67b549a7)