Skip to content

[fix](inverted index) Add a norms index property and a BE config to skip norms on variant paths - #68039

Open
eldenmoon wants to merge 6 commits into
apache:masterfrom
eldenmoon:fix-variant-subcolumn-index-norms
Open

eldenmoon wants to merge 6 commits into
apache:masterfrom
eldenmoon:fix-variant-subcolumn-index-norms

Conversation

@eldenmoon

@eldenmoon eldenmoon commented Sep 15, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Problem Summary:

An inverted index on a VARIANT column is copied to every extracted subcolumn, so a segment holds one
copy of it per path. Since #53980 every analyzed index calls setOmitNorms(false), and CLucene writes
norms densely: 12 header bytes plus one byte per segment row for every indexed field, including
the rows that hold no value for that field. For a VARIANT column that cost is multiplied by the
number of paths.

On a real table (~1400 paths, 7 non-BKD indexes per path) a single base-compacted segment held 9891
.nrm files of 4,055,884 bytes each: 37.36 GiB of norms out of a 38.47 GiB .idx, 97.1%.
Segments written before the upgrade had no .nrm at all, and the non-norms bytes had not grown.

Reproduced end to end on 1M rows / 1000 paths / 11 field_pattern indexes, by loading with 3.1 and
then upgrading the same data in place to 4.1:

index size after full compaction .nrm
3.1 99.6 MiB none
4.1, same data 934.1 MiB 875 files x 1,000,012 B = 834.5 MiB

9.4x, and the norms are the whole difference. A/B on the same data: norms on 457.3 MiB vs norms
off 99.6 MiB (4.6x), with identical MATCH row counts and sums.

What this PR changes

This PR gives operators a way to reclaim that space without changing what anyone gets by default,
and applies it the same way to the CLucene formats (V2/V3) and to SNII.

  1. A norms index property. An analyzed index writes norms unless it sets "norms" = "false",
    on a VARIANT path exactly as on an ordinary column. A subcolumn copy inherits the properties of
    the index it came from, so the property on a whole-column VARIANT index also settles every one of
    its subcolumn copies.
  2. A mutable BE config inverted_index_skip_norms_for_variant, off by default. Turning it on
    drops norms for every index on a VARIANT path (an index declared with a field_pattern, or the
    copy an extracted subcolumn inherits, which carries the path as its index suffix), whatever that
    index's property says, so a cluster hit by the size regression can recover the space without
    rewriting its index definitions.
  3. One policy function. should_write_index_norms(const TabletIndex&) holds the rule, and the
    three places that decide whether norms get written all call it: the CLucene writer, the SNII
    writer, and SNII direct compaction. SNII direct compaction rebuilds norms from the merged postings
    rather than copying them; the other SNII compaction path rebuilds the index through the SNII
    writer.
  4. BM25 scoring needs norms from every segment it reads, in both formats. MATCH filtering is
    unaffected; a query that computes score() on an analyzed index fails with
    INVERTED_INDEX_NOT_SUPPORTED when any segment of the field has no norms.
    • SNII already worked this way (resolve_snii_scoring_segment); its message now names the
      property and the config instead of suggesting that compaction will bring the norms back.
    • CLucene did not. It keeps a field's token count in the .nrm header, and a row without norms
      reads the fake norm encodeNorm(0), i.e. length 0. With no segment carrying norms, avgdl was
      0 and score() came out NaN. With only some segments carrying norms, as while the config is
      being turned on, avgdl stayed positive and the rows without norms ranked as the shortest
      possible documents, above otherwise identical rows. CollectionStatistics now refuses such a
      segment before any score is computed. An index that is not analyzed never writes norms and is
      collected as before, so SEARCH scoring over keyword fields is unchanged.

Compatibility

  • Defaults are unchanged: norms are still written everywhere unless someone opts out, and an index
    that has norms scores exactly as before.
  • No storage format change.
  • Turning the config on, or setting "norms" = "false", is for indexes that are never ranked with
    score(). For such an index, score() fails as soon as one segment without norms exists.
  • A table upgraded from a version that did not write norms (before 4.0) now fails score() on its
    analyzed indexes until compaction has rewritten the old segments, where it used to return NaN or
    skewed scores.
  • Change the property or the config only after every BE runs this version.

Release note

Added the norms inverted index property and the BE config inverted_index_skip_norms_for_variant
(off by default, mutable), which drops BM25 norms for inverted indexes on VARIANT paths and can cut
the index size of a VARIANT column with many indexed paths by several times. Both apply to the V2,
V3 and SNII index storage formats. A query that computes score() on an analyzed index now fails
when a segment it reads has no norms, instead of returning NaN or inconsistent scores.

Check List (For Author)

  • Test: Unit Test / Regression test
    • be/test/storage/segment/inverted_index_writer_test.cpp: NormsFollowIndexNormsProperty
    • be/test/storage/index/snii_writer_test.cpp: SniiWriterNorms.WritesNormsFollowSharedNormsPolicy
    • be/test/storage/index/snii/compaction/snii_compaction_eligibility_test.cpp:
      DestinationWritesNormsFollowSharedNormsPolicy
    • be/test/storage/index/inverted/similarity/collection_statistics_test.cpp:
      LegacyV3RejectsSegmentWrittenWithoutNorms (alone and next to a segment with norms),
      LegacyV3KeywordIndexWithoutNormsIsStillCollected, and the existing SNII rejection tests
    • fe/fe-core/src/test/java/org/apache/doris/analysis/InvertedIndexPropertiesTest.java
    • Regression: inverted_index_p0/test_variant_subcolumn_index_norms (checks the .nrm files)
      and inverted_index_p0/storage_format/test_storage_format_snii_norms (reads norms off the
      scores): MATCH still filters, score() fails without norms, including on a mixed-generation
      table. Both are nonConcurrent, since they flip the BE config. Also rerun:
      test_bm25_score_variant, test_omit_norms, test_search_score_topn_predicates,
      test_search_score_cache, test_search_score_topn_delete_predicate,
      test_storage_format_snii
  • Behavior changed: No for defaults. score() on an analyzed index with a segment that has no norms
    now fails instead of returning NaN or skewed scores.
  • Does this need documentation: Yes ([doc](inverted-index) Document the norms index property and its VARIANT default doris-website#4146)

🤖 Generated with Claude Code

### What problem does this PR solve?

Issue Number: None

Related PR: apache#53980, apache#60722

Problem Summary:

A VARIANT column with many sparse paths indexed by analyzed field_pattern inverted indexes can grow its index size by about 10x after compaction.

Root cause: since apache#53980, InvertedIndexColumnWriter::create_field enables CLucene norms. CLucene's DocumentsWriter::writeNorms stores one byte per document and fills documents without a value with defaultNorm, so every .nrm file is exactly as long as the segment has rows, however sparse the column is. Each extracted variant subcolumn gets its own index, so a segment pays rows * indexed paths * analyzed indexes bytes of norms. apache#60722 removed norms only for non-tokenized indexes.

Reproduction: 1M rows with 1000 typed sparse paths and 11 field_pattern indexes (3 analyzed), loaded on 3.1 and then fully compacted.
- Compacted on 3.1: .idx 99.6 MiB, no .nrm.
- Compacted after an in-place upgrade to 4.1: .idx 934.1 MiB (9.4x). 875 .nrm files of 1,000,012 bytes each account for 834.5 MiB; the rest is 99.3 MiB.

Fix: analyzed indexes on variant subcolumns (non-empty index suffix) no longer write norms. The mutable BE config inverted_index_write_norms_for_variant_subcolumn (default false) restores them. Indexes on ordinary columns are unchanged.

Without norms, BM25 scores used to become NaN: CLucene keeps a field's token count in the .nrm header, so sumTotalTermFreq() is empty, avgdl is 0, and BM25Similarity::compute_tf_cache divides 0 by 0. This already hit any norm-less segment. compute_tf_cache now skips length normalization when avgdl is 0, so scores stay finite and depend on term frequency and idf only.

With 1M rows compacted on this build, the norms switch off shrinks .idx from 457.3 MiB (357.6 MiB of norms) to 99.6 MiB, and MATCH queries return the same rows.

### Release note

Analyzed inverted indexes on variant subcolumns no longer write BM25 norms, which removes index bloat for variant columns with many sparse indexed paths. BM25 score() on variant subcolumns no longer applies document-length normalization; set BE config inverted_index_write_norms_for_variant_subcolumn=true to keep norms.

### Check List (For Author)

- Test:
    - Unit Test: BM25SimilarityTest.* and InvertedIndexWriterTest.* (34 tests, including the new ZeroAvgDlScoresWithoutLengthNorm and NormsFileSkippedForVariantSubcolumn)
    - Regression test: inverted_index_p0 test_variant_subcolumn_index_norms (new), test_bm25_score_variant, test_omit_norms
    - Manual test: 3.1 -> 4.1 upgrade reproduction, and a norms on/off comparison with BM25 score checks on this build
- Behavior changed: Yes. BM25 scores on variant subcolumn indexes no longer use length normalization by default.
- Does this need documentation: No

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

### What problem does this PR solve?

Issue Number: None

Related PR: apache#53980, apache#60722

Problem Summary:

The previous commit skipped norms for variant subcolumn indexes behind a BE config. Elasticsearch controls norms per field instead: `norms` is a mapping parameter, true by default for text and false for keyword, and a dynamic template can turn it off for a whole family of dynamically mapped fields. A Doris variant path is the equivalent of a dynamically mapped field, so the switch belongs on the index rather than on the BE.

This commit replaces the config with an inverted index property:

- PROPERTIES("norms" = "true" | "false") on the index.
- The default is false when the index is on a variant path: a field_pattern index, or the copy inherited by one extracted subcolumn, which carries the path as its index suffix.
- The default is true otherwise, so analyzed indexes on ordinary columns keep their norms.

FE accepts the key and rejects any value other than true or false. BE reads it in InvertedIndexColumnWriter::create_field through get_index_norms_from_properties, so the decision is made per index instead of per process, and one table can keep norms on the paths that need scoring while dropping them elsewhere.

### Release note

Inverted indexes accept a new "norms" property. Analyzed indexes on variant paths no longer write BM25 norms by default; PROPERTIES("norms" = "true") keeps them for one index, and "norms" = "false" drops them for an ordinary column.

### Check List (For Author)

- Test:
    - Unit Test: BE BM25SimilarityTest.* and InvertedIndexWriterTest.*, 34 tests passed, including NormsFollowIndexNormsProperty which covers a subcolumn index by default, a subcolumn index with norms = true, a field_pattern index by default, and an ordinary column with norms = false; FE InvertedIndexPropertiesTest, 51 tests passed, including the accepted and rejected property values
    - Regression test: inverted_index_p0 test_variant_subcolumn_index_norms now asserts norms per index suffix (ordinary column keeps them, s_* paths drop them, a t_* pattern index with norms = true keeps them); test_bm25_score_variant and test_omit_norms pass
- Behavior changed: Yes, the BE config from the previous commit is gone and the default now lives on the index.
- Does this need documentation: Yes, the inverted index property list needs the new key (doc PR to follow)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eldenmoon eldenmoon changed the title [fix](inverted index) Skip BM25 norms for variant subcolumn indexes [fix](inverted index) Add a norms index property and skip norms on variant path indexes Sep 16, 2026
@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (4/4) 🎉
Increment coverage report
Complete coverage report

…s test

### What problem does this PR solve?

Problem Summary: The norms regression test only covered indexes declared with a
field_pattern. An inverted index built on a VARIANT column without a field_pattern
is copied to every extracted subcolumn, and that copy carries the properties of the
index it was copied from, so the `norms` property on the parent index decides the
behaviour of all of its subcolumn copies. Add two such indexes to the test, one
taking the default and one asking for norms back, so the inherited path is covered
as well:

  norms by index suffix: [:true, v.s_host:false, v.s_note:false, v.t_note:true,
                          vd.a_host:false, vd.other:false, vn.b_host:true, vn.other:true]

### Release note

None

### Check List (For Author)

- Test: Regression test
    - regression-test/suites/inverted_index_p0/test_variant_subcolumn_index_norms.groovy
- Behavior changed: No
- Does this need documentation: No

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

### What problem does this PR solve?

Problem Summary: The "norms" property did not mean the same thing on every index. An analyzed index
on a variant path defaulted to writing no norms while an analyzed index on any other column defaulted
to writing them, so the default came from the shape of the index and the property only corrected it.
That also changed how variant path indexes rank, for every user, as soon as the fix landed.

Give the property one meaning everywhere -- an analyzed index writes norms unless the property says
otherwise, on a variant path as on an ordinary column -- and move the variant skip into the new
mutable BE config inverted_index_skip_norms_for_variant, which is off by default. Turning it on drops
norms for every index on a variant path (an index declared with a field_pattern, or the copy that
each extracted subcolumn inherits from it) whatever that index's property says, so a cluster that
cares about the space can reclaim it without rewriting its index definitions, and a cluster that
cares about ranking keeps what it has.

Default behaviour therefore matches the state before this PR: norms are written everywhere.

### Release note

Added the BE config inverted_index_skip_norms_for_variant (off by default, mutable). Turning it on
drops BM25 norms for every inverted index on a VARIANT path, whatever the index's "norms" property
says.

### Check List (For Author)

- Test: Unit Test / Regression test
    - be/test/storage/segment/inverted_index_writer_test.cpp: NormsFollowIndexNormsProperty covers
      the default and the property in both directions on an ordinary column, a variant subcolumn and
      a field_pattern index, and then the config dropping norms for variant path indexes (including
      one that sets "norms" = "true") while leaving an ordinary column index alone
      (InvertedIndexWriterTest.*: 18 passed)
    - regression-test/suites/inverted_index_p0/test_variant_subcolumn_index_norms.groovy: the
      default and "norms" = "false" on field_pattern and whole-column VARIANT indexes, plus a
      setBeConfigTemporary case proving the config takes effect without a restart; the .out was
      regenerated because variant paths now keep norms, so BM25 length normalization changes those
      scores
    - test_bm25_score_variant and test_omit_norms rerun on the same build
- Behavior changed: No (defaults unchanged; the variant skip is opt-in)
- Does this need documentation: Yes (apache/doris-website#4146)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eldenmoon eldenmoon changed the title [fix](inverted index) Add a norms index property and skip norms on variant path indexes [fix](inverted index) Add a norms index property and a BE config to skip norms on variant paths Sep 16, 2026
@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

@eldenmoon

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review summary

Request changes. The fresh V2/V3 writer path and the all-normless BM25 fallback are useful, but the patch still mis-ranks mixed normed/normless generations and silently accepts a norms policy that SNII ignores. The config-changing regression suite also needs isolation, and the config's nearest documentation states the opposite property precedence.

Critical checkpoint conclusions

  • Goal and proof: Partially achieved for fresh CLucene V2/V3 writes and an entirely normless collection. Mixed generations and SNII prevent the feature from being correct end to end.
  • Scope and clarity: The code is otherwise focused and reuses the existing index-property map and config machinery.
  • Concurrency: No new production lock or shared-object lifecycle was introduced. The regression suite itself races other normal-pool suites because it mutates every BE without the required nonConcurrent group (inline comment).
  • Lifecycle: Forward/reverse config transitions and rolling writers can mix norm-bearing and normless segments; collection-wide statistics then apply false length normalization (inline comment). The suspected direct-compaction gap was traced and dismissed because inherited VARIANT indexes retain the root VARIANT UID and fail the slice-type fast-compaction gate.
  • Configuration: The mutable config is observed by subsequent CLucene field creation, but its comment contradicts the implemented and tested precedence over norms=true (inline comment).
  • Compatibility and persistence: The default preserves existing behavior and the property persists through the existing generic metadata map, with no new FE-BE protocol or EditLog field. Rolling/config-transition compatibility is not correct because of mixed-generation scoring.
  • Parallel paths: SNII fresh writes, raw rebuilds, and direct compaction ignore both controls even though FE accepts the property; SNII scoring also requires norms today (inline comment).
  • Conditions and error handling: FE's lowercase boolean validation and BE's default-true parsing agree. The new avgdl <= 0 condition is too narrow for a mixed collection; no separate unchecked-Status or exception-boundary regression was found.
  • Tests and results: BE, FE, and ordered regression coverage was added, but it covers fresh/all-normless behavior only; mixed-generation and SNII cases are absent, and the global-config suite is not isolated. This was a static-only review: no local build or test was run under the review contract.
  • Observability: No new metric or log is required for this local policy; the remaining semantic failures should be covered deterministically by tests.
  • Transactions, data writes, and failure handling: No transaction/failover protocol changes were introduced, and index files retain the existing writer lifecycle. No distinct crash/leak/atomicity defect was found.
  • FE-BE variable propagation: No new RPC field is needed because properties use the existing map; CLucene consumes it, while the missing SNII consumption is called out.
  • Memory, nullability, and performance: No new ownership or nullable-column path was introduced. The cache fill is bounded by the existing table. The intended one-byte-per-row-per-path saving is valid; no separate hot-path regression was found.
  • Other issues: The duplicated stale config comment and test preamble should be corrected together with the inline documentation finding.

No additional user focus was supplied. The review converged after round 2; the final sweep covered all 13 changed files and left no unresolved candidate.

Comment thread be/src/common/config.cpp Outdated
// CLucene keeps a field's token count in its .nrm header, so avgdl is 0 when no segment of the
// field stores norms (e.g. variant subcolumn indexes). Every document then has an unknown length:
// score without length normalization instead of computing 0 / 0.
if (_avgdl <= 0.0F) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P1] Handle mixed normed and normless segments

This fallback runs only when the collection-wide avgdl is zero. During the supported transition, old segments still have norms while new ones omit them: collection statistics count documents from both but add zero tokens for the normless segment, so any old segment keeps avgdl > 0. Both scoring paths then feed a default 0/1 norm for the normless rows into this positive-avgdl cache, treating them as extremely short documents and boosting them over otherwise identical old rows. Please track missing norms and apply one consistent policy to the whole mixed collection (or per segment), and add a mixed-generation scoring test.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

throw exception

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (4/4) 🎉
Increment coverage report
Complete coverage report

…s without norms

### What problem does this PR solve?

Problem Summary: The "norms" index property and inverted_index_skip_norms_for_variant only reached
the CLucene writer. SNII decided on its own: its writer set _writes_norms from the analyzer and the
positions flag, and its direct compaction from the analyzer alone, so on a SNII table both knobs
were silently ignored. SNII scoring also rejected any segment without norms, so it could not have
honoured them anyway.

- Move the rule into one function, should_write_index_norms(const TabletIndex&), and call it from
  the CLucene writer, the SNII writer and SNII direct compaction. SNII direct compaction rebuilds
  norms from the merged postings, so sources with and without norms merge correctly; the other SNII
  compaction path goes through the SNII writer.
- Let SNII score a segment without norms. SNII keeps the token count in its stats block, so avgdl
  stays correct. SniiStatsProvider::encoded_norm now returns std::nullopt for such a segment, and
  ScorerContext::score scores that document as if its length were avgdl, the same length-neutral
  form the CLucene BM25 fix uses. A document with a norm goes through the same arithmetic as
  before. resolve_snii_scoring_segment no longer takes has_norms.
- Mark both norms regression suites nonConcurrent, since they flip a BE config.

### Release note

The "norms" inverted index property and the BE config inverted_index_skip_norms_for_variant now
also apply to the SNII index storage format, and SNII scoring no longer fails on a segment written
without norms.

### Check List (For Author)

- Test: Unit Test / Regression test
    - SniiWriterNorms.WritesNormsFollowSharedNormsPolicy,
      SniiCompactionEligibilityTest.DestinationWritesNormsFollowSharedNormsPolicy,
      SniiScoringQuery.IndexWithoutNormsScoresWithoutLengthNormalization,
      CollectionStatisticsTest.SniiScoringAdmitsSegmentWithoutNorms
    - regression inverted_index_p0/storage_format/test_storage_format_snii_norms (new), plus
      test_variant_subcolumn_index_norms, test_bm25_score_variant, test_omit_norms and
      test_storage_format_snii
- Behavior changed: Yes. A SNII segment without norms is now scored without length normalization
  instead of failing the query.
- Does this need documentation: Yes (apache/doris-website#4146)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.21% (34340/45058)
Line Coverage 61.10% (385372/630725)
Region Coverage 57.54% (324655/564261)
Branch Coverage 58.27% (147721/253503)

### What problem does this PR solve?

Problem Summary: The previous commits of this PR let an analyzed index be written without norms
("norms" = "false", or inverted_index_skip_norms_for_variant on a variant path), and scored such
an index without length normalization. That left two problems:

- CLucene keeps a field's token count in its .nrm header. A segment without norms adds no tokens
  but still adds documents, and its rows read the fake norm encodeNorm(0), i.e. length 0. When some
  segments of a field have norms and others do not, as while the config is being turned on, avgdl
  stays positive, the zero-avgdl fallback never runs, and the rows without norms rank as the
  shortest possible documents, above otherwise identical rows.
- SNII was changed to score such segments too, which made the two formats and the transition
  harder to reason about.

Follow what SNII already did: BM25 scoring needs norms from every segment it reads.

- CollectionStatistics now refuses an analyzed CLucene segment whose field has no norms with
  INVERTED_INDEX_NOT_SUPPORTED, before any score is computed, so a collection with some or all
  segments lacking norms fails the score() query instead of ranking inconsistently. An index that
  is not analyzed never writes norms and is collected as before, so SEARCH scoring over keyword
  fields is unchanged.
- The zero-avgdl fallback in BM25Similarity is dropped: with the refusal it can no longer be reached
  by an analyzed index.
- SNII scoring is back to rejecting segments without norms (resolve_snii_scoring_segment,
  SniiStatsProvider::encoded_norm, ScorerContext::score are as on master). Its message now names
  the property and the config instead of suggesting that compaction will add the norms back.
- The writer side is unchanged: should_write_index_norms still decides for the CLucene writer, the
  SNII writer and SNII direct compaction.
- Fix the config comment, which still said the property could override the config.

MATCH filtering is not affected; only queries that compute score() need norms.

### Release note

A query that computes score() on an analyzed inverted index now fails when a segment it reads was
written without norms ("norms" = "false", inverted_index_skip_norms_for_variant, or a segment
written before norms were supported), instead of returning NaN or inconsistent scores.

### Check List (For Author)

- Test: Unit Test / Regression test
    - CollectionStatisticsTest.LegacyV3RejectsSegmentWrittenWithoutNorms (alone and mixed with a
      segment that has norms), CollectionStatisticsTest.LegacyV3KeywordIndexWithoutNormsIsStillCollected
    - regression test_variant_subcolumn_index_norms and test_storage_format_snii_norms: MATCH still
      filters, score() fails on indexes without norms and on a mixed-generation table; plus
      test_bm25_score_variant, test_omit_norms, test_search_score_topn_predicates,
      test_search_score_cache, test_search_score_topn_delete_predicate and test_storage_format_snii
- Behavior changed: Yes. score() on an analyzed index with a segment that has no norms fails
  instead of returning NaN or skewed scores.
- Does this need documentation: Yes (apache/doris-website#4146)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 2.02% (2/99) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (4/4) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 63.07% (29357/46545)
Line Coverage 48.01% (306391/638161)
Region Coverage 43.69% (247589/566720)
Branch Coverage 45.23% (115052/254345)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 50.00% (2/4) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.20% (34346/45072)
Line Coverage 61.09% (385390/630905)
Region Coverage 57.50% (324587/564479)
Branch Coverage 58.25% (147719/253574)

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 16884 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 6d36303905033dcc1dc72250ccd44402f972e2a7, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17606	3059	3047	3047
q2	2159	262	222	222
q3	10176	945	534	534
q4	4677	256	204	204
q5	7665	564	381	381
q6	144	123	95	95
q7	529	505	387	387
q8	9235	881	966	881
q9	3545	2393	2386	2386
q10	6506	860	710	710
q11	397	202	193	193
q12	630	267	206	206
q13	18098	1530	1162	1162
q14	168	149	143	143
q15	q16	445	398	370	370
q17	1350	897	846	846
q18	3128	2254	2248	2248
q19	1275	901	753	753
q20	377	282	206	206
q21	5673	1680	1913	1680
q22	333	270	230	230
Total cold run time: 94116 ms
Total hot run time: 16884 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3443	3331	3356	3331
q2	504	407	374	374
q3	2229	2346	2294	2294
q4	1184	1169	900	900
q5	2188	2133	2126	2126
q6	165	118	92	92
q7	1039	911	853	853
q8	1586	1387	1390	1387
q9	3146	3106	3098	3098
q10	1893	1857	1656	1656
q11	350	271	248	248
q12	456	436	343	343
q13	1492	1555	1173	1173
q14	174	183	158	158
q15	q16	396	403	363	363
q17	3634	3309	3215	3215
q18	4856	4427	4712	4427
q19	962	916	868	868
q20	1020	974	832	832
q21	3813	3265	3218	3218
q22	389	344	326	326
Total cold run time: 34919 ms
Total hot run time: 31282 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 82089 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 6d36303905033dcc1dc72250ccd44402f972e2a7, data reload: false

query5	4269	425	333	333
query6	374	133	123	123
query7	4970	424	227	227
query8	291	122	116	116
query9	8701	2917	2878	2878
query10	392	226	187	187
query11	5386	1041	907	907
query12	120	72	70	70
query13	1191	446	318	318
query14	6004	2211	2091	2091
query14_1	1964	1961	1967	1961
query15	175	116	115	115
query16	904	367	353	353
query17	784	444	357	357
query18	2326	336	233	233
query19	160	137	104	104
query20	72	69	72	69
query21	196	102	88	88
query22	5592	5512	5351	5351
query23	6533	6281	6171	6171
query23_1	6078	6019	6081	6019
query24	7275	1080	766	766
query24_1	768	800	790	790
query25	417	298	255	255
query26	1221	233	134	134
query27	2778	423	259	259
query28	4700	1540	1519	1519
query29	902	417	323	323
query30	252	153	131	131
query31	814	395	334	334
query32	125	70	68	68
query33	448	211	171	171
query34	998	816	508	508
query35	410	384	339	339
query36	577	578	555	555
query37	121	79	73	73
query38	1000	857	864	857
query39	491	471	468	468
query39_1	467	488	459	459
query40	197	88	75	75
query41	55	54	61	54
query42	74	71	72	71
query43	246	244	217	217
query44	994	534	547	534
query45	105	108	97	97
query46	808	829	536	536
query47	757	754	714	714
query48	310	297	218	218
query49	542	234	178	178
query50	785	269	200	200
query51	8288	8190	8051	8051
query52	70	69	65	65
query53	193	199	142	142
query54	221	177	162	162
query55	76	63	60	60
query56	192	167	152	152
query57	809	672	614	614
query58	205	158	162	158
query59	1227	1251	1088	1088
query60	266	170	170	170
query61	114	114	105	105
query62	351	219	181	181
query63	173	148	143	143
query64	2625	682	569	569
query65	1669	1622	1579	1579
query66	1885	279	232	232
query67	9988	9590	9521	9521
query68	3013	1209	771	771
query69	373	224	206	206
query70	688	621	587	587
query71	258	189	166	166
query72	2371	1641	1471	1471
query73	657	624	354	354
query74	2014	1238	1138	1138
query75	1197	1101	965	965
query76	2386	721	524	524
query77	261	257	200	200
query78	3981	3823	3236	3236
query79	2280	810	624	624
query80	1547	354	276	276
query81	495	154	133	133
query82	620	122	98	98
query83	275	215	191	191
query84	298	109	85	85
query85	759	339	272	272
query86	380	181	179	179
query87	1037	974	900	900
query88	2786	2124	2109	2109
query89	306	194	176	176
query90	1998	130	128	128
query91	128	112	92	92
query92	80	62	69	62
query93	1415	1096	706	706
query94	622	248	213	213
query95	510	255	295	255
query96	835	588	278	278
query97	1109	1045	1001	1001
query98	158	141	128	128
query99	414	347	310	310
Total cold run time: 178130 ms
Total hot run time: 82089 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.74 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 6d36303905033dcc1dc72250ccd44402f972e2a7, data reload: false

query1	0.01	0.01	0.01
query2	0.08	0.03	0.03
query3	0.25	0.11	0.12
query4	1.61	0.09	0.10
query5	0.17	0.16	0.15
query6	1.26	0.69	0.68
query7	0.04	0.01	0.00
query8	0.04	0.02	0.02
query9	0.29	0.22	0.22
query10	0.35	0.36	0.34
query11	0.16	0.12	0.12
query12	0.14	0.12	0.13
query13	0.30	0.31	0.31
query14	0.47	0.46	0.45
query15	0.38	0.35	0.36
query16	0.23	0.24	0.23
query17	0.69	0.73	0.68
query18	0.18	0.18	0.17
query19	1.10	1.23	1.22
query20	0.01	0.02	0.02
query21	15.46	0.15	0.11
query22	5.10	0.04	0.04
query23	16.18	0.25	0.09
query24	3.05	0.31	0.25
query25	0.12	0.05	0.04
query26	0.79	0.16	0.13
query27	0.03	0.03	0.03
query28	3.63	0.55	0.28
query29	12.46	3.20	2.58
query30	0.26	0.10	0.12
query31	2.76	0.38	0.18
query32	3.52	0.33	0.24
query33	1.38	1.38	1.60
query34	15.37	2.18	1.78
query35	1.78	1.76	1.68
query36	0.47	0.30	0.28
query37	0.07	0.04	0.04
query38	0.04	0.03	0.03
query39	0.03	0.02	0.02
query40	0.12	0.08	0.07
query41	0.08	0.02	0.02
query42	0.03	0.02	0.03
query43	0.03	0.03	0.03
Total cold run time: 90.52 s
Total hot run time: 14.74 s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants