MyCATApache/Mycat-Server · error · IllegalArgumentException
sql 注释 语法错误
Error message
sql 注释 语法错误
What it means
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).
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.
Example fix
// before SELECT * FROM t /*+ read hint FROM node_a LIMIT 10; // after SELECT * FROM t /*+ read hint from node_a */ LIMIT 10;
Defensive patterns
Strategy: validation
Validate before calling
// ensure comment blocks are terminated before sending SQL
int open = 0;
for (int i = 0; i < sql.length() - 1; i++) {
if (sql.startsWith("/*", i)) open++;
if (sql.startsWith("*/", i)) open--;
}
if (open != 0) throw new IllegalArgumentException("Unterminated /* comment in SQL"); Type guard
boolean commentsTerminated(String sql) {
if (sql == null) return false;
int depth = 0;
for (int i = 0; i < sql.length() - 1; i++) {
if (sql.regionMatches(i, "/*", 0, 2)) depth++;
else if (sql.regionMatches(i, "*/", 0, 2)) depth--;
}
return depth == 0;
} Try / catch
try { stmt = preprocess(stmt); } catch (IllegalArgumentException e) {
if (e.getMessage().contains("sql 注释 语法错误")) {
throw new IllegalArgumentException("SQL contains an unterminated /* comment; fix and retry");
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- not a query sql statement
- Can't identify the operation of of where
- Multi statements is not supported,use single statement…
- ER_PARSE_ERROR
- number of columns error
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/b034c4a2d02553d9.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/impl/DruidMycatRouteStrategy.java:830
* @return RouteResultset (数据路由集合)
* @author mycat
*/
private static RouteResultset analyseDescrSQL(SchemaConfig schema,
RouteResultset rrs, String stmt, int ind) {
final String MATCHED_FEATURE = "DESCRIBE ";
final String MATCHED2_FEATURE = "DESC ";
int pos = 0;
while (pos < stmt.length()) {
char ch = stmt.charAt(pos);
// 忽略处理注释 /* */ BEN
if(ch == '/' && pos+4 < stmt.length() && stmt.charAt(pos+1) == '*') {
if(stmt.substring(pos+2).indexOf("*/") != -1) {
pos += stmt.substring(pos+2).indexOf("*/")+4;
continue;
} else {
// 不应该发生这类情况。
throw new IllegalArgumentException("sql 注释 语法错误");
}
} else if(ch == 'D'||ch == 'd') {
// 匹配 [describe ]
if(pos+MATCHED_FEATURE.length() < stmt.length() && (stmt.substring(pos).toUpperCase().indexOf(MATCHED_FEATURE) != -1)) {
pos = pos + MATCHED_FEATURE.length();
break;
} else if(pos+MATCHED2_FEATURE.length() < stmt.length() && (stmt.substring(pos).toUpperCase().indexOf(MATCHED2_FEATURE) != -1)) {
pos = pos + MATCHED2_FEATURE.length();
break;
} else {
pos++;
}
} else {
break;
}
}
// 重置ind坐标。BEN GONGView on GitHub (pinned to 65f8d8beb7)