OtterMind/Chat2DB · error · IllegalArgumentException

Unsupported DM VARCHAR unit: {unit}

Error message

Unsupported DM VARCHAR unit: {unit}

What it means

Thrown by DMSqlGuards.requireUnit when a DM (Dameng) VARCHAR length unit is neither CHAR nor BYTE. Dameng supports CHAR/BYTE length semantics for VARCHAR, so this guard whitelists exactly those two units before they are interpolated into non-escapable DDL positions. Any other token (including null after trimming) is rejected.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-dm/src/main/java/ai/chat2db/plugin/dm/DMSqlGuards.java:52

        return value;
    }

    /**
     * Validates one complete DM column type expression, including
     * parameterized built-in and schema-qualified user-defined types.
     */
    public static String requireColumnTypeExpression(String typeName) {
        if (StringUtils.isBlank(typeName)) {
            throw invalid("column type", typeName);
        }
        scanExpression(typeName.trim(), true, "column type");
        return typeName;
    }

    public static String requireUnit(String unit) {
        String trimmed = StringUtils.trimToEmpty(unit);
        if (!"CHAR".equalsIgnoreCase(trimmed) && !"BYTE".equalsIgnoreCase(trimmed)) {
            throw new IllegalArgumentException("Unsupported DM VARCHAR unit: " + unit);
        }
        return trimmed;
    }

    public static String requireAscOrDesc(String value) {
        String trimmed = StringUtils.trimToEmpty(value);
        if ("ASC".equalsIgnoreCase(trimmed)) {
            return "ASC";
        }
        if ("DESC".equalsIgnoreCase(trimmed)) {
            return "DESC";
        }
        throw new IllegalArgumentException("Invalid DM index sort direction: " + value);
    }

    public static String requireBitLiteral(String value) {
        if (StringUtils.isBlank(value)) {
            return "NULL";

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Pass only "CHAR" or "BYTE" (any case) to requireUnit; trim happens internally so surrounding whitespace is fine.
  2. If the source of the unit is unknown, default it to the dialect default (usually BYTE) instead of forwarding an empty string.
  3. Constrain the UI/API for DM VARCHAR length semantics to a CHAR/BYTE dropdown so invalid tokens never reach the guard.

Example fix

// before
String unit = column.getLengthUnit(); // could be null or ""
DDL.append("VARCHAR(").append(size).append(" ").append(DMSqlGuards.requireUnit(unit));

// after
String unit = column.getLengthUnit();
if (StringUtils.isBlank(unit)) {
    unit = "BYTE"; // DM default length semantics
}
DDL.append("VARCHAR(").append(size).append(" ").append(DMSqlGuards.requireUnit(unit));
Defensive patterns

Strategy: validation

Validate before calling

static boolean isDmUnit(String unit) {
    if (unit == null) return false;
    String t = unit.trim();
    return "CHAR".equalsIgnoreCase(t) || "BYTE".equalsIgnoreCase(t);
}

Type guard

static String dmUnitOrDefault(String unit) {
    if ("CHAR".equalsIgnoreCase(unit) || "BYTE".equalsIgnoreCase(unit)) return unit.trim().toUpperCase(Locale.ROOT);
    return "BYTE"; // DM default length semantics
}

Prevention

When it happens

Trigger: Calling DMSqlGuards.requireUnit(unit) with a value other than "CHAR"/"BYTE" (case-insensitive), e.g. null, "", "WORD", "OCTET". Reached when building DM column DDL that carries an explicit length-semantic unit on a VARCHAR type.

Common situations: Migrating a schema from Oracle/PostgreSQL whose driver reports a different unit label; a form field letting users type a free-text unit; mapping a generic 'length semantics' enum that includes values Dameng does not support.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/80cd561a071fbadc. Report an issue: GitHub.