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

  1. Fix the query's literal/expression to match the target column type (e.g. use explicit CAST)
  2. Check the connector/pushdown code to ensure expectedType matches the actual column type metadata
  3. 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

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.