Skip to content

Unify global index construction behind a common table builder - #1091

Merged
JingsongLi merged 1 commit into
apache:mainfrom
JingsongLi:codex/unify-global-index-builder
Oct 10, 2026
Merged

JingsongLi merged 1 commit into
apache:mainfrom
JingsongLi:codex/unify-global-index-builder

Conversation

@JingsongLi

Copy link
Copy Markdown
Contributor

Purpose

Expose one global-index build API selected by index type, following Java's GlobalIndexer.create and GlobalIndexBuilderUtils. Sorting is an internal implementation choice; callers should not select separate sorted, full-text, Lumina or vindex table builders.

Brief change log

  • Introduce Table::new_global_index_build_builder() and GlobalIndexBuildBuilder for all existing Rust global-index families: BTree, bitmap, multivalue, FM, full-text, Lumina and the five vindex types.
  • Share column/type normalization, partition-filter validation and prepare/execute ownership. build() returns unpublished commit messages; execute() prepares and commits with the planned-snapshot guard.
  • Make the specialized builders private implementations and migrate Rust callers, examples, DataFusion procedures and the Python binding/stubs. Preserve the Lumina-specific SQL procedure's type restriction.
  • Use the table's REST-aware snapshot manager for vector preparation; honor per-build shard sizing and partition filters.
  • Apply Java-compatible external global-index placement and DEIX source metadata to prepared generic indexes so the existing commit conflict checks also protect their inputs.
  • Retain submitted or returned files on failed or uncertain commits; only failed private preparation cleans its own outputs.

Tests

  • cargo test -p paimon --features fulltext --lib index_build --no-fail-fast: 142 passed, 2 previously ignored.
  • cargo test -p paimon --lib global_index_build_builder: 54 passed, 1 previously ignored, including the build without the full-text feature.
  • cargo test -p paimon-datafusion --features fulltext --test procedures index --no-fail-fast: 27 passed.
  • cargo +1.98.0 clippy -p paimon -p pypaimon_rust --all-targets --features paimon/fulltext -- -D warnings: passed.
  • cargo fmt --all -- --check and git diff --check: passed.
  • Paired PyPaimon REST tests exercise real prepared full-text and all five vindex formats, both committers, partition conjunction, external placement, source conflicts and Python fast-search reads. Together with existing index-build tests: 153 passed and 19 subtests passed.

API and Format

Replaces the specialized public table factories/types with GlobalIndexBuildBuilder; the Python binding is a parameter/commit-message wrapper around core. The shared type-normalization helper is now named normalize_global_index_type.

Existing index formats and source metadata versions are unchanged. Generic builds now populate the already-supported DEIX source metadata.

Documentation

The new builder documents prepare vs execute, partition conjunction and supported column definitions; the Python stub and benchmark example use the common API.

@leaves12138 leaves12138 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewed 6c30863f, together with apache/paimon#10487 at 7e986c78. No blocking findings.

The common entry point follows Java's type-selected factory model while keeping sorting and specialized writers internal. Ordered composite BTree definitions, type aliases, partition-filter conjunction and per-build shard options are preserved. build() returns unpublished messages; execute() retains the planned-snapshot guard and does not delete files after a failed or uncertain submission. The shared external placement and DEIX source metadata also preserve commit ownership and indexed-column conflict protection.

Independent local validation with Rust 1.94.1 and a freshly rebuilt Python extension:

  • Core with full-text enabled: 4,010 passed, 6 ignored; formatting passed.
  • Core without full-text: 54 relevant tests passed, 1 ignored, including the explicit unsupported-feature path.
  • DataFusion index procedures: 27 passed.
  • Python bindings: 417 passed.
  • Paired REST/index-build suites: 153 passed, 19 subtests passed; 55 Native plans exercised.
  • Related index/search regressions: 119 passed, 19 subtests passed.
  • Additional reviewer tests: 34 passed for empty/all-NULL/sparse text shards, abort/rebuild ownership, effective option overrides and non-indexed-column updates; 3 passed against the previous Rust wheel to confirm early Classic fallback when the new factory is absent.

The real prepared full-text and all five vindex formats were read through existing Python fast-search paths and committed with both committers. Indexed-column changes reject the prepared messages without deleting their files; non-indexed-column changes remain committable.

Scope: Java alignment was checked against source and the DEIX byte contract, not a Java engine or production-storage interoperability run. The real Lumina-library test remains an existing ignore. Python intentionally retains its original nullable-vector construction path to preserve sparse relative row IDs.

@JingsongLi
JingsongLi merged commit 878c33d into apache:main Oct 10, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants