baomidou/mybatis-plus · error · MybatisPlusException

非法SQL,where条件中不能使用子查询,错误子查询SQL信息:{}

Error message

非法SQL,where条件中不能使用子查询,错误子查询SQL信息:{}

What it means

Thrown by IllegalSQLInnerInterceptor (jsqlparser 5.0 variant) when the right side of a BinaryExpression in the WHERE clause is a Subtraction node. Historically the interceptor used Subtraction as a heuristic marker for subselects (older JSqlParser represented some subqueries this way), so it reports '不能使用子查询' (subqueries not allowed) with the parsed fragment appended. It is a static-analysis rejection: the SQL never reaches the database.

Source

Thrown at mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java:191

        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等等,并且验证是否使用了索引
     *
     * @param joins      ignore
     * @param table      ignore
     * @param connection ignore
     */

View on GitHub (pinned to bf67d90747)

Solutions

  1. Replace the subquery with a JOIN or with a pre-queried value bound as a parameter: WHERE col = (SELECT MAX(x) FROM t) becomes a two-step query or WHERE col IN (SELECT ...) replaced by a join
  2. If the rejection is a false positive on plain arithmetic (a - b), rewrite the predicate to avoid Subtraction nodes (compute the value in Java and bind it)
  3. Remove or conditionally disable IllegalSQLInnerInterceptor if subqueries in WHERE are an accepted pattern in your project

Example fix

-- before
SELECT * FROM t_order o WHERE o.user_id = (SELECT id FROM t_user WHERE phone = #{phone});
-- after
SELECT o.* FROM t_order o JOIN t_user u ON o.user_id = u.id WHERE u.phone = #{phone};
Defensive patterns

Strategy: validation

Validate before calling

// Reject subquery-like right expressions before execution
Expression where = ((PlainSelect) ((Select) CCJSqlParserUtil.parse(sql).getSelectBody()).getSelectBody()).getWhere();
if (where instanceof BinaryExpression be
        && be.getRightExpression() instanceof Subtraction) {
    throw new IllegalArgumentException("Subquery/subtraction on right side of WHERE comparison");
}

Type guard

static boolean hasSubtractionRight(Expression where) {
    return where instanceof BinaryExpression be
        && be.getRightExpression() instanceof Subtraction;
}

Try / catch

try {
    return mapper.selectWithSubquery(param);
} catch (MybatisPlusException e) {
    if (e.getMessage() != null && e.getMessage().contains("不能使用子查询")) {
        return mapper.selectWithJoin(param); // pre-built join variant
    }
    throw e;
}

Prevention

When it happens

Trigger: Executing SQL through a MybatisPlusInterceptor chain containing IllegalSQLInnerInterceptor where a WHERE comparison's right expression parses as Subtraction — classically WHERE col = (SELECT ...) style subquery forms, or arithmetic like WHERE col = price - discount that JSqlParser models as Subtraction.

Common situations: Correlated/uncorrelated subqueries in legacy mapper XML after the interceptor is introduced; arithmetic subtraction in predicates being misclassified as a subquery; upgrading jsqlparser versions changing what parses as Subtraction.

Related errors


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/07a018d6d07eddd6. Report an issue: GitHub.