prestodb/presto · error · SemanticException

SCHEMA_ALREADY_EXISTS

SCHEMA_ALREADY_EXISTS

Error message

Schema '%s' already exists

What it means

CreateSchemaTask.execute throws SemanticException(SCHEMA_ALREADY_EXISTS) when metadata resolver's schemaExists reports the target schema present and the statement lacks IF NOT EXISTS (statement.isNotExists() is false). Presto treats schema creation as fail-fast on duplicates unless the caller opted into tolerant behavior.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/CreateSchemaTask.java:66

    @Override
    public String explain(CreateSchema statement, List<Expression> parameters)
    {
        return "CREATE SCHEMA " + statement.getSchemaName();
    }

    @Override
    public ListenableFuture<?> execute(CreateSchema statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)
    {
        CatalogSchemaName schema = createCatalogSchemaName(session, statement, Optional.of(statement.getSchemaName()), metadata);

        // Make sure catalog exists before access control checks
        ConnectorId connectorId = getConnectorIdOrThrow(session, metadata, schema.getCatalogName());

        accessControl.checkCanCreateSchema(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), schema);

        if (metadata.getMetadataResolver(session).schemaExists(schema)) {
            if (!statement.isNotExists()) {
                throw new SemanticException(SCHEMA_ALREADY_EXISTS, statement, "Schema '%s' already exists", schema);
            }
            return immediateFuture(null);
        }

        Map<String, Object> properties = metadata.getSchemaPropertyManager().getProperties(
                connectorId,
                schema.getCatalogName(),
                mapFromProperties(statement.getProperties()),
                session,
                metadata,
                parameterExtractor(statement, parameters));

        metadata.createSchema(session, schema, properties);

        return immediateFuture(null);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Add IF NOT EXISTS: CREATE SCHEMA IF NOT EXISTS cat.schema_name;
  2. Check existence before creating (schemaExists / SHOW SCHEMAS FROM cat).
  3. Make migration/bootstrap scripts tolerate SCHEMA_ALREADY_EXISTS as success.
  4. Use a unique schema name if a genuinely different schema is intended.

Example fix

-- before
CREATE SCHEMA hive.analytics; -- fails on rerun

-- after
CREATE SCHEMA IF NOT EXISTS hive.analytics;
Defensive patterns

Strategy: try-catch

Validate before calling

if (metadata.getMetadataResolver(session).schemaExists(schema) && !statement.isNotExists()) {
    // skip creation or add IF NOT EXISTS to the statement
    return;
}

Type guard

boolean schemaMissing(Session session, Metadata metadata, QualifiedObjectName schema) {
    return !metadata.getMetadataResolver(session).schemaExists(schema);
}

Try / catch

try {
    createSchema(session, statement, parameters);
} catch (SemanticException e) {
    if (e.getCode() == SCHEMA_ALREADY_EXISTS) {
        // idempotent bootstrap: treat as success
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: CREATE SCHEMA cat.schema_name where the schema already exists and neither 'IF NOT EXISTS' was specified; also hit by idempotent bootstrap scripts re-running the same DDL.

Common situations: Repeated deployment of bootstrap SQL; concurrent jobs both creating the same schema; case-normalization surprises where an identically-named schema exists after identifier normalization.

Related errors


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