{"record":{"id":"2403cc33c16a0289","repo":"prestodb/presto","slug":"already-exists-2403cc","errorCode":"ALREADY_EXISTS","errorMessage":"Column already exists: ${columnName}","messagePattern":"Column already exists: (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/file/FileHiveMetastore.java","lineNumber":546,"sourceCode":"        requireNonNull(newTableName, \"newTableName is null\");\n        getRequiredDatabase(metastoreContext, newDatabaseName);\n\n        // verify new table does not exist\n        verifyTableNotExists(metastoreContext, newDatabaseName, newTableName);\n\n        Path metadataDirectory = getTableMetadataDirectory(databaseName, tableName);\n        Path newMetadataDirectory = getTableMetadataDirectory(newDatabaseName, newTableName);\n        renameTable(metadataDirectory, newMetadataDirectory);\n\n        return EMPTY_RESULT;\n    }\n\n    @Override\n    public synchronized MetastoreOperationResult addColumn(MetastoreContext metastoreContext, String databaseName, String tableName, String columnName, HiveType columnType, String columnComment)\n    {\n        alterTable(databaseName, tableName, oldTable -> {\n            if (oldTable.getColumn(columnName).isPresent()) {\n                throw new PrestoException(ALREADY_EXISTS, \"Column already exists: \" + columnName);\n            }\n\n            return oldTable.withDataColumns(ImmutableList.<Column>builder()\n                    .addAll(oldTable.getDataColumns())\n                    .add(new Column(columnName, columnType, Optional.ofNullable(columnComment), Optional.empty()))\n                    .build());\n        });\n\n        return EMPTY_RESULT;\n    }\n\n    @Override\n    public synchronized MetastoreOperationResult renameColumn(MetastoreContext metastoreContext, String databaseName, String tableName, String oldColumnName, String newColumnName)\n    {\n        alterTable(databaseName, tableName, oldTable -> {\n            if (oldTable.getColumn(newColumnName).isPresent()) {\n                throw new PrestoException(ALREADY_EXISTS, \"Column already exists: \" + newColumnName);\n            }","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/file/FileHiveMetastore.java#L528-L564","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the existing schema first (getTableColumnNames / SHOW COLUMNS) and skip the add if the column already exists.","If the intent was to change the column type or comment, use modifyColumn instead of addColumn.","Make migration scripts idempotent: wrap the addColumn call in an existence check or catch ALREADY_EXISTS and treat as success.","If a stale cached table view caused a false positive, re-fetch the table metadata and retry once."],"exampleFix":"// before\nmetastore.addColumn(context, db, table, \"extra_col\", HiveType.HIVE_INT, null);\n// after\nTable table = metastore.getTable(context, db, table).orElseThrow(...);\nif (table.getColumn(\"extra_col\").isEmpty()) {\n    metastore.addColumn(context, db, table, \"extra_col\", HiveType.HIVE_INT, null);\n}","handlingStrategy":"validation","validationCode":"boolean columnExists = metastore.getTable(metastoreContext, db, table)\n        .orElseThrow(() -> new TableNotFoundException(new SchemaTableName(db, table)))\n        .getColumn(\"extra_col\").isPresent();\nif (!columnExists) { metastore.addColumn(metastoreContext, db, table, \"extra_col\", HiveType.HIVE_INT, null); }","typeGuard":null,"tryCatchPattern":"try {\n    metastore.addColumn(ctx, db, table, name, type, comment);\n}\ncatch (PrestoException e) {\n    if (e.getErrorCode().getName().equals(\"ALREADY_EXISTS\")) { /* treat as success */ }\n    else { throw e; }\n}","preventionTips":["Always read the current table schema before schema-altering calls.","Make DDL migration scripts idempotent (check-then-apply or catch-and-continue).","Remember Presto identifiers are case-insensitive; compare names case-insensitively."],"tags":["hive-metastore","schema","column-exists","ddl"],"backgroundTag":"column-already-exists","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}