{"record":{"id":"16508f6e3c2193cc","repo":"Tencent/APIJSON","slug":"jointype-table-originkey-16508f","errorCode":null,"errorMessage":"joinType + \"/.../\" + table + \"/\" + originKey + \" 中字符 \" + k + \" 不合法！与或非逻辑符仅支持 '!' 非逻辑符 ！","messagePattern":"joinType \\+ \"/\\.\\.\\./\" \\+ table \\+ \"/\" \\+ originKey \\+ \" 中字符 \" \\+ k \\+ \" 不合法！与或非逻辑符仅支持 '!' 非逻辑符 ！","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/Join.java","lineNumber":340,"sourceCode":"\t\t\telse if (originKey.endsWith(\"<=\")) {\n\t\t\t\tsetRelateType(\"<=\");\n\t\t\t\tk = originKey.substring(0, originKey.length() - 2);\n\t\t\t}\n\t\t\telse if (originKey.endsWith(\">\")) {\n\t\t\t\tsetRelateType(\">\");\n\t\t\t\tk = originKey.substring(0, originKey.length() - 1);\n\t\t\t}\n\t\t\telse if (originKey.endsWith(\"<\")) {\n\t\t\t\tsetRelateType(\"<\");\n\t\t\t\tk = originKey.substring(0, originKey.length() - 1);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsetRelateType(\"\");\n\t\t\t\tk = originKey;\n\t\t\t}\n\n\t\t\tif (k != null && (k.contains(\"&\") || k.contains(\"|\"))) {\n\t\t\t\tthrow new UnsupportedOperationException(joinType + \"/.../\" + table + \"/\" + originKey + \" 中字符 \" + k + \" 不合法！与或非逻辑符仅支持 '!' 非逻辑符 ！\");\n\t\t\t}\n\n\t\t\t//TODO if (c3 == '-') { // 表示 key 和 value 顺序反过来: value LIKE key\n\n\t\t\tLogic l = new Logic(k);\n\t\t\tsetLogic(l);\n\n\t\t\tif (StringUtil.isName(l.getKey()) == false) {\n\t\t\t\tthrow new IllegalArgumentException(joinType + \"/.../\" + table + \"/\" + originKey + \" 中字符 \" + l.getKey() + \" 不合法！必须符合字段命名格式！\");\n\t\t\t}\n\n\t\t\tsetKey(l.getKey());\n\t\t}\n\n  }\n\n}\n","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/Join.java#L322-L358","documentation":"After operator suffixes are stripped, the remaining join key k must not contain '&' or '|'. In normal where conditions APIJSON supports key&{} / key|{} combining logic, but inside a @join reference map only the negation prefix '!' is implemented, so any other logic operator in a join key throws UnsupportedOperationException ('与或非逻辑符仅支持 ! 非逻辑符').","triggerScenarios":"A join table object uses a key like \"tag|{}@\":\"/Moment/tagList\" or \"a&{}@\":... — i.e. & or | logic inside the join field key. The check k.contains(\"&\") || k.contains(\"|\") runs after relate-type parsing, before Logic wrapping, and throws.","commonSituations":"Copy-pasting a working top-level condition key (e.g. 'id|{}') into a joined table's object expecting the same semantics; trying to express OR-match against the referenced field; upgrading from a version that silently ignored such keys.","solutions":["Remove & / | from join keys; express the OR condition on the main table object instead of inside the join reference.","Use '!' negation where applicable: \"key!@\" is supported inside join maps.","If you need OR across joined fields, issue two requests or use a server-side custom SQL/service (SQLConfig custom) — join keys cannot carry & / |."],"exampleFix":"// before\n\"join\":\"/User/id@\",\n\"User\":{\"id@\":\"/Moment/userId\",\"name|{}@\":\"/Moment/tags\"}  // '|' rejected\n// after\n\"join\":\"/User/id@\",\n\"User\":{\"id@\":\"/Moment/userId\"}  // move OR condition elsewhere, e.g.\n// \"Moment\":{\"tag|{}\":[\"a\",\"b\"]} on the main table","handlingStrategy":"validation","validationCode":"for (String k : joinObj.keySet()) {\n  String bare = k.replaceAll(\"(\\\\{\\\\}|\\\\[\\\\]|<>|\\\\$|\\\\*?~|>=|<=|>|<|\\?|%)$\", \"\");\n  if (bare.contains(\"&\") || bare.contains(\"|\"))\n    throw new IllegalArgumentException(\"join key '\" + k + \"': only '!' logic is supported in join maps\");\n}","typeGuard":"function isJoinKeyLogicFree(k) { const bare = k.replace(/[\\{\\}\\[\\]<>$~%_?|&>=!*]+$/, ''); return !/[&|]/.test(bare) || bare.startsWith('!'); }","tryCatchPattern":null,"preventionTips":["Keep & / | condition keys on the main table object, never inside @join table maps.","If an OR across joined fields is needed, split into multiple requests or a custom service."],"tags":["apijson","join","logic-operators","request-syntax"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}