github-actions[bot] commented on code in PR #66872:
URL: https://github.com/apache/doris/pull/66872#discussion_r3840617728


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckScoreUsage.java:
##########
@@ -133,31 +133,42 @@ private static void 
checkSelectedIndexPolicyAdmission(Index selectedIndex,
         if (selectedIndex == null) {
             return;
         }
+        boolean isSnii = scan.getTable().getInvertedIndexFileStorageFormat()
+                == TInvertedIndexFileStorageFormat.SNII;
         Map<String, String> properties = selectedIndex.getProperties();
-        if (properties == null
-                || !properties.containsKey(
-                        
InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY)) {
+        String analyzerName = properties == null ? null : properties.get(
+                InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY);
+        if (analyzerName == null) {
+            if (isSnii) {
+                throw nonScoringSniiIndex(selectedIndex);
+            }
             return;
         }
 
-        String analyzerName = properties.get(
-                InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY);
         boolean usesCommonGrams;
         try {
             usesCommonGrams = 
indexPolicyMgr.validateAnalyzerUsesCommonGrams(analyzerName);
         } catch (DdlException e) {
             throw new AnalysisException("score() cannot use inverted index '"
                     + selectedIndex.getIndexName() + "': " + e.getMessage(), 
e);
         }
-        if (usesCommonGrams
-                && scan.getTable().getInvertedIndexFileStorageFormat()
-                        != TInvertedIndexFileStorageFormat.SNII) {
+        if (isSnii && !usesCommonGrams) {

Review Comment:
   [P1] Resolve SEARCH admission with the runtime query type
   
   On a field with both a plain and a CommonGrams index, this can validate the 
wrong physical index:
   
   ```text
   TopN(order by s)
     Project(score() AS s)
       Filter(search('body:EXACT(alpha)'))
         Scan(SNII; idx_keyword(body), idx_cg(body, CommonGrams))
   ```
   
   resolveSelectedInvertedIndex(slot, null) follows OlapTable.getInvertedIndex 
and chooses the analyzed idx_cg, so this condition admits the plan. BE 
deliberately maps EXACT to EQUAL_QUERY, ignores the binding analyzer key for 
equality, and select_best_inverted_index_candidate prefers the untokenized 
STRING_TYPE index; the existing test_search_exact_multi_index.groovy regression 
codifies that routing. Scoring then opens idx_keyword, which lacks SNII scoring 
metadata, and fails after FE admission. Please resolve admission per 
score-bearing SEARCH leaf with the same query-type/index preference as BE, and 
cover EXACT plus ANY/ALL on a multi-index SNII field.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckScoreUsage.java:
##########
@@ -133,31 +133,42 @@ private static void 
checkSelectedIndexPolicyAdmission(Index selectedIndex,
         if (selectedIndex == null) {
             return;
         }
+        boolean isSnii = scan.getTable().getInvertedIndexFileStorageFormat()
+                == TInvertedIndexFileStorageFormat.SNII;
         Map<String, String> properties = selectedIndex.getProperties();
-        if (properties == null
-                || !properties.containsKey(
-                        
InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY)) {
+        String analyzerName = properties == null ? null : properties.get(
+                InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY);
+        if (analyzerName == null) {
+            if (isSnii) {

Review Comment:
   [P1] Check only predicates that contribute to score
   
   This rejects every SNII index encountered in the filter, even when that 
predicate is only a boolean filter. For example:
   
   ```text
   TopN(order by s)
     Project(score() AS s)
       Filter(search('body:ANY(alpha) AND tag:pre*'))
         Scan(SNII; body=CommonGrams, tag=plain index)
   ```
   
   RewriteSearchToSlots binds both fields, so this branch rejects the 
analyzerless tag index. BE scoring deliberately ignores that leaf: 
SearchPredicateCollector returns unless the type is TERM, EXACT, PHRASE, MATCH, 
ANY, or ALL; PREFIX, WILDCARD, REGEXP, RANGE, and LIST remain ordinary filters. 
The direct-MATCH loop has the same problem for a mixed `body MATCH_ANY 'alpha' 
AND tag MATCH_REGEXP 'pre.*'` plan: MatchPredicateCollector emits no scoring 
info for MATCH_REGEXP or MATCH_PHRASE_EDGE. In both cases the score is 
well-defined from body. Please mirror the BE contributor classification for 
both MATCH and SEARCH and add mixed scoring/non-scoring predicate tests.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckScoreUsage.java:
##########
@@ -133,31 +133,42 @@ private static void 
checkSelectedIndexPolicyAdmission(Index selectedIndex,
         if (selectedIndex == null) {
             return;
         }
+        boolean isSnii = scan.getTable().getInvertedIndexFileStorageFormat()
+                == TInvertedIndexFileStorageFormat.SNII;
         Map<String, String> properties = selectedIndex.getProperties();
-        if (properties == null
-                || !properties.containsKey(
-                        
InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY)) {
+        String analyzerName = properties == null ? null : properties.get(
+                InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY);
+        if (analyzerName == null) {
+            if (isSnii) {
+                throw nonScoringSniiIndex(selectedIndex);
+            }
             return;
         }
 
-        String analyzerName = properties.get(
-                InvertedIndexProperties.INVERTED_INDEX_ANALYZER_NAME_KEY);
         boolean usesCommonGrams;
         try {
             usesCommonGrams = 
indexPolicyMgr.validateAnalyzerUsesCommonGrams(analyzerName);
         } catch (DdlException e) {
             throw new AnalysisException("score() cannot use inverted index '"
                     + selectedIndex.getIndexName() + "': " + e.getMessage(), 
e);
         }
-        if (usesCommonGrams
-                && scan.getTable().getInvertedIndexFileStorageFormat()
-                        != TInvertedIndexFileStorageFormat.SNII) {
+        if (isSnii && !usesCommonGrams) {
+            throw nonScoringSniiIndex(selectedIndex);
+        }
+        if (usesCommonGrams && !isSnii) {
             throw new AnalysisException("score() cannot use CommonGrams 
analyzer '"
                     + analyzerName + "' on inverted index '" + 
selectedIndex.getIndexName()
                     + "': CommonGrams scoring is supported only by SNII");
         }
     }
 
+    private static AnalysisException nonScoringSniiIndex(Index selectedIndex) {
+        return new AnalysisException("score() cannot use SNII inverted index '"
+                + selectedIndex.getIndexName()
+                + "': the index does not persist scoring data; SNII scoring 
requires"
+                + " an index created with a CommonGrams analyzer");

Review Comment:
   [P1] Gate on persisted scoring capability, not analyzer type
   
   This treats the current analyzer graph as proof that the index actually 
contains scoring data:
   
   ```text
   TopN(order by s)
     Project(score() AS s)
       Filter(body MATCH_PHRASE 'alpha beta')
         Scan(SNII, CommonGrams policy; a visible segment was written with the 
build switch off)
   ```
   
   validateAnalyzerUsesCommonGrams returns true, but SniiIndexColumnWriter 
snapshots mutable enable_common_grams_index_build and writes the docs/positions 
tier without norms or semantic metadata when it is false. Existing cases in 
test_common_grams_snii.groovy:885-930 and 932-978 construct all-missing and 
mixed CommonGrams segments and fail later with `SNII semantic scoring metadata 
is missing`; legacy or replica-divergent segments have the same shape. 
CommonGrams is therefore necessary, not sufficient. Please gate on a durable 
capability covering every visible segment/replica, or retain only unconditional 
FE rejections and leave persisted-capability admission authoritative in BE. Add 
missing/mixed-segment coverage instead of only mocking the policy boolean.



-- 
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