prestodb/presto · error · SemanticException
TYPE_MISMATCH
TYPE_MISMATCH
Error message
Cannot cast type %s to %s
What it means
When evaluating a constant expression (e.g. for partition pruning or dynamic filtering), Presto analyzes the expression and checks that its actual type can coerce to the expected type. If FunctionAndTypeManager.canCoerce fails, it throws TYPE_MISMATCH 'Cannot cast type X to Y'. This guards constant-expression evaluation against type inconsistencies between planner expectations and expression analysis.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/ExpressionInterpreter.java:202
}
public static ExpressionInterpreter expressionOptimizer(Expression expression, Metadata metadata, Session session, Map<NodeRef<Expression>, Type> expressionTypes)
{
requireNonNull(expression, "expression is null");
requireNonNull(metadata, "metadata is null");
requireNonNull(session, "session is null");
return new ExpressionInterpreter(expression, metadata, session, expressionTypes, true);
}
public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, Map<NodeRef<Parameter>, Expression> parameters)
{
ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata.getFunctionAndTypeManager().getFunctionAndTypeResolver(), session, parameters, WarningCollector.NOOP);
analyzer.analyze(expression, Scope.create());
Type actualType = analyzer.getExpressionTypes().get(NodeRef.of(expression));
if (!metadata.getFunctionAndTypeManager().canCoerce(actualType, expectedType)) {
throw new SemanticException(SemanticErrorCode.TYPE_MISMATCH, expression, format("Cannot cast type %s to %s",
actualType.getTypeSignature(),
expectedType.getTypeSignature()));
}
Map<NodeRef<Expression>, Type> coercions = ImmutableMap.<NodeRef<Expression>, Type>builder()
.putAll(analyzer.getExpressionCoercions())
.put(NodeRef.of(expression), expectedType)
.build();
return evaluateConstantExpression(expression, coercions, analyzer.getTypeOnlyCoercions(), metadata, session, ImmutableSet.of(), parameters);
}
private static Object evaluateConstantExpression(
Expression expression,
Map<NodeRef<Expression>, Type> coercions,
Set<NodeRef<Expression>> typeOnlyCoercions,
Metadata metadata,
Session session,
Set<NodeRef<Expression>> columnReferences,View on GitHub (pinned to 55bb57d202)
Solutions
- Fix the query's literal/expression to match the target column type (e.g. use explicit CAST)
- Check the connector/pushdown code to ensure expectedType matches the actual column type metadata
- Upgrade Presto if a previously working predicate now fails due to coercion rule changes
Example fix
// before (connector pushdown)
TupleDomain<ColumnHandle> domain = ...; // expectedType = BIGINT for a VARCHAR column
// after
Type expectedType = columnHandle.getType(); // derive from actual column metadata
if (!metadata.canCoerce(actualType, expectedType)) { skip pushdown; } Defensive patterns
Strategy: validation
Validate before calling
// Check coercibility before constant-expression pushdown
Type actual = analyzer.getExpressionTypes().get(NodeRef.of(expression));
if (!metadata.getFunctionAndTypeManager().canCoerce(actual, expectedType)) {
// skip pushdown or CAST the expression first
} Type guard
boolean canPushConstant(Metadata metadata, Type actualType, Type expectedType) {
return metadata.getFunctionAndTypeManager().canCoerce(actualType, expectedType);
} Try / catch
try { result = expressionInterpreter.evaluateConstantExpression(expr, expectedType, ...); } catch (SemanticException e) { if (e.getCode().equals(TYPE_MISMATCH) && e.getMessage().startsWith("Cannot cast type")) { skipPushdown(); } else throw e; } Prevention
- Ensure expectedType always comes from real column metadata, not hardcoded types
- Use explicit CAST in queries when literal types may differ from column types
- When building connectors, derive pushdown types from the declared column handles
- Retest predicate pushdown after Presto upgrades, as coercion rules can change
When it happens
Trigger: Pushdown of predicates/partition filters where the literal's analyzed type cannot be coerced to the column type (e.g. passing a varchar where an interval is expected, or incompatible struct shapes).
Common situations: Connector pushdown code supplying a wrong expectedType; queries with literals typed incompatibly against partition columns; custom connector filter translation bugs; changes to type coercion rules after an upgrade.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/663d9507e96bb9f7.
Report an issue: GitHub.