baomidou/mybatis-plus · error · MybatisPlusException
非法SQL,where条件中不能使用数据库函数,错误函数信息:{}
Error message
非法SQL,where条件中不能使用数据库函数,错误函数信息:{} What it means
Thrown by IllegalSQLInnerInterceptor (jsqlparser 5.0 variant) when it walks a WHERE expression tree and finds a JSqlParser Function on the left side of a BinaryExpression. The interceptor is an optional 'illegal SQL' firewall that forbids database functions in WHERE conditions because they prevent index usage. The message appends the offending function's SQL text after '错误函数信息:'.
Source
Thrown at mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java:187
ParenthesedExpressionList<Expression> parenthesis = (ParenthesedExpressionList) expression;
expression = parenthesis.get(0);
}
//where条件使用了 or 关键字
if (expression instanceof OrExpression) {
OrExpression orExpression = (OrExpression) expression;
throw new MybatisPlusException("非法SQL,where条件中不能使用【or】关键字,错误or信息:" + orExpression.toString());
} else if (expression instanceof NotEqualsTo) {
NotEqualsTo notEqualsTo = (NotEqualsTo) expression;
throw new MybatisPlusException("非法SQL,where条件中不能使用【!=】关键字,错误!=信息:" + notEqualsTo.toString());
} else if (expression instanceof BinaryExpression) {
BinaryExpression binaryExpression = (BinaryExpression) expression;
// TODO 升级 jsqlparser 后待实现
// if (binaryExpression.isNot()) {
// throw new MybatisPlusException("非法SQL,where条件中不能使用【not】关键字,错误not信息:" + binaryExpression.toString());
// }
if (binaryExpression.getLeftExpression() instanceof Function) {
Function function = (Function) binaryExpression.getLeftExpression();
throw new MybatisPlusException("非法SQL,where条件中不能使用数据库函数,错误函数信息:" + function.toString());
}
if (binaryExpression.getRightExpression() instanceof Subtraction) {
Subtraction subSelect = (Subtraction) binaryExpression.getRightExpression();
throw new MybatisPlusException("非法SQL,where条件中不能使用子查询,错误子查询SQL信息:" + subSelect.toString());
}
} else if (expression instanceof InExpression) {
InExpression inExpression = (InExpression) expression;
if (inExpression.getRightExpression() instanceof Subtraction) {
Subtraction subSelect = (Subtraction) inExpression.getRightExpression();
throw new MybatisPlusException("非法SQL,where条件中不能使用子查询,错误子查询SQL信息:" + subSelect.toString());
}
}
}
/**
* 如果SQL用了 left Join,验证是否有or、not等等,并且验证是否使用了索引
*View on GitHub (pinned to bf67d90747)
Solutions
- Rewrite the predicate so the column stands alone, e.g. WHERE DATE(create_time) = ? becomes WHERE create_time >= ? AND create_time < ? (range form)
- If the function filter is too strict for your team, remove IllegalSQLInnerInterceptor from the MybatisPlusInterceptor chain or make it conditional per environment (enabled only in dev/test)
- Move the computation to the value side: WHERE col = TRIM(?) is computed in Java instead — WHERE col = ?
- Add a computed/generated column with an index and filter on that column instead of the function
Example fix
-- before SELECT * FROM t_order WHERE DATE(create_time) = '2024-01-01'; -- after SELECT * FROM t_order WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02';
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: reject WHERE predicates with a function on the left of a comparison
Statement st = CCJSqlParserUtil.parse(sql);
if (st instanceof Select select) {
Expression where = ((PlainSelect) select.getSelectBody()).getWhere();
if (where instanceof BinaryExpression be && be.getLeftExpression() instanceof Function) {
throw new IllegalArgumentException("Function in WHERE: " + be.getLeftExpression());
}
} Type guard
static boolean hasLeftFunctionInWhere(Expression where) {
return where instanceof BinaryExpression be
&& be.getLeftExpression() instanceof Function;
} Try / catch
try {
orderMapper.selectByDay(date);
} catch (MybatisPlusException e) {
if (e.getMessage() != null && e.getMessage().contains("不能使用数据库函数")) {
// rewrite predicate to sargable form or fail with context
throw new IllegalArgumentException("Non-sargable WHERE predicate blocked by IllegalSQLInnerInterceptor", e);
}
throw e;
} Prevention
- Keep WHERE predicates sargable: compare raw columns to bound values, never wrap columns in functions
- Run a SQL lint step in CI that flags function-wrapped columns in WHERE if the interceptor is enabled
- Enable IllegalSQLInnerInterceptor first in a dev profile to inventory offending legacy SQL
When it happens
Trigger: Adding IllegalSQLInnerInterceptor to MybatisPlusInterceptor and executing SQL whose WHERE clause contains a function on the left of a comparison, e.g. WHERE DATE(create_time) = '2024-01-01', WHERE UPPER(name) = 'X', or WHERE IFNULL(col,0) > 0. Any mapper XML or wrapper-generated SQL matching that shape triggers it before execution.
Common situations: Teams enable the interceptor to enforce index-friendly SQL, then legacy mappers with DATE()/SUBSTRING()/UPPER() predicates start failing. Also hit when porting SQL from projects without the interceptor, or after upgrading to mybatis-plus 3.5.x with the jsqlparser-5.0 support module where this class lives.
Related errors
- 非法SQL,where条件中不能使用数据库函数,错误函数信息:{}
- 非法SQL,SQL未使用到索引, table:{}, columnName:{}
- 非法SQL,where条件中不能使用子查询,错误子查询SQL信息:{}
- 非法SQL,SQL未使用到索引, table:{}, columnName:{}
- 非法SQL,where条件中不能使用【or】关键字,错误or信息:
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/b5a17601631f7aa4.
Report an issue: GitHub.