prestodb/presto · error · SemanticException

TYPE_MISMATCH

TYPE_MISMATCH

Error message

Type %s is invalid. Supported table version AS OF/BEFORE expression type is Timestamp or Timestamp with Time Zone.

What it means

The AS OF/BEFORE version expression in CREATE BRANCH was declared as a TIMESTAMP version, but its analyzed expression type is neither TimestampType nor TimestampWithTimeZoneType. The analyzer computes the constant expression's type and throws SemanticException TYPE_MISMATCH when it doesn't match the required timestamp family.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/CreateBranchTask.java:108

        if (statement.getTableVersion().isPresent()) {
            TableVersionExpression tableVersionExpr = statement.getTableVersion().get();
            Expression stateExpr = tableVersionExpr.getStateExpression();
            TableVersionExpression.TableVersionType tableVersionType = tableVersionExpr.getTableVersionType();
            TableVersionExpression.TableVersionOperator tableVersionOperator = tableVersionExpr.getTableVersionOperator();

            Map<NodeRef<Parameter>, Expression> parameterLookup = parameterExtractor(statement, parameters);

            ExpressionAnalyzer analyzer = ExpressionAnalyzer.createConstantAnalyzer(
                    metadata.getFunctionAndTypeManager().getFunctionAndTypeResolver(),
                    session,
                    parameterLookup,
                    WarningCollector.NOOP);
            analyzer.analyze(stateExpr, Scope.create());
            Type stateExprType = analyzer.getExpressionTypes().get(NodeRef.of(stateExpr));

            if (tableVersionType == TIMESTAMP) {
                if (!(stateExprType instanceof TimestampWithTimeZoneType || stateExprType instanceof TimestampType)) {
                    throw new SemanticException(TYPE_MISMATCH, stateExpr,
                            "Type %s is invalid. Supported table version AS OF/BEFORE expression type is Timestamp or Timestamp with Time Zone.",
                            stateExprType.getDisplayName());
                }
            }
            else if (tableVersionType == VERSION) {
                if (!(stateExprType instanceof BigintType || stateExprType instanceof VarcharType)) {
                    throw new SemanticException(TYPE_MISMATCH, stateExpr, "Type %s is invalid. Supported table version AS OF/BEFORE expression type is BIGINT or VARCHAR", stateExprType.getDisplayName());
                }
            }

            Object evalStateExpr = evaluateConstantExpression(stateExpr, stateExprType, metadata, session, parameterLookup);
            VersionType versionType = tableVersionType == TIMESTAMP ? VersionType.TIMESTAMP : VersionType.VERSION;
            VersionOperator versionOperator = tableVersionOperator == TableVersionExpression.TableVersionOperator.EQUAL
                    ? VersionOperator.EQUAL : VersionOperator.LESS_THAN;

            tableVersion = Optional.of(new ConnectorTableVersion(versionType, versionOperator, stateExprType, evalStateExpr));
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. CAST the expression to TIMESTAMP or TIMESTAMP WITH TIME ZONE, e.g. FOR TIMESTAMP AS OF TIMESTAMP '2024-01-01 00:00:00'
  2. Replace DATE expressions with current_timestamp or CAST(current_date AS TIMESTAMP)
  3. Verify the analyzed type of the expression matches the declared version type (TIMESTAMP vs VERSION)
  4. If a bigint/varchar snapshot id was intended, use FOR VERSION AS OF instead of FOR TIMESTAMP AS OF

Example fix

// before
CREATE BRANCH b FROM t FOR TIMESTAMP AS OF '2024-01-01 00:00:00';
// after
CREATE BRANCH b FROM t FOR TIMESTAMP AS OF CAST('2024-01-01 00:00:00' AS TIMESTAMP);
Defensive patterns

Strategy: validation

Validate before calling

// ensure the timestamp expr is a proper TIMESTAMP literal
String tsExpr = "CAST('" + iso + "' AS TIMESTAMP)"; // not a raw string

Prevention

When it happens

Trigger: CREATE BRANCH ... FOR TIMESTAMP AS OF <expr> where <expr> evaluates to VARCHAR, BIGINT, DATE, or another non-timestamp type; forgetting a CAST on a string or date literal used as the timestamp.

Common situations: Passing a plain string '2024-01-01 00:00:00' without CAST(... AS TIMESTAMP); using current_date (DATE) instead of current_timestamp; refactored queries where a parameter's type changed.

Related errors


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