MyCATApache/Mycat-Server · error · java.lang.RuntimeException
Can't identify the operation of of where
Error message
Can't identify the operation of of where
What it means
JoinParser parses a join query's WHERE clause and only understands equality (=), AND and OR binary operators (and IN-lists). Any other binary operator in the WHERE expression reaches the final else branch, which throws a RuntimeException. It is a parser capability limit of the catlet join SQL parser, not a syntax error in your SQL.
Solutions
- Rewrite the WHERE clause of the join query to use only = combined with AND/OR/IN when going through the join catlet
- Push non-equality predicates (range, LIKE) to a subquery or to the single-node query instead of the join parser
- Set the table/route so the query does not go through the JoinParser path (e.g. direct route to a single node)
- Patch JoinParser.parserWhere to handle the operator you need, or upgrade to a Mycat version with broader operator support
Example fix
// before ... JOIN b ON a.id=b.id WHERE a.created > '2024-01-01' // after (filter applied outside join parser, e.g. subquery) SELECT * FROM a JOIN b ON a.id=b.id WHERE a.id IN (SELECT id FROM a WHERE created > '2024-01-01')
Defensive patterns
Strategy: validation
Validate before calling
// pre-validate WHERE clause before invoking the join catlet path
java.util.regex.Pattern allowed = java.util.regex.Pattern.compile(
"(\\s*(AND|OR)\\s+)?\\s*\\w+\\.\\w+\\s*(=|IN)\\s*", java.util.regex.Pattern.CASE_INSENSITIVE);
// reject if where contains >, <, LIKE, != etc. and reroute to single-node execution Type guard
boolean isJoinParserSafe(SQLBinaryOperator op) {
return op == SQLBinaryOperator.Equality
|| op == SQLBinaryOperator.BooleanAnd
|| op == SQLBinaryOperator.BooleanOr;
} Try / catch
try {
joinExec.execute(query);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Can't identify the operation")) {
LOG.warn("unsupported where operator for join catlet, falling back to direct route");
return directNodeExecute(query);
}
throw e;
} Prevention
- Use only = / AND / OR / IN in WHERE clauses routed through join catlets
- Apply range and LIKE filters in subqueries or on single-node routes
- Keep operator support in mind when migrating hand-written SQL into Mycat-sharded joins
When it happens
Trigger: Running a JOIN query through a catlet (e.g. ShareJoin / JoinParser path) whose WHERE clause contains an operator other than =, AND, OR, or IN — such as >, <, >=, LIKE, <>, or BETWEEN in the where section handled by parserWhere.
Common situations: Users writing range filters or LIKE predicates in a join query routed via a catlet; queries generated by ORMs that emit != or LIKE; upgrading SQL and adding non-equality predicates to an existing working join.
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
- not a query sql statement
- Multi statements is not supported,use single statement…
- In case of slice table,there is no rule field in the…
- sql 注释 语法错误
- multi insert not provided
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/5603e28bb8aad41e.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/catlets/JoinParser.java:246
if (aexpr instanceof SQLBinaryOpExpr){
SQLBinaryOpExpr expr=(SQLBinaryOpExpr)aexpr;
SQLExpr exprL=expr.getLeft();
if (!(exprL instanceof SQLBinaryOpExpr))
{
opSQLExpr((SQLBinaryOpExpr)aexpr,Operator);
}
else {
// if (expr.getOperator().getName().equals("AND")) {
if (expr.getOperator()==SQLBinaryOperator.BooleanAnd) {
//parserWhere(exprL);
//parserWhere(expr.getRight());
andorWhere(exprL,expr.getOperator().getName(),expr.getRight());
}
else if (expr.getOperator()==SQLBinaryOperator.BooleanOr){//.getName().equals("OR")) {
andorWhere(exprL,expr.getOperator().getName(),expr.getRight());
}
else {
throw new RuntimeException("Can't identify the operation of of where");
}
}
}else if(aexpr instanceof SQLInListExpr){
SQLInListExpr expr = (SQLInListExpr)aexpr;
SQLExpr exprL = expr.getExpr();
String field=exprL.toString();
tableFilter.addWhere(field, SQLUtils.toMySqlString(expr), Operator);
}
}
private void andorWhere(SQLExpr exprL,String Operator,SQLExpr exprR ){
parserWhere(exprL,"");
parserWhere(exprR,Operator);
}
private void opSQLExpr(SQLBinaryOpExpr expr,String Operator) {
if (expr==null) {
View on GitHub (pinned to 65f8d8beb7)