Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Apache Paimon RowKind

From Leeroopedia


Knowledge Sources
Domains Changelog, Stream Processing
Last Updated 2026-02-08 00:00 GMT

Overview

RowKind is an enumeration that lists all kinds of changes a row can describe in a changelog, supporting streaming table semantics.

Description

RowKind is a public enum defining four change operations for row-level modifications in streaming and changelog scenarios: INSERT (+I), UPDATE_BEFORE (-U), UPDATE_AFTER (+U), and DELETE (-D). Each enum constant is associated with a short string representation and a stable byte value for serialization purposes, ensuring consistency across different JVM instances where enum hash codes may vary.

The enum provides utility methods for classification: isRetract() returns true for UPDATE_BEFORE and DELETE operations that remove previous state, while isAdd() returns true for INSERT and UPDATE_AFTER operations that add new state. This distinction is crucial for maintaining correct changelog semantics in streaming systems where some operations must be paired (UPDATE_BEFORE with UPDATE_AFTER for non-idempotent updates) while others can stand alone (INSERT, DELETE, or idempotent UPDATE_AFTER).

RowKind supports bidirectional conversion between its representations via fromByteValue() and toByteValue() methods for byte-based serialization, and fromShortString() and shortString() for human-readable formats. The byte values (0-3) are stable and intended for persistent storage, while short strings (+I, -U, +U, -D) provide intuitive visualization of change operations. Available since version 0.4.0 as @Public API, RowKind is fundamental to Paimon's streaming table implementation and change data capture (CDC) support.

Usage

Use RowKind when working with changelog streams, implementing change data capture, processing streaming table updates, or building systems that need to track and replay row-level modifications. It is essential for maintaining consistency in streaming data pipelines.

Code Reference

Source Location

Signature

@Public
public enum RowKind {
    INSERT("+I", (byte) 0),
    UPDATE_BEFORE("-U", (byte) 1),
    UPDATE_AFTER("+U", (byte) 2),
    DELETE("-D", (byte) 3);

    public String shortString()

    public byte toByteValue()

    public boolean isRetract()

    public boolean isAdd()

    public static RowKind fromByteValue(byte value)

    public static RowKind fromShortString(String value)
}

Import

import org.apache.paimon.types.RowKind;

I/O Contract

Inputs

Name Type Required Description
Byte value byte Context-dependent Value 0-3 for deserialization
Short string String Context-dependent String "+I", "-U", "+U", or "-D" for parsing

Outputs

Name Type Description
RowKind RowKind The enum constant representing the change type
Short string String Human-readable representation (+I, -U, +U, -D)
Byte value byte Stable numeric value (0-3) for serialization
Classification boolean Whether operation is retract or add

Usage Examples

// Using RowKind constants
RowKind insert = RowKind.INSERT;
RowKind updateBefore = RowKind.UPDATE_BEFORE;
RowKind updateAfter = RowKind.UPDATE_AFTER;
RowKind delete = RowKind.DELETE;

// Get short string representation
String insertStr = insert.shortString(); // "+I"
String deleteStr = delete.shortString(); // "-D"

// Get byte value for serialization
byte insertByte = insert.toByteValue(); // 0
byte updateBeforeByte = updateBefore.toByteValue(); // 1
byte updateAfterByte = updateAfter.toByteValue(); // 2
byte deleteByte = delete.toByteValue(); // 3

// Check if operation is retract (removes state)
boolean isInsertRetract = insert.isRetract(); // false
boolean isDeleteRetract = delete.isRetract(); // true
boolean isUpdateBeforeRetract = updateBefore.isRetract(); // true
boolean isUpdateAfterRetract = updateAfter.isRetract(); // false

// Check if operation is add (adds state)
boolean isInsertAdd = insert.isAdd(); // true
boolean isDeleteAdd = delete.isAdd(); // false
boolean isUpdateAfterAdd = updateAfter.isAdd(); // true

// Convert from byte value
RowKind fromByte0 = RowKind.fromByteValue((byte) 0); // INSERT
RowKind fromByte3 = RowKind.fromByteValue((byte) 3); // DELETE

// Convert from short string (case-insensitive)
RowKind fromString1 = RowKind.fromShortString("+I"); // INSERT
RowKind fromString2 = RowKind.fromShortString("-u"); // UPDATE_BEFORE
RowKind fromString3 = RowKind.fromShortString("+U"); // UPDATE_AFTER

// Example: Processing changelog entries
public void processChange(RowKind kind, Object[] row) {
    if (kind.isRetract()) {
        // Remove previous state
        removeFromState(row);
    }
    if (kind.isAdd()) {
        // Add new state
        addToState(row);
    }
}

// Example: Handling update operations
public void handleUpdate(RowKind kind, Object[] row) {
    switch (kind) {
        case INSERT:
            insertRow(row);
            break;
        case UPDATE_BEFORE:
            // Retract old version
            retractRow(row);
            break;
        case UPDATE_AFTER:
            // Apply new version
            upsertRow(row);
            break;
        case DELETE:
            deleteRow(row);
            break;
    }
}

// Example: Idempotent vs non-idempotent updates
// Non-idempotent: Must send both UPDATE_BEFORE and UPDATE_AFTER
emitChange(RowKind.UPDATE_BEFORE, oldRow);
emitChange(RowKind.UPDATE_AFTER, newRow);

// Idempotent: Only UPDATE_AFTER needed (with primary key)
emitChange(RowKind.UPDATE_AFTER, newRowWithKey);

Related Pages

Page Connections

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