zzwqqq commented on code in PR #5385:
URL: https://github.com/apache/calcite/pull/5385#discussion_r4534566700


##########
core/src/main/java/org/apache/calcite/plan/RelOptUtil.java:
##########
@@ -287,6 +302,128 @@ public static List<CorrelationId> 
getVariablesSetAndUsed(RelNode rel0,
     return result;
   }
 
+  /** Returns whether a relational expression, its inputs and sub-queries are
+   * deterministic according to their operator declarations.
+   *
+   * <p>Assumes parameters, correlation bindings, query context and table 
contents
+   * stay fixed within the query. Function calls use
+   * {@link SqlOperator#isDeterministic()}, which allows query-stable functions
+   * such as {@code CURRENT_TIMESTAMP}. A {@link Sample} must declare 
repeatability.
+   * Unknown relational operators return false. Planner wrappers are not 
expanded.
+   *
+   * <p>Input order must also be stable where it affects the result. This 
method
+   * does not establish that property, for example for an unordered FETCH.
+   * It does not trim fields or modify the expression.
+   */
+  public static boolean isDeterministic(RelNode rel) {
+    if (rel instanceof Sample
+        && !((Sample) rel).getSamplingParameters().isRepeatable()) {
+      return false;
+    }
+    if (rel instanceof Aggregate
+        || rel instanceof Window
+        || rel instanceof Match
+        || rel instanceof Project
+        || rel instanceof Filter
+        || rel instanceof Calc
+        || rel instanceof Join
+        || rel instanceof Correlate
+        || rel instanceof Sort
+        || rel instanceof SetOp
+        || rel instanceof Exchange
+        || rel instanceof TableScan
+        || rel instanceof Values
+        || rel instanceof TableFunctionScan
+        || rel instanceof Snapshot
+        || rel instanceof Collect
+        || rel instanceof Uncollect
+        || rel instanceof Sample) {
+      try {
+        if (!tryVisitExpressions(rel, DeterminismChecker.INSTANCE)) {
+          return false;
+        }
+        if (rel instanceof Aggregate) {
+          for (AggregateCall call : ((Aggregate) rel).getAggCallList()) {
+            if (!call.getAggregation().isDeterministic()) {
+              return false;
+            }
+          }
+        }
+        for (RelNode input : rel.getInputs()) {
+          if (!isDeterministic(input)) {
+            return false;
+          }
+        }
+        return true;
+      } catch (Util.FoundOne e) {
+        Util.swallow(e, null);
+      }
+    }
+    return false;
+  }
+
+  /** Visits a supported node's expression fields for read-only analysis.

Review Comment:
   Yes. It visits the node's expression fields, but not its relational inputs. 
The returned expressions are not applied to the node. I've clarified the 
Javadoc.



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