apache/seatunnel · error · ParserException
Unsupported syntax: <insertSql>
Error message
Unsupported syntax: <insertSql>
What it means
Thrown by parseInsertSql when the FROM item of the INSERT's SELECT is not a simple table. The parser only supports reading from a named table (Table node); subqueries, joins, functions and other FromItem types are rejected.
Source
Thrown at seatunnel-config/seatunnel-config-sql/src/main/java/org/apache/seatunnel/config/sql/SqlConfigBuilder.java:391
String targetTableName = insertSql.getTable().getName();
if (select.getSelectBody() instanceof PlainSelect) {
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
String pluginInputIdentifier;
String pluginOutputIdentifier;
if (plainSelect.getFromItem() == null) {
List<SelectItem<?>> selectItems = plainSelect.getSelectItems();
if (selectItems.size() != 1) {
throw new ParserException(
"Source table must be specified in SQL: " + insertSql);
}
SelectItem<?> selectItem = selectItems.get(0);
Column column = (Column) selectItem.getExpression();
pluginInputIdentifier = column.getColumnName();
pluginOutputIdentifier = pluginInputIdentifier;
} else {
if (!(plainSelect.getFromItem() instanceof Table)) {
throw new ParserException("Unsupported syntax: " + insertSql);
}
Table table = (Table) plainSelect.getFromItem();
pluginInputIdentifier = table.getName();
pluginOutputIdentifier =
pluginInputIdentifier
+ TEMP_TABLE_SUFFIX
+ tempTableIndex.getAndIncrement();
String query = select.toString();
transformConfig.setPluginInputIdentifier(pluginInputIdentifier);
transformConfig.setPluginOutputIdentifier(pluginOutputIdentifier);
transformConfig.setQuery(query);
seaTunnelConfig.getTransformConfigs().add(transformConfig);
}
if (!sqlTables.containsKey(pluginInputIdentifier)
|| (!OPTION_TABLE_TYPE_SOURCE.equalsIgnoreCase(
sqlTables.get(pluginInputIdentifier).getType())
&& !OPTION_TABLE_TYPE_TRANSFORM.equalsIgnoreCase(View on GitHub (pinned to cf67b549a7)
Solutions
- Materialize the subquery into a temp table via CREATE TABLE tmp AS SELECT ... first, then INSERT INTO sink SELECT * FROM tmp
- Use only a plain table name in the FROM clause of INSERT statements
- Move joins/transformations into a separate CREATE TABLE ... AS SELECT step
Example fix
// before INSERT INTO sink_t SELECT * FROM (SELECT * FROM src) s // after CREATE TABLE tmp AS SELECT * FROM src; INSERT INTO sink_t SELECT * FROM tmp
Defensive patterns
Strategy: validation
Validate before calling
// FROM item of INSERT SELECT must be a plain table name
Matcher m = Pattern.compile("(?si)INSERT\\s+INTO\\s+\\w+\\s+SELECT\\s+.*?FROM\\s+([^\\s;]+)").matcher(sql);
if (m.find() && m.group(1).startsWith("(")) {
throw new IllegalArgumentException("INSERT SELECT FROM must be a plain table, not a subquery");
} Try / catch
try {
SeaTunnelConfig c = SqlConfigBuilder.of(sql);
} catch (ParserException e) {
if (e.getMessage().startsWith("Unsupported syntax:")) {
// materialize subquery as a CTAS temp table first
}
} Prevention
- Materialize subqueries/joins into CREATE TABLE ... AS SELECT temp tables before INSERT
- Use only 'FROM table_name' in INSERT statements
- Push complex query logic into the CTAS transform step
When it happens
Trigger: INSERT INTO sink_t SELECT * FROM (SELECT ...) subquery; FROM a table-valued function; joins as the FROM item in an INSERT statement.
Common situations: Users writing rich queries inline in the INSERT; porting complex Spark/Flink SQL that uses subqueries in FROM.
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
- Insert sql must not have columns
- Insert sql must have select statement
- Unsupported syntax: %s
- Source table must be specified in SQL: <insertSql>
- The sink table[%s] is not found
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/42be92a29918b78a.
Report an issue: GitHub.