{"record":{"id":"b5a17601631f7aa4","repo":"baomidou/mybatis-plus","slug":"sql-where-b5a176","errorCode":null,"errorMessage":"非法SQL，where条件中不能使用数据库函数，错误函数信息：{}","messagePattern":"非法SQL，where条件中不能使用数据库函数，错误函数信息：(.+?)","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":187,"sourceCode":"            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) {\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     *","sourceCodeStart":169,"sourceCodeEnd":205,"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#L169-L205","documentation":"Thrown by IllegalSQLInnerInterceptor (jsqlparser 5.0 variant) when it walks a WHERE expression tree and finds a JSqlParser Function on the left side of a BinaryExpression. The interceptor is an optional 'illegal SQL' firewall that forbids database functions in WHERE conditions because they prevent index usage. The message appends the offending function's SQL text after '错误函数信息：'.","triggerScenarios":"Adding IllegalSQLInnerInterceptor to MybatisPlusInterceptor and executing SQL whose WHERE clause contains a function on the left of a comparison, e.g. WHERE DATE(create_time) = '2024-01-01', WHERE UPPER(name) = 'X', or WHERE IFNULL(col,0) > 0. Any mapper XML or wrapper-generated SQL matching that shape triggers it before execution.","commonSituations":"Teams enable the interceptor to enforce index-friendly SQL, then legacy mappers with DATE()/SUBSTRING()/UPPER() predicates start failing. Also hit when porting SQL from projects without the interceptor, or after upgrading to mybatis-plus 3.5.x with the jsqlparser-5.0 support module where this class lives.","solutions":["Rewrite the predicate so the column stands alone, e.g. WHERE DATE(create_time) = ? becomes WHERE create_time >= ? AND create_time < ? (range form)","If the function filter is too strict for your team, remove IllegalSQLInnerInterceptor from the MybatisPlusInterceptor chain or make it conditional per environment (enabled only in dev/test)","Move the computation to the value side: WHERE col = TRIM(?) is computed in Java instead — WHERE col = ?","Add a computed/generated column with an index and filter on that column instead of the function"],"exampleFix":"-- before\nSELECT * FROM t_order WHERE DATE(create_time) = '2024-01-01';\n-- after\nSELECT * FROM t_order WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02';","handlingStrategy":"try-catch","validationCode":"// Pre-flight: reject WHERE predicates with a function on the left of a comparison\nStatement st = CCJSqlParserUtil.parse(sql);\nif (st instanceof Select select) {\n    Expression where = ((PlainSelect) select.getSelectBody()).getWhere();\n    if (where instanceof BinaryExpression be && be.getLeftExpression() instanceof Function) {\n        throw new IllegalArgumentException(\"Function in WHERE: \" + be.getLeftExpression());\n    }\n}","typeGuard":"static boolean hasLeftFunctionInWhere(Expression where) {\n    return where instanceof BinaryExpression be\n        && be.getLeftExpression() instanceof Function;\n}","tryCatchPattern":"try {\n    orderMapper.selectByDay(date);\n} catch (MybatisPlusException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"不能使用数据库函数\")) {\n        // rewrite predicate to sargable form or fail with context\n        throw new IllegalArgumentException(\"Non-sargable WHERE predicate blocked by IllegalSQLInnerInterceptor\", e);\n    }\n    throw e;\n}","preventionTips":["Keep WHERE predicates sargable: compare raw columns to bound values, never wrap columns in functions","Run a SQL lint step in CI that flags function-wrapped columns in WHERE if the interceptor is enabled","Enable IllegalSQLInnerInterceptor first in a dev profile to inventory offending legacy SQL"],"tags":["mybatis-plus","sql","jsqlparser","interceptor","index"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}