{"record":{"id":"991a15f49ac44828","repo":"baomidou/mybatis-plus","slug":"sql-where-or-or-991a15","errorCode":null,"errorMessage":"非法SQL，where条件中不能使用【or】关键字，错误or信息：{}","messagePattern":"非法SQL，where条件中不能使用【or】关键字，错误or信息：(.+?)","errorType":"exception","errorClass":"MybatisPlusException","httpStatus":null,"severity":"error","filePath":"mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java","lineNumber":175,"sourceCode":"        List<Join> joins = delete.getJoins();\n        validWhere(where, table, (Connection) obj);\n        validJoins(joins, table, (Connection) obj);\n    }\n\n    /**\n     * 验证expression对象是不是 or、not等等\n     *\n     * @param expression ignore\n     */\n    private void validExpression(Expression expression) {\n        while (expression instanceof ParenthesedExpressionList) {\n            ParenthesedExpressionList<Expression> parenthesis = (ParenthesedExpressionList) expression;\n            expression = parenthesis.get(0);\n        }\n        //where条件使用了 or 关键字\n        if (expression instanceof OrExpression) {\n            OrExpression orExpression = (OrExpression) expression;\n            throw new MybatisPlusException(\"非法SQL，where条件中不能使用【or】关键字，错误or信息：\" + orExpression.toString());\n        } else if (expression instanceof NotEqualsTo) {\n            NotEqualsTo notEqualsTo = (NotEqualsTo) expression;\n            throw new MybatisPlusException(\"非法SQL，where条件中不能使用【!=】关键字，错误!=信息：\" + notEqualsTo.toString());\n        } else if (expression instanceof BinaryExpression) {\n            BinaryExpression binaryExpression = (BinaryExpression) expression;\n            // TODO 升级 jsqlparser 后待实现\n//            if (binaryExpression.isNot()) {\n//                throw new MybatisPlusException(\"非法SQL，where条件中不能使用【not】关键字，错误not信息：\" + binaryExpression.toString());\n//            }\n            if (binaryExpression.getLeftExpression() instanceof Function) {\n                Function function = (Function) binaryExpression.getLeftExpression();\n                throw new MybatisPlusException(\"非法SQL，where条件中不能使用数据库函数，错误函数信息：\" + function.toString());\n            }\n            if (binaryExpression.getRightExpression() instanceof Subtraction) {\n                Subtraction subSelect = (Subtraction) binaryExpression.getRightExpression();\n                throw new MybatisPlusException(\"非法SQL，where条件中不能使用子查询，错误子查询SQL信息：\" + subSelect.toString());\n            }\n        } else if (expression instanceof InExpression) {","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/baomidou/mybatis-plus/blob/bf67d907478c724120bf76292da54abf9e73c2b3/mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java#L157-L193","documentation":"IllegalSQLInnerInterceptor from the jsqlparser-5.0 module: after unwrapping ParenthesedExpressionList (the jsqlparser 5.x replacement for Parenthesis), a top-level OrExpression in the WHERE clause is rejected. Same anti-OR policy as the 4.9 build, adapted to the 5.x AST.","triggerScenarios":"Executing a statement whose WHERE has a top-level OR (queryWrapper.or(...), .or wrappers, or native SQL) while the 5.0 IllegalSQLInnerInterceptor is registered in the MybatisPlusInterceptor chain.","commonSituations":"Adopting the 5.0 jsqlparser support module and keeping the strict SQL policy; developers adding OR conditions in wrappers; parentheses no longer hide the OR because ParenthesedExpressionList is unwrapped to its first element.","solutions":["Replace OR with IN/BETWEEN/range predicates or split the query.","Exclude the statement from the policy with @InterceptorIgnore(illegalSql = \"true\").","Drop IllegalSQLInnerInterceptor from the chain if OR with proper indexes is acceptable to the team."],"exampleFix":"// before\nwrapper.eq(User::getName, \"a\").or().eq(User::getId, 1);\n\n// after\nwrapper.and(w -> w.eq(User::getId, 1).eq(User::getName, \"a\")); // indexed first, no OR","handlingStrategy":"validation","validationCode":"// Same static guard as 4.9: forbid top-level OR before runtime\n// ArchUnit-style rule banning QueryWrapper#or, plus XML scan for \" OR \" at WHERE top level\n// git grep -niE \"where.+\\bor\\b\" -- src/main/resources/mapper","typeGuard":null,"tryCatchPattern":"try {\n    mapper.selectList(wrapper);\n} catch (MybatisPlusException e) {\n    if (String.valueOf(e.getMessage()).contains(\"不能使用【or】\")) {\n        log.error(\"policy violation: remove OR: {}\", e.getMessage());\n    }\n}","preventionTips":["Ban wrapper.or() in team code style; supply IN/range alternatives.","Add SQL static checks to CI so OR never reaches the interceptor at runtime.","Keep @InterceptorIgnore usages rare and documented."],"tags":["mybatis-plus","jsqlparser","sql-parsing","interceptor","policy"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}