Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Apache Paimon ViewChange

From Leeroopedia


Knowledge Sources
Domains View Management, DDL Operations
Last Updated 2026-02-08 00:00 GMT

Overview

ViewChange is a sealed interface hierarchy that defines all possible modification operations that can be applied to Paimon views, analogous to SchemaChange for tables.

Description

ViewChange represents the contract for view evolution in Apache Paimon. Similar to SchemaChange, it uses Jackson JSON polymorphic type annotations to enable serialization and deserialization, making it suitable for REST APIs, catalog operations, and DDL execution. The interface provides static factory methods for creating each type of view modification, including operations on view options (SetViewOption, RemoveViewOption), view metadata (UpdateViewComment), and dialect-specific query management (AddDialect, UpdateDialect, DropDialect).

Each view change type is implemented as a final inner class with immutable fields, ensuring thread-safety and predictability. The dialect-related operations are particularly important for Paimon's multi-dialect view support, allowing views to store SQL query definitions for different compute engines (e.g., Flink SQL, Spark SQL, Hive SQL). This enables a view to be queried from multiple engines while maintaining engine-specific optimizations or syntax variations.

The interface is marked with @Public annotation, indicating its stability as part of the Paimon public API. This ensures backward compatibility and makes it suitable for use by external tools, catalog implementations, and REST endpoints that need to modify view definitions programmatically.

Usage

Use ViewChange when implementing ALTER VIEW operations, view evolution logic in catalogs, or when serializing view modifications for storage or transmission. Each static factory method creates an appropriate ViewChange instance that can be applied to a view definition.

Code Reference

Source Location

Signature

@Public
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY,
              property = ViewChange.Actions.FIELD_TYPE)
@JsonSubTypes({
    @JsonSubTypes.Type(value = ViewChange.SetViewOption.class, name = "setOption"),
    @JsonSubTypes.Type(value = ViewChange.RemoveViewOption.class, name = "removeOption"),
    @JsonSubTypes.Type(value = ViewChange.UpdateViewComment.class, name = "updateComment"),
    @JsonSubTypes.Type(value = ViewChange.AddDialect.class, name = "addDialect"),
    @JsonSubTypes.Type(value = ViewChange.UpdateDialect.class, name = "updateDialect"),
    @JsonSubTypes.Type(value = ViewChange.DropDialect.class, name = "dropDialect")
})
public interface ViewChange extends Serializable {
    static ViewChange setOption(String key, String value);
    static ViewChange removeOption(String key);
    static ViewChange updateComment(String comment);
    static ViewChange addDialect(String dialect, String query);
    static ViewChange updateDialect(String dialect, String query);
    static ViewChange dropDialect(String dialect);
}

Import

import org.apache.paimon.view.ViewChange;

I/O Contract

Inputs

Name Type Required Description
key String yes Configuration key for SetViewOption/RemoveViewOption
value String yes Configuration value for SetViewOption
comment String yes Comment text for UpdateViewComment
dialect String yes SQL dialect name (e.g., "flink", "spark", "hive")
query String yes SQL query definition for the dialect

Outputs

Name Type Description
viewChange ViewChange Immutable view change instance representing the operation

Usage Examples

Managing View Options

// Set a view option
ViewChange setOpt = ViewChange.setOption(
    "refresh.interval",
    "10min"
);

// Remove a view option
ViewChange removeOpt = ViewChange.removeOption("refresh.interval");

// Update view comment
ViewChange updateComment = ViewChange.updateComment(
    "Materialized view of daily user statistics"
);

Adding Dialect-Specific Queries

// Add Flink SQL dialect
ViewChange addFlink = ViewChange.addDialect(
    "flink",
    "SELECT user_id, COUNT(*) as cnt FROM orders GROUP BY user_id"
);

// Add Spark SQL dialect with different syntax
ViewChange addSpark = ViewChange.addDialect(
    "spark",
    "SELECT user_id, COUNT(1) as cnt FROM orders GROUP BY user_id"
);

// Add Hive SQL dialect
ViewChange addHive = ViewChange.addDialect(
    "hive",
    "SELECT user_id, count(*) as cnt FROM orders GROUP BY user_id"
);

Updating Dialect Queries

// Update existing dialect query
ViewChange updateQuery = ViewChange.updateDialect(
    "flink",
    "SELECT user_id, COUNT(*) as cnt, SUM(amount) as total " +
    "FROM orders GROUP BY user_id"
);

// Update to use different window function
ViewChange updateWindow = ViewChange.updateDialect(
    "flink",
    "SELECT user_id, " +
    "       COUNT(*) OVER (PARTITION BY user_id) as cnt " +
    "FROM orders"
);

Removing Dialect Support

// Drop dialect support
ViewChange dropDialect = ViewChange.dropDialect("hive");

// Remove obsolete dialect
ViewChange removeOldDialect = ViewChange.dropDialect("legacy-sql");

Multi-Dialect View Creation

// Create view with multiple dialect support
public List<ViewChange> createMultiDialectView() {
    List<ViewChange> changes = new ArrayList<>();

    // Set view metadata
    changes.add(ViewChange.updateComment(
        "User order summary view"
    ));

    // Add Flink SQL version
    changes.add(ViewChange.addDialect(
        "flink",
        "SELECT u.user_id, u.name, " +
        "       COUNT(o.order_id) as order_count, " +
        "       SUM(o.amount) as total_amount " +
        "FROM users u " +
        "LEFT JOIN orders o ON u.user_id = o.user_id " +
        "GROUP BY u.user_id, u.name"
    ));

    // Add Spark SQL version (similar but may have dialect differences)
    changes.add(ViewChange.addDialect(
        "spark",
        "SELECT u.user_id, u.name, " +
        "       COUNT(o.order_id) as order_count, " +
        "       SUM(o.amount) as total_amount " +
        "FROM users u " +
        "LEFT JOIN orders o ON u.user_id = o.user_id " +
        "GROUP BY u.user_id, u.name"
    ));

    return changes;
}

View Evolution Workflow

// Complete view modification workflow
public void evolveView(String viewName, String newQuery) {
    List<ViewChange> changes = new ArrayList<>();

    // Update comment
    changes.add(ViewChange.updateComment(
        "Updated view definition - " + LocalDateTime.now()
    ));

    // Update Flink dialect
    changes.add(ViewChange.updateDialect("flink", newQuery));

    // Apply changes through catalog
    catalog.alterView(
        new ObjectPath("default", viewName),
        changes
    );
}

Conditional Dialect Management

// Add or update dialect based on existence
public ViewChange upsertDialect(String dialect, String query,
                                 boolean dialectExists) {
    if (dialectExists) {
        return ViewChange.updateDialect(dialect, query);
    } else {
        return ViewChange.addDialect(dialect, query);
    }
}

// Migrate from one dialect to another
public List<ViewChange> migrateDialect(String fromDialect,
                                        String toDialect,
                                        String newQuery) {
    return Arrays.asList(
        ViewChange.dropDialect(fromDialect),
        ViewChange.addDialect(toDialect, newQuery)
    );
}

View Configuration Management

// Configure view refresh settings
public List<ViewChange> configureRefresh(Duration interval,
                                          boolean autoRefresh) {
    List<ViewChange> changes = new ArrayList<>();

    changes.add(ViewChange.setOption(
        "refresh.interval",
        interval.toString()
    ));

    changes.add(ViewChange.setOption(
        "refresh.auto",
        String.valueOf(autoRefresh)
    ));

    return changes;
}

// Clear view configuration
public List<ViewChange> clearConfiguration(List<String> keys) {
    return keys.stream()
        .map(ViewChange::removeOption)
        .collect(Collectors.toList());
}

Serialization Example

// Serialize view changes to JSON
ObjectMapper mapper = new ObjectMapper();

ViewChange change = ViewChange.addDialect(
    "flink",
    "SELECT * FROM source_table"
);

String json = mapper.writeValueAsString(change);
// JSON includes action type and parameters

// Deserialize from JSON
ViewChange restored = mapper.readValue(json, ViewChange.class);

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment