Skip to content

Conversation

@tdcmeehan
Copy link
Contributor

@tdcmeehan tdcmeehan commented Dec 10, 2025

Description

Add configurable freshness thresholds for materialized views. Users can specify a staleness window and behavior (FAIL or USE_VIEW_QUERY) when the view is stale beyond the threshold.

For Iceberg, materialized view properties are added which allow toggling both the stale threshold and the behavior:

    CREATE MATERIALIZED VIEW hourly_sales
    WITH (
        stale_read_behavior = 'FAIL',
        staleness_window = '1h'
    )
    AS SELECT date_trunc('hour', sale_time) as hour, SUM(amount) as total
    FROM sales GROUP BY 1;

Motivation and Context

Materialized views can become stale when base tables change. This feature allows users to configure how Presto handles stale reads - either fail with an error or fall back to querying base tables directly.

Impact

Support added for configurable freshness thresholds

Test Plan

  • TestMaterializedViewRewrite - new tests for staleness tolerance, FAIL/USE_VIEW_QUERY behaviors
  • TestFeaturesConfig - tests for new config property

Contributor checklist

  • Please make sure your submission complies with our contributing guide, in particular code style and commit standards.
  • PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced.
  • Documented new properties (with its default value), SQL syntax, functions, or other functionality.
  • If release notes are required, they follow the release notes guidelines.
  • Adequate tests were added if applicable.
  • CI passed.
  • If adding new dependencies, verified they have an OpenSSF Scorecard score of 5.0 or higher (or obtained explicit TSC approval for lower scores).

Release Notes

Please follow release notes guidelines and fill in the release notes below.

== RELEASE NOTES ==


  General Changes
  * Add configurable freshness thresholds for materialized views via ``materialized_view_stale_read_behavior`` session property and ``materialized-view-stale-read-behavior`` config property.

  Iceberg Connector Changes
  * Add ``stale_read_behavior`` and ``staleness_window`` table properties for materialized views.

@prestodb-ci prestodb-ci added the from:IBM PR from IBM label Dec 10, 2025
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 10, 2025

Reviewer's Guide

Adds configurable staleness handling for materialized views, including new SPI types, config and session properties, connector- and engine-level plumbing (notably for Iceberg and memory connectors), optimizer changes to respect staleness behavior and window, and tests/docs for the new behavior.

Sequence diagram for materialized view rewrite with staleness handling

sequenceDiagram
    actor User
    participant Session
    participant Planner as MaterializedViewRewrite
    participant Metadata as MetadataResolver
    participant Connector as ConnectorMetadata

    User->>Session: submit query referencing MV
    Session->>Planner: optimize plan

    Planner->>Metadata: getMaterializedView(viewName)
    Metadata->>Connector: getMaterializedView(viewName)
    Connector-->>Metadata: MaterializedViewDefinition(definition)
    Metadata-->>Planner: MaterializedViewDefinition(definition)

    Planner->>Metadata: getMaterializedViewStatus(viewName,TupleDomain.all)
    Metadata->>Connector: getMaterializedViewStatus(viewName,TupleDomain.all)
    Connector-->>Metadata: MaterializedViewStatus(status,lastFreshTime)
    Metadata-->>Planner: MaterializedViewStatus(status,lastFreshTime)

    alt fully materialized
        Planner->>Planner: canUseDataTableWithSecurityChecks(definition,status)
        Planner-->>Session: use data table
    else not fully materialized and stalenessConfig present
        Planner->>Planner: isStalenessBeyondTolerance(stalenessConfig,status)
        alt within stalenessWindow
            Planner->>Planner: canUseDataTableWithSecurityChecks(definition,status)
            Planner-->>Session: use data table
        else beyond stalenessWindow
            alt staleReadBehavior == FAIL
                Planner-->>User: error MATERIALIZED_VIEW_STALE
            else staleReadBehavior == USE_VIEW_QUERY
                Planner-->>Session: do not use data table
            end
        end
    else no stalenessConfig
        Planner->>Session: getMaterializedViewStaleReadBehavior
        alt sessionBehavior == USE_VIEW_QUERY
            Planner-->>Session: do not use data table
        else sessionBehavior == FAIL
            Planner-->>User: error MATERIALIZED_VIEW_STALE
        end
    end
Loading

Updated class diagram for materialized view staleness model

classDiagram
    class MaterializedViewDefinition {
        - String originalSql
        - String schema
        - String table
        - List~SchemaTableName~ baseTables
        - Optional~String~ owner
        - Optional~ViewSecurity~ securityMode
        - List~ColumnMapping~ columnMappings
        - List~SchemaTableName~ baseTablesOnOuterJoinSide
        - Optional~List~ validRefreshColumns
        - Optional~MaterializedViewStalenessConfig~ stalenessConfig
        - Optional~MaterializedViewRefreshType~ refreshType
        + MaterializedViewDefinition(originalSql,schema,table,baseTables,owner,securityMode,columnMappings,baseTablesOnOuterJoinSide,validRefreshColumns,stalenessConfig,refreshType)
        + Optional~MaterializedViewStalenessConfig~ getStalenessConfig()
        + Optional~MaterializedViewRefreshType~ getRefreshType()
    }

    class MaterializedViewStalenessConfig {
        - MaterializedViewStaleReadBehavior staleReadBehavior
        - Duration stalenessWindow
        + MaterializedViewStalenessConfig(staleReadBehavior,stalenessWindow)
        + MaterializedViewStaleReadBehavior getStaleReadBehavior()
        + Duration getStalenessWindow()
    }

    class MaterializedViewStatus {
        - MaterializedViewState materializedViewState
        - Map~SchemaTableName,MaterializedDataPredicates~ partitionsFromBaseTables
        - Optional~Long~ lastFreshTime
        + MaterializedViewStatus(materializedViewState)
        + MaterializedViewStatus(materializedViewState,partitionsFromBaseTables)
        + MaterializedViewStatus(materializedViewState,partitionsFromBaseTables,lastFreshTime)
        + MaterializedViewState getMaterializedViewState()
        + Map~SchemaTableName,MaterializedDataPredicates~ getPartitionsFromBaseTables()
        + Optional~Long~ getLastFreshTime()
    }

    class MaterializedViewStaleReadBehavior {
        <<enum>>
        FAIL
        USE_VIEW_QUERY
    }

    class MaterializedViewRefreshType {
        <<enum>>
        FULL
    }

    class FeaturesConfig {
        - MaterializedViewStaleReadBehavior materializedViewStaleReadBehavior
        + MaterializedViewStaleReadBehavior getMaterializedViewStaleReadBehavior()
        + FeaturesConfig setMaterializedViewStaleReadBehavior(materializedViewStaleReadBehavior)
    }

    class SystemSessionProperties {
        + static MaterializedViewStaleReadBehavior getMaterializedViewStaleReadBehavior(Session)
    }

    class IcebergTableProperties {
        + static Optional~MaterializedViewStaleReadBehavior~ getMaterializedViewStaleReadBehavior(Map)
        + static Optional~Duration~ getMaterializedViewStalenessWindow(Map)
        + static MaterializedViewRefreshType getMaterializedViewRefreshType(Map)
        + List~PropertyMetadata~ getMaterializedViewProperties()
    }

    class MaterializedViewRewrite {
        - boolean isUseDataTable(MaterializedViewScanNode,MetadataResolver,Session)
        - boolean isStalenessBeyondTolerance(MaterializedViewStalenessConfig,MaterializedViewStatus)
        - boolean applyStaleReadBehavior(MaterializedViewStalenessConfig,QualifiedObjectName)
        - boolean canUseDataTableWithSecurityChecks(MaterializedViewScanNode,MetadataResolver,Session,MaterializedViewDefinition)
    }

    MaterializedViewDefinition --> "0..1" MaterializedViewStalenessConfig : stalenessConfig
    MaterializedViewDefinition --> "0..1" MaterializedViewRefreshType : refreshType
    MaterializedViewStalenessConfig --> MaterializedViewStaleReadBehavior : uses
    MaterializedViewStatus --> "0..1" Long : lastFreshTime
    FeaturesConfig --> MaterializedViewStaleReadBehavior : defaultBehavior
    SystemSessionProperties --> MaterializedViewStaleReadBehavior : sessionBehavior
    IcebergTableProperties --> MaterializedViewStaleReadBehavior : tableProperty
    IcebergTableProperties --> MaterializedViewRefreshType : tableProperty
    MaterializedViewRewrite --> MaterializedViewDefinition : reads
    MaterializedViewRewrite --> MaterializedViewStatus : reads
    MaterializedViewRewrite --> MaterializedViewStalenessConfig : evaluates
    MaterializedViewRewrite --> MaterializedViewStaleReadBehavior : applies
Loading

File-Level Changes

Change Details Files
Introduce SPI types and metadata extensions to carry materialized view staleness configuration and refresh semantics, plus richer status information.
  • Extend MaterializedViewDefinition to carry optional staleness config and refresh type and expose them via JSON properties and accessors, keeping backward-compatible constructors.
  • Add MaterializedViewStalenessConfig, MaterializedViewStaleReadBehavior, and MaterializedViewRefreshType SPI types to represent stale-read behavior, staleness window, and refresh mode.
  • Extend MaterializedViewStatus to carry an optional lastFreshTime and add new constructors/accessor.
  • Add new StandardErrorCode values for stale materialized views and invalid materialized view properties.
  • Introduce MaterializedViewPropertyManager to manage connector materialized view properties and expose it through the Metadata API and delegating/test implementations.
presto-spi/src/main/java/com/facebook/presto/spi/MaterializedViewDefinition.java
presto-spi/src/main/java/com/facebook/presto/spi/MaterializedViewStalenessConfig.java
presto-spi/src/main/java/com/facebook/presto/spi/MaterializedViewStaleReadBehavior.java
presto-spi/src/main/java/com/facebook/presto/spi/MaterializedViewRefreshType.java
presto-spi/src/main/java/com/facebook/presto/spi/MaterializedViewStatus.java
presto-spi/src/main/java/com/facebook/presto/spi/StandardErrorCode.java
presto-main-base/src/main/java/com/facebook/presto/metadata/MaterializedViewPropertyManager.java
presto-main-base/src/main/java/com/facebook/presto/metadata/Metadata.java
presto-main-base/src/main/java/com/facebook/presto/metadata/MetadataManager.java
presto-main-base/src/main/java/com/facebook/presto/metadata/DelegatingMetadataManager.java
presto-main-base/src/test/java/com/facebook/presto/metadata/AbstractMockMetadata.java
Wire materialized view properties and staleness metadata through connectors (notably Iceberg and Memory) and the connector lifecycle.
  • Extend Connector interface and connector manager plumbing to support per-connector materialized view properties, including registration and removal.
  • In Iceberg, define materialized view properties for stale-read behavior, staleness window, and refresh type, expose them via IcebergConnector, and use them when creating/parsing materialized view definitions.
  • Compute and propagate lastFreshTime for materialized views in Iceberg and Memory connectors based on underlying table snapshots/versions, and include it in MaterializedViewStatus.
  • Switch CreateMaterializedViewTask to use the new MaterializedViewPropertyManager for resolving MV properties.
  • Update tests and internal connector factories to supply and use the new materialized view property metadata.
presto-spi/src/main/java/com/facebook/presto/spi/connector/Connector.java
presto-main-base/src/main/java/com/facebook/presto/connector/ConnectorManager.java
presto-main-base/src/main/java/com/facebook/presto/execution/CreateMaterializedViewTask.java
presto-main-base/src/test/java/com/facebook/presto/execution/TestCreateMaterializedViewTask.java
presto-main-base/src/main/java/com/facebook/presto/metadata/MetadataManager.java
presto-main-base/src/main/java/com/facebook/presto/metadata/Metadata.java
presto-main-base/src/main/java/com/facebook/presto/metadata/DelegatingMetadataManager.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergTableProperties.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergConnector.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/InternalIcebergConnectorFactory.java
presto-memory/src/main/java/com/facebook/presto/plugin/memory/MemoryMetadata.java
Add engine-level configuration and session property for default stale-read behavior of materialized views.
  • Extend FeaturesConfig with a materialized-view-stale-read-behavior config property including default and explicit mapping tests.
  • Expose MATERIALIZED_VIEW_STALE_READ_BEHAVIOR as a system session property, including parsing/serialization helpers and a getter.
  • Update TestFeaturesConfig to validate defaults and explicit mappings for the new property.
presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/FeaturesConfig.java
presto-main-base/src/main/java/com/facebook/presto/SystemSessionProperties.java
presto-main-base/src/test/java/com/facebook/presto/sql/analyzer/TestFeaturesConfig.java
Change materialized view rewrite logic to honor staleness configuration and last refresh time, including FAIL/USE_VIEW_QUERY semantics.
  • Refactor MaterializedViewRewrite to first check FULLY_MATERIALIZED status, then apply stalenessConfig if present, and fall back to session-level stale-read behavior when config is absent.
  • Implement staleness checks using lastFreshTime and configured staleness window, throwing MATERIALIZED_VIEW_STALE or forcing view-query usage based on behavior.
  • Extract security checks for using the data table into a helper that is reused across fully materialized and tolerated-staleness cases.
  • Extend existing test metadata helpers to construct definitions with staleness config and provide MaterializedViewStatus with lastFreshTime.
  • Add targeted unit tests for combinations of staleness window, lastFreshTime, and behaviors (FAIL, USE_VIEW_QUERY, within/outside tolerance, never refreshed).
presto-main-base/src/main/java/com/facebook/presto/sql/planner/iterative/rule/MaterializedViewRewrite.java
presto-main-base/src/test/java/com/facebook/presto/sql/planner/iterative/rule/TestMaterializedViewRewrite.java
Add new error handling, property validation utilities, and doc stubs around materialized view staleness.
  • Introduce INVALID_MATERIALIZED_VIEW_PROPERTY error code and use it from MaterializedViewPropertyManager and Iceberg property parsing helpers.
  • Add reusable helpers in IcebergAbstractMetadata for parsing optional enum and duration properties with proper error reporting for invalid values.
  • Extend docs stubs/placeholders for materialized view properties, session properties, and Iceberg connector configuration (files touched but content not shown in diff).
presto-spi/src/main/java/com/facebook/presto/spi/StandardErrorCode.java
presto-main-base/src/main/java/com/facebook/presto/metadata/MaterializedViewPropertyManager.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java
presto-docs/src/main/sphinx/admin/materialized-views.rst
presto-docs/src/main/sphinx/admin/properties-session.rst
presto-docs/src/main/sphinx/admin/properties.rst
presto-docs/src/main/sphinx/connector/iceberg.rst

Possibly linked issues

  • #(not provided): PR implements the issue’s configurable MV staleness window/behavior, session default, and Iceberg MV table properties, minus tracking modes.
  • #: PR implements Iceberg MV freshness tracking, staleness window, behavior, and refresh type, directly fulfilling requested basic MV support.

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

@tdcmeehan tdcmeehan force-pushed the mv-freshness branch 2 times, most recently from cd250c1 to d9f4b9a Compare December 10, 2025 14:05
@tdcmeehan tdcmeehan marked this pull request as ready for review December 10, 2025 21:50
@prestodb-ci prestodb-ci requested review from a team, Mariamalmesfer and pramodsatya and removed request for a team December 10, 2025 21:50
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The staleness evaluation in MaterializedViewRewrite uses currentTimeMillis() directly, which makes behavior time-dependent and slightly non-deterministic in tests; consider injecting a clock or passing the evaluation time via MaterializedViewStatus to make the logic and tests fully deterministic.
  • Several new tests in TestMaterializedViewRewrite appear to cover overlapping scenarios (e.g., the two 'within tolerance' and two 'beyond tolerance' cases); you could consolidate or parameterize these to reduce duplication while keeping the coverage.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The staleness evaluation in MaterializedViewRewrite uses currentTimeMillis() directly, which makes behavior time-dependent and slightly non-deterministic in tests; consider injecting a clock or passing the evaluation time via MaterializedViewStatus to make the logic and tests fully deterministic.
- Several new tests in TestMaterializedViewRewrite appear to cover overlapping scenarios (e.g., the two 'within tolerance' and two 'beyond tolerance' cases); you could consolidate or parameterize these to reduce duplication while keeping the coverage.

## Individual Comments

### Comment 1
<location> `presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java:1718-1723` </location>
<code_context>
             return new MaterializedViewStatus(NOT_MATERIALIZED, ImmutableMap.of());
         }

+        Optional<Long> lastFreshTime = definition.get().getBaseTables().stream()
+                .map(baseTable -> getIcebergTable(session, baseTable))
+                .map(Table::currentSnapshot)
+                .filter(Objects::nonNull)
+                .map(Snapshot::timestampMillis)
+                .max(Long::compareTo);
+
         for (SchemaTableName baseTable : definition.get().getBaseTables()) {
</code_context>

<issue_to_address>
**suggestion (performance):** Avoid recomputing Iceberg tables twice when determining status and last fresh time.

`lastFreshTime` is computed by calling `getIcebergTable(session, baseTable)` for every base table, and then the `for` loop calls `getIcebergTable` again for the same tables. This doubles catalog/metadata access. Either derive `lastFreshTime` from the `baseIcebergTable` already fetched in the loop, or build a single map of base table → snapshot and reuse it in both places to avoid repeated lookups.

Suggested implementation:

```java
        Map<SchemaTableName, Table> baseIcebergTables = new HashMap<>();
        for (SchemaTableName baseTable : definition.get().getBaseTables()) {
            baseIcebergTables.put(baseTable, getIcebergTable(session, baseTable));
        }

        Optional<Long> lastFreshTime = baseIcebergTables.values().stream()
                .map(Table::currentSnapshot)
                .filter(Objects::nonNull)
                .map(Snapshot::timestampMillis)
                .max(Long::compareTo);

        for (SchemaTableName baseTable : definition.get().getBaseTables()) {
            Table baseIcebergTable = baseIcebergTables.get(baseTable);

```

1. Ensure the following imports exist at the top of `IcebergAbstractMetadata.java` (or equivalent, depending on your existing imports):
   - `import java.util.HashMap;`
   - `import java.util.Map;`
2. If the file already has these imports under a different grouping/order, integrate them according to your existing import style.
</issue_to_address>

### Comment 2
<location> `presto-main-base/src/test/java/com/facebook/presto/sql/planner/iterative/rule/TestMaterializedViewRewrite.java:225-234` </location>
<code_context>
+        assertThrows(PrestoException.class, () ->
</code_context>

<issue_to_address>
**suggestion (testing):** Strengthen failure tests by asserting on error code/message instead of only exception type

In the failure tests (`testFailWhenStaleAndSessionPropertyIsFail`, `testFailWhenStalenessBeyondToleranceWithFailBehavior`, `testFailWhenNeverRefreshedWithStalenessConfig`, `testFailWhenStalenessBeyondToleranceWindow`), consider using the `assertThrows` overload that returns the exception and then assert on `getErrorCode()` (and optionally the message) so the tests verify the specific `MATERIALIZED_VIEW_STALE` / `INVALID_MATERIALIZED_VIEW_PROPERTY` failures, not just the exception type.

Suggested implementation:

```java
        Metadata metadata = new TestingMetadataWithMaterializedViewStatus(false);

        PrestoException exception = assertThrows(PrestoException.class, () ->
                testerWithFail.assertThat(new MaterializedViewRewrite(metadata, new AllowAllAccessControl()))
                        .on(planBuilder -> {
                            VariableReferenceExpression outputA = planBuilder.variable("a", BIGINT);
                            VariableReferenceExpression dataTableA = planBuilder.variable("data_table_a", BIGINT);
                            VariableReferenceExpression viewQueryA = planBuilder.variable("view_query_a", BIGINT);

                            return planBuilder.materializedViewScan(
                                    materializedViewName,
                                    planBuilder.values(dataTableA),
                                    planBuilder.values(viewQueryA),

```

1. After this block (in the same test method), add:
   `assertEquals(MATERIALIZED_VIEW_STALE.toErrorCode(), exception.getErrorCode());`
   (or `INVALID_MATERIALIZED_VIEW_PROPERTY.toErrorCode()` where appropriate).
2. Ensure you have `import static org.testng.Assert.assertEquals;` at the top of the file.
3. Ensure you have static imports for the error codes you want to assert, e.g.:
   `import static com.facebook.presto.spi.StandardErrorCode.MATERIALIZED_VIEW_STALE;`
   and/or
   `import static com.facebook.presto.spi.StandardErrorCode.INVALID_MATERIALIZED_VIEW_PROPERTY;`.
4. Apply the same pattern to:
   - `testFailWhenStaleAndSessionPropertyIsFail`
   - `testFailWhenStalenessBeyondToleranceWithFailBehavior`
   - `testFailWhenNeverRefreshedWithStalenessConfig`
   - `testFailWhenStalenessBeyondToleranceWindow`
   by:
   - Capturing the thrown `PrestoException` into a local variable.
   - Asserting `getErrorCode()` matches the specific expected error code.
   - Optionally asserting on `getMessage()` if you want stronger guarantees about the failure reason.
</issue_to_address>

### Comment 3
<location> `presto-main-base/src/test/java/com/facebook/presto/execution/TestCreateMaterializedViewTask.java:128-133` </location>
<code_context>
         ColumnPropertyManager columnPropertyManager = new ColumnPropertyManager();
         columnPropertyManager.addProperties(testCatalog.getConnectorId(), ImmutableList.of());

+        MaterializedViewPropertyManager materializedViewPropertyManager = new MaterializedViewPropertyManager();
+        materializedViewPropertyManager.addProperties(testCatalog.getConnectorId(), ImmutableList.of());
+
</code_context>

<issue_to_address>
**suggestion (testing):** Consider adding a test that exercises materialized view creation with the new MV properties

`MaterializedViewPropertyManager` is now wired into `CreateMaterializedViewTask`, but tests here still only validate table properties. Please add a test that creates a materialized view with MV-specific properties (e.g., `materialized_view_stale_read_behavior`, `materialized_view_staleness_window`, `materialized_view_refresh_type`) set in SQL, and asserts they are correctly propagated into `ConnectorTableMetadata` (or the stored definition).
</issue_to_address>

### Comment 4
<location> `presto-docs/src/main/sphinx/admin/materialized-views.rst:66` </location>
<code_context>
+
+When no per-view configuration is specified, the default behavior is ``FAIL`` (query fails with
+an error). This can be changed using the ``materialized_view_stale_read_behavior`` session property
+or the ``materialized-view-stale-read-behavior`` configuration property. Setting to ``USE_VIEW_QUERY``
+causes Presto to fall back to executing the underlying view query against the base tables.
+
 Required Permissions
</code_context>

<issue_to_address>
**suggestion (typo):** Add a missing word in "Setting to ``USE_VIEW_QUERY``` for correct grammar.

The phrase is missing an object. Please rephrase to something like “Setting it to ``USE_VIEW_QUERY```” or “Setting this to ``USE_VIEW_QUERY```” for correct grammar.

```suggestion
or the ``materialized-view-stale-read-behavior`` configuration property. Setting it to ``USE_VIEW_QUERY``
```
</issue_to_address>

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.

Copy link
Member

@hantangwangd hantangwangd left a comment

Choose a reason for hiding this comment

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

@tdcmeehan thanks for this feature, overall lgtm. I've left a few comments—mostly small things.

Comment on lines +1723 to +1727
Optional<Long> lastFreshTime = baseIcebergTables.values().stream()
.map(Table::currentSnapshot)
.filter(Objects::nonNull)
.map(Snapshot::timestampMillis)
.max(Long::compareTo);
Copy link
Member

Choose a reason for hiding this comment

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

The code here appears to obtain the timestamp of the latest snapshot for all base tables. Are we supposed to use the timestamps of the base tables' snapshots that are recorded in the MV's properties?

private final SessionPropertyManager sessionPropertyManager;
private final SchemaPropertyManager schemaPropertyManager;
private final TablePropertyManager tablePropertyManager;
private final MaterializedViewPropertyManager materializedViewPropertyManager = new MaterializedViewPropertyManager();
Copy link
Member

Choose a reason for hiding this comment

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

One quick question: was it intentional that materializedViewPropertyManager is not handled via injection like the other property managers?

false))
.build();

List<PropertyMetadata<?>> mvOnlyProperties = ImmutableList.<PropertyMetadata<?>>builder()
Copy link
Member

Choose a reason for hiding this comment

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

Really like the clean separation of MV properties here—makes things much clearer. I was wondering if it would be possible to move these MV properties to a dedicated class?

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

Labels

from:IBM PR from IBM

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add table properties to govern Iceberg materialized view refresh and query behavior

3 participants