Repository navigation
Conversation
### Background ANN indexes store vector entries using segment row IDs. Empty arrays can occur in delete rows, but the current writer rejects them as dimension mismatches; simply omitting them would shift HNSW labels and make range-search complements include rows without vectors. Group Commit also needs to reject invalid dimensions before accepting blocks into its background write path. ### What problem does this PR solve? Issue Number: None Related PR: None PR Type: Enhancement Problem Summary: Add an explicit opt-in for empty arrays in ANN-indexed columns while preserving data-file row IDs. Nonempty vectors retain native IVF labels, and HNSW uses IDMap only when a segment contains empty arrays. Approximate distance functions return NULL for empty arrays, including scalar fallback, and sparse-segment TopN uses normal SQL evaluation and sorting to preserve NULL ordering and LIMIT. Existing writes continue to reject empty arrays by default. ### Details - **Change map:** 524 changed production lines and 961 changed test lines; no generated files. The production changes cover writer validation/row IDs and native FAISS persistence, range-search domains, Group Commit validation, and nullable approximate-distance evaluation/materialization. Tests cover writer state, FAISS reload/filtering, reader contracts, expression nullability, and SQL differential checks. - **Before and after:** With the flag disabled, an empty ANN array fails with an actionable error. With it enabled, empty rows remain in the data file but have no ANN entry. Range predicates exclude them on both sides of a comparison; scalar approximate distance returns NULL. Sparse TopN falls back so NULLS FIRST/LAST and limits larger than the vector count remain correct. - **Configs and defaults:** New mutable BE config `enable_ann_index_empty_array=false`. After writing empty arrays, keep it enabled, including across restarts, compaction, index rebuilds, and Group Commit WAL replay. Readers do not consult the flag. - **Impact on existing users:** Dense segments retain the existing native index representation and TopN path. Dense IVF complements do not scan all list IDs. Legacy NULL-coordinate writer behavior is preserved so this change does not reject historical rows during rewrites; scalar distance NULL-input errors remain unchanged. - **Behavior change:** `l2_distance_approximate` and `inner_product_approximate` are nullable in FE and return NULL if either array is empty in scalar evaluation. Nonempty dimension mismatches remain errors. Exact distance functions are unchanged. Sparse-segment TopN trades ANN acceleration for correct SQL NULL handling. - **Compatibility:** Upgrade BEs first, then FEs; enable empty-array writes only after every FE and BE is upgraded. The new BE preserves the non-nullable output layout of plans from old FEs. Once empty arrays have been written, downgrade to a BE without this support is unsupported: native FAISS deserialization alone does not make old complement, HNSW range-search, empty-IVF, or rewrite paths compatible. Disabling the flag does not convert persisted data. New FEs with old BEs are not a supported mixed-version configuration for this change; rolling back before opt-in requires reverting FEs before BEs and cross-version verification. - **Implementation:** All-empty segments persist an empty index without training; complement results retain the required null distance/row-ID pointers. Sparse range domains are derived lazily from FAISS IDs, protected by a mutex, and published only after successful initialization. HNSW range queries translate selectors and returned labels around the child index to preserve derived search parameters with the pinned FAISS version. The FAISS dependency and on-disk filenames are unchanged. ### Testing Passed locally on macOS arm64: - Repository clang-format v16 scripts (`clang-format.sh` and `check-format.sh`) on a scoped snapshot of the 22 modified C++ files. - `bash build-support/check-build-hygiene.sh`. - `git diff --cached --check`. Added/extended tests: - Writer opt-in rejection without partial buffer mutation, cross-batch sparse labels, all-empty finish, and legacy NULL-coordinate writes. - HNSW/IVF/IVF_ON_DISK native reload, selector filtering, both range directions, concurrent domain initialization and IO failure/retry, and the dense-IVF fast path. - Reader-level all-empty range contracts for both metrics and every index type. - Approximate empty-array NULLs, constant query vectors, old-FE result layout, nonempty dimension errors, and unchanged exact-distance behavior; FE nullable expressions. - Group Commit validation and regression coverage for off/sync/async writes. Differential SQL checks compare forced scalar fallback with index execution and cached results, including sparse/all-empty segments and NULL ordering. No handwritten result files. Attempted but blocked before tests ran: - `bash run-be-ut.sh --run --filter='AnnIndexWriterTest.*:AnnIndexReaderTest.*:VectorSearchTest.*:GroupCommitAnnValidationTest.*:FunctionArrayApproximateDistanceTest.*:ExtractQueryVectorTest.*' -j4`. - `bash run-fe-ut.sh --run org.apache.doris.nereids.trees.expressions.functions.scalar.ApproximateDistanceTest`. - `bash run-regression-test.sh -d ann_index_p0 -s ann_empty_array_queries,ann_delete_group_commit`. The environment has no Java/JDK 17 or installed third-party build dependencies. BE/FE compilation, Checkstyle, clang-tidy, and runtime tests have not completed. Compaction/restart/WAL recovery and actual old/new-binary upgrade/downgrade scenarios still need validation. This PR is a draft pending those checks. ### Release note Add opt-in support for empty arrays in ANN-indexed columns through `enable_ann_index_empty_array`, disabled by default. Approximate distances return NULL for empty arrays; sparse segments use scalar TopN evaluation to preserve NULL ordering. Upgrade all FEs and BEs before enabling the flag, and keep it enabled after writing such data. Downgrading to a BE without sparse ANN support after these writes is unsupported. ### Check List (For Author) - Behavior changed: Yes (see Details). - Does this need documentation: Yes; document the BE config, NULL semantics, upgrade order, and downgrade restriction in the ANN user documentation before marking ready. - Pre-submission status: Not ready: draft pending compilation, runtime tests, recovery tests, and cross-version validation. ### AI Disclosure - Tool: OpenAI Codex (GPT-6). - Generated: Code, tests, and this description. - Human review: Design and compatibility constraints discussed with the author; final implementation review pending.
### Background ANN data rows may contain empty arrays after opting in. Query vectors still need valid coordinates and dimensions. ### What problem does this PR solve? Issue Number: None Related PR: apache#70552 (follow-up) PR Type: Bugfix Problem Summary: Empty query vectors were incorrectly treated as NULL distances, and sparse TopN could skip dimension validation when falling back. Only empty data vectors should produce NULL. ### Details - **Frequency:** Queries with empty vectors or wrong dimensions on sparse segments. - **Root cause:** The empty-data semantics were also applied to query arguments, and metadata dimension validation happened after fallback decisions. - **Why existing tests missed it:** The initial tests explicitly accepted empty query vectors and did not cover metadata validation before sparse TopN fallback. - **Fix:** Restore nonempty query extraction, reject empty query arguments in scalar evaluation, and validate TopN dimensions before fallback. Preserve NULL results for empty data vectors and existing NULL-input rejection. - **Other paths and branches:** Cover scalar projection, range predicates, TopN, and a constant query in either argument position. No dependency or protocol change. ### Testing Repository clang-format v16 scripts, build hygiene and git diff checks passed. Targeted BE UT execution was attempted but stopped at the Java check; Java/JDK 17 is unavailable. Updated UT and differential regression coverage have not run. ### Release note Empty ANN data arrays produce NULL approximate distances. Empty, NULL, NULL-coordinate and dimension-mismatched query vectors are rejected. ### Check List (For Author) - Behavior changed: Yes (query validation described above). - Does this need documentation: Covered by the parent PR's documentation plan. - Pre-submission status: Not ready: parent PR remains draft pending builds and runtime verification. ### AI Disclosure - Tool: OpenAI Codex (GPT-6). - Generated: Code, tests and description. - Human review: Query validation semantics confirmed by the author; final implementation review pending.
### Background ANN empty-array support needs scalar fallback to agree with indexed queries. The previous revision only made approximate distances nullable, rejected missing query vectors, and retained a non-nullable result layout for old FEs. ### What problem does this PR solve? Issue Number: None Related PR: None PR Type: Enhancement Problem Summary: Return NULL from all array-distance functions when either vector is NULL or empty, including literals. Preserve filtering, ordering and LIMIT by falling back before FAISS for missing query vectors, and align FE nullability and constant folding with BE evaluation. ### Details - **Change map:** 195 changed production lines and 515 changed test lines; no generated files. Production changes cover shared distance evaluation, FE return types/constant folding, and ANN missing-query fallback. Tests cover functions, query extraction, segment fallback and SQL behavior. - **Before and after:** Empty/NULL query literals no longer fail. Exact and approximate array functions now return nullable FLOAT, including NULL for [] versus []. NULL array elements and mismatched nonempty dimensions remain errors. - **Configs and defaults:** No new configuration in this commit; the existing empty-array ANN write opt-in remains default-off and independent of distance evaluation. - **Impact on existing users:** Plan a coordinated FE/BE upgrade and restart; remove old-FE result-layout adaptation. Nonempty zero-vector behavior and the MAP inner_product overload remain unchanged. - **Behavior change:** Missing queries use scalar TopN/range evaluation without calling FAISS. TopN retains candidate rows and normal SQL NULL ordering and LIMIT. A separate constant-NULL/no-vector-read optimization is not included. ### Testing - Passed repository clang-format v16 scripts, build hygiene and staged diff checks. - Passed Checkstyle 9.3 (the version pinned by fe/pom.xml) on all 11 changed Java files, using the repository configuration and standalone JDK 21. This is a style check, not a JDK 17 compilation or test run. - BE/FE UT and regression runner attempts stopped at the missing JDK 17 prerequisite. Installed BE third-party dependencies are absent. No compilation or runtime-test success is claimed. - Added/updated parameterized distance tests, FE nullable/constant-folding tests, missing-query extraction and SegmentIterator fallback tests, and regression queries. - Regression .out regeneration and clang-tidy after a successful build remain pending. Expected outputs were not handwritten. ### Release note Array distance and similarity functions return NULL for NULL or empty vectors, whether passed as literals or read from data. Missing ANN query vectors fall back to scalar evaluation. Upgrade and restart FE and BE together. ### Check List (For Author) - Behavior changed: Yes (see Details). - Does this need documentation: Yes; update vector-distance NULL semantics and coordinated-upgrade guidance. - Pre-submission status: Not ready: draft pending compilation, runtime tests and regenerated regression outputs. ### AI Disclosure - Tool: OpenAI Codex (GPT-6). - Generated: Code, tests and commit description. - Human review: The author specified the final semantics; final implementation review is pending.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
ANN indexes identify vectors by their row IDs in a segment. Empty arrays have no index entry, so omitting them requires preserving those IDs and excluding missing vectors from range-search complements. Distance expressions also run without an ANN index, including when index training is skipped or a query falls back to a scan.
What problem does this PR solve?
Issue Number: None
Related PR: None
PR Type: Enhancement
Problem Summary:
Allow empty arrays in ANN-indexed columns through an explicit, default-off BE option while preserving segment row IDs. Unify array-distance semantics: NULL and empty vectors produce NULL distances, whether they come from data rows or query literals. Both indexed and scalar query paths handle missing vectors consistently; most of the additional changes cover tests and nullable expression results.
Details
enable_ann_index_empty_array=false, empty ANN arrays still fail writes. With it enabled, empty rows remain in the data file and retain their positions while nonempty vectors are indexed under their data-file row IDs. Range comparisons exclude empty vectors in both directions. NULL or empty query vectors return NULL distances through scalar evaluation instead of entering FAISS.enable_ann_index_empty_array=false, observed during write validation. After persisting empty arrays, keep the flag enabled across restarts, compaction, index rebuilds and WAL replay. Readers do not consult the flag; toggling it does not convert stored data.l1_distance,l2_distance,inner_product,cosine_distance,cosine_similarity,l2_distance_approximateandinner_product_approximatereturn nullable FLOAT. Either whole-array NULL or an empty array yields NULL, including[]versus[]and explicit literals. NULL elements in non-NULL arrays and mismatched nonempty dimensions remain errors. Nonempty zero-vector behavior and the MAP overload ofinner_productare unchanged.Testing
Passed locally on macOS arm64:
bash build-support/check-build-hygiene.sh.git diff --cached --check.Added or extended tests cover:
Attempted this revision but blocked before execution:
run-be-ut.sh --runfor the ANN writer/reader/search, Group Commit, distance, extraction and SegmentIterator suites.run-fe-ut.sh --runforArrayDistanceTest,InnerProductTestandArrayArithmeticTest.run-regression-test.sh --run -d ann_index_p0 -s ann_empty_array_queries,ann_delete_group_commit,cast_string_as_array -forceGenOut.run-regression-test.sh --run -d query_p0/sql_functions/array_functions -s test_array_distance_functions -forceGenOut.The scripts stop at the JDK 17 prerequisite; the available standalone JDK is 21 and installed BE third-party dependencies are also absent. Compilation, UT and regression results are not verified. Clang-tidy is pending a successful BE build and compilation database. Changed regression
.outfiles have not been regenerated; existing snapshots must be refreshed through the runner before this PR is ready. Recovery/compaction and actual old/new-binary compatibility scenarios also remain unverified. No expected results were handwritten.Notes for Reviewers
Source self-review checkpoints:
Release note
Add default-off
enable_ann_index_empty_arraysupport for ANN writes. Array distance and similarity functions return NULL for NULL or empty vectors, including query literals. Missing-query and sparse TopN paths preserve SQL NULL ordering through scalar evaluation. Upgrade and restart all FEs and BEs together; keep the write flag enabled after storing empty arrays, and do not downgrade those data files to an unsupported BE version.Check List (For Author)
AI Disclosure