MyCATApache/Mycat-Server · error · SQLNonTransientException
invalid route in sql, multi tables found but datanode has…
Error message
invalid route in sql, multi tables found but datanode has no intersection sql:" + ctx.getSql()
What it means
Thrown by RouterUtil when routing a SQL statement that touches multiple sharded tables: each table's sharding key resolves to a set of datanodes, and the code intersects the sets (retailAll). When the intersection is empty, no single datanode can serve all tables and the route is impossible, so a SQLNonTransientException is thrown with the original SQL attached. This fires for cross-shard joins/lookups whose sharding values point at disjoint nodes; it is deterministic (non-transient) — the SQL or data distribution must change, not be retried.
Solutions
- Rewrite the SQL so the joined/related tables route to at least one common datanode, e.g. use the sharding column values of the child-table constraint in the WHERE clause so each table's route set overlaps
- Check that the sharding columns used in the SQL actually restrict routes on all involved tables; add equality predicates on sharding keys for tables whose route set is unconstrained (null/empty routes also throw)
- If the query legitimately spans unrelated shards, split it into multiple statements per shard or use a global table / different sharding strategy so routes intersect
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:1324 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/0552d4f77f2f2d2a.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:1324
}
boolean isFirstAdd = true;
for(Map.Entry<String, Set<String>> entry : tablesRouteMap.entrySet()) {
if(entry.getValue() == null || entry.getValue().size() == 0) {
throw new SQLNonTransientException("parent key can't find any valid datanode ");
} else {
if(isFirstAdd) {
retNodesSet.addAll(entry.getValue());
isFirstAdd = false;
} else {
retNodesSet.retainAll(entry.getValue());
if(retNodesSet.size() == 0) {//两个表的路由无交集
String errMsg = "invalid route in sql, multi tables found but datanode has no intersection "
+ " sql:" + ctx.getSql();
LOGGER.warn(errMsg);
throw new SQLNonTransientException(errMsg);
}
}
}
}
if(retNodesSet != null && retNodesSet.size() > 0) {
String tableName = tables.get(0);
TableConfig tableConfig = schema.getTables().get(tableName.toUpperCase());
if(tableConfig.isDistTable()){
routeToDistTableNode(schema, rrs, ctx.getSql(), tablesAndConditions, cachePool, isSelect, null);
return rrs;
}
if(retNodesSet.size() > 1 && isAllGlobalTable(ctx, schema)) {
// mulit routes ,not cache route result
if (isSelect) {
rrs.setCacheAble(false);
ArrayList<String> retNodeList = new ArrayList<String>(retNodesSet);
Collections.shuffle(retNodeList);//by kaiz : add shuffle
View on GitHub (pinned to 65f8d8beb7)