MyCATApache/Mycat-Server · warning · SQLNonTransientException
TODO:insert into .... select .... not supported!
Error message
TODO:insert into .... select .... not supported!
What it means
DruidInsertParser does not implement routing for INSERT INTO ... SELECT statements. When the parsed SQLInsertStatement has a query part (a SELECT source instead of VALUES), it throws SQLNonTransientException with a literal TODO message.
Solutions
- Rewrite as a plain INSERT with explicit VALUES
- Split into SELECT first, then INSERT per row from the application
- Execute the INSERT...SELECT directly on the datanode's MySQL, bypassing MyCat routing
- Upgrade MyCat versions — check release notes for INSERT-SELECT support
Example fix
// before INSERT INTO t SELECT id, name FROM src; // after SELECT id, name FROM src; -- then INSERT INTO t VALUES (...) per row from client
Defensive patterns
Strategy: try-catch
Validate before calling
if (sql.matches("(?is)\\s*insert\\s+.*\\bselect\\b.*")) throw new UnsupportedSqlException("INSERT...SELECT not supported by MyCat router"); Try / catch
try { route(sql); } catch (SQLNonTransientException e) { if (e.getMessage().contains("insert into .... select")) { fallbackToClientSideInsert(sql); } else throw e; } Prevention
- Ban INSERT...SELECT in code review for MyCat-fronted schemas
- Implement ETL copy logic in the application instead of SQL
- Document the limitation for DBAs writing migration scripts
When it happens
Trigger: statementParse -> parserBatchInsert (or the insert parse path) receives `INSERT INTO t SELECT ...` — insertStmt.getQuery() != null.
Common situations: Migration scripts using INSERT...SELECT to copy data; ORM or ETL tools generating INSERT-SELECT; developers assuming MyCat passes arbitrary SQL through to MySQL.
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
- bad insert sql columnSize != valueSize:values:
- "joinKey not provided :" + tc.getJoinKey()+ "," + insertStmt
- "bad insert sql (sharding column:"+ partitionColumn + " not…
- number of columns error
- number of values and columns have to match
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/372675f16c9635d2.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java:324
nodes[count] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex),
rrs.getSqlType(),insertStmt.toString());
}
if(algorithm instanceof SlotFunction) {
nodes[count].setSlot(slotsMap.get(nodeIndex));
nodes[count].setStatement(ParseUtil.changeInsertAddSlot(nodes[count].getStatement(),nodes[count].getSlot()));
}
nodes[count++].setSource(rrs);
}
rrs.setNodes(nodes);
rrs.setFinishedRoute(true);
}
} else if(insertStmt.getQuery() != null) { // insert into .... select ....
String msg = "TODO:insert into .... select .... not supported!";
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
}
private String getShardingValue(SQLExpr expr) throws SQLNonTransientException {
String shardingValue = null;
if(expr instanceof SQLIntegerExpr) {
SQLIntegerExpr intExpr = (SQLIntegerExpr)expr;
shardingValue = intExpr.getNumber() + "";
} else if (expr instanceof SQLCharExpr) {
SQLCharExpr charExpr = (SQLCharExpr)expr;
shardingValue = charExpr.getText();
} else if (expr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodInvokeExpr = (SQLMethodInvokeExpr)expr;
try {
shardingValue = tryInvokeSQLMethod(methodInvokeExpr);
}catch (Exception e){
LOGGER.error("",e);
}View on GitHub (pinned to 65f8d8beb7)