Tencent/APIJSON · error · IllegalArgumentException
字符 {expression} 不合法!{key}:value 中 value 里的 SQL 函数必须为 functio
Error message
字符 {expression} 不合法!{key}:value 中 value 里的 SQL 函数必须为 function(arg0,arg1,...) 这种格式! What it means
In the window/full-text branch of parseSQLExpression, the expression is split at ')OVER(' or ')AGAINST(' into s1 and s2; if the first '(' in s1 is positioned at or after the last ')' of s2 (adjusted by s1.length()), the expression is not in the supported fun(args) OVER (args) shape and this IllegalArgumentException is thrown.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:2613
throw new UnsupportedOperationException("字符串 " + suffix + " 不合法!预编译模式下 " + key
+ ":\"column?value;function(arg0,arg1,...)?value...\""
+ " 中 ?value 必须符合正则表达式 " + PATTERN_RANGE + " 且不包含连续减号 -- 或注释符 /* !不允许多余的空格!");
}
String origin = fun + "(" + (distinct ? PREFIX_DISTINCT : "") + StringUtil.get(ckeys) + ")" + suffix;
expression = origin + (StringUtil.isEmpty(alias, true) ? "" : gainAs() + quote + alias + quote);
}
else {
//是窗口函数 fun(arg0,agr1) OVER (agr0 agr1 ...)
int keyIndex = containOver ? overIndex : againstIndex;
String s1 = expression.substring(0, keyIndex + 1); // OVER 前半部分
String s2 = expression.substring(keyIndex + 1); // OVER 后半部分
int index1 = s1.indexOf("("); // 函数 "(" 的起始位置
int end = s2.lastIndexOf(")"); // 后半部分 “)” 的位置
if (index1 >= end + s1.length()) {
throw new IllegalArgumentException("字符 " + expression + " 不合法!"
+ key + ":value 中 value 里的 SQL 函数必须为 function(arg0,arg1,...) 这种格式!");
}
String fun = s1.substring(0, index1); // 函数名称
if (fun.isEmpty() == false) {
if (SQL_FUNCTION_MAP == null || SQL_FUNCTION_MAP.isEmpty()) {
if (StringUtil.isName(fun) == false) {
throw new IllegalArgumentException("字符 " + fun + " 不合法!预编译模式下 " + example
+ " 中 function 必须符合小写英文单词的 SQL 函数名格式!");
}
}
else if (SQL_FUNCTION_MAP.containsKey(fun) == false) {
throw new IllegalArgumentException("字符 " + fun + " 不合法!预编译模式下 " + example
+ " 中 function 必须符合小写英文单词的 SQL 函数名格式!且必须是后端允许调用的 SQL 函数!");
}
}
// 获取前半部分函数的参数解析 fun(arg0,agr1)View on GitHub (pinned to 5284052872)
Solutions
- Use the exact format fun(args)OVER(args2) with no spaces around OVER and balanced parentheses, e.g. "row_number()OVER(PARTITION BY id ORDER BY id ASC)".
- Validate parenthesis balance client-side before sending.
- Register complex window expressions as @raw on the server.
Example fix
// before
{"Comment":{"@column":"rank()OVER(PARTITION BY userId"}}
// after
{"Comment":{"@column":"rank()OVER(PARTITION BY userId ORDER BY id ASC)"}} Defensive patterns
Strategy: validation
Validate before calling
function balanced(s){let d=0;for(const c of s){if(c==='(')d++;if(c===')')d--;if(d<0)return false}return d===0}
const m=expr.match(/^([A-Za-z][A-Za-z0-9_]*\([^()]*\))(OVER|AGAINST)\((.*)\)$/);
if(!m||!balanced(expr))throw new Error('expect fn(args)OVER(args)'); Type guard
null
Try / catch
catch IllegalArgumentException; fix parens/spaces and re-send
Prevention
- Use the exact ')OVER(' marker without spaces
- Template window functions, never hand-edit
- Validate balance before send
When it happens
Trigger: Malformed window expressions such as "@column":"rank() OVER (PARTITION BY id" (missing final ')'), "@column":"OVER (x)rank()", or extra characters that shift the parenthesis indices so index1 >= end + s1.length().
Common situations: Hand-writing window functions without the exact no-space ')OVER(' marker; truncation of long expressions; refactoring expressions and unbalancing parens.
Related errors
- 字符 {expression} 不合法!预编译模式下 {example} 中 function 必须符合小写英文单词的
- 字符 {expression} 不合法!{key}:value 中 value 里的 SQL函数必须为 function
- HEAD请求: 字符 {alias} 不合法!预编译模式下 @column:value 中 value里面用 , 分割的
- HEAD请求: 字符{origin} 不合法!预编译模式下 @column:value 中 value里面用 , 分割的
- HEAD请求: 字符 {origin.substring(0, start)} 不合法!预编译模式下 @column:v
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/fe36790c03014c45.
Report an issue: GitHub.