featzhang commented on code in PR #28681:
URL: https://github.com/apache/flink/pull/28681#discussion_r3541689138


##########
flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/plan/utils/RelTreeWriterImpl.scala:
##########
@@ -23,14 +23,17 @@ import 
org.apache.flink.table.planner.plan.metadata.FlinkRelMetadataQuery
 import org.apache.flink.table.planner.plan.nodes.physical.FlinkPhysicalRel
 import org.apache.flink.table.planner.plan.nodes.physical.stream._
 
+import org.apache.calcite.plan.RelOptUtil

Review Comment:
   sanity check: containsSubQuery walks every RexNode we print, so for plans 
with many predicates this adds a visitor pass per item. probably fine given 
explain is not hot, but curious if you measured any explain-time regression in 
the planner tests.



##########
flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/plan/utils/RelTreeWriterImpl.scala:
##########
@@ -279,6 +240,122 @@ class RelTreeWriterImpl(
     pw.println()
   }
 
+  override def item(term: String, value: AnyRef): RelWriter = {
+    if (withQueryHint || withQueryBlockAlias) {
+      value match {
+        case rexNode: RexNode if containsSubQuery(rexNode) =>
+          return super.item(term, toHintAwareSubQueryString(rexNode))
+        case _ =>
+      }
+    }
+    super.item(term, value)
+  }
+

Review Comment:
   the string-replace trick here worries me a bit: you build result from 
node.toString, then look for RelOptUtil.toString(subQuery.rel) inside it via 
indexOf. if the two toString calls ever render the same sub-rel slightly 
differently (they can, e.g. with/without id prefix or trait diffs), start stays 
-1 and the hint silently disappears from that sub-query. did you check a case 
with a nested sub-query (sub-query inside a sub-query)? might be safer to 
render each sub-query rel directly into the spot instead of matching on a 
substring.



##########
flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/plan/utils/RelTreeWriterImpl.scala:
##########
@@ -279,6 +240,122 @@ class RelTreeWriterImpl(
     pw.println()
   }
 
+  override def item(term: String, value: AnyRef): RelWriter = {
+    if (withQueryHint || withQueryBlockAlias) {
+      value match {
+        case rexNode: RexNode if containsSubQuery(rexNode) =>
+          return super.item(term, toHintAwareSubQueryString(rexNode))
+        case _ =>
+      }
+    }
+    super.item(term, value)
+  }
+
+  private def containsSubQuery(node: RexNode): Boolean = {
+    var found = false
+    node.accept(new RexVisitorImpl[Void](true) {
+      override def visitSubQuery(subQuery: RexSubQuery): Void = {
+        found = true
+        null
+      }
+    })
+    found
+  }
+
+  private def addHintItems(rel: RelNode, addItem: (String, AnyRef) => Unit): 
Unit = {
+    addQueryHintItems(rel, addItem)
+    addQueryBlockAliasHintItems(rel, addItem)
+  }
+
+  private def addQueryHintItems(rel: RelNode, addItem: (String, AnyRef) => 
Unit): Unit = {
+    if (withQueryHint) {
+      rel match {
+        case hintable: Hintable if rel.isInstanceOf[Join] || 
rel.isInstanceOf[Correlate] =>
+          val hints = hintable.getHints
+          addJoinHintItems(hints, addItem)
+          addStateTtlHintItems(hints, addItem)
+        case aggregate: Aggregate =>
+          addStateTtlHintItems(aggregate.getHints, addItem)
+        case aggregate: StreamPhysicalGroupAggregateBase =>

Review Comment:
   here done calls back into item, and item can re-enter 
toHintAwareSubQueryString for any RexNode value. for a normal rel node the 
printed values will not be RexNodes, so no infinite loop in practice - but it 
is a subtle coupling between item and this writer. a short comment on why done 
delegates to item (rather than printValues.add directly) would help the next 
reader.



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/hints/batch/JoinHintTestBase.java:
##########
@@ -51,9 +51,6 @@
  * A test base for join hint.
  *
  * <p>TODO add test to cover legacy table source.
- *

Review Comment:
   nice that you cover sibling sub-queries with different hints. would be good 
to also assert the optimized plan (not just ast) prints the hint on the 
sub-query join, since the bug was about explain output and the optimized rel is 
what users actually see in EXPLAIN. the xml already has the optimized plan 
captured, so the assertion is mostly there.



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