Jackie-Jiang commented on code in PR #17017:
URL: https://github.com/apache/pinot/pull/17017#discussion_r2434221012


##########
pinot-common/src/main/java/org/apache/pinot/common/utils/request/RequestUtils.java:
##########
@@ -664,4 +670,49 @@ public static void applyTimestampIndexOverrideHints(
       }
     }
   }
+
+  /**
+   * Infers the expression type by recursively traversing the expression tree 
for function calls. The provided schema
+   * is used to resolve the types for identifier expressions. Note that for 
function calls, only scalar functions are
+   * supported here currently. Transform functions that don't have equivalent 
scalar functions, and aggregation
+   * functions aren't supported and {@link ColumnDataType#UNKNOWN} will be 
returned for them.
+   */
+  @Nullable
+  public static ColumnDataType inferExpressionType(@Nullable Expression 
expression, Schema schema) {
+    if (expression == null) {
+      return null;
+    }
+
+    if (expression.isSetIdentifier()) {
+      String columnName = expression.getIdentifier().getName();
+      FieldSpec fieldSpec = schema.getFieldSpecFor(columnName);
+      if (fieldSpec == null) {
+        return ColumnDataType.UNKNOWN;
+      }
+      return ColumnDataType.fromDataType(fieldSpec.getDataType(), 
fieldSpec.isSingleValueField());
+    }
+
+    if (expression.isSetLiteral()) {
+      LiteralContext literalContext = new 
LiteralContext(expression.getLiteral());
+      return ColumnDataType.fromDataType(literalContext.getType(), 
literalContext.isSingleValue());
+    }
+
+    if (expression.isSetFunctionCall()) {
+      Function fn = expression.getFunctionCall();
+      int numOperands = fn.getOperandsSize();
+      ColumnDataType[] argTypes = new ColumnDataType[numOperands];
+      for (int i = 0; i < numOperands; i++) {
+        ColumnDataType argType = inferExpressionType(fn.getOperands().get(i), 
schema);
+        argTypes[i] = argType != null ? argType : ColumnDataType.UNKNOWN;
+      }
+      FunctionInfo functionInfo = 
FunctionRegistry.lookupFunctionInfo(fn.getOperator(), argTypes);
+      if (functionInfo != null) {
+        Class<?> returnClass = functionInfo.getMethod().getReturnType();

Review Comment:
   This is probably not enough, especially when a function returns `Object` 
because various types of value can be returned by the same function based on 
the argument, e.g. `JSON_EXTRACT_SCALAR`.
   Ideally we want to use `SqlReturnTypeInference` to inference the return type 
of a function. This info should be available from `PinotOperatorTable`. All the 
working functions (at least in MSE) are already registered there



##########
pinot-common/src/main/java/org/apache/pinot/common/utils/request/RequestUtils.java:
##########
@@ -664,4 +670,49 @@ public static void applyTimestampIndexOverrideHints(
       }
     }
   }
+
+  /**
+   * Infers the expression type by recursively traversing the expression tree 
for function calls. The provided schema
+   * is used to resolve the types for identifier expressions. Note that for 
function calls, only scalar functions are
+   * supported here currently. Transform functions that don't have equivalent 
scalar functions, and aggregation
+   * functions aren't supported and {@link ColumnDataType#UNKNOWN} will be 
returned for them.
+   */
+  @Nullable
+  public static ColumnDataType inferExpressionType(@Nullable Expression 
expression, Schema schema) {

Review Comment:
   I don't think we want to accept `null` expression here. If we don't accept 
`null` expression, the return is also always not null



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