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
- Pass only "CHAR" or "BYTE" (any case) to requireUnit; trim happens internally so surrounding whitespace is fine.
- If the source of the unit is unknown, default it to the dialect default (usually BYTE) instead of forwarding an empty string.
- 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
- Default a blank VARCHAR unit to the DM default (BYTE) before calling the guard.
- Restrict the DM length-semantics input to a CHAR/BYTE choice.
- Normalize Oracle/MariaDB unit labels to CHAR/BYTE when importing schemas.
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
- Invalid DM index sort direction: {value}
- Invalid DM BIT literal: {value}
- DM index must contain at least one named column
- Invalid DB2 index column ordering: {ascOrDesc}
- Unsafe column type name from metadata: {typeName}
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/80cd561a071fbadc.
Report an issue: GitHub.