prestodb/presto · error · SemanticException

COLUMN_ALREADY_EXISTS

COLUMN_ALREADY_EXISTS

Error message

Column '%s' already exists

What it means

SemanticException thrown by RenameColumnTask when the target column name of a RENAME COLUMN already exists in the table. Allowing the rename would create a duplicate column, so Presto rejects it. Rename the source to a name not present in the table's column handles.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/RenameColumnTask.java:90

        Identifier sourceName = statement.getSource();
        String source = metadata.normalizeIdentifier(session, tableName.getCatalogName(), sourceName.getValue());
        Identifier targetName = statement.getTarget();
        String target = metadata.normalizeIdentifier(session, tableName.getCatalogName(), targetName.getValue());

        accessControl.checkCanRenameColumn(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), tableName);

        Map<String, ColumnHandle> columnHandles = metadata.getColumnHandles(session, tableHandle);
        ColumnHandle columnHandle = columnHandles.get(source);
        if (columnHandle == null) {
            if (!statement.isColumnExists()) {
                throw new SemanticException(MISSING_COLUMN, statement, "Column '%s' does not exist", source);
            }
            return immediateFuture(null);
        }

        if (columnHandles.containsKey(target)) {
            throw new SemanticException(COLUMN_ALREADY_EXISTS, statement, "Column '%s' already exists", target);
        }

        if (metadata.getColumnMetadata(session, tableHandle, columnHandle).isHidden()) {
            throw new SemanticException(NOT_SUPPORTED, statement, "Cannot rename hidden column");
        }

        metadata.renameColumn(session, tableHandle, columnHandle, target);

        return immediateFuture(null);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Choose a distinct target name that doesn't exist in the table
  2. Drop or rename the conflicting existing column first
  3. Check DESCRIBE table output to pick a non-colliding name
  4. Add migration logic that verifies the source exists and target doesn't before issuing the rename

Example fix

-- before
ALTER TABLE shop.orders RENAME COLUMN id TO customer_id; -- customer_id exists
-- after
ALTER TABLE shop.orders RENAME COLUMN id TO order_id; -- unique target
Defensive patterns

Strategy: validation

Validate before calling

Set<String> cols = describeColumns("shop.orders");
if (cols.contains("customer_id")) {
    throw new IllegalStateException("target column customer_id already exists");
}

Try / catch

try {
    execute("ALTER TABLE shop.orders RENAME COLUMN id TO customer_id");
} catch (SemanticException e) {
    if (e.getCode() == COLUMN_ALREADY_EXISTS) { /* pick another name or drop conflict */ }
    else throw e;
}

Prevention

When it happens

Trigger: ALTER TABLE ... RENAME COLUMN where columnHandles.containsKey(target) is true, i.e. the destination name collides with an existing column.

Common situations: Destination name collides with an existing column (e.g. renaming 'id' to 'customer_id' when 'customer_id' already exists); migrating from systems that auto-suffix duplicates; partially-completed prior migration already added the target name.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/dca1d9b16058a3cd. Report an issue: GitHub.