xiangfu0 commented on code in PR #19883:
URL: https://github.com/apache/pinot/pull/19883#discussion_r4285790826


##########
pinot-broker/src/test/java/org/apache/pinot/broker/requesthandler/QueryValidationTest.java:
##########
@@ -167,6 +171,51 @@ public void testReplicaGroupToQueryInvalidQuery() {
         () -> BaseSingleStageBrokerRequestHandler.validateRequest(pinotQuery, 
10));
   }
 
+  @Test
+  public void testExprMinMaxWithoutRewriters() {

Review Comment:
   Minor: this test (and `testExprMinMaxWithoutResultRewriter`) rely on the 
global `QueryRewriterFactory`/`ResultRewriterFactory` statics being in their 
default state, but don't reset them in a `finally` of their own. It works today 
because the other test resets in `finally`, but it's fragile against reordering 
or another test class in the same fork leaving state behind. Non-blocking.



##########
pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseSingleStageBrokerRequestHandler.java:
##########
@@ -2464,11 +2474,97 @@ static void validateRequest(PinotQuery pinotQuery, int 
queryResponseLimit) {
           "Value for 'LIMIT' (" + limit + ") exceeds maximum allowed value of 
" + queryResponseLimit);
     }
     QueryOptionsUtils.getNumReplicaGroupsToQuery(pinotQuery.getQueryOptions());
+    validateExprMinMax(pinotQuery);
     if (pinotQuery.getDataSource().getSubquery() != null) {
       validateRequest(pinotQuery.getDataSource().getSubquery(), 
queryResponseLimit);
     }
   }
 
+  /// Servers cannot execute EXPR_MIN/EXPR_MAX directly. The broker must 
rewrite them into parent and child
+  /// aggregations with [ExprMinMaxRewriter], and merge the parent result back 
into the child columns with
+  /// [ParentAggregationResultRewriter]. Neither rewriter is enabled by 
default.
+  ///
+  /// Without this check, a query that still has EXPR_MIN/EXPR_MAX fails on 
the servers, and a query without the
+  /// result rewriter returns the placeholder values of the child aggregations 
instead of the expected values.
+  @VisibleForTesting
+  static void validateExprMinMax(PinotQuery pinotQuery) {
+    String exprMinMax = findFunction(pinotQuery, EXPR_MIN_MAX_FUNCTIONS);
+    if (exprMinMax != null) {
+      String functionName = exprMinMax.equals(EXPR_MIN) ? "EXPR_MIN" : 
"EXPR_MAX";
+      boolean queryRewriterEnabled =
+          
CalciteSqlParser.QUERY_REWRITERS.stream().anyMatch(ExprMinMaxRewriter.class::isInstance);
+      if (!queryRewriterEnabled) {
+        throw new BadQueryRequestException(
+            functionName + " is not enabled on this broker. To enable it, add 
'" + ExprMinMaxRewriter.class.getName()
+                + "' to '" + 
Broker.CONFIG_OF_BROKER_QUERY_REWRITER_CLASS_NAMES + "' and '"
+                + ParentAggregationResultRewriter.class.getName() + "' to '"
+                + Broker.CONFIG_OF_BROKER_RESULT_REWRITER_CLASS_NAMES + "'");
+      }
+      // The rewriter only handles the top-level expressions of the select 
list, so the function is nested in another
+      // expression or has an alias.
+      throw new BadQueryRequestException(
+          functionName + " is only supported as a top-level expression in the 
select list, without an alias");

Review Comment:
   Minor: this branch also fires when EXPR_MIN/EXPR_MAX appears in WHERE / 
GROUP BY / HAVING / ORDER BY (since `findFunction` searches all of them), but 
the message only mentions the select list and alias. For a query like `WHERE 
EXPR_MIN(a,b) > 5` the message is a little misleading. Could soften it to 
something like "EXPR_MIN is only supported as a top-level select expression 
without an alias" and note other locations aren't supported. Non-blocking.



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