MyCATApache/Mycat-Server · error · IllegalArgumentException
sql 注释 语法错误
Error message
sql 注释 语法错误
What it means
StringUtil.getTableName scans a SQL string to find the table name, skipping block comments. If it encounters '/*' with no closing '*/' later in the string (a malformed comment), it throws IllegalArgumentException('sql 注释 语法错误' — 'SQL comment syntax error').
Solutions
- Close the block comment with '*/' in the SQL string
- Replace the unterminated comment with '-- ' line comment or remove it
- If SQL comes from a template/log truncation, ensure the full statement is passed to getTableName
- Note the scan condition requires pos+4 < sql.length(); very short trailing input can also land here — keep comments well-formed
Example fix
// before String sql = "select * from t1 /* test"; // after String sql = "select * from t1 /* test */";
Defensive patterns
Strategy: validation
Validate before calling
static boolean hasBalancedBlockComments(String sql){
if (sql == null) return true;
int open = 0;
for (int i = 0; i < sql.length()-1; i++) {
if (sql.startsWith("/*", i)) { open++; i++; }
else if (sql.startsWith("*/", i)) { open--; i++; if (open < 0) return false; }
}
return open == 0;
} Try / catch
try { table = StringUtil.getTableName(sql); }
catch (IllegalArgumentException e) { throw new IllegalArgumentException("SQL contains unterminated /* comment", e); } Prevention
- Always close /* */ comments, including optimizer hints
- Run comment-balance checks on SQL generated from templates
- Prefer '--' line comments for quick annotations in scripts
- Avoid truncating SQL when copying from logs before parsing
When it happens
Trigger: Passing SQL whose '/*' comment is never closed, e.g. getTableName("select * from t1 /* hint") — the code detects '*/' is absent and aborts.
Common situations: Hand-written hints like /*+index*/ accidentally cut off by string truncation or editors; generated SQL where a comment template failed to close; copy/paste dropping the tail of the query.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- toString(buf)
- outside range [ , ]
- Interval year-month string was null
- Interval string does not match year-month format of 'y-m':
- Error parsing interval year-month string:
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/d77a105833d9afc1.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/util/StringUtil.java:503
} else
{
sql=oriSql;
}
int pos = 0;
boolean insertFound = false;
boolean intoFound = false;
int tableStartIndx = -1;
int tableEndIndex = -1;
while (pos < sql.length()) {
char ch = sql.charAt(pos);
// 忽略处理注释 /* */ BEN
if(ch == '/' && pos+4 < sql.length() && sql.charAt(pos+1) == '*') {
if(sql.substring(pos+2).indexOf("*/") != -1) {
pos += sql.substring(pos+2).indexOf("*/")+4;
continue;
} else {
// 不应该发生这类情况。
throw new IllegalArgumentException("sql 注释 语法错误");
}
} else if (ch <= ' ' || ch == '(' || ch=='`') {//
if (tableStartIndx > 0) {
tableEndIndex = pos;
break;
} else {
pos++;
continue;
}
} else if (ch == 'i' || ch == 'I') {
if (intoFound) {
if (tableStartIndx == -1 && ch!='`') {
tableStartIndx = pos;
}
pos++;
} else if (insertFound) {// into start
// 必须全部都为INTO才认为是into
if(pos+5 < sql.length() && (sql.charAt(pos+1) == 'n' || sql.charAt(pos+1) == 'N') && (sql.charAt(pos+2) == 't' || sql.charAt(pos+2) == 'T') && (sql.charAt(pos+3) == 'o' || sql.charAt(pos+3) == 'O') && (sql.charAt(pos+4) <= ' ')) {View on GitHub (pinned to 65f8d8beb7)