prestodb/presto · error · PrestoException

ALREADY_EXISTS

ALREADY_EXISTS

Error message

Column already exists: ${columnName}

What it means

FileHiveMetastore.addColumn throws this because the target column name is already present in the table's schema (checked via oldTable.getColumn(columnName).isPresent()). The file-based metastore stores schema as JSON files and enforces uniqueness of column names within a table at alterTable time. This is a client-side validation error: you asked to add a column that already exists instead of using rename or modifyColumn.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/file/FileHiveMetastore.java:546

        requireNonNull(newTableName, "newTableName is null");
        getRequiredDatabase(metastoreContext, newDatabaseName);

        // verify new table does not exist
        verifyTableNotExists(metastoreContext, newDatabaseName, newTableName);

        Path metadataDirectory = getTableMetadataDirectory(databaseName, tableName);
        Path newMetadataDirectory = getTableMetadataDirectory(newDatabaseName, newTableName);
        renameTable(metadataDirectory, newMetadataDirectory);

        return EMPTY_RESULT;
    }

    @Override
    public synchronized MetastoreOperationResult addColumn(MetastoreContext metastoreContext, String databaseName, String tableName, String columnName, HiveType columnType, String columnComment)
    {
        alterTable(databaseName, tableName, oldTable -> {
            if (oldTable.getColumn(columnName).isPresent()) {
                throw new PrestoException(ALREADY_EXISTS, "Column already exists: " + columnName);
            }

            return oldTable.withDataColumns(ImmutableList.<Column>builder()
                    .addAll(oldTable.getDataColumns())
                    .add(new Column(columnName, columnType, Optional.ofNullable(columnComment), Optional.empty()))
                    .build());
        });

        return EMPTY_RESULT;
    }

    @Override
    public synchronized MetastoreOperationResult renameColumn(MetastoreContext metastoreContext, String databaseName, String tableName, String oldColumnName, String newColumnName)
    {
        alterTable(databaseName, tableName, oldTable -> {
            if (oldTable.getColumn(newColumnName).isPresent()) {
                throw new PrestoException(ALREADY_EXISTS, "Column already exists: " + newColumnName);
            }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the existing schema first (getTableColumnNames / SHOW COLUMNS) and skip the add if the column already exists.
  2. If the intent was to change the column type or comment, use modifyColumn instead of addColumn.
  3. Make migration scripts idempotent: wrap the addColumn call in an existence check or catch ALREADY_EXISTS and treat as success.
  4. If a stale cached table view caused a false positive, re-fetch the table metadata and retry once.

Example fix

// before
metastore.addColumn(context, db, table, "extra_col", HiveType.HIVE_INT, null);
// after
Table table = metastore.getTable(context, db, table).orElseThrow(...);
if (table.getColumn("extra_col").isEmpty()) {
    metastore.addColumn(context, db, table, "extra_col", HiveType.HIVE_INT, null);
}
Defensive patterns

Strategy: validation

Validate before calling

boolean columnExists = metastore.getTable(metastoreContext, db, table)
        .orElseThrow(() -> new TableNotFoundException(new SchemaTableName(db, table)))
        .getColumn("extra_col").isPresent();
if (!columnExists) { metastore.addColumn(metastoreContext, db, table, "extra_col", HiveType.HIVE_INT, null); }

Try / catch

try {
    metastore.addColumn(ctx, db, table, name, type, comment);
}
catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("ALREADY_EXISTS")) { /* treat as success */ }
    else { throw e; }
}

Prevention

When it happens

Trigger: Calling Metastore.addColumn (directly or via ALTER TABLE ADD COLUMN) with a columnName that already appears in the table's data columns; re-running a non-idempotent migration script that adds the same column twice.

Common situations: Migration/ETL scripts executed twice; concurrent ALTER TABLE ADD COLUMN from two sessions on a table backed by FileHiveMetastore (schema is checked inside synchronized alterTable, but callers often pre-check and race); schema drift between an external Hive catalog and the Presto file metastore.

Related errors


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