Implementation:Apache Flink EnrichedRowData
| Knowledge Sources | |
|---|---|
| Domains | Connectors, Table |
| Last Updated | 2026-02-09 00:00 GMT |
Overview
EnrichedRowData is an internal implementation of the RowData interface that merges two separate row data instances (a fixed row and a mutable row) into a single composite row, using an index mapping to route field accesses to the correct underlying row.
Description
EnrichedRowData enables the file connector to augment physical rows read from files with additional columns such as partition values or file metadata without copying the original row data. It is backed by two RowData instances:
- A fixedRow that holds static, immutable data (e.g., partition column values).
- A mutableRow that can be swapped at runtime for performant iteration in hot code paths.
The class uses an indexMapping array to determine which underlying row provides each field. Positive indexes refer to positions in the mutable row, while negative indexes (with a -1 offset) refer to positions in the fixed row. For example, an index mapping of [0, 1, -1, -2, 2] means:
- Index 0 maps to mutable row position 0
- Index 1 maps to mutable row position 1
- Index -1 maps to fixed row position 0
- Index -2 maps to fixed row position 1
- Index 2 maps to mutable row position 2
The RowKind is always inherited from the mutable row. All RowData accessor methods (getBoolean, getInt, getString, getDecimal, etc.) delegate to either the fixed or mutable row based on the index mapping.
A static factory method from() computes the index mapping automatically from lists of field names for the produced row, the mutable row, and the fixed row. The companion static method computeIndexMapping() performs the actual index mapping computation.
Usage
Use EnrichedRowData when reading from file-based sources where the physical row data needs to be enriched with additional columns such as partition values, file metadata, or other computed fields. This is an internal class annotated with @Internal and is not intended for direct use by end users.
The typical workflow is:
- Create an EnrichedRowData instance via the from() factory method, passing the fixed row and the field name lists.
- For each record read from a file, call replaceMutableRow() to swap in the new physical row data.
- Access the merged row through the standard RowData interface.
Code Reference
Source Location
- Repository: Apache_Flink
- File: flink-connectors/flink-connector-files/src/main/java/org/apache/flink/connector/file/table/EnrichedRowData.java
- Lines: 1-334
Signature
@Internal
public class EnrichedRowData implements RowData {
public EnrichedRowData(RowData fixedRow, int[] indexMapping)
public EnrichedRowData replaceMutableRow(RowData mutableRow)
public static EnrichedRowData from(
RowData fixedRow,
List<String> producedRowFields,
List<String> mutableRowFields,
List<String> fixedRowFields)
public static int[] computeIndexMapping(
List<String> producedRowFields,
List<String> mutableRowFields,
List<String> fixedRowFields)
}
Import
import org.apache.flink.connector.file.table.EnrichedRowData;
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| fixedRow | RowData | Yes | The immutable row containing static field values (e.g., partition columns) |
| indexMapping | int[] | Yes | Array mapping composite row positions to underlying row positions; positive values index the mutable row, negative values (with -1 offset) index the fixed row |
| mutableRow | RowData | Yes (via replaceMutableRow) | The swappable row containing the physical record data read from a file |
| producedRowFields | List<String> | Yes (for factory method) | Ordered field names of the full composite row |
| mutableRowFields | List<String> | Yes (for factory method) | Ordered field names of the mutable row |
| fixedRowFields | List<String> | Yes (for factory method) | Ordered field names of the fixed row |
Outputs
| Name | Type | Description |
|---|---|---|
| EnrichedRowData | RowData | A composite RowData instance that transparently merges the fixed and mutable rows according to the index mapping |
| indexMapping | int[] | The computed index mapping array (from computeIndexMapping) |
Usage Examples
Basic Usage
// Define field names for the composite, mutable, and fixed rows
List<String> producedFields = Arrays.asList("id", "name", "partition_date");
List<String> mutableFields = Arrays.asList("id", "name");
List<String> fixedFields = Arrays.asList("partition_date");
// Create the fixed row with partition value
GenericRowData fixedRow = new GenericRowData(1);
fixedRow.setField(0, StringData.fromString("2024-01-15"));
// Create the EnrichedRowData using the factory method
EnrichedRowData enrichedRow = EnrichedRowData.from(
fixedRow, producedFields, mutableFields, fixedFields);
// For each record read from a file, swap in the mutable row
RowData physicalRow = readNextFromFile();
enrichedRow.replaceMutableRow(physicalRow);
// Access fields through the composite RowData interface
int id = enrichedRow.getInt(0); // from mutable row
StringData name = enrichedRow.getString(1); // from mutable row
StringData date = enrichedRow.getString(2); // from fixed row