prestodb/presto · error · PrestoException
ALREADY_EXISTS
ALREADY_EXISTS
Error message
ALREADY_EXISTS: SQLException
What it means
PostgreSqlClient.createTable wraps SQLExceptions from the underlying CREATE TABLE statement. When PostgreSQL reports SQLSTATE 42P07 (duplicate_table), it is translated into a PrestoException with function code ALREADY_EXISTS so callers can distinguish 'table already exists' from other JDBC failures.
Source
Thrown at presto-postgresql/src/main/java/com/facebook/presto/plugin/postgresql/PostgreSqlClient.java:178
else if (typeHandle.getJdbcTypeName().equals("uuid")) {
return Optional.of(uuidReadMapping());
}
else if (typeName.equalsIgnoreCase(GEOMETRY) || typeName.equalsIgnoreCase(SPHERICAL_GEOGRAPHY)) {
return Optional.of(geometryReadMapping());
}
return super.toPrestoType(session, typeHandle);
}
@Override
public void createTable(ConnectorSession session, ConnectorTableMetadata tableMetadata)
{
try {
createTable(tableMetadata, session, tableMetadata.getTable().getTableName());
}
catch (SQLException e) {
if (DUPLICATE_TABLE_SQLSTATE.equals(e.getSQLState())) {
throw new PrestoException(ALREADY_EXISTS, e);
}
throw new PrestoException(JDBC_ERROR, e);
}
}
@Override
protected void renameTable(JdbcIdentity identity, String catalogName, SchemaTableName oldTable, SchemaTableName newTable)
{
// PostgreSQL does not allow qualifying the target of a rename
try (Connection connection = connectionFactory.openConnection(identity)) {
String sql = format(
"ALTER TABLE %s RENAME TO %s",
quoted(catalogName, oldTable.getSchemaName(), oldTable.getTableName()),
quoted(newTable.getTableName()));
execute(connection, sql);
}
catch (SQLException e) {
throw new PrestoException(JDBC_ERROR, e);View on GitHub (pinned to 55bb57d202)
Solutions
- Drop the existing table first if it is stale: DROP TABLE <schema>.<table> (in PostgreSQL or via the connector)
- Use CREATE TABLE IF NOT EXISTS at the caller level / check existence via SHOW TABLES before creating
- Serialize DDL so concurrent workers don't race to create the same table
- If the name collision is unintentional, choose a different target table name
Example fix
// before CREATE TABLE catalog.schema.my_table (...); // after DROP TABLE IF EXISTS catalog.schema.my_table; CREATE TABLE catalog.schema.my_table (...);
Defensive patterns
Strategy: try-catch
Validate before calling
sql SELECT 1 FROM information_schema.tables WHERE table_schema = '<schema>' AND table_name = '<table>';
Try / catch
java
try {
client.createTable(session, tableMetadata);
} catch (PrestoException e) {
if (e.getErrorCode() == ALREADY_EXISTS.toErrorCode().getCode()) {
// table already exists — treat as no-op or drop and recreate
} else {
throw e;
}
} Prevention
- Use CREATE TABLE IF NOT EXISTS or existence checks before DDL
- Serialize DDL across workers/clients to avoid races
- Clean up leftover tables from failed runs before retrying
- Use deterministic, unique table names per job/run
When it happens
Trigger: Executing CREATE TABLE against PostgreSQL when a table with the same schema-qualified name already exists in the backing database (DUPLICATE_TABLE_SQLSTATE = 42P07).
Common situations: CREATE TABLE IF NOT EXISTS semantics racing with another query/connector writing the same table, retrying a DDL statement that partially succeeded, two Presto workers executing the same metadata DDL concurrently, or a leftover table from a previous failed run.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/6b358f06bcd5d400.
Report an issue: GitHub.