{"record":{"id":"07a018d6d07eddd6","repo":"baomidou/mybatis-plus","slug":"sql-where-sql-07a018","errorCode":null,"errorMessage":"非法SQL，where条件中不能使用子查询，错误子查询SQL信息：{}","messagePattern":"非法SQL，where条件中不能使用子查询，错误子查询SQL信息：(.+?)","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":191,"sourceCode":"        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) {\n            InExpression inExpression = (InExpression) expression;\n            if (inExpression.getRightExpression() instanceof Subtraction) {\n                Subtraction subSelect = (Subtraction) inExpression.getRightExpression();\n                throw new MybatisPlusException(\"非法SQL，where条件中不能使用子查询，错误子查询SQL信息：\" + subSelect.toString());\n            }\n        }\n\n    }\n\n    /**\n     * 如果SQL用了 left Join，验证是否有or、not等等，并且验证是否使用了索引\n     *\n     * @param joins      ignore\n     * @param table      ignore\n     * @param connection ignore\n     */","sourceCodeStart":173,"sourceCodeEnd":209,"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#L173-L209","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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","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)","Remove or conditionally disable IllegalSQLInnerInterceptor if subqueries in WHERE are an accepted pattern in your project"],"exampleFix":"-- before\nSELECT * FROM t_order o WHERE o.user_id = (SELECT id FROM t_user WHERE phone = #{phone});\n-- after\nSELECT o.* FROM t_order o JOIN t_user u ON o.user_id = u.id WHERE u.phone = #{phone};","handlingStrategy":"validation","validationCode":"// Reject subquery-like right expressions before execution\nExpression where = ((PlainSelect) ((Select) CCJSqlParserUtil.parse(sql).getSelectBody()).getSelectBody()).getWhere();\nif (where instanceof BinaryExpression be\n        && be.getRightExpression() instanceof Subtraction) {\n    throw new IllegalArgumentException(\"Subquery/subtraction on right side of WHERE comparison\");\n}","typeGuard":"static boolean hasSubtractionRight(Expression where) {\n    return where instanceof BinaryExpression be\n        && be.getRightExpression() instanceof Subtraction;\n}","tryCatchPattern":"try {\n    return mapper.selectWithSubquery(param);\n} catch (MybatisPlusException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"不能使用子查询\")) {\n        return mapper.selectWithJoin(param); // pre-built join variant\n    }\n    throw e;\n}","preventionTips":["Prefer JOINs or two-step parameter-bound queries over scalar subqueries in WHERE","Watch for plain subtraction (a - b) on the right of comparisons being misclassified; compute in Java instead","Document the interceptor's SQL rules for the team when it is first enabled"],"tags":["mybatis-plus","sql","jsqlparser","subquery","interceptor"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}