{"record":{"id":"220374d20f4b8261","repo":"prestodb/presto","slug":"constraint-already-exists","errorCode":null,"errorMessage":"Constraint already exists","messagePattern":"Constraint already exists","errorType":"exception","errorClass":"TableConstraintAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java","lineNumber":1763,"sourceCode":"            callableName = \"addNotNullConstraint\";\n            apiStats = stats.getAddNotNullConstraint();\n            callableClient = apiStats.wrap(() ->\n                    getMetastoreClientThenCall(metastoreContext, client -> {\n                        client.addNotNullConstraint(notNullConstraint);\n                        return null;\n                    }));\n        }\n        else {\n            throw new PrestoException(NOT_SUPPORTED, \"This connector can only handle Unique/Primary Key/Not Null constraints at this time\");\n        }\n\n        try {\n            retry()\n                    .stopOnIllegalExceptions()\n                    .run(callableName, callableClient);\n        }\n        catch (AlreadyExistsException e) {\n            throw new TableConstraintAlreadyExistsException(tableConstraint.getName());\n        }\n        catch (TException e) {\n            throw new PrestoException(HIVE_METASTORE_ERROR, e);\n        }\n        catch (Exception e) {\n            throw propagate(e);\n        }\n\n        return EMPTY_RESULT;\n    }\n\n    @Override\n    public long lock(MetastoreContext metastoreContext, String databaseName, String tableName)\n    {\n        try {\n            final LockComponent lockComponent = new LockComponent(EXCLUSIVE, LockLevel.TABLE, databaseName);\n            lockComponent.setTablename(tableName);\n            final LockRequest lockRequest = new LockRequest(Lists.newArrayList(lockComponent),","sourceCodeStart":1745,"sourceCodeEnd":1781,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java#L1745-L1781","documentation":"When the metastore's addConstraint RPC raises AlreadyExistsException, ThriftHiveMetastore throws TableConstraintAlreadyExistsException ('Constraint already exists') with the constraint name. The constraint you are adding is already present on the table.","triggerScenarios":"Calling addConstraint with a constraint whose name collides with an existing constraint on the table, or re-running a migration that already added the primary key/unique/not-null constraint.","commonSituations":"Non-idempotent migration scripts run twice, default constraint names colliding across retry attempts, constraint added concurrently by another session, replaying DDL after a partial failure where the first attempt actually succeeded.","solutions":["Check existing constraints (SHOW CREATE TABLE) before adding; skip if the same constraint already exists.","Make migrations idempotent by catching TableConstraintAlreadyExistsException and treating it as success.","Use unique, descriptive constraint names to avoid collisions.","If the existing constraint differs from what you want, drop it first then re-add."],"exampleFix":"// before\nmetastore.addConstraint(context, db, table, constraint);\n\n// after: idempotent\ntry {\n    metastore.addConstraint(context, db, table, constraint);\n} catch (TableConstraintAlreadyExistsException e) {\n    // constraint already present; ignore\n}","handlingStrategy":"try-catch","validationCode":"// inspect existing constraints before adding\n// e.g. via table metadata: existingNames = tableConstraints.stream().map(TableConstraint::getName).collect(toSet());\nif (existingNames.contains(constraint.getName())) return; // already present","typeGuard":null,"tryCatchPattern":"try {\n    metastore.addConstraint(context, db, table, constraint);\n} catch (TableConstraintAlreadyExistsException e) {\n    // idempotent: already added, treat as success\n}","preventionTips":["Make constraint migrations idempotent (check-then-add or catch-already-exists).","Use unique, deterministic constraint names.","Guard against concurrent DDL from multiple sessions on the same table."],"tags":["hive","metastore","constraint","duplicate"],"backgroundTag":"constraint-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"}