{"record":{"id":"ec6d89660c6d7155","repo":"OtterMind/Chat2DB","slug":"invalid-dm-bit-literal-value","errorCode":null,"errorMessage":"Invalid DM BIT literal: {value}","messagePattern":"Invalid DM BIT literal: (.+?)","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":79,"sourceCode":"        }\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<>();\n        List<String> topLevelWords = new ArrayList<>();\n        boolean sawToken = false;\n\n        for (int i = 0; i < expression.length(); i++) {\n            char c = expression.charAt(i);\n            if (Character.isISOControl(c)) {\n                throw invalid(description, expression);\n            }\n            if (Character.isWhitespace(c)) {\n                continue;\n            }\n            sawToken = true;\n\n            if (isAlternativeQuoteStart(expression, i)) {","sourceCodeStart":61,"sourceCodeEnd":97,"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#L61-L97","documentation":"Thrown by DMSqlGuards.requireBitLiteral when a DM BIT column default literal is not one of the accepted truthy/falsy forms. The guard accepts blank (returns \"NULL\"), \"0\"/\"false\" (returns \"0\"), and \"1\"/\"true\" (returns \"1\"); any other value is rejected so a non-escapable default cannot be embedded in DDL.","triggerScenarios":"Calling DMSqlGuards.requireBitLiteral(value) with a value like \"2\", \"T\", \"yes\", \"b'1'\", or an expression string. Reached when generating DDL for a DM BIT column whose default value is being normalized.","commonSituations":"Copying a BIT/TINYINT(1) default from MySQL-style schemas that use 0/1 with extra formatting; a UI submitting a boolean as \"on\"/\"off\" or \"yes\"; importing metadata whose default text includes quotes or casts.","solutions":["Convert boolean-ish inputs to \"0\"/\"1\" before calling requireBitLiteral.","Leave the default blank if the column should default to NULL.","Normalize at the import layer: map on/yes/true->\"1\" and off/no/false->\"0\"."],"exampleFix":"// before\nString d = column.getDefaultValue(); // \"yes\"\nDDL.append(\" DEFAULT \").append(DMSqlGuards.requireBitLiteral(d));\n\n// after\nString d = column.getDefaultValue();\nif (\"on\".equalsIgnoreCase(d) || \"yes\".equalsIgnoreCase(d) || \"true\".equalsIgnoreCase(d)) d = \"1\";\nelse if (\"off\".equalsIgnoreCase(d) || \"no\".equalsIgnoreCase(d) || \"false\".equalsIgnoreCase(d)) d = \"0\";\nDDL.append(\" DEFAULT \").append(DMSqlGuards.requireBitLiteral(d));","handlingStrategy":"validation","validationCode":"static boolean isDmBitLiteral(String v) {\n    if (v == null || v.trim().isEmpty()) return true; // -> NULL\n    String t = v.trim().toLowerCase(Locale.ROOT);\n    return \"0\".equals(t) || \"1\".equals(t) || \"true\".equals(t) || \"false\".equals(t);\n}","typeGuard":"static String dmBitOrSkip(String v) {\n    if (v == null || v.trim().isEmpty()) return null; // skip DEFAULT\n    String t = v.trim().toLowerCase(Locale.ROOT);\n    if (Set.of(\"0\",\"false\").contains(t)) return \"0\";\n    if (Set.of(\"1\",\"true\").contains(t)) return \"1\";\n    return null; // unsupported -> skip\n}","tryCatchPattern":null,"preventionTips":["Normalize boolean-ish inputs (yes/no/on/off/true/false) to 0/1 at the import boundary.","Leave the BIT default blank to emit DEFAULT NULL.","Constrain the BIT default UI to 0/1/(null)."],"tags":["dm","dameng","sql-guard","ddl","bit","validation"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}