{"record":{"id":"ffdd38df04b12b09","repo":"OtterMind/Chat2DB","slug":"invalid-dm-index-sort-direction-value","errorCode":null,"errorMessage":"Invalid DM index sort direction: {value}","messagePattern":"Invalid DM index sort direction: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-plugins/chat2db-community-dm/src/main/java/ai/chat2db/plugin/dm/DMSqlGuards.java","lineNumber":65,"sourceCode":"    }\n\n    public static String requireUnit(String unit) {\n        String trimmed = StringUtils.trimToEmpty(unit);\n        if (!\"CHAR\".equalsIgnoreCase(trimmed) && !\"BYTE\".equalsIgnoreCase(trimmed)) {\n            throw new IllegalArgumentException(\"Unsupported DM VARCHAR unit: \" + unit);\n        }\n        return trimmed;\n    }\n\n    public static String requireAscOrDesc(String value) {\n        String trimmed = StringUtils.trimToEmpty(value);\n        if (\"ASC\".equalsIgnoreCase(trimmed)) {\n            return \"ASC\";\n        }\n        if (\"DESC\".equalsIgnoreCase(trimmed)) {\n            return \"DESC\";\n        }\n        throw new IllegalArgumentException(\"Invalid DM index sort direction: \" + value);\n    }\n\n    public static String requireBitLiteral(String value) {\n        if (StringUtils.isBlank(value)) {\n            return \"NULL\";\n        }\n        String trimmed = StringUtils.trimToEmpty(value);\n        if (\"0\".equals(trimmed) || \"false\".equalsIgnoreCase(trimmed)) {\n            return \"0\";\n        }\n        if (\"1\".equals(trimmed) || \"true\".equalsIgnoreCase(trimmed)) {\n            return \"1\";\n        }\n        throw new IllegalArgumentException(\"Invalid DM BIT literal: \" + value);\n    }\n\n    private static void scanExpression(String expression, boolean typeExpression, String description) {\n        Deque<Character> delimiters = new ArrayDeque<>();","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-plugins/chat2db-community-dm/src/main/java/ai/chat2db/plugin/dm/DMSqlGuards.java#L47-L83","documentation":"Thrown by DMSqlGuards.requireAscOrDesc when an index sort direction is neither ASC nor DESC. Unlike the DB2 variant, this method normalizes the value to canonical uppercase before returning, but it still rejects every other token. It is used inside DM index DDL generation to keep non-escapable ordering tokens safe.","triggerScenarios":"Calling DMSqlGuards.requireAscOrDesc(value) with a value that trims to something other than ASC/DESC, or invoking DMIndexTypeEnum.buildIndexScript on an index whose column.ascOrDesc carries a bad token (and the index type is not PRIMARY_KEY, which skips the check).","commonSituations":"Index metadata imported from a non-DM source with a free-text sort field; a column model reused across dialects where another DB stored an unsupported direction; UI defaulting ascOrDesc to a placeholder like \"NONE\".","solutions":["Ensure ascOrDesc is \"ASC\", \"DESC\", or blank (blank is skipped by the caller before requireAscOrDesc runs).","Map foreign sort-direction codes to ASC/DESC at the metadata import boundary.","For primary-key-style indexes the check is bypassed; verify the index type is correctly set to PRIMARY_KEY when you intend to skip direction validation."],"exampleFix":"// before\ncolumn.setAscOrDesc(\"N\"); // non-standard\nDMSqlGuards.requireAscOrDesc(column.getAscOrDesc());\n\n// after\nString dir = column.getAscOrDesc();\ndir = \"N\".equalsIgnoreCase(dir) ? null : dir;\ncolumn.setAscOrDesc(dir); // blank -> skipped; otherwise ASC/DESC","handlingStrategy":"validation","validationCode":"static boolean isDmDir(String v) {\n    return v != null && (\"ASC\".equalsIgnoreCase(v.trim()) || \"DESC\".equalsIgnoreCase(v.trim()));\n}","typeGuard":"static String dmDirOrNull(String v) {\n    if (v == null) return null;\n    String t = v.trim();\n    if (\"ASC\".equalsIgnoreCase(t)) return \"ASC\";\n    if (\"DESC\".equalsIgnoreCase(t)) return \"DESC\";\n    return null;\n}","tryCatchPattern":null,"preventionTips":["Pass blank/null ascOrDesc so the caller skips the direction clause.","Mark primary-key indexes with the PRIMARY_KEY type so the direction check is bypassed.","Import foreign direction codes as ASC/DESC before they reach the builder."],"tags":["dm","dameng","sql-guard","ddl","index","validation"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}