prestodb/presto · error · SemanticException
DUPLICATE_COLUMN_NAME
DUPLICATE_COLUMN_NAME
Error message
Insert column name is specified more than once: %s
What it means
When an INSERT statement lists its target columns explicitly, Presto requires each column to appear at most once. StatementAnalyzer.visitInsert uses a HashSet while iterating the provided insertColumns; if a name is added twice (columnNames.add returns false), it throws DUPLICATE_COLUMN_NAME.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:563
List<String> tableColumns = columnsMetadata.stream()
.filter(column -> !column.isHidden())
.map(ColumnMetadata::getName)
.collect(toImmutableList());
List<String> insertColumns;
if (insert.getColumns().isPresent()) {
insertColumns = insert.getColumns().get().stream()
.map(Identifier::getValue)
.map(column -> metadata.normalizeIdentifier(session, targetTable.getCatalogName(), column))
.collect(toImmutableList());
Set<String> columnNames = new HashSet<>();
for (String insertColumn : insertColumns) {
if (!tableColumns.contains(insertColumn)) {
throw new SemanticException(MISSING_COLUMN, insert, "Insert column name does not exist in target table: %s", insertColumn);
}
if (!columnNames.add(insertColumn)) {
throw new SemanticException(DUPLICATE_COLUMN_NAME, insert, "Insert column name is specified more than once: %s", insertColumn);
}
}
}
else {
insertColumns = tableColumns;
}
List<ColumnMetadata> expectedColumns = insertColumns.stream()
.map(insertColumn -> getColumnMetadata(columnsMetadata, insertColumn))
.collect(toImmutableList());
checkTypesMatchForInsert(insert, queryScope, expectedColumns);
Map<String, ColumnHandle> columnHandles = tableColumnsMetadata.getColumnHandles();
analysis.setInsert(new Analysis.Insert(
tableColumnsMetadata.getTableHandle().get(),
insertColumns.stream().map(columnHandles::get).collect(toImmutableList())));
View on GitHub (pinned to 55bb57d202)
Solutions
- Remove the duplicated name from the INSERT column list so each target column appears exactly once.
- If your driver/templating builds the column list, deduplicate or assert uniqueness on the list before rendering the SQL.
- Omit the column list entirely to target all table columns in order (values must then match the full table schema).
Example fix
// before INSERT INTO orders (orderkey, custkey, custkey) VALUES (1, 2, 2); // after INSERT INTO orders (orderkey, custkey) VALUES (1, 2);
Defensive patterns
Strategy: validation
Validate before calling
// JS-style pre-check on generated column lists:
const cols = ['orderkey', 'custkey', 'custkey'];
const dupes = cols.filter((c, i) => cols.indexOf(c) !== i);
if (dupes.length) throw new Error('Duplicate INSERT columns: ' + dupes.join(', ')); Prevention
- Deduplicate column lists in any query-builder/templating code before rendering SQL.
- When editing INSERT statements manually, re-read the full column list after additions.
- Add a unit test asserting uniqueness of generated INSERT column lists.
When it happens
Trigger: INSERT INTO t (a, a, b) VALUES (...) — the same column name appears twice in the explicit column list of the INSERT.
Common situations: Copy-paste or generated SQL accidentally repeating a column; adding a column to the list without removing the old positional entry; templating bugs in query builders that concatenate column lists.
Related errors
- MISSING_COLUMN
- MUST_BE_AGGREGATE_OR_GROUP_BY
- NESTED_AGGREGATION
- NESTED_WINDOW
- MUST_BE_AGGREGATION_FUNCTION
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/7d259f67885d1bcd.
Report an issue: GitHub.