{"record":{"id":"c648a9617ba638c5","repo":"Tencent/APIJSON","slug":"value-key-c648a9","errorCode":null,"errorMessage":"{}:value 中 key 不合法！比较运算 [>, <, >=, <=] 不支持 [&, !, |] 中任何逻辑运算符 ！","messagePattern":"(.+?):value 中 key 不合法！比较运算 \\[>, <, >=, <=\\] 不支持 \\[&, !, \\|\\] 中任何逻辑运算符 ！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java","lineNumber":4058,"sourceCode":"\n\t\tString rc = column.endsWith(\"[\") || column.endsWith(\"{\") ? column.substring(0, column.length() - 1) : column;\n\t\tif (StringUtil.isName(rc) == false) {\n\t\t\tthrow new IllegalArgumentException(key + \":value 中key不合法！不支持 ! 以外的逻辑符 ！\");\n\t\t}\n\n\t\tString logic = value == null && rawSQL == null ? (not ? SQL.IS_NOT : SQL.IS) : (not ? \" != \" : \" = \");\n\t\treturn gainKey(column) + logic + (value instanceof Subquery ? gainSubqueryString((Subquery<T, M, L>) value)\n\t\t\t\t: (rawSQL != null ? rawSQL : gainValue(key, column, value)));\n\t}\n\n\tpublic String gainCompareString(String key, String column, Object value, String type, String rawSQL) throws Exception {\n\t\tif (value != null && JSON.isBoolOrNumOrStr(value) == false && value instanceof Subquery == false) {\n\t\t\tthrow new IllegalArgumentException(key + \":value 中 value 不合法！比较运算 [>, <, >=, <=] 只支持 [Boolean, Number, String] 内的类型 ！\");\n\t\t}\n\n\t\tString rc = column.endsWith(\"[\") || column.endsWith(\"{\") ? column.substring(0, column.length() - 1) : column;\n\t\tif ( ! StringUtil.isName(rc)) {\n\t\t\tthrow new IllegalArgumentException(key + \":value 中 key 不合法！比较运算 [>, <, >=, <=] 不支持 [&, !, |] 中任何逻辑运算符 ！\");\n\t\t}\n\n\t\treturn gainKey(column) + \" \" + type + \" \" + (value instanceof Subquery ? gainSubqueryString((Subquery<T, M, L>) value)\n\t\t\t\t: (rawSQL != null ? rawSQL : gainValue(key, column, value)));\n\t}\n\n\tpublic String gainKey(@NotNull String key) {\n\t\tString lenFun = \"\";\n\t\tif (key.endsWith(\"[\")) {\n\t\t\tlenFun = isSQLServer() || isKingBaseSQLServer() ? \"datalength\" : \"length\";\n\t\t\tkey = key.substring(0, key.length() - 1);\n\t\t}\n\t\telse if (key.endsWith(\"{\")) {\n\t\t\tlenFun = \"json_length\";\n\t\t\tkey = key.substring(0, key.length() - 1);\n\t\t}\n\t\telse if (isTest()) {\n\t\t\tif (key.contains(\"'\")) {  // || key.contains(\"#\") || key.contains(\"--\")) {","sourceCodeStart":4040,"sourceCodeEnd":4076,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L4040-L4076","documentation":"Thrown by gainCompareString when the column part of a comparison key fails StringUtil.isName(). Comparison keys (>, <, >=, <=) do not accept the '!' NOT suffix or '& |' logic characters, unlike the equality path; anything beyond a legal identifier is rejected.","triggerScenarios":"Keys like \"age!>\" 10, \"price|>\" 5, or comparison keys containing invalid identifier characters after the operator suffix is stripped.","commonSituations":"Assuming '!' works everywhere (it only works on plain equality keys); building comparison keys dynamically and appending extra symbols.","solutions":["Remove '!', '&', '|' from comparison keys: use \"age>\" not \"age!>\".","To negate a range, invert the operator (\"age<=\" instead of \"!(age>)\") or use @combine with NOT semantics.","Keep the base name a valid column identifier."],"exampleFix":"// before\n{\"User\": {\"age!>\": 18}}\n// after\n{\"User\": {\"age<=\": 18}}","handlingStrategy":"validation","validationCode":"function isName(s) { return /^[A-Za-z_$][\\w$]*(\\.[A-Za-z_$][\\w$]*)*$/.test(s); }\nfor (const k of Object.keys(tableObj)) {\n  const m = k.match(/^(.+?)(>=|<=|>|<)$/);\n  if (m && !isName(m[1].replace(/[!\\[\\{]$/, ''))) throw new Error('bad compare key ' + k);\n  if (m && /[&!|]/.test(m[1])) throw new Error('compare key must not contain & ! |');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never append '!' or logic symbols to comparison keys.","Invert the operator to express negation instead."],"tags":["apijson","column-name","compare","validation"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}