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

  1. 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)".
  2. Validate parenthesis balance client-side before sending.
  3. 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

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


AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14). Data as JSON: /api/errors/fe36790c03014c45. Report an issue: GitHub.