refactor(table): unify vector search scan and read APIs - #822
Conversation
leaves12138
left a comment
There was a problem hiding this comment.
Reviewed 024fabb, including the shared scan/plan/read contracts, snapshot-scoped result materialization, PK residual/physical-range intersection, ANN/exact filtering, plan reuse, C handle ownership, and Hybrid/DataFusion call sites. One CI-blocking finding is recorded inline; I did not find another concrete blocking correctness issue in the reviewed paths.
Local validation passed: core vector unit tests (452), the four PK integration suites (26), Hybrid builder tests (12), C vector tests (15), DataFusion vector-search unit tests (7), executor tests (11), and cargo fmt --all -- --check. These are targeted suites, not a full workspace/platform matrix. The narrowed local Clippy run fails with the same five diagnostics as the hosted check job.
| enum VectorReadKind { | ||
| DataEvolution(DeVectorRead), | ||
| PrimaryKey(PkVectorRead), | ||
| } |
There was a problem hiding this comment.
[P2] Fix the new Clippy errors so the check job can pass
The current head fails the hosted check job in Clippy, not because of an intermittent runner failure. I reproduced the same five diagnostics locally with cargo clippy -p paimon --offline --features fulltext --lib -- -D warnings:
large_enum_varianthere onVectorReadKind, and onVectorScanWork(vector_scan.rs:50) andVectorScanKind(vector_scan.rs:129). For example, this enum embeds a 1,232-byte PK reader alongside a 24-byte DE reader.too_many_argumentsonBatchVectorRead::new(vector_read.rs:71, 8 arguments).needless_borrowontable: Some(&pinned_table)(de_vector_read.rs:228);pinned_tableis already a reference.
Please address the enum layout warnings (for example by boxing the large variants), remove the redundant borrow, and refactor or narrowly annotate the constructor argument count. Then rerun the workspace Clippy command used by CI. These are errors under the existing -D warnings policy, so passing the runtime tests alone does not make this head pass CI.
leaves12138
left a comment
There was a problem hiding this comment.
Re-reviewed be23031. The previous Clippy blockers are resolved; no additional blocking findings in the six-file follow-up. The large enum variants are boxed, both builder paths still construct and validate the same PlanContext before creating their readers, and the redundant borrow and test casts are removed. Archive comparison confirms all other files are unchanged from the reviewed head.
Re-ran locally: core vector unit tests (452), the four PK integration suites (26), C vector tests (15), and formatting; all passed. Clippy also passes locally for all non-Python workspace targets with fulltext,vortex and -D warnings. The full local workspace attempt was blocked by the installed Python distribution lacking a shared library, so I additionally checked the hosted check job: its full-workspace, all-targets Clippy command and formatting both passed on this exact commit.
This approval does not imply that the complete hosted platform/integration matrix has finished.
…em-table * upstream/main: feat(datafusion): support ANALYZE TABLE on catalog-managed format tables (apache#815) refactor(table): unify vector search scan and read APIs (apache#822) fix(rest): sign the query string the client actually sends (apache#821) feat(datafusion): add MSCK REPAIR TABLE for catalog-managed format tables (apache#817) feat(table): execute a primary-key vector search over engine-planned splits (apache#771) feat(datafusion): add SHOW, ADD and DROP PARTITION for catalog-managed format tables (apache#816) feat(table): read the registered partitions of a catalog-managed format table (apache#814) fix: report unsupported time travel instead of returning current data (apache#753) fix(file_index): skip pruning for narrowing integer schema changes (apache#806) fix(c): align append vector filter with core behavior (apache#793) fix(table): skip staging files and list format table partitions concurrently (apache#813) feat(rest): add partition registration, lookup and statistics APIs (apache#812) fix(datafusion): keep format table partition columns out of decoder filters (apache#811) fix(read): null-fill nested fields a data file predates (apache#805) fix(scan): prune NOT IN predicates using file stats (apache#795) fix(spec): accept the legacy first_not_null_value aggregate name (apache#794) fix(table): check batch arity instead of asserting it in debug builds (apache#801) fix(vindex): bound a deletion-vector position by its own source file (apache#802) fix(lumina): decide on the index size before parsing the metric (apache#803) # Conflicts: # crates/integrations/datafusion/src/physical_plan/scan.rs
Purpose
Vector search planning, DE/PK execution, and row materialization were concentrated in
vector_search_builder.rs, with separate result and execution paths for primary-key tables. This change exposes a shared Scan → Plan → Read flow, following the Java API structure, so native and externally planned searches use the same readers.Related: #771.
Brief change log
Separate the single-query and batch builders, DE/PK scanners and readers, query validation, result reads, and their tests into focused modules.
Introduce common
VectorScan,VectorScanPlan,VectorRead, andBatchVectorReadAPIs. Readers own their configuration, and plans can be reused across queries without replanning.Unify DE global row IDs and PK physical positions under a snapshot-scoped
SearchResult, with projected row materialization throughnew_read_builder(). Update Hybrid and DataFusion callers.Move Java bucket-split byte decoding to a standalone C API. Construct a common plan from decoded split handles and execute it through the shared C reader, preserving supplied snapshots, files, and row ranges.
Align PK row filtering with Java
rowRangesByFile: replaceFileRowSelectionwith merged per-file ranges, coalesce residual matches during reads, and use ranges in both ANN and exact search.Tests
cargo test -p paimon --offline --features fulltext --lib vector).-Wall -Wextra -Werror; compiled the Java serializer example withjavac.git diff --checkpassed.Regression coverage includes residual-range coalescing without bridging gaps, compact inclusive range intersection, the shared ANN mask size bound, plan reuse across single and batch readers, handle lifetimes, plan/reader context mismatches, invalid C inputs, and reading Java-planned PK splits after removing the index manifest.
API and Format
This intentionally changes Rust vector-search APIs: builders return the common
SearchResult, and row reads are configured from that result. The bucket-specific Rust execution entry and Cpaimon_vector_search_builder_execute_read_for_bucket_splitsentry are removed in favor of separate decoding, plan construction, and reading. The ordinary Cpaimon_vector_search_builder_execute_readremains a local convenience operation.No persisted table or split format changes. The standalone decoder accepts Java's versioned
PKVSPLITformat; Java object-stream envelopes and serialized DE index/raw splits are not supported. DE uses the common native scan/plan/read API.Documentation
Extend
docs/src/c-binding.mdwith the shared vector API and a complete Java-to-C example covering split serialization, table metadata, scalar residuals, Arrow ownership, cleanup, plan reuse, and distributed Top-K merging.