Get desktop application:
View/edit binary Protocol Buffers messages
Used in:
Used in:
Used in: ,
Used in: ,
Parquet write only. The shuffle writer rejects this codec.
A `google.protobuf.Any`-shaped envelope for out-of-tree contrib scan messages. Hand-rolled (rather than importing the well-known `google.protobuf.Any`) so the wire format needs no well-known-type import -- Comet compiles this .proto with two toolchains (Rust `prost-build` and the Maven `protoc-jar` plugin) and the latter cannot reliably resolve the bundled well-known types. Field layout is deliberately identical to `Any` (`type_url` + serialized `value` bytes) so the JVM can populate it from a standard `Any.pack(...)` and the native side routes purely on `type_url`.
Used in:
Type name of `value`, namespaced to the owning contrib -- e.g. `type.googleapis.com/comet.contrib.delta.DeltaScan`. The native dispatcher matches on this to pick the contrib that decodes `value`; core itself names no contrib type. This is the contrib's identifier for its own message, NOT necessarily the proto package the message is compiled under today. Contrib scan messages currently live in this file only because a contrib proto build pipeline does not exist yet; they are meant to move under `contrib/<name>/proto`. Keying on a contrib-owned name keeps that relocation invisible on the wire.
The serialized contrib scan message (e.g. an encoded `DeltaScan`).
Used in:
Used in:
Used in: ,
(message has no fields)
Helper message for deduplicating delete file lists
Used in:
Indices into IcebergScanCommon.delete_file_pool
Mirrors delta_kernel::actions::deletion_vector::DeletionVectorDescriptor. Carries everything an executor needs to read + decode the DV bitmap, without materialising it on the driver.
Used in:
"u" (UUID-named, relative to <table_root>/_delta_log/deletion_vectors/) "p" (absolute URI in path_or_inline_dv) "i" (inline -- bytes carried in inline_bytes)
For "u": Delta-encoded UUID path component. For "p": absolute URI. For "i": empty.
Byte offset within the DV file ("u"/"p" only). Absent ≡ 0.
Size in bytes of the serialised RoaringBitmap entry.
Number of deleted rows (descriptor metadata; the executor doesn't need to count).
Inline-DV bytes (storage_type="i" only). Empty for "u"/"p".
Used in:
Operator payload for a Delta scan.
Absolute URL of the Delta table root, used by the executor to resolve relative ("u" storage-type) DV paths via kernel's `absolute_path` -- kernel joins `_delta_log/deletion_vectors/<uuid>` onto this, so it MUST end with `/` (the driver normalises before sending). Empty for tables with no DVs (executor simply never decodes), but populate it whenever known.
Per-scan invariants. Lives at the head of every Delta scan operator payload.
Used in:
Required (output) schema -- pure-logical at every nesting level. The kernel-read path physicalises it via `column_mappings`; partition columns are split out by name.
Partition columns (stored in add actions, not in file paths).
Cloud storage credentials / options, keyed by Hadoop-style names.
Root path of the Delta table (file:// or s3://...).
Optional snapshot version; unset = latest.
Per-file parallelism knob within a single Spark task.
Informational label for debug output.
When true the DataSourceExec swallows object-store NotFound errors as empty streams; matches Spark's `spark.sql.files.ignoreMissingFiles=true` semantics.
When true the native parquet reader matches Spark schema fields to parquet file fields by `PARQUET:field_id` metadata rather than by name. Used by Delta tables with `delta.columnMapping.mode = id` (the contrib copies `delta.columnMapping.id` to `PARQUET:field_id` on each schema field).
Delta synthetic columns to append to the scan output via `DeltaSyntheticColumnsExec`. The corresponding columns must NOT appear in `data_schema` or `required_schema` -- they're synthesised at exec time from row positions / DV bitmaps and inserted after the parquet read.
Row-tracking synthesis (row_id = baseRowId + physical_row_index, row_commit_version = defaultRowCommitVersion). Per-task baseRowId / defaultRowCommitVersion travel on `DeltaScanTask` (fields 6 + 7).
When synthetic columns aren't a contiguous suffix of `required_schema`, this sequence tells the native dispatcher how to project the final output. Each entry is an index into [parquet_output, appended_synthetics] -- positive means a column from the (stripped) parquet read at that index; the synthetic tail comes after, in the canonical row_index, is_row_deleted, row_id, row_commit_version order. Empty = synthetics are already a suffix; no reorder needed.
Override for the row_index column name. Defaults to "__delta_internal_row_index" when empty. Delta plans that read `_metadata.row_index` from row-tracking-enabled tables expose the row index as `_tmp_metadata_row_index` (the Delta-internal physical name from `DeltaParquetFileFormat.TMP_METADATA_ROW_INDEX_COLUMN_NAME`) rather than the canonical `__delta_internal_row_index`. Setting this lets the contrib produce a column with the alternate name from the same native synthesis.
Spark `_metadata.*` virtual columns the scan must surface. Delta's `PreprocessTableWithDVs` strategy and the row-tracking projection both inject these into the FileScan output: `file_path`, `file_name`, `file_size`, `file_block_start`, `file_block_length`, `file_modification_time`. Each appears as a flat top-level column in the scan's output schema. Native synthesizes them per-task from `DeltaScanTask` data (file_path, file_size, modification_time) and per-batch derivations. Empty list = no metadata columns to emit. Names are emitted in the order given, appended AFTER synthetic columns (row_index / is_row_deleted / row_id / row_commit_version) unless `final_output_indices` reorders them.
Kernel-built data-column schemas for the kernel-read path, produced by the driver from `delta-kernel-rs`'s `Scan` (`scan.physical_schema()` / `scan.logical_schema()`), serialized as Arrow IPC schema messages. The physical schema carries the correct physical names AND field-ids at EVERY nesting level (kernel's own column-mapping resolution); the logical schema is the matching pure-logical shape. The executor reads parquet with the physical schema and relabels physical->logical via the schema pair -- no Comet-side physicalisation. Empty when the driver didn't build them (e.g. the non-kernel-read add-files path), in which case the executor falls back to physicalising `required_schema` via `column_mappings`.
Stage B/C: when true, DeltaKernelScanExec produces ALL synthetic columns itself (row_index / row_id / file_path via kernel metadata columns; is_row_deleted by inverting the decoded DV; row_commit_version + Spark `_metadata.*` as per-file constants) and assembles the full output by name -- so the standalone DeltaSyntheticColumnsExec is NOT stacked on top and no `final_output_indices` reorder is needed. Default false (legacy DeltaSyntheticColumnsExec path). When set, `required_schema` is the FULL output (synthetics NOT stripped) and the per-file synthesis inputs ride on DeltaScanTask (base_row_id / default_row_commit_version / modification_time / byte range / dv).
Change Data Feed (CDF / readChangeFeed): when true, DeltaKernelScanExec reads table changes via delta-kernel-rs's `TableChanges` API (single partition reconstructs TableChanges(start, end) and calls `execute()`), emitting the data columns plus `_change_type` / `_commit_version` / `_commit_timestamp`. The version range is below; `required_schema` is the full CDF output (assembled by name). No per-file tasks -- the worker enumerates + reads the whole range itself (kernel's CDF per-file API is pub(crate); only execute() is public). Default false.
Inclusive start version of the CDF range.
Inclusive end version of the CDF range. `has_cdf_end_version` distinguishes "latest" (unset).
Delta's test-only deletion-vector filename prefix (`spark.databricks.delta.testOnly.dvFileNamePrefix`, default `test%dv%prefix-` under `Utils.isTesting`, empty in production). Delta prepends it to the DV filename at write time (`<prefix>deletion_vector_<uuid>.bin`) but delta-kernel-rs resolves the un-prefixed name, so executor-side DV reads splice it back in for "u"-storage DVs. Empty = no-op (production).
Used in: ,
File-splitting byte range. Both unset = read whole file.
File modification time in epoch milliseconds. Surfaced through Spark's `_metadata.file_modification_time` column when emit_metadata_columns includes "file_modification_time". Unset = 0 (rare; AddFile usually carries one).
Deletion-vector descriptor for this file (absent = no DV applies). Mirrors delta_kernel::actions::deletion_vector::DeletionVectorDescriptor. The executor reads the actual DV bitmap on-task via dv_reader::read_dv_indexes -- the driver only ships the path/offset/size, so the per-scan-exec heap stays KB-scale regardless of DV size.
Kernel's own fully-resolved physical->logical transform for THIS file, serialized as JSON (serde of `delta_kernel::expressions::Expression`). The driver gets it from kernel's scan enumeration (`ScanMetadata.scan_file_transforms`, one per scan file), where partition values and `baseRowId` (for row_id `GenerateRowId`) are already baked in as literals. The executor deserializes it and applies `transform_to_logical` -- so partition injection, column-mapping relabel (incl. nested), and row-tracking come from kernel rather than Comet-side reconstruction. Empty when the driver has no kernel transform for this file (e.g. a plain table with no mapping / partitions / row-tracking -> identity), in which case the executor uses a pass-through read.
JNI return value from planDeltaScan -- the list of tasks for a given snapshot.
Kernel-built data-column schemas (Arrow IPC), produced by the driver from the projected `Scan` (`scan.physical_schema()` / `scan.logical_schema()`). Carried back to Scala and copied onto `DeltaScanCommon.kernel_physical_schema` / `kernel_logical_schema`. Empty when the driver had no projection to build the scan against.
Used in:
Used in:
The array expression to explode into multiple rows
Whether this is explode_outer (produces null row for empty/null arrays)
Expressions for other columns to project alongside the exploded values
Whether to emit a position column alongside the exploded values (posexplode)
Used in:
Used in:
Used for ROWS frames. Integer row count.
Used for RANGE frames. Carries the typed offset value so the native side can build a ScalarValue whose type matches the ORDER BY column.
Used in:
Per-expression modes for mixed-mode aggregates (e.g., PartialMerge + Partial). When set, each entry corresponds to agg_exprs at the same index. When empty, all expressions use the `mode` field.
Offset in the child's output where aggregate buffer attributes start. Used by PartialMerge to locate state fields in the input.
Used in:
True for BroadcastHashJoinExec null-aware anti-joins (NOT IN subquery semantics). When true, any null in the build side suppresses all left rows.
Used in:
A decimal literal. `scale`/`precision` let the native side build a self-typed Datum for predicate pushdown (iceberg-rust's Datum is self-typed); partition-value decode reads only `unscaled`. Predicate decimal pushdown is deferred (iceberg-rust page-index gap), so today only `unscaled` is consumed.
Used in:
unscaled value, two's-complement big-endian
Iceberg delete file for MOR tables (positional or equality deletes) Positional: (file_path, row_position) pairs to skip Equality: Column values to filter out (specified by equality_ids)
Used in:
Delete file path
POSITION_DELETES or EQUALITY_DELETES
Partition spec ID
Equality field IDs (empty for positional deletes)
Serialized StandardKeyMetadata for an encrypted delete file, from DeleteFile.keyMetadata(). Absent for unencrypted tables. Decoded directly by iceberg-rust; no KMS unwrap needed.
Iceberg FileScanTask containing data file, delete files, and residual filter
Used in:
Data file path (e.g., s3://bucket/warehouse/db/table/data/00000-0-abc.parquet)
Byte range to read (for split files)
Record count if reading entire file
Total file size from the manifest entry, used to skip stat/HEAD calls
Serialized StandardKeyMetadata (plaintext DEK + AAD prefix) for an encrypted data file, taken verbatim from Iceberg's DataFile.keyMetadata(). Absent for unencrypted tables. iceberg-rust decodes this directly; no KMS unwrap is needed on the native side.
Indices into IcebergScan deduplication pools
A typed Iceberg primitive value, shared by partition values and predicate literals. The oneof case is the type tag (iceberg-rust's Datum is self-typed and Predicate::bind does not coerce, so the type must be known at construction). Grows by adding a case as Iceberg adds primitives (GEOMETRY/VARIANT/nanosecond timestamps); unrecognized values decode to no-op, never an error.
Used in: , ,
days since epoch
micros since epoch, no tz
micros since epoch, utc
Used in:
Iceberg residual predicate for row-group pruning, mirroring iceberg::expr::Predicate. Only a pruning hint: the post-scan CometFilter enforces correctness, so an unrepresentable predicate is simply omitted. Carries no expr_id/query_context (those are for native ANSI error reporting on executable expressions; a residual never errors), which also lets identical residuals dedup.
Used in: ,
IS_NULL / NOT_NULL / IS_NAN / NOT_NAN
column OP literal
IN only emitted; not_in is inherently unprunable from stats
Mirrors iceberg-rust PredicateOperator (crates/iceberg/src/expr/mod.rs) so the mapping on both sides is 1:1. The driver emits a subset by design: NOT_IN never prunes from column stats (inherent, matches Iceberg-Java), and IS_NAN/STARTS_WITH are not produced by the current residual path. Unspecified/unrecognized decodes to no-pushdown.
Used in: , ,
Used in:
Common data shared across partitions (pools, metadata, catalog props)
Single partition's file scan tasks
Common data shared by all partitions in split mode (sent once, captured in closure)
Used in:
Catalog-specific configuration for FileIO (credentials, S3/GCS config, etc.)
Table metadata file path for FileIO initialization
Schema to read
Deduplication pools (must contain all entries for cross-partition deduplication)
Index-aligned with partition_spec_pool: entry i is the StructType JSON for the spec at partition_spec_pool[i]. Native uses this pairing to recover each entry's spec_id when merging partition types across historical specs (see parse_file_scan_tasks_from_common in planner.rs), which partition_type_pool cannot express on its own since it is only resolved field types, not specs.
Number of data files to read concurrently within a single task
Spark V2 catalog name that loaded this table. Forwarded as the dispatchKey to CometS3CredentialDispatcher.ensureInitialized so two catalogs sharing one provider class get isolated provider instances. Empty string when the table has no catalog identity (e.g. HadoopTables loaded by raw path).
Flat pool of unique delete files, referenced by index from DeleteFileList. Iceberg's default partition delete granularity has one delete file apply to many data files, so interning each delete file here (rather than embedding copies per delete_files_pool set) keeps the broadcast common message from growing with the number of references.
Iceberg's SparkScan.hashCode() (folds in pushed filters, snapshot, branch, and read schema). A self-join/self-merge can read the same table (same metadata_location) twice with different projections or filters, so PlanDataInjector keys planning data by (metadata_location, scan_hash_code) rather than metadata_location alone.
Used in:
Used in:
Used in: , ,
Used in:
Used in:
Used in:
Common data shared across partitions (schemas, filters, projections, config)
Single partition's file list (injected at execution time)
Common data shared by all partitions in split mode (sent once at planning)
Used in:
SPARK-53535 (Spark 4.1+): when reading a struct whose requested fields are all missing in the Parquet file, true returns the entire struct as null (legacy pre-4.1 behavior); false preserves the parent struct's nullness from the file so non-null parents return a struct of all-null fields.
True when spark.sql.parquet.fieldId.read.enabled is set and the requested schema actually carries parquet.field.id metadata. When false the native scan keeps its existing name-based path with no extra work.
True when spark.sql.parquet.fieldId.read.ignoreMissing is set.
Whether widening type promotion is allowed (e.g. INT32 -> INT64, FLOAT -> DOUBLE). Set from Comet's per-Spark-version constant in ShimCometConf (false on 3.x, true on 4.x). When false, reading a column with a disallowed promoted type throws an error matching Spark's SchemaColumnConvertNotSupportedException behavior.
When true, reading a Parquet TimestampLTZ column as TimestampNTZ is permitted (Spark 4.0+, SPARK-47447); when false, it is rejected with SchemaColumnConvertNotSupportedException (Spark 3.x, SPARK-36182). Set from Comet's per-Spark-version constant in ShimCometConf.
The basic message representing a Spark operator.
Used in:
The child operators of this
Spark plan ID
Pool of distinct SQL texts referenced by `QueryContext.sql_text_idx`. Every expression that carries a QueryContext needs the full query text to render Spark's `== SQL ... ==` error block, and in a typical plan they all want the *same* text -- embedding it per expression made the query text over 95% of the serialized plan. The JVM interns the texts into this pool on the root operator of each serialized native block (see `QueryContextInterner`) and leaves `QueryContext.sql_text` empty. Only populated on the root operator; nested operators leave it empty.
Extension point for optional, out-of-tree contrib scans (Delta, Lance, ...). The concrete scan message (e.g. `DeltaScan`) is packed into this envelope on the JVM side and dispatched by `type_url` on the native side. Using a single permanent field -- rather than a new oneof variant per format -- means core's proto never has to change when a contrib is added, and avoids field-number collisions between independent contrib PRs. Only decoded when core is built with the matching contrib Cargo feature (e.g. `--features contrib-delta`); default builds reject any `contrib_scan` with a clear "not compiled in" error, so the contrib has zero runtime cost.
Used in:
Working directory for temporary files (used by FileCommitProtocol) If not set, files are written directly to output_path
Job ID for tracking this write operation
Task attempt ID for this specific task
Options for configuring object stores such as AWS S3, GCS, etc. The key-value pairs are taken from Hadoop configuration for compatibility with Hadoop FileSystem implementations of object stores. The configuration values have hadoop. or spark.hadoop. prefix trimmed. For instance, the configuration value "spark.hadoop.fs.s3a.access.key" will be stored as "fs.s3a.access.key" in the map.
Catalyst's target schema, including top-level nullability and Parquet field IDs. Nested collection field IDs are carried by the corresponding DataType messages.
Collection of partition values for a single partition
Used in:
Partition value for Iceberg partition data
Used in:
Used in:
Used for ROWS frames. Integer row count.
Used for RANGE frames. Carries the typed offset value so the native side can build a ScalarValue whose type matches the ORDER BY column.
Helper message for deduplicating field ID lists
Used in:
Used in:
Sampling without replacement. Spark's SampleExec also supports sampling with replacement, but that path is not serialized to native yet, so there is no `with_replacement` field.
Used in:
Seed before the partition index is added, which happens on the native side.
Used in:
The source of the scan (e.g. file scan, broadcast exchange, shuffle, etc). This is purely for informational purposes when viewing native query plans in debug mode.
Used in:
Informational label for debug output (e.g., "CometShuffleExchangeExec [id=5]")
Used in:
Size of the write buffer in bytes used when writing shuffle data to disk. Larger values may improve write performance but use more memory.
Spark-declared output schema of the writer's child. When the child is an inlined native subtree, the native planner casts the child's actual output to this schema before serializing to shuffle blocks, since there is no FFI boundary or ScanExec between them to absorb DataFusion-vs-Spark type drift. Empty when the child is a placeholder Scan; that path already has a cast point upstream.
Maximum number of bytes that the writer buffers in memory before spilling to disk. Zero means no limit, in which case spilling is driven only by memory pool pressure.
Used in:
Used in:
This name and the one above are not great, but they correspond to the (unfortunate) Spark names. I prepended "Spark" since I think there's a name collision on the native side, but we can revisit.
Used in: ,
Used in:
Used in: , , , , ,
Spark field metadata. Currently used to carry parquet.field.id through to the native side. Empty when not needed.
Used in:
(message has no fields)
Used in:
(message has no fields)
Used in:
Used in:
Used in:
Spark's expected result type. Used to cast the native window function output when DataFusion's return type differs (e.g. row_number returns UInt64 but Spark expects Int32).
Used in:
Used in:
Used in: