prestodb/presto · error · UnsupportedOperationException

Unsupported Type:

Error message

Unsupported Type: 

What it means

AstBuilder.visitTableVersionState (table version / temporal query handling) throws this UnsupportedOperationException when the tableVersionType token is not TIMESTAMP, SYSTEM_VERSION, or VERSION. It means the version specifier in a FOR ... clause is a type the builder does not map.

Source

Thrown at presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java:2033

                new SubqueryExpression(getLocation(context.query()), (Query) visit(context.query())));
    }

    // ************** value expressions **************

    @Override
    public Node visitTableVersion(SqlBaseParser.TableVersionContext context)
    {
        Expression child = (Expression) visit(context.valueExpression());

        switch (context.tableVersionType.getType()) {
            case SqlBaseLexer.SYSTEM_TIME:
            case SqlBaseLexer.TIMESTAMP:
                return timestampExpression(getLocation(context), getTableVersionOperator((Token) context.tableVersionState().getChild(0).getPayload()), child);
            case SqlBaseLexer.SYSTEM_VERSION:
            case SqlBaseLexer.VERSION:
                return versionExpression(getLocation(context), getTableVersionOperator((Token) context.tableVersionState().getChild(0).getPayload()), child);
            default:
                throw new UnsupportedOperationException("Unsupported Type: " + context.tableVersionType.getText());
        }
    }

    @Override
    public Node visitArithmeticUnary(SqlBaseParser.ArithmeticUnaryContext context)
    {
        Expression child = (Expression) visit(context.valueExpression());

        switch (context.operator.getType()) {
            case SqlBaseLexer.MINUS:
                return ArithmeticUnaryExpression.negative(getLocation(context), child);
            case SqlBaseLexer.PLUS:
                return ArithmeticUnaryExpression.positive(getLocation(context), child);
            default:
                throw new UnsupportedOperationException("Unsupported sign: " + context.operator.getText());
        }
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Use FOR TIMESTAMP <expr>, FOR SYSTEM_VERSION AS OF ..., or FOR VERSION AS OF ... syntax.
  2. Check the exact text of the version keyword for typos.
  3. If the grammar defines extra version types, extend this switch to map them to versionExpression/timestampExpression.
  4. Regenerate the parser so grammar and AstBuilder agree.

Example fix

// before
SELECT * FROM t FOR SNAPSHOT AS OF '2024-01-01';
// after
SELECT * FROM t FOR VERSION AS OF '2024-01-01';
Defensive patterns

Strategy: validation

Validate before calling

// temporal clause must be TIMESTAMP, SYSTEM_VERSION or VERSION
if (!Pattern.compile("(?i)FOR\\s+(TIMESTAMP|SYSTEM_VERSION|VERSION)\\b").matcher(sql).find()
        && Pattern.compile("(?i)\\bFOR\\s+\\w+\\s+(AS\\s+OF|\\S+)").matcher(sql).find()) {
    throw new IllegalArgumentException("Unsupported table version type");
}

Type guard

boolean isSupportedVersionType(String token) {
    return token != null && Set.of("TIMESTAMP", "SYSTEM_VERSION", "VERSION")
        .contains(token.toUpperCase(Locale.ROOT));
}

Try / catch

try {
    parser.createStatement(sql);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().startsWith("Unsupported Type:")) {
        throw new IllegalArgumentException("Use FOR TIMESTAMP/FOR VERSION/FOR SYSTEM_VERSION clauses: " + e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Parsing temporal syntax like 'SELECT ... FROM t FOR <type> <value>' where <type> is not TIMESTAMP, SYSTEM_VERSION or VERSION, e.g. fork-added version tokens not wired into the switch.

Common situations: Forked/patched grammars adding new temporal clause forms, or dialect-specific version keywords (e.g. 'AS OF') pasted into Presto SQL.

Related errors


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