This is an automated email from the ASF dual-hosted git repository.

xiangfu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new 17e1aa11a4 Fix chained literal functions evaluation (#12248)
17e1aa11a4 is described below

commit 17e1aa11a40db55959e97b300dc7d2b836669f0d
Author: Xiang Fu <xiangfu.1...@gmail.com>
AuthorDate: Thu Jan 18 13:40:39 2024 -0800

    Fix chained literal functions evaluation (#12248)
---
 .../rel/rules/PinotEvaluateLiteralRule.java        | 23 +++++-
 .../resources/queries/LiteralEvaluationPlans.json  | 93 ++++++++++++++++++++++
 2 files changed, 113 insertions(+), 3 deletions(-)

diff --git 
a/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java
 
b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java
index ea0d531faa..9cbaed6773 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java
@@ -129,7 +129,11 @@ public class PinotEvaluateLiteralRule {
     public RexNode visitCall(RexCall call) {
       RexCall visitedCall = (RexCall) super.visitCall(call);
       // Check if all operands are RexLiteral
-      if (visitedCall.operands.stream().allMatch(operand -> operand instanceof 
RexLiteral)) {
+      if (visitedCall.operands.stream().allMatch(operand ->
+          operand instanceof RexLiteral
+              || (operand instanceof RexCall && ((RexCall) 
operand).getOperands().stream()
+                  .allMatch(op -> op instanceof RexLiteral))
+      )) {
         return evaluateLiteralOnlyFunction(visitedCall, _rexBuilder);
       } else {
         return visitedCall;
@@ -144,7 +148,9 @@ public class PinotEvaluateLiteralRule {
   private static RexNode evaluateLiteralOnlyFunction(RexCall rexCall, 
RexBuilder rexBuilder) {
     String functionName = PinotRuleUtils.extractFunctionName(rexCall);
     List<RexNode> operands = rexCall.getOperands();
-    assert operands.stream().allMatch(operand -> operand instanceof 
RexLiteral);
+    assert operands.stream().allMatch(operand -> operand instanceof RexLiteral
+        || (operand instanceof RexCall && ((RexCall) 
operand).getOperands().stream()
+        .allMatch(op -> op instanceof RexLiteral)));
     int numOperands = operands.size();
     FunctionInfo functionInfo = FunctionRegistry.getFunctionInfo(functionName, 
numOperands);
     if (functionInfo == null) {
@@ -153,7 +159,18 @@ public class PinotEvaluateLiteralRule {
     }
     Object[] arguments = new Object[numOperands];
     for (int i = 0; i < numOperands; i++) {
-      arguments[i] = getLiteralValue((RexLiteral) operands.get(i));
+      RexNode rexNode = operands.get(i);
+      if (rexNode instanceof RexCall
+          && ((RexCall) 
rexNode).getOperator().getName().equalsIgnoreCase("CAST")) {
+        // this must be a cast function
+        RexCall operand = (RexCall) rexNode;
+        arguments[i] = getLiteralValue((RexLiteral) 
operand.getOperands().get(0));
+      } else if (rexNode instanceof RexLiteral) {
+        arguments[i] = getLiteralValue((RexLiteral) rexNode);
+      } else {
+        // Function operands cannot be evaluated, skip
+        return rexCall;
+      }
     }
     RelDataType rexNodeType = rexCall.getType();
     Object resultValue;
diff --git 
a/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json 
b/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json
index 902648f1cc..cbbfa67d9e 100644
--- a/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json
+++ b/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json
@@ -160,6 +160,99 @@
           "\n"
         ]
       },
+      {
+        "description": "select two functions chaining",
+        "sql": "EXPLAIN PLAN FOR SELECT ToEpochDays(fromDateTime('1970-01-15', 
'yyyy-MM-dd')) FROM a",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[14:BIGINT])",
+          "\n  LogicalTableScan(table=[[a]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "select two functions chaining with one more arithmetic 
function",
+        "sql": "EXPLAIN PLAN FOR SELECT 1 + 
ToEpochDays(fromDateTime('1970-01-15', 'yyyy-MM-dd')) FROM a",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[15.0:BIGINT])",
+          "\n  LogicalTableScan(table=[[a]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "select int array literal",
+        "sql": "EXPLAIN PLAN FOR SELECT ARRAY[1,2,3] FROM a",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[ARRAY(1, 2, 3)])",
+          "\n  LogicalTableScan(table=[[a]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "select int array literal",
+        "sql": "EXPLAIN PLAN FOR SELECT ARRAY[1,2,3]",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[ARRAY(1, 2, 3)])",
+          "\n  LogicalValues(tuples=[[{ 0 }]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "select float array literal",
+        "sql": "EXPLAIN PLAN FOR SELECT ARRAY[0.1,0.2,0.3] FROM a",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[ARRAY(0.1:DECIMAL(2, 1), 0.2:DECIMAL(2, 
1), 0.3:DECIMAL(2, 1))])",
+          "\n  LogicalTableScan(table=[[a]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "select float array literal",
+        "sql": "EXPLAIN PLAN FOR SELECT ARRAY[0.1,0.2,0.3]",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[ARRAY(0.1:DECIMAL(2, 1), 0.2:DECIMAL(2, 
1), 0.3:DECIMAL(2, 1))])",
+          "\n  LogicalValues(tuples=[[{ 0 }]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "select string array literal",
+        "sql": "EXPLAIN PLAN FOR SELECT ARRAY['a','b','c'] FROM a",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[ARRAY(_UTF-8'a', _UTF-8'b', _UTF-8'c')])",
+          "\n  LogicalTableScan(table=[[a]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "select string array literal",
+        "sql": "EXPLAIN PLAN FOR SELECT ARRAY['a','b','c']",
+        "output": [
+          "Execution Plan",
+          "\nLogicalProject(EXPR$0=[ARRAY(_UTF-8'a', _UTF-8'b', _UTF-8'c')])",
+          "\n  LogicalValues(tuples=[[{ 0 }]])",
+          "\n"
+        ]
+      },
+      {
+        "description": "filter with two functions chaining",
+        "sql": "EXPLAIN PLAN FOR SELECT count(*) FROM a WHERE col1 > 
ToEpochDays(fromDateTime('1970-01-15', 'yyyy-MM-dd'))",
+        "output": [
+          "Execution Plan",
+          "\nLogicalAggregate(group=[{}], agg#0=[COUNT($0)])",
+          "\n  PinotLogicalExchange(distribution=[hash])",
+          "\n    LogicalAggregate(group=[{}], agg#0=[COUNT()])",
+          "\n      LogicalFilter(condition=[>(CAST($0):BIGINT NOT NULL, 14)])",
+          "\n        LogicalTableScan(table=[[a]])",
+          "\n"
+        ]
+      },
       {
         "description": "select non-exist literal function",
         "sql": "EXPLAIN PLAN FOR Select nonExistFun(1,2) FROM a",


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to