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

libenchao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new 4f46cbfaec [CALCITE-5783] Support hint for TableFunctionScan
4f46cbfaec is described below

commit 4f46cbfaec2962bfaa1315a3e1994238c92b4a9f
Author: Aitozi <[email protected]>
AuthorDate: Thu Jun 15 17:47:55 2023 +0800

    [CALCITE-5783] Support hint for TableFunctionScan
    
    Close apache/calcite#3268
---
 .../apache/calcite/rel/core/TableFunctionScan.java | 42 ++++++++++++++++++++--
 .../apache/calcite/rel/hint/HintPredicates.java    |  5 +++
 .../calcite/rel/hint/NodeTypeHintPredicate.java    |  8 ++++-
 .../rel/logical/LogicalTableFunctionScan.java      | 35 +++++++++++++++++-
 .../apache/calcite/test/SqlHintsConverterTest.java | 14 +++++++-
 .../apache/calcite/test/SqlHintsConverterTest.xml  | 11 ++++++
 6 files changed, 110 insertions(+), 5 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java 
b/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java
index 987233b36e..87854e77ce 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java
@@ -23,6 +23,8 @@ import org.apache.calcite.rel.AbstractRelNode;
 import org.apache.calcite.rel.RelInput;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.hint.Hintable;
+import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.metadata.RelColumnMapping;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.calcite.rel.type.RelDataType;
@@ -36,6 +38,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
 
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -50,7 +53,8 @@ import static java.util.Objects.requireNonNull;
  *
  * @see org.apache.calcite.rel.logical.LogicalTableFunctionScan
  */
-public abstract class TableFunctionScan extends AbstractRelNode {
+public abstract class TableFunctionScan extends AbstractRelNode implements
+    Hintable {
   //~ Instance fields --------------------------------------------------------
 
   private final RexNode rexCall;
@@ -61,6 +65,8 @@ public abstract class TableFunctionScan extends 
AbstractRelNode {
 
   protected final @Nullable ImmutableSet<RelColumnMapping> columnMappings;
 
+  protected final ImmutableList<RelHint> hints;
+
   //~ Constructors -----------------------------------------------------------
 
   /**
@@ -68,6 +74,7 @@ public abstract class TableFunctionScan extends 
AbstractRelNode {
    *
    * @param cluster        Cluster that this relational expression belongs to
    * @param inputs         0 or more relational inputs
+   * @param hints          hints of this node.
    * @param traitSet       Trait set
    * @param rexCall        Function invocation expression
    * @param elementType    Element type of the collection that will implement
@@ -78,6 +85,7 @@ public abstract class TableFunctionScan extends 
AbstractRelNode {
   protected TableFunctionScan(
       RelOptCluster cluster,
       RelTraitSet traitSet,
+      List<RelHint> hints,
       List<RelNode> inputs,
       RexNode rexCall,
       @Nullable Type elementType,
@@ -90,6 +98,31 @@ public abstract class TableFunctionScan extends 
AbstractRelNode {
     this.inputs = ImmutableList.copyOf(inputs);
     this.columnMappings =
         columnMappings == null ? null : ImmutableSet.copyOf(columnMappings);
+    this.hints = ImmutableList.copyOf(hints);
+  }
+
+  /**
+   * Creates a <code>TableFunctionScan</code>.
+   *
+   * @param cluster        Cluster that this relational expression belongs to
+   * @param inputs         0 or more relational inputs
+   * @param traitSet       Trait set
+   * @param rexCall        Function invocation expression
+   * @param elementType    Element type of the collection that will implement
+   *                       this table
+   * @param rowType        Row type produced by function
+   * @param columnMappings Column mappings associated with this function
+   */
+  protected TableFunctionScan(
+      RelOptCluster cluster,
+      RelTraitSet traitSet,
+      List<RelNode> inputs,
+      RexNode rexCall,
+      @Nullable Type elementType,
+      RelDataType rowType,
+      @Nullable Set<RelColumnMapping> columnMappings) {
+    this(cluster, traitSet, ImmutableList.of(), inputs, rexCall,
+        elementType, rowType, columnMappings);
   }
 
   /**
@@ -97,7 +130,8 @@ public abstract class TableFunctionScan extends 
AbstractRelNode {
    */
   protected TableFunctionScan(RelInput input) {
     this(
-        input.getCluster(), input.getTraitSet(), input.getInputs(),
+        input.getCluster(), input.getTraitSet(),
+        Collections.emptyList(), input.getInputs(),
         requireNonNull(input.getExpression("invocation"), "invocation"),
         (Type) input.get("elementType"),
         input.getRowType("rowType"),
@@ -218,4 +252,8 @@ public abstract class TableFunctionScan extends 
AbstractRelNode {
   public @Nullable Type getElementType() {
     return elementType;
   }
+
+  @Override public ImmutableList<RelHint> getHints() {
+    return hints;
+  }
 }
diff --git a/core/src/main/java/org/apache/calcite/rel/hint/HintPredicates.java 
b/core/src/main/java/org/apache/calcite/rel/hint/HintPredicates.java
index b2d8756d8d..184d0012fa 100644
--- a/core/src/main/java/org/apache/calcite/rel/hint/HintPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/hint/HintPredicates.java
@@ -85,6 +85,11 @@ public abstract class HintPredicates {
   public static final HintPredicate SNAPSHOT =
       new NodeTypeHintPredicate(NodeTypeHintPredicate.NodeType.SNAPSHOT);
 
+  /** A hint predicate that indicates a hint can only be used to
+   * {@link org.apache.calcite.rel.core.TableFunctionScan} nodes. */
+  public static final HintPredicate TABLE_FUNCTION_SCAN =
+      new 
NodeTypeHintPredicate(NodeTypeHintPredicate.NodeType.TABLE_FUNCTION_SCAN);
+
   /**
    * Returns a composed hint predicate that represents a short-circuiting 
logical
    * AND of an array of hint predicates {@code hintPredicates}.  When 
evaluating the composed
diff --git 
a/core/src/main/java/org/apache/calcite/rel/hint/NodeTypeHintPredicate.java 
b/core/src/main/java/org/apache/calcite/rel/hint/NodeTypeHintPredicate.java
index 7fd3b78411..6dbfa6b75a 100644
--- a/core/src/main/java/org/apache/calcite/rel/hint/NodeTypeHintPredicate.java
+++ b/core/src/main/java/org/apache/calcite/rel/hint/NodeTypeHintPredicate.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.SetOp;
 import org.apache.calcite.rel.core.Snapshot;
 import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.TableFunctionScan;
 import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.core.Values;
 import org.apache.calcite.rel.core.Window;
@@ -105,7 +106,12 @@ public class NodeTypeHintPredicate implements 
HintPredicate {
     /**
      * The hint would be propagated to the Snapshot nodes.
      */
-    SNAPSHOT(Snapshot.class);
+    SNAPSHOT(Snapshot.class),
+
+    /**
+     * The hint would be propagated to the TableFunctionScan nodes.
+     */
+    TABLE_FUNCTION_SCAN(TableFunctionScan.class);
 
     /** Relational expression clazz that the hint can apply to. */
     @SuppressWarnings("ImmutableEnumChecker")
diff --git 
a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
 
b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
index cacfd8c4e7..07765eb6bf 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
@@ -24,6 +24,7 @@ import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelInput;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.TableFunctionScan;
+import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.metadata.RelColumnMapping;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.calcite.rel.type.RelDataType;
@@ -32,6 +33,7 @@ import org.apache.calcite.rex.RexNode;
 import org.checkerframework.checker.nullness.qual.Nullable;
 
 import java.lang.reflect.Type;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -46,6 +48,7 @@ public class LogicalTableFunctionScan extends 
TableFunctionScan {
    * Creates a <code>LogicalTableFunctionScan</code>.
    *
    * @param cluster        Cluster that this relational expression belongs to
+   * @param hints          The hints of this node.
    * @param inputs         0 or more relational inputs
    * @param traitSet       Trait set
    * @param rexCall        Function invocation expression
@@ -57,11 +60,35 @@ public class LogicalTableFunctionScan extends 
TableFunctionScan {
   public LogicalTableFunctionScan(
       RelOptCluster cluster,
       RelTraitSet traitSet,
+      List<RelHint> hints,
       List<RelNode> inputs,
       RexNode rexCall,
       @Nullable Type elementType, RelDataType rowType,
       @Nullable Set<RelColumnMapping> columnMappings) {
-    super(cluster, traitSet, inputs, rexCall, elementType, rowType,
+    super(cluster, traitSet, hints, inputs, rexCall, elementType, rowType,
+        columnMappings);
+  }
+
+  /**
+   * Creates a <code>LogicalTableFunctionScan</code>.
+   *
+   * @param cluster        Cluster that this relational expression belongs to
+   * @param inputs         0 or more relational inputs
+   * @param traitSet       Trait set
+   * @param rexCall        Function invocation expression
+   * @param elementType    Element type of the collection that will implement
+   *                       this table
+   * @param rowType        Row type produced by function
+   * @param columnMappings Column mappings associated with this function
+   */
+  public LogicalTableFunctionScan(
+      RelOptCluster cluster,
+      RelTraitSet traitSet,
+      List<RelNode> inputs,
+      RexNode rexCall,
+      @Nullable Type elementType, RelDataType rowType,
+      @Nullable Set<RelColumnMapping> columnMappings) {
+    this(cluster, traitSet, Collections.emptyList(), inputs, rexCall, 
elementType, rowType,
         columnMappings);
   }
 
@@ -121,4 +148,10 @@ public class LogicalTableFunctionScan extends 
TableFunctionScan {
     // for an abstract rel?
     return planner.getCostFactory().makeHugeCost();
   }
+
+  @Override public RelNode withHints(
+      final List<RelHint> hintList) {
+    return new LogicalTableFunctionScan(getCluster(), getTraitSet(), hintList,
+        getInputs(), getCall(), getElementType(), getRowType(), 
columnMappings);
+  }
 }
diff --git 
a/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java 
b/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
index ff4b549fa0..2eb6d0f9f6 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
@@ -38,6 +38,7 @@ import org.apache.calcite.rel.core.Filter;
 import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinInfo;
 import org.apache.calcite.rel.core.Snapshot;
+import org.apache.calcite.rel.core.TableFunctionScan;
 import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.core.Window;
 import org.apache.calcite.rel.hint.HintPredicate;
@@ -264,6 +265,11 @@ class SqlHintsConverterTest {
     sql(sql).ok();
   }
 
+  @Test void testTableFunctionScanHints() {
+    final String sql = "select /*+ resource(parallelism='3') */ * from 
TABLE(ramp(5))";
+    sql(sql).ok();
+  }
+
   @Test void testHintsInSubQueryWithDecorrelation() {
     final String sql = "select /*+ resource(parallelism='3'), 
AGG_STRATEGY(TWO_PHASE) */\n"
         + "sum(e1.empno) from emp e1, dept d1\n"
@@ -931,6 +937,11 @@ class SqlHintsConverterTest {
           if (snapshot.getHints().size() > 0) {
             this.hintsCollect.add("Snapshot:" + snapshot.getHints());
           }
+        } else if (other instanceof TableFunctionScan) {
+          TableFunctionScan scan = (TableFunctionScan) other;
+          if (scan.getHints().size() > 0) {
+            this.hintsCollect.add("TableFunctionScan:" + scan.getHints());
+          }
         }
         return super.visit(other);
       }
@@ -1001,7 +1012,8 @@ class SqlHintsConverterTest {
         .hintStrategy(
             "resource", HintPredicates.or(
             HintPredicates.PROJECT, HintPredicates.AGGREGATE,
-                HintPredicates.CALC, HintPredicates.VALUES, 
HintPredicates.FILTER))
+                HintPredicates.CALC, HintPredicates.VALUES,
+                HintPredicates.FILTER, HintPredicates.TABLE_FUNCTION_SCAN))
         .hintStrategy("AGG_STRATEGY",
             HintStrategy.builder(HintPredicates.AGGREGATE)
                 .optionChecker(
diff --git 
a/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml 
b/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
index 7c422656d2..8ac1e96de7 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
@@ -384,6 +384,17 @@ Snapshot:[[FAST_SNAPSHOT inheritPath:[0, 1] 
options:[PRODUCTS_TEMPORAL]]]
     <Resource name="hints">
       <![CDATA[
 Sort:[[ASYNC_MERGE inheritPath:[]]]
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testTableFunctionScanHints">
+    <Resource name="sql">
+      <![CDATA[select /*+ resource(parallelism='3') */ * from TABLE(ramp(5))]]>
+    </Resource>
+    <Resource name="hints">
+      <![CDATA[
+Project:[[RESOURCE inheritPath:[] options:{PARALLELISM=3}]]
+TableFunctionScan:[[RESOURCE inheritPath:[0] options:{PARALLELISM=3}]]
 ]]>
     </Resource>
   </TestCase>

Reply via email to