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


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckScoreUsage.java:
##########
@@ -17,31 +17,120 @@
 
 package org.apache.doris.nereids.rules.rewrite;
 
+import org.apache.doris.nereids.StatementContext;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleType;
 import org.apache.doris.nereids.trees.expressions.Alias;
+import org.apache.doris.nereids.trees.expressions.CTEId;
 import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.WindowExpression;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Score;
+import org.apache.doris.nereids.trees.plans.JoinType;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
+import org.apache.doris.nereids.trees.plans.logical.LogicalCTEConsumer;
+import org.apache.doris.nereids.trees.plans.logical.LogicalCTEProducer;
+import org.apache.doris.nereids.trees.plans.logical.LogicalCheckPolicy;
+import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
+import org.apache.doris.nereids.trees.plans.logical.LogicalHaving;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
 import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+import org.apache.doris.nereids.trees.plans.logical.LogicalQualify;
+import org.apache.doris.nereids.trees.plans.logical.LogicalRelation;
+import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint;
+import org.apache.doris.nereids.trees.plans.logical.LogicalSort;
+import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
+import org.apache.doris.nereids.trees.plans.logical.LogicalUnion;
+import org.apache.doris.nereids.trees.plans.logical.LogicalView;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
- * Check score function usage in project and aggregate without proper 
optimization context.
- *
- * This rule ensures that score() function is used only in contexts where it 
can be optimized,
- * requiring WHERE clause with MATCH function, ORDER BY and LIMIT.
+ * Reject score() calls outside a supported scan scoring context.
+ * Aggregates cannot consume raw score() calls.
  */
 public class CheckScoreUsage implements RewriteRuleFactory {
     private static final Logger LOG = 
LogManager.getLogger(CheckScoreUsage.class);
+    private static final String SCORE_CONTEXT_ERROR =
+            "score() function requires WHERE clause with MATCH function, ORDER 
BY and LIMIT for optimization, "
+                    + "or a supported minimum score filter with MATCH or 
SEARCH";
+    private static final String SCORE_FILTER_CONTEXT_ERROR =
+            "score() filter must be in the WHERE clause of a query on one 
table with a MATCH or SEARCH "
+                    + "predicate. It cannot filter the result of an inner, 
cross or full join, an aggregation, "
+                    + "a window or another operator; put the MATCH or SEARCH 
predicate and the score() filter "
+                    + "in a subquery on that table";
+
+    /**
+     * Fail a score() filter whose input combines or recomputes rows. score() 
has no input slot, so
+     * predicate pushdown would treat it as a constant and move it below a 
window, an aggregation
+     * or an inner join, changing the result or filtering another scan. Called 
after analysis,
+     * before any pushdown or CTE inlining.
+     */
+    public static void checkScoreFilterContext(Plan plan, StatementContext 
statementContext) {
+        if (!(plan instanceof LogicalFilter || plan instanceof LogicalHaving 
|| plan instanceof LogicalQualify)) {
+            return;
+        }
+        if (plan.getExpressions().stream().noneMatch(expr -> 
expr.containsType(Score.class))) {

Review Comment:
   [P2] Resolve score aliases before the early context check
   
   The new early return misses score calls behind projected slots. For example, 
using the ANN regression fixture:
   
   ```sql
   SELECT id, rn FROM (
     SELECT id, row_number() OVER (ORDER BY id) AS rn, score() AS s
     FROM test_score_filter_ann WHERE c1 MATCH 'apple'
   ) w WHERE s > 0.5;
   ```
   
   Both analysis checks see `Filter(s > 0.5)` with no raw `Score`. 
`ExtractAndNormalizeWindowExpression` leaves `score() AS s` in a Project above 
Window; `PushDownFilterThroughProject` then substitutes `s` with raw Score, and 
`PushDownFilterThroughWindow` accepts its empty input-slot set:
   
   ```text
   Window(row_number() OVER (ORDER BY id) AS rn)
     Filter(MATCH, score() > 0.5)
       OlapScan
   ```
   
   The outer SELECT omits `s`, so column pruning removes its original 
projection before the late check; the standalone rule binds/removes the score 
filter below Window. Matching id 2 then gets `rn=1` instead of retaining `rn=2`.
   
   This is a distinct alias-expansion bypass of this new guard: the 
raw-score/direct and CTE-window examples in the existing threads are now 
rejected, but this Score is exposed only after both early checks. Resolve 
score-producing aliases during context validation, or stop their expanded 
predicates before they cross row-changing operators, and cover this alias case.



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