FANNG1 opened a new pull request, #67039:
URL: https://github.com/apache/doris/pull/67039

   ### What problem does this PR solve?
   
   Issue Number: Part of #66495
   
   Problem Summary:
   
   #66512 gave `vector_search()` end-to-end coverage for all six Lance ANN 
algorithms, but only
   with **Float32 + L2**. Reviewer feedback there was to merge it and follow up 
with the other
   element types, which is what this PR does.
   
   The gap is not only a dependency-compatibility one. #66841 made the FE 
metric-aware: Doris
   plans an indexed split only when the requested metric equals the metric the 
index was built
   with (`LanceScanNode.metricMatches`), and otherwise plans flat splits rather 
than letting
   Lance fall back to brute force silently. Until now the **cosine and dot 
branches of that
   comparison had never run against a real index**, because no non-L2 index 
existed anywhere in
   the fixture. This PR covers them, in both directions.
   
   ### What is changed?
   
   There is no FE or BE production-code change.
   
   #### New indexed tables
   
   One table per remaining metric and per remaining element type, rather than 
the full
   algorithm x element type x metric cross product, so every Doris code path is 
exercised
   without multiplying the committed binary fixture:
   
   | Table | Index | Element type | Metric |
   |---|---|---|---|
   | `vs_ivf_flat_f32_cosine` | IVF_FLAT | Float32 | cosine |
   | `vs_ivf_pq_f32_cosine` | IVF_PQ | Float32 | cosine |
   | `vs_ivf_pq_f32_dot` | IVF_PQ | Float32 | dot |
   | `vs_ivf_flat_f64` | IVF_FLAT | Float64 | l2 |
   | `vs_ivf_flat_f16_cosine` | IVF_FLAT | Float16 | cosine |
   | `vs_ivf_flat_u8` | IVF_FLAT | UInt8 | hamming |
   
   Float16 uses cosine because building a Float16 L2 index does not complete in 
the embedded
   Lance version. UInt8 uses hamming with IVF_FLAT because that is the only 
combination Lance
   accepts for it. Int8 is still absent: Lance has no complete Int8 index build 
path, and
   searching a nullable Int8 column aborts the BE with the Lance version 
`lance-c v0.1.6`
   embeds. The compatibility matrix behind these choices is documented in the 
companion
   doris-website PR.
   
   #### Two new suites
   
   - `test_lance_vector_search_metrics` - the cosine and dot tables. Asserts 
through
     `lanceSearchIndexSegments` in EXPLAIN that a matching metric plans an 
indexed split, and
     that a mismatched metric and an omitted metric both do not. Plus the 
`nprobes=1`
     silent-fallback discriminator per table, and full-probe-equals-flat for 
IVF_FLAT.
   - `test_lance_vector_search_indexed_element_types` - the Float64, Float16 
and UInt8 tables.
     `test_lance_vector_search_element_types` deliberately stays on flat search 
and covers
     query-vector encoding; this is the other half, the same element types read 
through an index.
   
   #### Data shapes
   
   The generator is now driven by data profiles rather than one hardcoded 
shape, because the
   collinear `embedding[j] = (row_id - 1) + j` data the L2 tables use is 
degenerate under the
   new metrics. Measured with the pinned writer:
   
   - under **dot**, every query returns the same highest-norm rows regardless 
of the query;
   - under **cosine**, the row directions converge until the top distances 
collapse to `0.0` and
     the ranking is arbitrary tie-breaking.
   
   So cosine and dot tables use directions from an irrational rotation with an 
independently
   varying norm, verified tie-free and verified to rank *differently* under l2, 
cosine and dot -
   that last property is what lets a suite tell a respected metric from an 
ignored one. UInt8
   uses a thermometer code, which makes Lance's bitwise hamming work out to 
exactly `|a - b|`
   and reproduces the symmetric ladder the L2 tables have.
   
   #### Writer pin
   
   `pylance` moves from 4.0.1 to 7.0.0, the Lance generation the BE reads 
through `lance-c
   v0.1.6`. It was previously pinned to the oldest reader so Spark could read 
the shared
   `__manifest`; that is no longer possible, because on Lance 4 the Float64 and 
UInt8 index
   builds either panic or produce an index whose every search fails. Spark 
compatibility is now
   verified by the regression run rather than guaranteed by the pin.
   
   Rebuilding retrains every index, which moved two discriminator rows - the 
`ef` discriminator
   to row 518 and the UInt8 boundary to row 513. Both are decided by kmeans and 
move on any
   rebuild, so both self-checks now report the rows that still work when they 
fail, instead of
   leaving the next person to search by hand.
   
   ### Test
   
   - Fixture self-check passes for all 12 tables.
   - `external_table_p0/lance`: **12 suites, all passing on a normal golden 
comparison**, not
     only on generation. The run was done against a MinIO bucket with the lance 
prefix cleared
     first, so no stale fixture generation could mask a problem. It includes 
the Spark and REST
     catalog suites that share the Directory Namespace manifest this writer 
produced, which is
     the check that moving the pin did not break `lance-java 4.0.0` as a reader.
   - The goldens reproduce, through Doris, the same rows and distances the 
generator measured
     directly with pylance: Float64 keeps the exact 0, 16, 64, 144, 256 ladder, 
UInt8 gives
     hamming 0, 1, 2, 3, 4, and the cosine tables match to float32 display 
precision.
   
   Existing goldens moved only where the retrained partitions moved: the 
`nprobes=1` boundary
   queries now reach the neighbours on the other side of the edge (rows 254, 
253, 252, 251 where
   they used to be 260, 261, 262, 263). The distance sequence is unchanged, 
because the data is
   symmetric around the boundary row. No suite assertion changed.
   
   ### Release note
   
   None
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to