{"record":{"id":"b034c4a2d02553d9","repo":"MyCATApache/Mycat-Server","slug":"sql","errorCode":null,"errorMessage":"sql 注释 语法错误","messagePattern":"sql 注释 语法错误","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/impl/DruidMycatRouteStrategy.java","lineNumber":830,"sourceCode":"\t * @return RouteResultset\t\t(数据路由集合)\n\t * @author mycat\n\t */\n\tprivate static RouteResultset analyseDescrSQL(SchemaConfig schema,\n\t\t\tRouteResultset rrs, String stmt, int ind) {\n\n\t\tfinal String MATCHED_FEATURE = \"DESCRIBE \";\n\t\tfinal String MATCHED2_FEATURE = \"DESC \";\n\t\tint pos = 0;\n\t\twhile (pos < stmt.length()) {\n\t\t\tchar ch = stmt.charAt(pos);\n\t\t\t// 忽略处理注释 /* */ BEN\n\t\t\tif(ch == '/' &&  pos+4 < stmt.length() && stmt.charAt(pos+1) == '*') {\n\t\t\t\tif(stmt.substring(pos+2).indexOf(\"*/\") != -1) {\n\t\t\t\t\tpos += stmt.substring(pos+2).indexOf(\"*/\")+4;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\t// 不应该发生这类情况。\n\t\t\t\t\tthrow new IllegalArgumentException(\"sql 注释 语法错误\");\n\t\t\t\t}\n\t\t\t} else if(ch == 'D'||ch == 'd') {\n\t\t\t\t// 匹配 [describe ]\n\t\t\t\tif(pos+MATCHED_FEATURE.length() < stmt.length() && (stmt.substring(pos).toUpperCase().indexOf(MATCHED_FEATURE) != -1)) {\n\t\t\t\t\tpos = pos + MATCHED_FEATURE.length();\n\t\t\t\t\tbreak;\n\t\t\t\t} else if(pos+MATCHED2_FEATURE.length() < stmt.length() && (stmt.substring(pos).toUpperCase().indexOf(MATCHED2_FEATURE) != -1)) {\n\t\t\t\t\tpos = pos + MATCHED2_FEATURE.length();\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// 重置ind坐标。BEN GONG","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/impl/DruidMycatRouteStrategy.java#L812-L848","documentation":"Mycat's statement pre-processing scans for comment/feature prefixes (e.g. to strip comments and detect 'describe'); when it encounters '/*' it requires a closing '*/' later in the statement. If the comment is unterminated, the scanner throws IllegalArgumentException 'sql 注释 语法错误' (SQL comment syntax error).","triggerScenarios":"Sending SQL containing '/*' without a matching '*/' — e.g. truncated hint comments like '/*' or '/*+hint' with no terminator — through the statement pre-processing in DruidMycatRouteStrategy (pos+4 < stmt.length() guard also means very short statements with '/*' near the end can hit it).","commonSituations":"Hand-written hint comments missing the closing */; string truncation by an upstream proxy or client cutting the SQL; generated SQL from tools that emit malformed comments; pasted SQL where a comment's tail was lost.","solutions":["Fix the SQL so every '/*' comment is properly closed with '*/'.","Remove the malformed comment from the statement entirely.","Check the client/proxy for truncation of long SQL strings and increase its max packet/length limits.","Validate the statement in the application (count balanced '/*' and '*/') before sending it to Mycat."],"exampleFix":"// before\nSELECT * FROM t /*+ read hint FROM node_a LIMIT 10;\n// after\nSELECT * FROM t /*+ read hint from node_a */ LIMIT 10;","handlingStrategy":"validation","validationCode":"// ensure comment blocks are terminated before sending SQL\nint open = 0;\nfor (int i = 0; i < sql.length() - 1; i++) {\n    if (sql.startsWith(\"/*\", i)) open++;\n    if (sql.startsWith(\"*/\", i)) open--;\n}\nif (open != 0) throw new IllegalArgumentException(\"Unterminated /* comment in SQL\");","typeGuard":"boolean commentsTerminated(String sql) {\n    if (sql == null) return false;\n    int depth = 0;\n    for (int i = 0; i < sql.length() - 1; i++) {\n        if (sql.regionMatches(i, \"/*\", 0, 2)) depth++;\n        else if (sql.regionMatches(i, \"*/\", 0, 2)) depth--;\n    }\n    return depth == 0;\n}","tryCatchPattern":"try { stmt = preprocess(stmt); } catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"sql 注释 语法错误\")) {\n        throw new IllegalArgumentException(\"SQL contains an unterminated /* comment; fix and retry\");\n    } else throw e;\n}","preventionTips":["Always close hint/comment blocks with '*/'.","Sanitize/validate generated SQL for balanced comment markers.","Check proxies and drivers for SQL truncation that can cut off a comment tail.","Strip or normalize comments at the application layer before sending to Mycat."],"tags":["sql","comment","parser"],"backgroundTag":"invalid-sql-comment-syntax","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}