asolimando commented on code in PR #2876:
URL: https://github.com/apache/calcite/pull/2876#discussion_r1020892294


##########
core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewRule.java:
##########
@@ -1252,6 +1285,193 @@ protected RexNode replaceWithOriginalReferences(final 
RexBuilder rexBuilder,
     }
   }
 
+  /**
+   * Used to generate a view predicate that is added to a materialized view 
that aggregates
+   * over a FLOOR(datetime) when the query has a range predicate on the same 
column.
+   */
+  static class ImplicitViewPredicateShuttle extends RexShuttle {
+
+    private final RexBuilder rexBuilder;
+    private final RexCall floorCall;
+    private final RexInputRef rexInputRef;
+    private final boolean generateViewFilter;
+    private long lowerBound;
+    private long upperBound;
+
+    ImplicitViewPredicateShuttle(RexBuilder rexBuilder, RexCall floorCall,
+        RexInputRef rexInputRef,
+        boolean generateViewFilter) {
+      this.floorCall = floorCall;
+      this.rexBuilder = rexBuilder;
+      this.rexInputRef = rexInputRef;
+      this.generateViewFilter = generateViewFilter;
+    }
+
+    private RexNode transformCall(RexCall call, boolean isLowerBound) {
+      SqlOperator transformedCallOperator = isLowerBound
+          ? SqlStdOperatorTable.GREATER_THAN_OR_EQUAL : 
SqlStdOperatorTable.LESS_THAN;
+      // matches functions of the form x > 5 or 5 > x
+      RexNode literalOperand = call.operands.get(0);
+      RexNode tableInputRefOperand = call.operands.get(1);
+      final int floorIndex = ((RexInputRef) 
floorCall.getOperands().get(0)).getIndex();
+      boolean reverseOperands = false;
+      if ((literalOperand.getKind() == SqlKind.LITERAL
+          && tableInputRefOperand.getKind() == SqlKind.TABLE_INPUT_REF)
+          || (literalOperand.getKind() == SqlKind.TABLE_INPUT_REF
+          && tableInputRefOperand.getKind() == SqlKind.LITERAL)) {
+        if (literalOperand.getKind() == SqlKind.TABLE_INPUT_REF
+            && tableInputRefOperand.getKind() == SqlKind.LITERAL) {
+          literalOperand = call.operands.get(1);
+          tableInputRefOperand = call.operands.get(0);
+          reverseOperands = true;
+        }
+        int predicateIndex = ((RexTableInputRef) 
tableInputRefOperand).getIndex();
+        if (floorIndex == predicateIndex) {
+          // if the query predicate contains a range over the column that is 
floored in the
+          // materialized view we can generate a filter on the view
+          boolean shiftTruncatedVal = call.getOperator() != 
transformedCallOperator;
+          long truncatedVal = getModifiedVal(shiftTruncatedVal, isLowerBound, 
literalOperand);
+          RexNode truncatedLiteral =
+              
rexBuilder.makeTimestampLiteral(TimestampString.fromMillisSinceEpoch(truncatedVal),
+                  0);
+          if (isLowerBound) {
+            lowerBound = truncatedVal;
+          } else {
+            upperBound = truncatedVal;
+          }
+          if (generateViewFilter) {
+            tableInputRefOperand = rexInputRef;
+          }
+          RexNode modifiedCall = rexBuilder.makeCall(call.getType(), 
transformedCallOperator,
+              reverseOperands ? ImmutableList.of(tableInputRefOperand, 
truncatedLiteral)
+                  : ImmutableList.of(truncatedLiteral, tableInputRefOperand));
+          return modifiedCall;

Review Comment:
   I guess you use the variable for easing debug, for modern debuggers can step 
past the return expression, I think we lose clarity and we don't gain much, I 
suggest to drop the variable and return immediately.



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

Reply via email to