{"record":{"id":"6800ec2d11da59ed","repo":"prestodb/presto","slug":"table-already-exists","errorCode":"TABLE_ALREADY_EXISTS","errorMessage":"Table '%s' already exists","messagePattern":"Table '(.+?)' already exists","errorType":"error_code","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/execution/CreateTableTask.java","lineNumber":112,"sourceCode":"    }\n\n    @Override\n    public ListenableFuture<?> execute(CreateTable statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)\n    {\n        return internalExecute(statement, metadata, accessControl, session, parameters, warningCollector, query);\n    }\n\n    @VisibleForTesting\n    public ListenableFuture<?> internalExecute(CreateTable statement, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)\n    {\n        checkArgument(!statement.getElements().isEmpty(), \"no columns for table\");\n\n        Map<NodeRef<Parameter>, Expression> parameterLookup = parameterExtractor(statement, parameters);\n        QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getName(), metadata);\n        Optional<TableHandle> tableHandle = metadata.getMetadataResolver(session).getTableHandle(tableName);\n        if (tableHandle.isPresent()) {\n            if (!statement.isNotExists()) {\n                throw new SemanticException(TABLE_ALREADY_EXISTS, statement, \"Table '%s' already exists\", tableName);\n            }\n            return immediateFuture(null);\n        }\n\n        ConnectorId connectorId = getConnectorIdOrThrow(session, metadata, tableName.getCatalogName());\n\n        LinkedHashMap<String, ColumnMetadata> columns = new LinkedHashMap<>();\n        Map<String, Object> inheritedProperties = ImmutableMap.of();\n        boolean includingProperties = false;\n        List<TableConstraint<String>> constraints = new ArrayList<>();\n        for (TableElement element : statement.getElements()) {\n            if (element instanceof ColumnDefinition) {\n                ColumnDefinition column = (ColumnDefinition) element;\n                String columnName = column.getName().getValue();\n                String name = metadata.normalizeIdentifier(session, tableName.getCatalogName(), columnName);\n                Type type;\n                try {\n                    type = metadata.getType(parseTypeSignature(column.getType()));","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/execution/CreateTableTask.java#L94-L130","documentation":"CreateTableTask.internalExecute throws SemanticException(TABLE_ALREADY_EXISTS) when a table handle is already resolvable for the target qualified name and the statement did not include IF NOT EXISTS. The check happens against the metadata resolver before any connector-side table creation, so the error is raised before side effects.","triggerScenarios":"CREATE TABLE cat.schema.tbl ... where getTableHandle returns a handle and isNotExists() is false; re-running DDL scripts; concurrent pipelines racing to create the same table.","commonSituations":"Non-idempotent ETL bootstrap SQL; jobs retried after partial failure where the first attempt created the table; name collisions after identifier normalization.","solutions":["Use CREATE TABLE IF NOT EXISTS to tolerate pre-existing tables.","Check existence first (SHOW TABLES / metadata.getTableHandle) before issuing DDL.","Drop the existing table explicitly if it is stale: DROP TABLE before re-creating.","Have retry scripts treat TABLE_ALREADY_EXISTS as a no-op success."],"exampleFix":"-- before\nCREATE TABLE hive.default.events (id BIGINT); -- fails on rerun\n\n-- after\nCREATE TABLE IF NOT EXISTS hive.default.events (id BIGINT);","handlingStrategy":"try-catch","validationCode":"QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getName(), metadata);\nif (metadata.getMetadataResolver(session).getTableHandle(tableName).isPresent() && !statement.isNotExists()) {\n    // skip creation or add IF NOT EXISTS\n    return;\n}","typeGuard":"boolean tableMissing(Session session, Metadata metadata, QualifiedObjectName tableName) {\n    return metadata.getMetadataResolver(session).getTableHandle(tableName).isEmpty();\n}","tryCatchPattern":"try {\n    createTable(session, statement, parameters);\n} catch (SemanticException e) {\n    if (e.getCode() == TABLE_ALREADY_EXISTS) {\n        // idempotent: verify schema matches, then continue\n    } else {\n        throw e;\n    }\n}","preventionTips":["Use CREATE TABLE IF NOT EXISTS for rerunnable pipelines","Check getTableHandle before issuing CREATE TABLE in scripts","Clean up partially created tables on retried jobs, or make DDL idempotent","Prefer CREATE OR REPLACE semantics where the connector supports it"],"tags":["presto","table","duplicate","ddl","idempotency"],"backgroundTag":"table-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"}