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>