Skip to content

feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421)#27421

Merged
kevintang2022 merged 1 commit into
prestodb:masterfrom
apurva-meta:export-D97600298
Apr 6, 2026
Merged

feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421)#27421
kevintang2022 merged 1 commit into
prestodb:masterfrom
apurva-meta:export-D97600298

Conversation

@apurva-meta

@apurva-meta apurva-meta commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (FOR TIMESTAMP AS OF, FOR SYSTEM_TIME AS OF) via the ConnectorTableVersion SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the timestamp table name encoding.

This change:

  1. Adds the 3-argument getTableHandle(session, tableName, tableVersion) override to PrismMetadata that converts the SQL time travel clause into the existing timestamp encoding
  2. Extends StatementAnalyzer to accept BIGINT and VARCHAR expression types in FOR TIMESTAMP AS OF clauses (previously only TimestampType and TimestampWithTimeZoneType were allowed)

This enables users to write clean time travel queries with multiple syntax options:

-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'

instead of the current session-property approach:

SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;

Benefits

  • Per-table granularity: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
  • Self-documenting: Timestamp is in the SQL, not hidden in session state
  • SQL-standard: Compatible with Athena, Spark 3.3+, SQL-2011
  • Multiple input formats: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
  • No session state management: Just write the query
  • Backward compatible: Existing session properties continue to work unchanged

Supported SQL syntax

  • FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles' (TimestampWithTimeZoneType)
  • FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822' (TimestampType)
  • FOR TIMESTAMP AS OF CURRENT_TIMESTAMP (CurrentTime)
  • FOR TIMESTAMP AS OF BIGINT '1624893589000' (BIGINT epoch millis — NEW)
  • FOR TIMESTAMP AS OF '1624893589000' (VARCHAR epoch millis string — NEW)

Implementation

StatementAnalyzer (presto-trunk)

  • Modified type check in FOR TIMESTAMP AS OF validation to also accept BigintType and VarcharType (in addition to TimestampType and TimestampWithTimeZoneType)
  • Updated error message to list all supported types

PrismMetadata (presto-facebook-trunk)

  • PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>) — new 3-arg override
  • PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs) — reuses existing timestamp encoding
  • PrismMetadata.extractTimestampMillis(version) — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
  • VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: IcebergAbstractMetadata.getSnapshotIdForTableVersion()

== NO RELEASE NOTE ==

Reviewed By: ghelmling

Differential Revision: D97600298

@apurva-meta apurva-meta requested review from a team, feilong-liu and jaystarshot as code owners March 24, 2026 08:32
@sourcery-ai

sourcery-ai Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Extends Prism’s table version/time-travel support by wiring the SQL-standard FOR TIMESTAMP AS OF clause through the connector metadata (encoding it into existing timestamp-based table names) and broadens analyzer validation to accept additional literal types for timestamp-based table versioning (BIGINT and VARCHAR).

Sequence diagram for FOR TIMESTAMP AS OF resolution in Prism connector

sequenceDiagram
    actor User
    participant PrestoParser
    participant StatementAnalyzer
    participant PrismMetadata
    participant PrismMetastoreClient as Metastore

    User->>PrestoParser: SQL with FOR TIMESTAMP AS OF
    PrestoParser-->>StatementAnalyzer: Parsed query AST with TableVersion

    StatementAnalyzer->>StatementAnalyzer: evaluateConstantExpression(stateExpression, stateExpressionType, metadata, session, parameters)
    StatementAnalyzer->>StatementAnalyzer: validate type is TimestampType
    StatementAnalyzer->>StatementAnalyzer: or TimestampWithTimeZoneType
    StatementAnalyzer->>StatementAnalyzer: or BigintType or VarcharType
    StatementAnalyzer-->>PrismMetadata: getTableHandle(session, schemaTableName, tableVersion)

    PrismMetadata->>PrismMetadata: extractTimestampMillis(tableVersion)
    PrismMetadata->>PrismMetadata: encodeTableNameWithVersion(schemaTableName, timestampMillis)
    PrismMetadata->>Metastore: getTable(encodedSchemaTableName)
    Metastore-->>PrismMetadata: PrismTable
    PrismMetadata-->>StatementAnalyzer: TableHandle for snapshot
    StatementAnalyzer-->>User: Query analyzed with time-travel table handle
Loading

Class diagram for updated PrismMetadata time travel support

classDiagram
    class ConnectorMetadata {
        <<interface>>
        +getTableHandle(session, schemaTableName) TableHandle
        +getTableHandle(session, schemaTableName, tableVersion) TableHandle
    }

    class ConnectorTableVersion {
        +versionType
        +expression
    }

    class PrismMetadata {
        +getTableHandle(session, schemaTableName) TableHandle
        +getTableHandle(session, schemaTableName, tableVersion) TableHandle
        -encodeTableNameWithVersion(schemaTableName, timestampMillis) SchemaTableName
        -extractTimestampMillis(tableVersion) long
    }

    class PrismMetastoreClient {
        +getTable(schemaTableName) PrismTable
    }

    class SchemaTableName {
        +schemaName
        +tableName
    }

    class TableHandle

    class PrismTable {
        +schemaTableName
        +snapshotTimestampMillis
    }

    ConnectorMetadata <|.. PrismMetadata
    PrismMetadata --> ConnectorTableVersion : uses
    PrismMetadata --> PrismMetastoreClient : uses
    PrismMetadata --> SchemaTableName : encodes
    PrismMetastoreClient --> PrismTable : returns
    PrismMetadata --> TableHandle : creates
Loading

Class diagram for StatementAnalyzer table version validation

classDiagram
    class StatementAnalyzer {
        -analysis
        -metadata
        -session
        -evaluateConstantExpression(expression, type, metadata, session, parameters) Object
        -processTableVersion(table, qualifiedObjectName, tableVersionType, stateExpression, stateExpressionType) Optional~TableHandle~
    }

    class Table
    class QualifiedObjectName
    class TableHandle

    class TableVersionType {
        <<enum>>
        TIMESTAMP
        SYSTEM_TIME
        VERSION
    }

    class Type
    class TimestampType
    class TimestampWithTimeZoneType
    class BigintType
    class VarcharType

    StatementAnalyzer --> Table : processes
    StatementAnalyzer --> QualifiedObjectName : resolves
    StatementAnalyzer --> TableHandle : returns
    StatementAnalyzer --> TableVersionType : checks
    StatementAnalyzer --> Type : uses
    Type <|-- TimestampType
    Type <|-- TimestampWithTimeZoneType
    Type <|-- BigintType
    Type <|-- VarcharType
Loading

File-Level Changes

Change Details Files
Wire SQL-standard time travel syntax into Prism connector metadata by mapping FOR TIMESTAMP AS OF to the existing timestamp-encoded table naming scheme.
  • Add the 3-argument getTableHandle(session, tableName, Optional<ConnectorTableVersion>) override in Prism metadata to receive table version information from the analyzer.
  • Translate TIMESTAMP / TIMESTAMP WITH TIME ZONE table version expressions into epoch-millis using a helper, then encode them into the timestamp-based table name format already understood by Metastore.
  • Preserve existing session-property-based snapshot selection behavior so that both explicit SQL time travel and the legacy session mechanism work without change.
  • Explicitly reject unsupported table versioning modes such as VERSION-based time travel and BEFORE with clear error messages until Metastore supports them.
presto-main-base/src/main/java/com/facebook/presto/plugin/prism/PrismMetadata.java
Relax analyzer validation so timestamp-based table versioning accepts BIGINT and VARCHAR literals in addition to timestamp types.
  • Update type-checking for FOR TIMESTAMP AS OF / FOR SYSTEM_TIME AS OF / BEFORE so that BIGINT (epoch millis) and VARCHAR (parsable timestamp string) expressions are allowed for TIMESTAMP table versions.
  • Adjust the semantic error message to document the expanded set of supported types: Timestamp, Timestamp with Time Zone, BIGINT, and VARCHAR.
  • Keep restriction scoped to TIMESTAMP-style table versioning, leaving other versioning types unchanged.
presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Now that BIGINT and VARCHAR are accepted for TIMESTAMP-based AS OF/BEFORE clauses, consider normalizing those constant values to a single internal representation (e.g., Timestamp/TimestampWithTimeZone) immediately after evaluateConstantExpression so downstream code does not have to handle additional Java types.
  • If VARCHAR is meant to support only specific timestamp formats or time zones, it may be safer to enforce that format here and fail fast with a targeted error message rather than relying on downstream parsing behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Now that BIGINT and VARCHAR are accepted for TIMESTAMP-based AS OF/BEFORE clauses, consider normalizing those constant values to a single internal representation (e.g., Timestamp/TimestampWithTimeZone) immediately after `evaluateConstantExpression` so downstream code does not have to handle additional Java types.
- If VARCHAR is meant to support only specific timestamp formats or time zones, it may be safer to enforce that format here and fail fast with a targeted error message rather than relying on downstream parsing behavior.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@apurva-meta apurva-meta changed the title [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector Feat: [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector Mar 24, 2026
@steveburnett

Copy link
Copy Markdown
Contributor
  • Please add a release note - or NO RELEASE NOTE - following the Release Notes Guidelines to pass the failing but not required CI check.

  • Please edit the PR title to follow semantic commit style to pass the failing and required CI check. I think the problem is as simple as "feat" should not be capitalized at the beginning. See the failure in the test for advice. If you can't edit the PR title, let us know and we can help.

@meta-codesync meta-codesync Bot changed the title Feat: [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector (#27421) Mar 24, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 24, 2026
… in Prism connector (prestodb#27421)

Summary:

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

Differential Revision: D97600298
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 24, 2026
… in Prism connector (prestodb#27421)

Summary:
Pull Request resolved: prestodb#27421

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

Differential Revision: D97600298
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 24, 2026
… in Prism connector (prestodb#27421)

Summary:

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector (#27421) feat: [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism and Iceberg connector (#27421) Mar 24, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 24, 2026
…AS OF) in Prism and Iceberg connector (prestodb#27421)

Summary:

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism and iceberg connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title feat: [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism and Iceberg connector (#27421) [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector (#27421) Mar 24, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 24, 2026
… in Prism connector (prestodb#27421)

Summary:

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector (#27421) feat: [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector (#27421) Mar 25, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 25, 2026
…AS OF) in Prism connector (prestodb#27421)

Summary:

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

== RELEASE NOTES ==

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

Differential Revision: D97600298
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 25, 2026
…AS OF) in Prism connector (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608


The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title feat: [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector (#27421) Feat: [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) in Prism connector (#27421) Mar 25, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 25, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608

Pull Request resolved: prestodb#27421

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) Mar 25, 2026
@meta-codesync meta-codesync Bot changed the title feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) Mar 26, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 26, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608


The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 26, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608

Pull Request resolved: prestodb#27421

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) Mar 26, 2026
@meta-codesync meta-codesync Bot changed the title feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) Mar 26, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 26, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 26, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) Mar 26, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 26, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608

Pull Request resolved: prestodb#27421

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
@meta-codesync meta-codesync Bot changed the title feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) feat: Prism <> Iceberg [prism] Support SQL-standard time travel syntax (FOR TIMESTAMP AS OF) (#27421) Mar 26, 2026
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 26, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608


The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
apurva-meta added a commit to apurva-meta/presto that referenced this pull request Mar 26, 2026
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608

Pull Request resolved: prestodb#27421

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Differential Revision: D97600298
…x (FOR TIMESTAMP AS OF) (prestodb#27421)

Summary:
X-link: https://github.com/facebookexternal/presto-facebook/pull/3608

Pull Request resolved: prestodb#27421

The Presto parser and analyzer already support the SQL-2011 temporal query syntax (`FOR TIMESTAMP AS OF`, `FOR SYSTEM_TIME AS OF`) via the `ConnectorTableVersion` SPI. The Iceberg connector implements it. The Prism connector does not, despite Metastore already supporting snapshot versioning through the `timestamp` table name encoding.

This change:
1. Adds the 3-argument `getTableHandle(session, tableName, tableVersion)` override to `PrismMetadata` that converts the SQL time travel clause into the existing `timestamp` encoding
2. Extends `StatementAnalyzer` to accept `BIGINT` and `VARCHAR` expression types in `FOR TIMESTAMP AS OF` clauses (previously only `TimestampType` and `TimestampWithTimeZoneType` were allowed)

This enables users to write clean time travel queries with multiple syntax options:

```sql
-- Timestamp syntax (existing)
SELECT * FROM dim_users FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 10:00:00'

-- BIGINT epoch millis (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF BIGINT '1705312800000'

-- VARCHAR epoch millis string (new)
SELECT * FROM dim_users FOR TIMESTAMP AS OF '1705312800000'
```

instead of the current session-property approach:

```sql
SET SESSION prism.source_table_snapshots_enabled = true;
SET SESSION prism.source_table_snapshots_timestamp_ms = 1705312800000;
SELECT * FROM dim_users;
```

## Benefits
- **Per-table granularity**: Different tables in the same query can time-travel to different timestamps (impossible with session properties)
- **Self-documenting**: Timestamp is in the SQL, not hidden in session state
- **SQL-standard**: Compatible with Athena, Spark 3.3+, SQL-2011
- **Multiple input formats**: Accepts TIMESTAMP, TIMESTAMP WITH TIME ZONE, BIGINT epoch millis, or VARCHAR epoch millis strings
- **No session state management**: Just write the query
- **Backward compatible**: Existing session properties continue to work unchanged

## Supported SQL syntax
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822 America/Los_Angeles'` (TimestampWithTimeZoneType)
- `FOR TIMESTAMP AS OF TIMESTAMP '2023-08-17 13:29:46.822'` (TimestampType)
- `FOR TIMESTAMP AS OF CURRENT_TIMESTAMP` (CurrentTime)
- `FOR TIMESTAMP AS OF BIGINT '1624893589000'` (BIGINT epoch millis — NEW)
- `FOR TIMESTAMP AS OF '1624893589000'` (VARCHAR epoch millis string — NEW)

## Implementation

### StatementAnalyzer (presto-trunk)
- Modified type check in `FOR TIMESTAMP AS OF` validation to also accept `BigintType` and `VarcharType` (in addition to `TimestampType` and `TimestampWithTimeZoneType`)
- Updated error message to list all supported types

### PrismMetadata (presto-facebook-trunk)
- `PrismMetadata.getTableHandle(session, tableName, Optional<ConnectorTableVersion>)` — new 3-arg override
- `PrismMetadata.encodeTableNameWithVersion(tableName, timestampMs)` — reuses existing `timestamp` encoding
- `PrismMetadata.extractTimestampMillis(version)` — handles TimestampType, TimestampWithTimeZoneType, BigintType, and VarcharType
- VERSION-based time travel and BEFORE operator are rejected with clear error messages

Reference implementation: `IcebergAbstractMetadata.getSnapshotIdForTableVersion()`

== NO RELEASE NOTE ==

Reviewed By: ghelmling

Differential Revision: D97600298
@apurva-meta

apurva-meta commented Apr 1, 2026

Copy link
Copy Markdown
Contributor Author

@feilong-liu Can you merge this PR too, this has been internally merged at fb: https://github.com/facebookexternal/presto-facebook/commit/d4a19690896202720039a01cf8a88ab4f656f6c6

@kevintang2022

Copy link
Copy Markdown
Contributor

@apurva-meta Is there a reason we don't merge this PR?

@kevintang2022

Copy link
Copy Markdown
Contributor

Maybe you don't have the permissions?

@apurva-meta

apurva-meta commented Apr 6, 2026 via email

Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants