baomidou/mybatis-plus · error · MybatisPlusException

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

Error message

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

What it means

Non-5.0 variant of the subquery rejection: IllegalSQLInnerInterceptor.validExpression sees a Subtraction node on the right of a BinaryExpression in WHERE and throws '不能使用子查询' with the fragment text. The Subtraction check is a heuristic carried over from older JSqlParser where subquery expressions surfaced this way, so genuine arithmetic right-hand sides can also be caught.

Source

Thrown at mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/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 scalar subquery with a JOIN or a pre-fetched bound parameter
  2. If it is real arithmetic being misclassified, move the arithmetic to Java and bind the result, or restructure the predicate to avoid a Subtraction node on the right
  3. Drop IllegalSQLInnerInterceptor if the rule does not fit the project

Example fix

-- before
SELECT * FROM t_sku WHERE price = (SELECT max_price FROM t_config WHERE id = 1);
-- after
SELECT s.* FROM t_sku s JOIN t_config c ON s.price = c.max_price WHERE c.id = 1;
Defensive patterns

Strategy: validation

Validate before calling

// Reject Subtraction-on-right WHERE comparisons 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-shaped right expression in WHERE");
}

Type guard

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

Try / catch

try {
    return mapper.selectWithScalarSub(p);
} catch (MybatisPlusException e) {
    if (e.getMessage() != null && e.getMessage().contains("不能使用子查询")) {
        return mapper.selectWithJoin(p);
    }
    throw e;
}

Prevention

When it happens

Trigger: Executing WHERE col = (SELECT ...) forms or WHERE with subtraction on the right (WHERE total = price - discount) while IllegalSQLInnerInterceptor from the mybatis-plus-jsqlparser module is registered.

Common situations: Reporting SQL with scalar subqueries; price/discount arithmetic in WHERE being misidentified; upgrading jsqlparser dependency versions altering parse shapes.

Related errors


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