prestodb/presto · error · SemanticException
DUPLICATE_COLUMN_NAME
DUPLICATE_COLUMN_NAME
Error message
Column name '%s' specified more than once
What it means
CreateTableTask.internalExecute throws SemanticException(DUPLICATE_COLUMN_NAME) when two column definitions normalize to the same name (columns.containsKey(name) after metadata.normalizeIdentifier). Duplicate column names make the resulting table schema ambiguous, so creation is rejected.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/CreateTableTask.java:139
boolean includingProperties = false;
List<TableConstraint<String>> constraints = new ArrayList<>();
for (TableElement element : statement.getElements()) {
if (element instanceof ColumnDefinition) {
ColumnDefinition column = (ColumnDefinition) element;
String columnName = column.getName().getValue();
String name = metadata.normalizeIdentifier(session, tableName.getCatalogName(), columnName);
Type type;
try {
type = metadata.getType(parseTypeSignature(column.getType()));
}
catch (IllegalArgumentException | UnknownTypeException e) {
throw new SemanticException(TYPE_MISMATCH, element, "Unknown type '%s' for column '%s'", column.getType(), column.getName());
}
if (type.equals(UNKNOWN)) {
throw new SemanticException(TYPE_MISMATCH, element, "Unknown type '%s' for column '%s'", column.getType(), column.getName());
}
if (columns.containsKey(name)) {
throw new SemanticException(DUPLICATE_COLUMN_NAME, column, "Column name '%s' specified more than once", column.getName());
}
if (!column.isNullable() && !metadata.getConnectorCapabilities(session, connectorId).contains(NOT_NULL_COLUMN_CONSTRAINT)) {
throw new SemanticException(NOT_SUPPORTED, column, "Catalog '%s' does not support non-null column for column name '%s'", connectorId.getCatalogName(), column.getName());
}
Map<String, Expression> sqlProperties = mapFromProperties(column.getProperties());
Map<String, Object> columnProperties = metadata.getColumnPropertyManager().getProperties(
connectorId,
tableName.getCatalogName(),
sqlProperties,
session,
metadata,
parameterLookup);
columns.put(name, ColumnMetadata.builder()
.setName(name)
.setType(type)
.setNullable(column.isNullable())View on GitHub (pinned to 55bb57d202)
Solutions
- Remove or rename the duplicate column so all names are unique after normalization.
- De-duplicate generated column lists before emitting DDL (e.g. LinkedHashMap keyed by normalized name).
- Check identifier normalization rules of the target catalog to avoid case-collisions.
- Validate the column list for duplicates before submitting the statement.
Example fix
-- before CREATE TABLE t (id BIGINT, ID VARCHAR); -- after CREATE TABLE t (id BIGINT, id_label VARCHAR);
Defensive patterns
Strategy: validation
Validate before calling
Map<String, Boolean> seen = new LinkedHashMap<>();
for (ColumnDefinition c : statement.getElements()) {
String name = metadata.normalizeIdentifier(session, catalog, c.getName());
if (!seen.putIfAbsent(name, true) == null) {
throw new IllegalStateException("Duplicate column after normalization: " + name);
}
} Type guard
List<String> duplicateColumns(Session session, Metadata metadata, String catalog, List<ColumnDefinition> columns) {
Set<String> seen = new HashSet<>();
return columns.stream()
.map(c -> metadata.normalizeIdentifier(session, catalog, c.getName()))
.filter(n -> !seen.add(n))
.collect(Collectors.toList());
} Try / catch
try {
createTable(session, statement, parameters);
} catch (SemanticException e) {
if (e.getCode() == DUPLICATE_COLUMN_NAME) {
// de-duplicate/rename columns and resubmit
} else {
throw e;
}
} Prevention
- De-duplicate column lists by normalized name in DDL generators
- Remember identifiers normalize case-insensitively in many catalogs — 'Id' and 'ID' collide
- Unit-test generated schemas for duplicate normalized names
- Review merged column definitions from multiple sources for overlapping names
When it happens
Trigger: CREATE TABLE listing the same column name twice, or two names that normalize to the same key (case-insensitive/normalized identifiers, e.g. 'Id' and 'ID').
Common situations: Copy-pasted column lists that duplicate a column; generated DDL merging multiple sources with overlapping names; case-differing names in case-insensitive catalogs.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/dac4bf0dd8b17635.
Report an issue: GitHub.