baomidou/mybatis-plus · error · MybatisPlusException

非法SQL,where条件中不能使用【or】关键字,错误or信息:

Error message

非法SQL,where条件中不能使用【or】关键字,错误or信息:

What it means

Thrown by IllegalSQLInnerInterceptor.validExpression when the WHERE expression (after unwrapping ParenthesedExpressionList) is an OrExpression. The interceptor enforces a SQL standard that forbids OR in WHERE conditions — typically because OR defeats single-index usage — and appends the offending expression text after '错误or信息:'.

Source

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

        List<Join> joins = delete.getJoins();
        validWhere(where, table, (Connection) obj);
        validJoins(joins, table, (Connection) obj);
    }

    /**
     * 验证expression对象是不是 or、not等等
     *
     * @param expression ignore
     */
    private void validExpression(Expression expression) {
        while (expression instanceof ParenthesedExpressionList) {
            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) {

View on GitHub (pinned to bf67d90747)

Solutions

  1. Rewrite OR over the same column as IN: WHERE status = 1 OR status = 2 becomes WHERE status IN (1, 2)
  2. Rewrite cross-column OR as UNION / UNION ALL of two indexed queries
  3. Remove or disable IllegalSQLInnerInterceptor if OR conditions are an accepted part of your query patterns

Example fix

-- before
SELECT * FROM t_order WHERE status = 1 OR status = 2;
-- after
SELECT * FROM t_order WHERE status IN (1, 2);
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect OR at the top of a WHERE before execution
Expression where = ((PlainSelect) ((Select) CCJSqlParserUtil.parse(sql).getSelectBody()).getSelectBody()).getWhere();
while (where instanceof ParenthesedExpressionList<?> p) { where = (Expression) p.get(0); }
if (where instanceof OrExpression) {
    throw new IllegalArgumentException("OR in WHERE blocked by IllegalSQLInnerInterceptor");
}

Type guard

static boolean isOrExpression(Expression where) {
    return where instanceof OrExpression;
}

Try / catch

try {
    return mapper.search(a, b);
} catch (MybatisPlusException e) {
    if (e.getMessage() != null && e.getMessage().contains("【or】")) {
        return mapper.searchByIn(a, b); // IN or UNION variant
    }
    throw e;
}

Prevention

When it happens

Trigger: Registering IllegalSQLInnerInterceptor and executing any statement whose top-level WHERE contains OR, e.g. WHERE a = 1 OR b = 2, including parenthesized (a = 1 OR b = 2) since parenthesis wrappers are unwrapped before the check.

Common situations: Search/filter screens built with OR conditions; QueryWrapper.eq(...).or().eq(...) chains; legacy mappers using OR after the interceptor is introduced to enforce index discipline.

Related errors


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