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

In CREATE TAG ... AS OF/BEFORE <expr>, the version type was TIMESTAMP but the AS OF/BEFORE expression analyzed to a type other than Timestamp or Timestamp with Time Zone. CreateTagTask.execute analyzes the state expression and enforces type compatibility with the declared table version type, raising TYPE_MISMATCH otherwise.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/CreateTagTask.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: CREATE TAG t AS OF TIMESTAMP '2024-01-01 00:00:00'.
  2. Add a time zone for timestamp-with-time-zone support: AS OF TIMESTAMP '2024-01-01 00:00:00 UTC'.
  3. Alternatively declare/use a VERSION (bigint or varchar) table version if the expression is an ID, and use the matching AS OF form.

Example fix

// before
CREATE TAG t AS OF '2024-01-01 00:00:00' TAG 'v1';
// after
CREATE TAG t AS OF TIMESTAMP '2024-01-01 00:00:00' TAG 'v1';
Defensive patterns

Strategy: validation

Validate before calling

Type t = analyzer.getExpressionTypes().get(NodeRef.of(stateExpr));
if (tableVersionType == TIMESTAMP &&
    !(t instanceof TimestampWithTimeZoneType || t instanceof TimestampType)) {
    throw new IllegalArgumentException("AS OF/BEFORE expression must be TIMESTAMP, got " + t.getDisplayName());
}

Type guard

boolean isTimestampLike(Type t) {
    return t instanceof TimestampType || t instanceof TimestampWithTimeZoneType;
}

Try / catch

try {
    future = createTagTask.execute(statement, ...);
} catch (SemanticException e) {
    if (e.getCode() == TYPE_MISMATCH && e.getMessage().contains("table version")) {
        // rewrite with an explicit TIMESTAMP cast and retry
    }
}

Prevention

When it happens

Trigger: tableVersionType == TIMESTAMP and stateExprType is e.g. VARCHAR, DATE, BIGINT, or TIMESTAMP(3) WITH TIME ZONE variants not matching TimestampType/TimestampWithTimeZoneType — e.g. CREATE TAG t AS OF '2024-01-01' (string literal) or AS OF DATE '2024-01-01'.

Common situations: Passing a quoted date string instead of a proper TIMESTAMP literal; using DATE or unix epoch numbers for a timestamp-versioned tag; dialect differences where string-to-timestamp implicit casts are allowed elsewhere.

Related errors


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