{"record":{"id":"bb0ecac83ace078d","repo":"Tencent/APIJSON","slug":"range-value-value-all-any","errorCode":null,"errorMessage":"子查询 {}/{}:{ range:value } 中 value 只能为 [ALL, ANY] 中的一个！","messagePattern":"子查询 (.+?)/(.+?):(.+?) 中 value 只能为 \\[ALL, ANY\\] 中的一个！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java","lineNumber":424,"sourceCode":"\n    //private boolean hasOtherKeyNotFun = false;\n\n    /**解析普通成员\n\t * @param key\n\t * @param value\n\t * @return whether parse succeed\n\t */\n\t@Override\n\tpublic boolean onParse(@NotNull String key, @NotNull Object value) throws Exception {\n\t\tif (key.endsWith(\"@\")) {  // StringUtil.isPath((String) value)) {\n\t\t\t// [] 内主表 position > 0 时，用来生成 SQLConfig<T, M, L> 的键值对全都忽略，不解析\n\t\t\tif (value instanceof Map<?, ?>) {  // key{}@ getRealKey, SQL 子查询对象，JSONRequest -> SQLConfig.getSQL\n\t\t\t\tString replaceKey = key.substring(0, key.length() - 1);\n\n\t\t\t\tM subquery = (M) value;\n\t\t\t\tString range = getString(subquery, KEY_SUBQUERY_RANGE);\n\t\t\t\tif (range != null && SUBQUERY_RANGE_ALL.equals(range) == false && SUBQUERY_RANGE_ANY.equals(range) == false) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"子查询 \" + path + \"/\" + key + \":{ range:value } 中 value 只能为 [\"\n                            + SUBQUERY_RANGE_ALL + \", \" + SUBQUERY_RANGE_ANY + \"] 中的一个！\");\n\t\t\t\t}\n\n\t\t\t\tL arr = parser.onArrayParse(subquery, path, key, true, null);\n\n\t\t\t\tM obj = arr == null || arr.isEmpty() ? null : JSON.get(arr, 0);\n\t\t\t\tif (obj == null) {\n\t\t\t\t\tthrow new Exception(\"服务器内部错误，解析子查询 \" + path + \"/\" + key + \":{ } 为 Subquery 对象失败！\");\n\t\t\t\t}\n\n\t\t\t\tString from = getString(subquery, apijson.JSONRequest.KEY_SUBQUERY_FROM);\n\t\t\t\tboolean isEmpty = StringUtil.isEmpty(from);\n\t\t\t\tM arrObj = isEmpty ? null : JSON.get(obj, from);\n\t\t\t\tif (isEmpty) {\n\t\t\t\t\tSet<Entry<String, Object>> set = obj.entrySet();\n\t\t\t\t\tfor (Entry<String, Object> e : set) {\n\t\t\t\t\t\tString k = e == null ? null : e.getKey();\n\t\t\t\t\t\tObject v = k == null ? null : e.getValue();","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java#L406-L442","documentation":"When parsing a 'key{}@' subquery object, AbstractObjectParser reads its 'range' field and only allows the constants SUBQUERY_RANGE_ALL ('ALL') or SUBQUERY_RANGE_ANY ('ANY') — these map to SQL ALL/ANY quantifiers. If range is present and is neither of those exact strings (case-sensitive), an IllegalArgumentException is thrown naming the path and key.","triggerScenarios":"A request like \"id{}@\": { \"from\": \"Comment\", \"Comment\": { \"@column\": \"userId\" }, \"range\": \"all\" } — lowercase 'all', 'SOME', 'IN', or any other string. Omitting range entirely is fine (null passes).","commonSituations":"Writing 'all'/'any' in lowercase; assuming SQL 'SOME' or 'IN' semantics are supported; copy-pasting from docs that capitalize differently.","solutions":["Use exactly \"ALL\" or \"ANY\" (uppercase) for the range value.","Omit the range key entirely when you don't need the ALL/ANY quantifier.","For 'IN'-style membership, drop range and rely on the default subquery behavior instead of trying range values."],"exampleFix":"// before\n\"id{}@\": { \"from\": \"Comment\", \"range\": \"all\", \"Comment\": { \"@column\": \"userId\" } }\n// after\n\"id{}@\": { \"from\": \"Comment\", \"range\": \"ALL\", \"Comment\": { \"@column\": \"userId\" } }","handlingStrategy":"validation","validationCode":"Object range = subquery.get(\"range\");\nif (range != null && !\"ALL\".equals(range) && !\"ANY\".equals(range)) {\n  throw new IllegalArgumentException(\"range must be ALL or ANY (uppercase)\");\n}","typeGuard":"function isValidRange(r: unknown): boolean {\n  return r == null || r === 'ALL' || r === 'ANY';\n}","tryCatchPattern":null,"preventionTips":["Use exactly 'ALL' or 'ANY' (case-sensitive, uppercase).","Omit range when the default behavior suffices.","Centralize subquery building in one helper that enforces valid range values."],"tags":["apijson","subquery","range","validation","request-syntax"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}