prestodb/presto · error · PrestoException
SYNTAX_ERROR
SYNTAX_ERROR
Error message
Constraint name '%s' specified more than once
What it means
Two or more named constraints in the same CREATE TABLE share the same constraint name. After converting ConstraintSpecifications, the task groups named constraints and throws SYNTAX_ERROR if any name has count > 1.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/CreateTableTask.java:208
});
}
else if (element instanceof ConstraintSpecification) {
accessControl.checkCanAddConstraints(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), tableName);
constraints.add(convertToTableConstraint(metadata, session, connectorId, (ConstraintSpecification) element, warningCollector, query));
}
else {
throw new PrestoException(GENERIC_INTERNAL_ERROR, "Invalid TableElement: " + element.getClass().getName());
}
}
accessControl.checkCanCreateTable(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), tableName);
constraints.stream()
.filter(c -> c.getName().isPresent())
.collect(Collectors.groupingBy(c -> c.getName().get(), Collectors.counting()))
.forEach((constraintName, count) -> {
if (count > 1) {
throw new PrestoException(SYNTAX_ERROR, format("Constraint name '%s' specified more than once", constraintName));
}
});
if (constraints.stream()
.filter(PrimaryKeyConstraint.class::isInstance)
.collect(Collectors.groupingBy(c -> c.getName().orElse(""), Collectors.counting()))
.size() > 1) {
throw new PrestoException(SYNTAX_ERROR, "Multiple primary key constraints are not allowed");
}
Map<String, Expression> sqlProperties = mapFromProperties(statement.getProperties());
Map<String, Object> properties = metadata.getTablePropertyManager().getProperties(
connectorId,
tableName.getCatalogName(),
sqlProperties,
session,
metadata,
parameterLookup);View on GitHub (pinned to 55bb57d202)
Solutions
- Rename one of the duplicate constraints so all constraint names are unique.
- Remove the redundant constraint if both are unintentionally identical.
- Let the engine generate names by omitting the CONSTRAINT <name> clause where supported.
Example fix
// before CREATE TABLE t (a BIGINT, b BIGINT, CONSTRAINT c1 PRIMARY KEY (a), CONSTRAINT c1 UNIQUE (b)); // after CREATE TABLE t (a BIGINT, b BIGINT, CONSTRAINT c1 PRIMARY KEY (a), CONSTRAINT c2 UNIQUE (b));
Defensive patterns
Strategy: validation
Validate before calling
Map<String, Long> counts = constraints.stream()
.filter(c -> c.getName().isPresent())
.collect(Collectors.groupingBy(c -> c.getName().get(), Collectors.counting()));
if (counts.values().stream().anyMatch(n -> n > 1)) {
throw new IllegalArgumentException("duplicate constraint name");
} Type guard
null
Try / catch
try {
future = createTableTask.execute(statement, ...);
} catch (PrestoException e) {
if (e.getErrorCode() == SYNTAX_ERROR.toErrorCode() && e.getMessage().contains("Constraint name")) {
// regenerate DDL with unique constraint names
}
} Prevention
- Use unique, convention-based constraint names (table-prefixed) in DDL generators.
- Lint generated DDL for duplicate CONSTRAINT identifiers.
- Omit explicit constraint names when names are not needed downstream.
When it happens
Trigger: CREATE TABLE t (... , CONSTRAINT pk1 PRIMARY KEY (a), CONSTRAINT pk1 UNIQUE (b)); — any two constraints with identical names (primary key, unique, foreign key).
Common situations: Copy-pasting constraint blocks without renaming; templated DDL generators emitting the same placeholder constraint name; merging table definitions from multiple sources.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/ec54f4240c8f9402.
Report an issue: GitHub.