This is an automated email from the ASF dual-hosted git repository.
danny0405 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 6257609 [CALCITE-3730] Add hints to RelBuilder
6257609 is described below
commit 6257609c6be438ba9103666ea41e3191d851abd0
Author: yuzhao.cyz <[email protected]>
AuthorDate: Tue Jan 14 11:52:33 2020 +0800
[CALCITE-3730] Add hints to RelBuilder
* Add #hints to RelBuilder
* Add hints to RelNode factories
* In logical RelNode classes that implement Hintable, add hints to #create
method
---
.../org/apache/calcite/adapter/jdbc/JdbcRules.java | 8 +-
.../apache/calcite/plan/RelOptAbstractTable.java | 3 +-
.../apache/calcite/plan/RelOptMaterialization.java | 4 +-
.../java/org/apache/calcite/plan/RelOptUtil.java | 17 +--
.../org/apache/calcite/plan/ViewExpanders.java | 2 +-
.../apache/calcite/prepare/LixToRelTranslator.java | 7 +-
.../calcite/prepare/QueryableRelBuilder.java | 6 +-
.../apache/calcite/prepare/RelOptTableImpl.java | 6 +-
.../main/java/org/apache/calcite/rel/RelRoot.java | 6 +-
.../org/apache/calcite/rel/core/RelFactories.java | 79 ++++++++++----
.../calcite/rel/logical/LogicalAggregate.java | 19 +++-
.../apache/calcite/rel/logical/LogicalJoin.java | 33 ++++--
.../apache/calcite/rel/logical/LogicalProject.java | 20 +++-
.../calcite/rel/logical/LogicalTableScan.java | 9 +-
.../calcite/rel/logical/ToLogicalConverter.java | 2 +-
.../rel/rules/JoinAddRedundantSemiJoinRule.java | 2 +
.../calcite/rel/rules/LoptSemiJoinOptimizer.java | 4 +-
.../rel/rules/SemiJoinFilterTransposeRule.java | 3 +
.../rel/rules/SemiJoinJoinTransposeRule.java | 3 +
.../rel/rules/SemiJoinProjectTransposeRule.java | 7 +-
.../org/apache/calcite/rel/stream/StreamRules.java | 8 +-
.../main/java/org/apache/calcite/sql/SqlUtil.java | 6 +-
.../apache/calcite/sql2rel/RelDecorrelator.java | 11 +-
.../sql2rel/RelStructuredTypeFlattener.java | 8 +-
.../apache/calcite/sql2rel/SqlToRelConverter.java | 40 ++++---
.../java/org/apache/calcite/tools/RelBuilder.java | 117 ++++++++++++++++++---
.../org/apache/calcite/plan/RelOptUtilTest.java | 2 +
.../org/apache/calcite/plan/RelWriterTest.java | 12 ++-
.../calcite/plan/volcano/TraitPropagationTest.java | 3 +-
.../java/org/apache/calcite/test/Matchers.java | 12 +++
.../org/apache/calcite/test/RelBuilderTest.java | 89 ++++++++++++++++
.../org/apache/calcite/test/RelMetadataTest.java | 35 +++---
.../apache/calcite/test/SqlHintsConverterTest.java | 11 +-
.../org/apache/calcite/test/SqlToRelTestBase.java | 6 +-
.../calcite/test/catalog/MockCatalogReader.java | 11 +-
.../apache/calcite/test/SqlHintsConverterTest.xml | 4 +-
.../apache/calcite/adapter/druid/DruidTable.java | 2 +-
.../calcite/adapter/pig/PigRelFactories.java | 16 ++-
.../org/apache/calcite/piglet/PigRelBuilder.java | 4 +-
site/_docs/history.md | 1 +
.../calcite/adapter/splunk/SplunkPushDownRule.java | 5 +-
41 files changed, 480 insertions(+), 163 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
index 52525c0..c8a3e64 100644
--- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
+++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
@@ -96,7 +96,7 @@ public class JdbcRules {
protected static final Logger LOGGER = CalciteTrace.getPlannerTracer();
static final RelFactories.ProjectFactory PROJECT_FACTORY =
- (input, projects, fieldNames) -> {
+ (input, hints, projects, fieldNames) -> {
final RelOptCluster cluster = input.getCluster();
final RelDataType rowType =
RexUtil.createStructType(cluster.getTypeFactory(), projects,
@@ -114,7 +114,7 @@ public class JdbcRules {
};
static final RelFactories.JoinFactory JOIN_FACTORY =
- (left, right, condition, variablesSet, joinType, semiJoinDone) -> {
+ (left, right, hints, condition, variablesSet, joinType, semiJoinDone) ->
{
final RelOptCluster cluster = left.getCluster();
final RelTraitSet traitSet = cluster.traitSetOf(left.getConvention());
try {
@@ -146,7 +146,7 @@ public class JdbcRules {
};
public static final RelFactories.AggregateFactory AGGREGATE_FACTORY =
- (input, groupSet, groupSets, aggCalls) -> {
+ (input, hints, groupSet, groupSets, aggCalls) -> {
final RelOptCluster cluster = input.getCluster();
final RelTraitSet traitSet = cluster.traitSetOf(input.getConvention());
try {
@@ -187,7 +187,7 @@ public class JdbcRules {
};
public static final RelFactories.TableScanFactory TABLE_SCAN_FACTORY =
- (cluster, table) -> {
+ (cluster, table, hints) -> {
throw new UnsupportedOperationException();
};
diff --git
a/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java
b/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java
index 05333a3..216f7fb 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java
@@ -108,7 +108,8 @@ public abstract class RelOptAbstractTable implements
RelOptTable {
}
public RelNode toRel(ToRelContext context) {
- return LogicalTableScan.create(context.getCluster(), this);
+ return LogicalTableScan.create(context.getCluster(), this,
+ context.getTableHints());
}
public Expression getExpression(Class clazz) {
diff --git
a/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
b/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
index 1baf55f..0b9a48a 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
@@ -156,7 +156,7 @@ public class RelOptMaterialization {
Mappings.offsetSource(rightMapping, offset),
leftMapping.getTargetCount()));
final RelNode project = RelOptUtil.createProject(
- LogicalTableScan.create(cluster, leftRelOptTable),
+ LogicalTableScan.create(cluster, leftRelOptTable,
ImmutableList.of()),
Mappings.asList(mapping.inverse()));
final List<RexNode> conditions = new ArrayList<>();
if (left.condition != null) {
@@ -180,7 +180,7 @@ public class RelOptMaterialization {
Mappings.offsetSource(leftMapping, offset),
Mappings.offsetTarget(rightMapping, leftCount));
final RelNode project = RelOptUtil.createProject(
- LogicalTableScan.create(cluster, rightRelOptTable),
+ LogicalTableScan.create(cluster, rightRelOptTable,
ImmutableList.of()),
Mappings.asList(mapping.inverse()));
final List<RexNode> conditions = new ArrayList<>();
if (left.condition != null) {
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index a965a23..a69afcd 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -667,8 +667,8 @@ public abstract class RelOptUtil {
|| logic == RelOptUtil.Logic.TRUE_FALSE_UNKNOWN;
if (!outerJoin) {
final LogicalAggregate aggregate =
- LogicalAggregate.create(ret, ImmutableBitSet.range(keyCount), null,
- ImmutableList.of());
+ LogicalAggregate.create(ret, ImmutableList.of(),
ImmutableBitSet.range(keyCount),
+ null, ImmutableList.of());
return new Exists(aggregate, false, false);
}
@@ -867,14 +867,17 @@ public abstract class RelOptUtil {
final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
List<RexNode> castExps;
RelNode input;
+ List<RelHint> hints = ImmutableList.of();
if (rel instanceof Project) {
// No need to create another project node if the rel
// is already a project.
+ final Project project = (Project) rel;
castExps = RexUtil.generateCastExpressions(
rexBuilder,
castRowType,
((Project) rel).getProjects());
input = rel.getInput(0);
+ hints = project.getHints();
} else {
castExps = RexUtil.generateCastExpressions(
rexBuilder,
@@ -884,11 +887,11 @@ public abstract class RelOptUtil {
}
if (rename) {
// Use names and types from castRowType.
- return projectFactory.createProject(input, castExps,
+ return projectFactory.createProject(input, hints, castExps,
castRowType.getFieldNames());
} else {
// Use names from rowType, types from castRowType.
- return projectFactory.createProject(input, castExps,
+ return projectFactory.createProject(input, hints, castExps,
rowType.getFieldNames());
}
}
@@ -927,13 +930,15 @@ public abstract class RelOptUtil {
null));
}
- return LogicalAggregate.create(rel, ImmutableBitSet.of(), null, aggCalls);
+ return LogicalAggregate.create(rel, ImmutableList.of(),
ImmutableBitSet.of(),
+ null, aggCalls);
}
/** @deprecated Use {@link RelBuilder#distinct()}. */
@Deprecated // to be removed before 2.0
public static RelNode createDistinctRel(RelNode rel) {
return LogicalAggregate.create(rel,
+ ImmutableList.of(),
ImmutableBitSet.range(rel.getRowType().getFieldCount()), null,
ImmutableList.of());
}
@@ -3381,7 +3386,7 @@ public abstract class RelOptUtil {
: fieldNames.get(i));
exprList.add(rexBuilder.makeInputRef(rel, source));
}
- return projectFactory.createProject(rel, exprList, outputNameList);
+ return projectFactory.createProject(rel, ImmutableList.of(), exprList,
outputNameList);
}
/** Predicate for whether a {@link Calc} contains multisets or windowed
diff --git a/core/src/main/java/org/apache/calcite/plan/ViewExpanders.java
b/core/src/main/java/org/apache/calcite/plan/ViewExpanders.java
index 13c188e..0767307 100644
--- a/core/src/main/java/org/apache/calcite/plan/ViewExpanders.java
+++ b/core/src/main/java/org/apache/calcite/plan/ViewExpanders.java
@@ -80,7 +80,7 @@ public abstract class ViewExpanders {
}
public List<RelHint> getTableHints() {
- throw new UnsupportedOperationException();
+ return ImmutableList.of();
}
};
}
diff --git
a/core/src/main/java/org/apache/calcite/prepare/LixToRelTranslator.java
b/core/src/main/java/org/apache/calcite/prepare/LixToRelTranslator.java
index e6ab3bc..6bdb9be 100644
--- a/core/src/main/java/org/apache/calcite/prepare/LixToRelTranslator.java
+++ b/core/src/main/java/org/apache/calcite/prepare/LixToRelTranslator.java
@@ -88,6 +88,7 @@ class LixToRelTranslator {
case SELECT:
input = translate(call.targetExpression);
return LogicalProject.create(input,
+ ImmutableList.of(),
toRex(input, (FunctionExpression) call.expressions.get(0)),
(List<String>) null);
@@ -103,7 +104,8 @@ class LixToRelTranslator {
Types.toClass(
Types.getElementType(call.targetExpression.getType()))),
ImmutableList.of(),
- call.targetExpression));
+ call.targetExpression),
+ ImmutableList.of());
case SCHEMA_GET_TABLE:
return LogicalTableScan.create(cluster,
@@ -111,7 +113,8 @@ class LixToRelTranslator {
typeFactory.createJavaType((Class)
((ConstantExpression) call.expressions.get(1)).value),
ImmutableList.of(),
- call.targetExpression));
+ call.targetExpression),
+ ImmutableList.of());
default:
throw new UnsupportedOperationException(
diff --git
a/core/src/main/java/org/apache/calcite/prepare/QueryableRelBuilder.java
b/core/src/main/java/org/apache/calcite/prepare/QueryableRelBuilder.java
index b43c0b6..9624470 100644
--- a/core/src/main/java/org/apache/calcite/prepare/QueryableRelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/prepare/QueryableRelBuilder.java
@@ -48,6 +48,8 @@ import org.apache.calcite.schema.QueryableTable;
import org.apache.calcite.schema.TranslatableTable;
import org.apache.calcite.schema.impl.AbstractTableQueryable;
+import com.google.common.collect.ImmutableList;
+
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
@@ -102,7 +104,7 @@ class QueryableRelBuilder<T> implements QueryableFactory<T>
{
return ((TranslatableTable) table).toRel(translator.toRelContext(),
relOptTable);
} else {
- return LogicalTableScan.create(translator.cluster, relOptTable);
+ return LogicalTableScan.create(translator.cluster, relOptTable,
ImmutableList.of());
}
}
return translator.translate(queryable.getExpression());
@@ -536,7 +538,7 @@ class QueryableRelBuilder<T> implements QueryableFactory<T>
{
RelNode child = toRel(source);
List<RexNode> nodes = translator.toRexList(selector, child);
setRel(
- LogicalProject.create(child, nodes, (List<String>) null));
+ LogicalProject.create(child, ImmutableList.of(), nodes, (List<String>)
null));
return null;
}
diff --git a/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java
b/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java
index 769dd27..021a300 100644
--- a/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java
@@ -290,7 +290,7 @@ public class RelOptTableImpl extends
Prepare.AbstractPreparingTable {
}
final RelOptCluster cluster = context.getCluster();
if (Hook.ENABLE_BINDABLE.get(false)) {
- return LogicalTableScan.create(cluster, this);
+ return LogicalTableScan.create(cluster, this, context.getTableHints());
}
if (CalciteSystemProperty.ENABLE_ENUMERABLE.value()
&& table instanceof QueryableTable
@@ -301,7 +301,7 @@ public class RelOptTableImpl extends
Prepare.AbstractPreparingTable {
if (table instanceof ScannableTable
|| table instanceof FilterableTable
|| table instanceof ProjectableFilterableTable) {
- return LogicalTableScan.create(cluster, this);
+ return LogicalTableScan.create(cluster, this, context.getTableHints());
}
// Some tests rely on the old behavior when tables were immediately
converted to
// EnumerableTableScan
@@ -311,7 +311,7 @@ public class RelOptTableImpl extends
Prepare.AbstractPreparingTable {
|| EnumerableTableScan.canHandle(this))) {
return EnumerableTableScan.create(cluster, this);
}
- return LogicalTableScan.create(cluster, this);
+ return LogicalTableScan.create(cluster, this, context.getTableHints());
}
public List<RelCollation> getCollationList() {
diff --git a/core/src/main/java/org/apache/calcite/rel/RelRoot.java
b/core/src/main/java/org/apache/calcite/rel/RelRoot.java
index 80cd6ce..27e8e45 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelRoot.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelRoot.java
@@ -16,7 +16,6 @@
*/
package org.apache.calcite.rel;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rel.logical.LogicalProject;
import org.apache.calcite.rel.type.RelDataType;
@@ -167,10 +166,7 @@ public class RelRoot {
for (Pair<Integer, String> field : fields) {
projects.add(rexBuilder.makeInputRef(rel, field.left));
}
- return RelOptUtil.copyRelHints(
- rel,
- LogicalProject.create(rel, projects, Pair.right(fields)),
- false);
+ return LogicalProject.create(rel, hints, projects, Pair.right(fields));
}
public boolean isNameTrivial() {
diff --git a/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
b/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
index 92473bc..4518524 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
@@ -25,6 +25,7 @@ import org.apache.calcite.plan.ViewExpanders;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelDistribution;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rel.logical.LogicalAggregate;
import org.apache.calcite.rel.logical.LogicalCorrelate;
import org.apache.calcite.rel.logical.LogicalExchange;
@@ -143,9 +144,23 @@ public class RelFactories {
* appropriate type for this rule's calling convention.
*/
public interface ProjectFactory {
- /** Creates a project. */
- RelNode createProject(RelNode input, List<? extends RexNode> childExprs,
- List<String> fieldNames);
+ /**
+ * Creates a project.
+ *
+ * @param input The input
+ * @param hints The hints
+ * @param childExprs The projection expressions
+ * @param fieldNames The projection field names
+ * @return a project
+ */
+ RelNode createProject(RelNode input, List<RelHint> hints,
+ List<? extends RexNode> childExprs, List<String> fieldNames);
+
+ @Deprecated // to be removed before 1.23
+ default RelNode createProject(RelNode input,
+ List<? extends RexNode> childExprs, List<String> fieldNames) {
+ return createProject(input, ImmutableList.of(), childExprs, fieldNames);
+ }
}
/**
@@ -153,9 +168,9 @@ public class RelFactories {
* {@link org.apache.calcite.rel.logical.LogicalProject}.
*/
private static class ProjectFactoryImpl implements ProjectFactory {
- public RelNode createProject(RelNode input,
+ public RelNode createProject(RelNode input, List<RelHint> hints,
List<? extends RexNode> childExprs, List<String> fieldNames) {
- return LogicalProject.create(input, childExprs, fieldNames);
+ return LogicalProject.create(input, hints, childExprs, fieldNames);
}
}
@@ -272,15 +287,21 @@ public class RelFactories {
*/
public interface AggregateFactory {
/** Creates an aggregate. */
- RelNode createAggregate(RelNode input, ImmutableBitSet groupSet,
+ RelNode createAggregate(RelNode input, List<RelHint> hints,
ImmutableBitSet groupSet,
ImmutableList<ImmutableBitSet> groupSets, List<AggregateCall>
aggCalls);
- @Deprecated // to be removed before 2.0
+ @Deprecated // to be removed before 1.23
+ default RelNode createAggregate(RelNode input, ImmutableBitSet groupSet,
+ ImmutableList<ImmutableBitSet> groupSets, List<AggregateCall>
aggCalls) {
+ return createAggregate(input, ImmutableList.of(), groupSet, groupSets,
aggCalls);
+ }
+
+ @Deprecated // to be removed before 1.23
default RelNode createAggregate(RelNode input, boolean indicator,
ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
Aggregate.checkIndicator(indicator);
- return createAggregate(input, groupSet, groupSets, aggCalls);
+ return createAggregate(input, ImmutableList.of(), groupSet, groupSets,
aggCalls);
}
}
@@ -289,10 +310,10 @@ public class RelFactories {
* that returns a vanilla {@link LogicalAggregate}.
*/
private static class AggregateFactoryImpl implements AggregateFactory {
- public RelNode createAggregate(RelNode input,
+ public RelNode createAggregate(RelNode input, List<RelHint> hints,
ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
- return LogicalAggregate.create(input, groupSet, groupSets, aggCalls);
+ return LogicalAggregate.create(input, hints, groupSet, groupSets,
aggCalls);
}
}
@@ -346,6 +367,7 @@ public class RelFactories {
*
* @param left Left input
* @param right Right input
+ * @param hints Hints
* @param condition Join condition
* @param variablesSet Set of variables that are set by the
* LHS and used by the RHS and are not available to
@@ -354,15 +376,23 @@ public class RelFactories {
* @param semiJoinDone Whether this join has been translated to a
* semi-join
*/
- RelNode createJoin(RelNode left, RelNode right, RexNode condition,
- Set<CorrelationId> variablesSet, JoinRelType joinType,
+ RelNode createJoin(RelNode left, RelNode right, List<RelHint> hints,
+ RexNode condition, Set<CorrelationId> variablesSet, JoinRelType
joinType,
boolean semiJoinDone);
- @Deprecated // to be removed before 2.0
+ @Deprecated // to be removed before 1.23
+ default RelNode createJoin(RelNode left, RelNode right, RexNode condition,
+ Set<CorrelationId> variablesSet, JoinRelType joinType,
+ boolean semiJoinDone) {
+ return createJoin(left, right, ImmutableList.of(), condition,
variablesSet,
+ joinType, semiJoinDone);
+ }
+
+ @Deprecated // to be removed before 1.23
default RelNode createJoin(RelNode left, RelNode right, RexNode condition,
JoinRelType joinType, Set<String> variablesStopped,
boolean semiJoinDone) {
- return createJoin(left, right, condition,
+ return createJoin(left, right, ImmutableList.of(), condition,
CorrelationId.setOf(variablesStopped), joinType, semiJoinDone);
}
}
@@ -372,10 +402,10 @@ public class RelFactories {
* {@link org.apache.calcite.rel.logical.LogicalJoin}.
*/
private static class JoinFactoryImpl implements JoinFactory {
- public RelNode createJoin(RelNode left, RelNode right,
+ public RelNode createJoin(RelNode left, RelNode right, List<RelHint> hints,
RexNode condition, Set<CorrelationId> variablesSet,
JoinRelType joinType, boolean semiJoinDone) {
- return LogicalJoin.create(left, right, condition, variablesSet, joinType,
+ return LogicalJoin.create(left, right, hints, condition, variablesSet,
joinType,
semiJoinDone, ImmutableList.of());
}
}
@@ -479,7 +509,12 @@ public class RelFactories {
/**
* Creates a {@link TableScan}.
*/
- RelNode createScan(RelOptCluster cluster, RelOptTable table);
+ RelNode createScan(RelOptCluster cluster, RelOptTable table, List<RelHint>
hints);
+
+ @Deprecated // to be removed before 1.23
+ default RelNode createScan(RelOptCluster cluster, RelOptTable table) {
+ return createScan(cluster, table, ImmutableList.of());
+ }
}
/**
@@ -487,8 +522,8 @@ public class RelFactories {
* {@link LogicalTableScan}.
*/
private static class TableScanFactoryImpl implements TableScanFactory {
- public RelNode createScan(RelOptCluster cluster, RelOptTable table) {
- return LogicalTableScan.create(cluster, table);
+ public RelNode createScan(RelOptCluster cluster, RelOptTable table,
List<RelHint> hints) {
+ return LogicalTableScan.create(cluster, table, hints);
}
}
@@ -521,15 +556,15 @@ public class RelFactories {
@Nonnull public static TableScanFactory expandingScanFactory(
@Nonnull RelOptTable.ViewExpander viewExpander,
@Nonnull TableScanFactory tableScanFactory) {
- return (cluster, table) -> {
+ return (cluster, table, hints) -> {
final TranslatableTable translatableTable =
table.unwrap(TranslatableTable.class);
if (translatableTable != null) {
final RelOptTable.ToRelContext toRelContext =
- ViewExpanders.toRelContext(viewExpander, cluster);
+ ViewExpanders.toRelContext(viewExpander, cluster, hints);
return translatableTable.toRel(toRelContext, table);
}
- return tableScanFactory.createScan(cluster, table);
+ return tableScanFactory.createScan(cluster, table, hints);
};
}
diff --git
a/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
b/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
index 3da516b..115e423 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
@@ -107,9 +107,19 @@ public final class LogicalAggregate extends Aggregate {
/** Creates a LogicalAggregate. */
public static LogicalAggregate create(final RelNode input,
- ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets,
+ List<RelHint> hints,
+ ImmutableBitSet groupSet,
+ List<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
- return create_(input, groupSet, groupSets, aggCalls);
+ return create_(input, hints, groupSet, groupSets, aggCalls);
+ }
+
+ @Deprecated // to be removed before 2.0
+ public static LogicalAggregate create(final RelNode input,
+ ImmutableBitSet groupSet,
+ List<ImmutableBitSet> groupSets,
+ List<AggregateCall> aggCalls) {
+ return create_(input, ImmutableList.of(), groupSet, groupSets, aggCalls);
}
@Deprecated // to be removed before 2.0
@@ -119,16 +129,17 @@ public final class LogicalAggregate extends Aggregate {
List<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
checkIndicator(indicator);
- return create_(input, groupSet, groupSets, aggCalls);
+ return create_(input, ImmutableList.of(), groupSet, groupSets, aggCalls);
}
private static LogicalAggregate create_(final RelNode input,
+ List<RelHint> hints,
ImmutableBitSet groupSet,
List<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
final RelOptCluster cluster = input.getCluster();
final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
- return new LogicalAggregate(cluster, traitSet, ImmutableList.of(), input,
groupSet,
+ return new LogicalAggregate(cluster, traitSet, hints, input, groupSet,
groupSets, aggCalls);
}
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalJoin.java
b/core/src/main/java/org/apache/calcite/rel/logical/LogicalJoin.java
index a3fb061..f37c3d7 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalJoin.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalJoin.java
@@ -152,30 +152,45 @@ public final class LogicalJoin extends Join {
ImmutableList.of());
}
+ /** Creates a LogicalJoin. */
+ public static LogicalJoin create(RelNode left, RelNode right, List<RelHint>
hints,
+ RexNode condition, Set<CorrelationId> variablesSet, JoinRelType
joinType) {
+ return create(left, right, hints, condition, variablesSet, joinType, false,
+ ImmutableList.of());
+ }
+
/** Creates a LogicalJoin, flagged with whether it has been translated to a
* semi-join. */
- public static LogicalJoin create(RelNode left, RelNode right,
+ public static LogicalJoin create(RelNode left, RelNode right, List<RelHint>
hints,
RexNode condition, Set<CorrelationId> variablesSet, JoinRelType joinType,
boolean semiJoinDone, ImmutableList<RelDataTypeField> systemFieldList) {
final RelOptCluster cluster = left.getCluster();
final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
- return new LogicalJoin(cluster, traitSet, ImmutableList.of(), left, right,
condition,
+ return new LogicalJoin(cluster, traitSet, hints, left, right, condition,
variablesSet, joinType, semiJoinDone, systemFieldList);
}
- @Deprecated // to be removed before 2.0
+ @Deprecated // to be removed before 1.23
public static LogicalJoin create(RelNode left, RelNode right,
- RexNode condition, JoinRelType joinType, Set<String> variablesStopped,
+ RexNode condition, Set<CorrelationId> variablesSet, JoinRelType
joinType) {
+ return create(left, right, ImmutableList.of(), condition, variablesSet,
+ joinType, false, ImmutableList.of());
+ }
+
+ @Deprecated // to be removed before 1.23
+ public static LogicalJoin create(RelNode left, RelNode right,
+ RexNode condition, Set<CorrelationId> variablesSet, JoinRelType joinType,
boolean semiJoinDone, ImmutableList<RelDataTypeField> systemFieldList) {
- return create(left, right, condition,
CorrelationId.setOf(variablesStopped),
+ return create(left, right, ImmutableList.of(), condition, variablesSet,
joinType, semiJoinDone, systemFieldList);
}
- /** Creates a LogicalJoin. */
+ @Deprecated // to be removed before 2.0
public static LogicalJoin create(RelNode left, RelNode right,
- RexNode condition, Set<CorrelationId> variablesSet, JoinRelType
joinType) {
- return create(left, right, condition, variablesSet, joinType, false,
- ImmutableList.of());
+ RexNode condition, JoinRelType joinType, Set<String> variablesStopped,
+ boolean semiJoinDone, ImmutableList<RelDataTypeField> systemFieldList) {
+ return create(left, right, condition,
CorrelationId.setOf(variablesStopped),
+ joinType, semiJoinDone, systemFieldList);
}
@Deprecated // to be removed before 2.0
diff --git
a/core/src/main/java/org/apache/calcite/rel/logical/LogicalProject.java
b/core/src/main/java/org/apache/calcite/rel/logical/LogicalProject.java
index c5baecb..605b875 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalProject.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalProject.java
@@ -102,17 +102,17 @@ public final class LogicalProject extends Project {
//~ Methods ----------------------------------------------------------------
/** Creates a LogicalProject. */
- public static LogicalProject create(final RelNode input,
+ public static LogicalProject create(final RelNode input, List<RelHint> hints,
final List<? extends RexNode> projects, List<String> fieldNames) {
final RelOptCluster cluster = input.getCluster();
final RelDataType rowType =
RexUtil.createStructType(cluster.getTypeFactory(), projects,
fieldNames, SqlValidatorUtil.F_SUGGESTER);
- return create(input, projects, rowType);
+ return create(input, hints, projects, rowType);
}
/** Creates a LogicalProject, specifying row type rather than field names. */
- public static LogicalProject create(final RelNode input,
+ public static LogicalProject create(final RelNode input, List<RelHint> hints,
final List<? extends RexNode> projects, RelDataType rowType) {
final RelOptCluster cluster = input.getCluster();
final RelMetadataQuery mq = cluster.getMetadataQuery();
@@ -120,7 +120,19 @@ public final class LogicalProject extends Project {
cluster.traitSet().replace(Convention.NONE)
.replaceIfs(RelCollationTraitDef.INSTANCE,
() -> RelMdCollation.project(mq, input, projects));
- return new LogicalProject(cluster, traitSet, ImmutableList.of(), input,
projects, rowType);
+ return new LogicalProject(cluster, traitSet, hints, input, projects,
rowType);
+ }
+
+ @Deprecated // to be removed before 1.23
+ public static LogicalProject create(final RelNode input,
+ final List<? extends RexNode> projects, List<String> fieldNames) {
+ return create(input, ImmutableList.of(), projects, fieldNames);
+ }
+
+ @Deprecated // to be removed before 1.23
+ public static LogicalProject create(final RelNode input,
+ final List<? extends RexNode> projects, RelDataType rowType) {
+ return create(input, ImmutableList.of(), projects, rowType);
}
@Override public LogicalProject copy(RelTraitSet traitSet, RelNode input,
diff --git
a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
index 8876e01..9d62e37 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
@@ -29,7 +29,6 @@ import org.apache.calcite.schema.Table;
import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -115,14 +114,10 @@ public final class LogicalTableScan extends TableScan {
return new LogicalTableScan(cluster, traitSet, hints, relOptTable);
}
- /** Creates a LogicalTableScan.
- *
- * @param cluster Cluster
- * @param relOptTable Table
- */
+ @Deprecated // to be removed before 1.23
public static LogicalTableScan create(RelOptCluster cluster,
final RelOptTable relOptTable) {
- return create(cluster, relOptTable, new ArrayList<>());
+ return create(cluster, relOptTable, ImmutableList.of());
}
@Override public RelNode withHints(List<RelHint> hintList) {
diff --git
a/core/src/main/java/org/apache/calcite/rel/logical/ToLogicalConverter.java
b/core/src/main/java/org/apache/calcite/rel/logical/ToLogicalConverter.java
index 60ff322..5b262c2 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/ToLogicalConverter.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/ToLogicalConverter.java
@@ -52,7 +52,7 @@ public class ToLogicalConverter extends RelShuttleImpl {
}
@Override public RelNode visit(TableScan scan) {
- return LogicalTableScan.create(scan.getCluster(), scan.getTable());
+ return LogicalTableScan.create(scan.getCluster(), scan.getTable(),
scan.getHints());
}
@Override public RelNode visit(RelNode relNode) {
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/JoinAddRedundantSemiJoinRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/JoinAddRedundantSemiJoinRule.java
index de03c14..5cbd49d 100644
---
a/core/src/main/java/org/apache/calcite/rel/rules/JoinAddRedundantSemiJoinRule.java
+++
b/core/src/main/java/org/apache/calcite/rel/rules/JoinAddRedundantSemiJoinRule.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.core.RelFactories;
import org.apache.calcite.rel.logical.LogicalJoin;
import org.apache.calcite.tools.RelBuilderFactory;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
/**
@@ -74,6 +75,7 @@ public class JoinAddRedundantSemiJoinRule extends RelOptRule {
RelNode semiJoin =
LogicalJoin.create(origJoinRel.getLeft(),
origJoinRel.getRight(),
+ ImmutableList.of(),
origJoinRel.getCondition(),
ImmutableSet.of(),
JoinRelType.SEMI);
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/LoptSemiJoinOptimizer.java
b/core/src/main/java/org/apache/calcite/rel/rules/LoptSemiJoinOptimizer.java
index aed93a0..1ae11a5 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/LoptSemiJoinOptimizer.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/LoptSemiJoinOptimizer.java
@@ -37,6 +37,7 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Util;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
@@ -320,7 +321,7 @@ public class LoptSemiJoinOptimizer {
multiJoin.getNumFieldsInJoinFactor(factIdx),
semiJoinCondition);
}
- return LogicalJoin.create(factRel, dimRel, semiJoinCondition,
+ return LogicalJoin.create(factRel, dimRel, ImmutableList.of(),
semiJoinCondition,
ImmutableSet.of(), JoinRelType.SEMI);
}
@@ -581,6 +582,7 @@ public class LoptSemiJoinOptimizer {
LogicalJoin chosenSemiJoin =
LogicalJoin.create(factRel,
chosenSemiJoins[bestDimIdx],
+ ImmutableList.of(),
semiJoin.getCondition(),
ImmutableSet.of(),
JoinRelType.SEMI);
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinFilterTransposeRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinFilterTransposeRule.java
index b3068ba..1e15233 100644
---
a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinFilterTransposeRule.java
+++
b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinFilterTransposeRule.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.calcite.rel.logical.LogicalJoin;
import org.apache.calcite.tools.RelBuilderFactory;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
/**
@@ -65,6 +66,8 @@ public class SemiJoinFilterTransposeRule extends RelOptRule {
RelNode newSemiJoin =
LogicalJoin.create(filter.getInput(),
semiJoin.getRight(),
+ // No need to copy the hints, the framework would try to do that.
+ ImmutableList.of(),
semiJoin.getCondition(),
ImmutableSet.of(),
JoinRelType.SEMI);
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinJoinTransposeRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinJoinTransposeRule.java
index cf83391..824d5e6 100644
---
a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinJoinTransposeRule.java
+++
b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinJoinTransposeRule.java
@@ -29,6 +29,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.ImmutableIntList;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
@@ -159,6 +160,8 @@ public class SemiJoinJoinTransposeRule extends RelOptRule {
LogicalJoin newSemiJoin =
LogicalJoin.create(leftSemiJoinOp,
semiJoin.getRight(),
+ // No need to copy the hints, the framework would try to do that.
+ ImmutableList.of(),
newSemiJoinFilter,
ImmutableSet.of(),
JoinRelType.SEMI);
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinProjectTransposeRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinProjectTransposeRule.java
index f601893..e786d8a 100644
---
a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinProjectTransposeRule.java
+++
b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinProjectTransposeRule.java
@@ -36,6 +36,7 @@ import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.Pair;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.List;
@@ -83,7 +84,11 @@ public class SemiJoinProjectTransposeRule extends RelOptRule
{
RexNode newCondition = adjustCondition(project, semiJoin);
LogicalJoin newSemiJoin =
- LogicalJoin.create(project.getInput(), semiJoin.getRight(),
newCondition,
+ LogicalJoin.create(project.getInput(),
+ semiJoin.getRight(),
+ // No need to copy the hints, the framework would try to do that.
+ ImmutableList.of(),
+ newCondition,
ImmutableSet.of(), JoinRelType.SEMI);
// Create the new projection. Note that the projection expressions
diff --git a/core/src/main/java/org/apache/calcite/rel/stream/StreamRules.java
b/core/src/main/java/org/apache/calcite/rel/stream/StreamRules.java
index 14c0c67..03ebb7b 100644
--- a/core/src/main/java/org/apache/calcite/rel/stream/StreamRules.java
+++ b/core/src/main/java/org/apache/calcite/rel/stream/StreamRules.java
@@ -87,7 +87,9 @@ public class StreamRules {
final Project project = call.rel(1);
final LogicalDelta newDelta = LogicalDelta.create(project.getInput());
final LogicalProject newProject =
- LogicalProject.create(newDelta, project.getProjects(),
+ LogicalProject.create(newDelta,
+ project.getHints(),
+ project.getProjects(),
project.getRowType().getFieldNames());
call.transformTo(newProject);
}
@@ -142,7 +144,7 @@ public class StreamRules {
final LogicalDelta newDelta =
LogicalDelta.create(aggregate.getInput());
final LogicalAggregate newAggregate =
- LogicalAggregate.create(newDelta, aggregate.getGroupSet(),
+ LogicalAggregate.create(newDelta, aggregate.getHints(),
aggregate.getGroupSet(),
aggregate.groupSets, aggregate.getAggCallList());
call.transformTo(newAggregate);
}
@@ -241,7 +243,7 @@ public class StreamRules {
.addAll(relOptTable.getQualifiedName())
.add("(STREAM)").build());
final LogicalTableScan newScan =
- LogicalTableScan.create(cluster, relOptTable2);
+ LogicalTableScan.create(cluster, relOptTable2, scan.getHints());
call.transformTo(newScan);
}
}
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
index 640b080..4f09cc9 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
@@ -988,10 +988,10 @@ public abstract class SqlUtil {
* @return the {@code RelHint} list
*/
public static List<RelHint> getRelHint(HintStrategyTable hintStrategies,
SqlNodeList sqlHints) {
- final List<RelHint> relHints = new ArrayList<>();
if (sqlHints == null || sqlHints.size() == 0) {
- return relHints;
+ return ImmutableList.of();
}
+ final ImmutableList.Builder<RelHint> relHints = ImmutableList.builder();
for (SqlNode node : sqlHints) {
assert node instanceof SqlHint;
final SqlHint sqlHint = (SqlHint) node;
@@ -1017,7 +1017,7 @@ public abstract class SqlUtil {
relHints.add(relHint);
}
}
- return ImmutableList.copyOf(relHints);
+ return relHints.build();
}
/**
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
index 0eae4d6..61b6422 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
@@ -1183,7 +1183,7 @@ public class RelDecorrelator implements ReflectiveVisitor
{
final RexNode condition =
RexUtil.composeConjunction(relBuilder.getRexBuilder(), conditions);
RelNode newJoin = relBuilder.push(leftFrame.r).push(rightFrame.r)
- .join(rel.getJoinType(), condition, ImmutableSet.of()).build();
+ .join(rel.getJoinType(), condition).build();
return register(rel, newJoin, mapOldToNewOutputs, corDefOutputs);
}
@@ -1220,12 +1220,12 @@ public class RelDecorrelator implements
ReflectiveVisitor {
RelNode newJoin = relBuilder
.push(leftFrame.r)
.push(rightFrame.r)
- .join(rel.getJoinType(), decorrelateExpr(currentRel, map, cm,
rel.getCondition()),
+ .join(rel.getJoinType(),
+ decorrelateExpr(currentRel, map, cm, rel.getCondition()),
ImmutableSet.of())
+ .hints(rel.getHints())
.build();
- newJoin = RelOptUtil.copyRelHints(rel, newJoin);
-
// Create the mapping between the output of the old correlation rel
// and the new join rel
Map<Integer, Integer> mapOldToNewOutputs = new HashMap<>();
@@ -2299,8 +2299,7 @@ public class RelDecorrelator implements ReflectiveVisitor
{
"nullIndicator")));
Join join =
- (Join) relBuilder.push(left).push(right)
- .join(joinType, joinCond, ImmutableSet.of()).build();
+ (Join) relBuilder.push(left).push(right).join(joinType,
joinCond).build();
// To the consumer of joinOutputProjRel, nullIndicator is located
// at the end
diff --git
a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
index 5436a26..4bf07b1 100644
---
a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
+++
b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
@@ -434,12 +434,12 @@ public class RelStructuredTypeFlattener implements
ReflectiveVisitor {
}
public void rewriteRel(LogicalJoin rel) {
- LogicalJoin newRel =
+ final LogicalJoin newRel =
LogicalJoin.create(getNewForOldRel(rel.getLeft()),
getNewForOldRel(rel.getRight()),
+ rel.getHints(),
rel.getCondition().accept(new RewriteRexShuttle()),
rel.getVariablesSet(), rel.getJoinType());
- newRel = (LogicalJoin) RelOptUtil.copyRelHints(rel, newRel);
setNewForOldRel(rel, newRel);
}
@@ -508,10 +508,10 @@ public class RelStructuredTypeFlattener implements
ReflectiveVisitor {
RelNode newInput = getNewForOldRel(rel.getInput());
List<RexNode> newProjects = Pair.left(flattenedExpList);
List<String> newNames = Pair.right(flattenedExpList);
- RelNode newRel = relBuilder.push(newInput)
+ final RelNode newRel = relBuilder.push(newInput)
.projectNamed(newProjects, newNames, true)
+ .hints(rel.getHints())
.build();
- newRel = RelOptUtil.copyRelHints(rel, newRel);
setNewForOldRel(rel, newRel);
}
diff --git
a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index e22cb50..8ed2017 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -767,8 +767,8 @@ public class SqlToRelConverter {
}
}
rel =
- LogicalProject.create(rel, Pair.left(newProjects),
- Pair.right(newProjects));
+ LogicalProject.create(rel, ImmutableList.of(),
+ Pair.left(newProjects), Pair.right(newProjects));
bb.root = rel;
distinctify(bb, false);
rel = bb.root;
@@ -787,8 +787,8 @@ public class SqlToRelConverter {
}
rel =
- LogicalProject.create(rel, Pair.left(undoProjects),
- Pair.right(undoProjects));
+ LogicalProject.create(rel, ImmutableList.of(),
+ Pair.left(undoProjects), Pair.right(undoProjects));
bb.setRoot(
rel,
false);
@@ -863,7 +863,9 @@ public class SqlToRelConverter {
exprs.add(rexBuilder.makeInputRef(bb.root, i));
}
bb.setRoot(
- LogicalProject.create(bb.root, exprs,
+ LogicalProject.create(bb.root,
+ ImmutableList.of(),
+ exprs,
rowType.getFieldNames().subList(0, fieldCount)),
false);
}
@@ -1166,7 +1168,10 @@ public class SqlToRelConverter {
final int keyCount = leftKeys.size();
final List<Integer> args = ImmutableIntList.range(0, keyCount);
LogicalAggregate aggregate =
- LogicalAggregate.create(seek, ImmutableBitSet.of(), null,
+ LogicalAggregate.create(seek,
+ ImmutableList.of(),
+ ImmutableBitSet.of(),
+ null,
ImmutableList.of(
AggregateCall.create(SqlStdOperatorTable.COUNT, false,
false, false, ImmutableList.of(), -1,
RelCollations.EMPTY,
@@ -1174,8 +1179,8 @@ public class SqlToRelConverter {
AggregateCall.create(SqlStdOperatorTable.COUNT, false,
false, false, args, -1, RelCollations.EMPTY, longType,
null)));
LogicalJoin join =
- LogicalJoin.create(bb.root, aggregate,
rexBuilder.makeLiteral(true),
- ImmutableSet.of(), JoinRelType.INNER);
+ LogicalJoin.create(bb.root, aggregate, ImmutableList.of(),
+ rexBuilder.makeLiteral(true), ImmutableSet.of(),
JoinRelType.INNER);
bb.setRoot(join, false);
}
final RexNode rex =
@@ -2397,12 +2402,15 @@ public class SqlToRelConverter {
table = table.extend(extendedFields);
}
final RelNode tableRel;
- final List<RelHint> hints = SqlUtil.getRelHint(hintStrategies, tableHints);
+ // Review Danny 2020-01-13: hacky to construct a new table scan
+ // in order to apply the hint strategies.
+ final List<RelHint> hints = hintStrategies.apply(
+ SqlUtil.getRelHint(hintStrategies, tableHints),
+ LogicalTableScan.create(cluster, table, ImmutableList.of()));
if (config.isConvertTableAccess()) {
tableRel = toRel(table, hints);
} else {
- tableRel = SqlUtil.attachRelHint(hintStrategies,
- hints, LogicalTableScan.create(cluster, table));
+ tableRel = LogicalTableScan.create(cluster, table, hints);
}
bb.setRoot(tableRel, true);
if (usedDataset[0]) {
@@ -2564,7 +2572,7 @@ public class SqlToRelConverter {
final Join originalJoin =
(Join) RelFactories.DEFAULT_JOIN_FACTORY.createJoin(leftRel, rightRel,
- joinCond, ImmutableSet.of(), joinType, false);
+ ImmutableList.of(), joinCond, ImmutableSet.of(), joinType, false);
RelNode node = RelOptUtil.pushDownJoinConditions(originalJoin, relBuilder);
// If join conditions are pushed down, update the leaves.
@@ -3059,7 +3067,7 @@ public class SqlToRelConverter {
*/
protected RelNode createAggregate(Blackboard bb, ImmutableBitSet groupSet,
ImmutableList<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) {
- return LogicalAggregate.create(bb.root, groupSet, groupSets, aggCalls);
+ return LogicalAggregate.create(bb.root, ImmutableList.of(), groupSet,
groupSets, aggCalls);
}
public RexDynamicParam convertDynamicParam(
@@ -3382,10 +3390,7 @@ public class SqlToRelConverter {
}
public RelNode toRel(final RelOptTable table, @Nonnull final List<RelHint>
hints) {
- final RelNode rel = table.toRel(createToRelContext(hints));
- final RelNode scan = rel instanceof Hintable && hints.size() > 0
- ? SqlUtil.attachRelHint(hintStrategies, hints, (Hintable) rel)
- : rel;
+ final RelNode scan = table.toRel(createToRelContext(hints));
final InitializerExpressionFactory ief =
Util.first(table.unwrap(InitializerExpressionFactory.class),
@@ -3965,6 +3970,7 @@ public class SqlToRelConverter {
RelFactories.DEFAULT_JOIN_FACTORY.createJoin(
ret,
relNode,
+ ImmutableList.of(),
rexBuilder.makeLiteral(true),
ImmutableSet.of(),
JoinRelType.INNER,
diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
index f31d892..7b240e6 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -53,6 +53,8 @@ import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.TableSpool;
import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rel.hint.Hintable;
+import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.calcite.rel.logical.LogicalProject;
import org.apache.calcite.rel.metadata.RelColumnMapping;
@@ -1071,7 +1073,7 @@ public class RelBuilder {
if (relOptTable == null) {
throw RESOURCE.tableNotFound(String.join(".", names)).ex();
}
- final RelNode scan = scanFactory.createScan(cluster, relOptTable);
+ final RelNode scan = scanFactory.createScan(cluster, relOptTable,
ImmutableList.of());
push(scan);
rename(relOptTable.getRowType().getFieldNames());
@@ -1254,6 +1256,34 @@ public class RelBuilder {
return project(nodes, fieldNames, false);
}
+ /** Creates a {@link Project} of the given list
+ * of expressions, using the given names.
+ *
+ * <p>Names are deduced as follows:
+ * <ul>
+ * <li>If the length of {@code fieldNames} is greater than the index of
+ * the current entry in {@code nodes}, and the entry in
+ * {@code fieldNames} is not null, uses it; otherwise
+ * <li>If an expression projects an input field,
+ * or is a cast an input field,
+ * uses the input field name; otherwise
+ * <li>If an expression is a call to
+ * {@link SqlStdOperatorTable#AS}
+ * (see {@link #alias}), removes the call but uses the intended alias.
+ * </ul>
+ *
+ * <p>After the field names have been inferred, makes the
+ * field names unique by appending numeric suffixes.
+ *
+ * @param nodes Expressions
+ * @param fieldNames Suggested field names
+ * @param force create project even if it is identity
+ */
+ public RelBuilder project(Iterable<? extends RexNode> nodes,
+ Iterable<String> fieldNames, boolean force) {
+ return project_(nodes, fieldNames, ImmutableList.of(), force);
+ }
+
/** Creates a {@link Project} of all original fields, plus the given
* expressions. */
public RelBuilder projectPlus(RexNode... nodes) {
@@ -1319,11 +1349,13 @@ public class RelBuilder {
*
* @param nodes Expressions
* @param fieldNames Suggested field names
+ * @param hints Hints
* @param force create project even if it is identity
*/
- public RelBuilder project(
+ private RelBuilder project_(
Iterable<? extends RexNode> nodes,
Iterable<String> fieldNames,
+ Iterable<RelHint> hints,
boolean force) {
final Frame frame = stack.peek();
final RelDataType inputRowType = frame.rel.getRowType();
@@ -1379,7 +1411,10 @@ public class RelBuilder {
}
}
stack.push(new Frame(project.getInput(), ImmutableList.copyOf(fields)));
- return project(newNodes, fieldNameList, force);
+ final ImmutableSet.Builder<RelHint> mergedHints = ImmutableSet.builder();
+ mergedHints.addAll(project.getHints());
+ mergedHints.addAll(hints);
+ return project_(newNodes, fieldNameList, mergedHints.build(), force);
}
// Simplify expressions.
@@ -1439,12 +1474,15 @@ public class RelBuilder {
} else {
// create "virtual" row type for project only rename fields
stack.pop();
+ // Ignore the hints.
stack.push(new Frame(frame.rel, fields.build()));
- return this;
}
+ return this;
}
final RelNode project =
- projectFactory.createProject(frame.rel, ImmutableList.copyOf(nodeList),
+ projectFactory.createProject(frame.rel,
+ ImmutableList.copyOf(hints),
+ ImmutableList.copyOf(nodeList),
fieldNameList);
stack.pop();
stack.push(new Frame(project, fields.build()));
@@ -1497,7 +1535,7 @@ public class RelBuilder {
final Project childProject = (Project) frame.rel;
final Project newInput = childProject.copy(childProject.getTraitSet(),
childProject.getInput(), childProject.getProjects(), rowType);
- stack.push(new Frame(newInput, frame.fields));
+ stack.push(new Frame(newInput.attachHints(childProject.getHints()),
frame.fields));
}
} else {
project(nodeList, rowType.getFieldNames(), force);
@@ -1590,7 +1628,7 @@ public class RelBuilder {
.collect(Collectors.toList()));
}
- /** Creates an {@link Aggregate} with a list of
+ /** Creates an {@link Aggregate} with multiple
* calls. */
public RelBuilder aggregate(GroupKey groupKey, Iterable<AggCall> aggCalls) {
final Registrar registrar =
@@ -1736,7 +1774,7 @@ public class RelBuilder {
List<AggregateCall> aggregateCalls, List<RexNode> extraNodes,
ImmutableList<Field> inFields) {
final RelNode aggregate = aggregateFactory.createAggregate(input,
- groupSet, groupSets, aggregateCalls);
+ ImmutableList.of(), groupSet, groupSets, aggregateCalls);
// build field list
final ImmutableList.Builder<Field> fields = ImmutableList.builder();
@@ -1878,7 +1916,7 @@ public class RelBuilder {
rowType,
transientTable,
ImmutableList.of(tableName));
- RelNode scan = scanFactory.createScan(cluster, relOptTable);
+ RelNode scan = scanFactory.createScan(cluster, relOptTable,
ImmutableList.of());
push(scan);
rename(rowType.getFieldNames());
return this;
@@ -1973,7 +2011,7 @@ public class RelBuilder {
}
}
- /** Creates a {@link Join}. */
+ /** Creates a {@link Join} with an array of conditions. */
public RelBuilder join(JoinRelType joinType, RexNode condition0,
RexNode... conditions) {
return join(joinType, Lists.asList(condition0, conditions));
@@ -1987,12 +2025,12 @@ public class RelBuilder {
ImmutableSet.of());
}
+ /** Creates a {@link Join} with one condition. */
public RelBuilder join(JoinRelType joinType, RexNode condition) {
return join(joinType, condition, ImmutableSet.of());
}
- /** Creates a {@link Join} with correlating
- * variables. */
+ /** Creates a {@link Join} with correlating variables. */
public RelBuilder join(JoinRelType joinType, RexNode condition,
Set<CorrelationId> variablesSet) {
Frame right = stack.pop();
@@ -2032,7 +2070,7 @@ public class RelBuilder {
join = correlateFactory.createCorrelate(left.rel, right.rel, id,
requiredColumns, joinType);
} else {
- join = joinFactory.createJoin(left.rel, right.rel, condition,
+ join = joinFactory.createJoin(left.rel, right.rel, ImmutableList.of(),
condition,
variablesSet, joinType, false);
}
final ImmutableList.Builder<Field> fields = ImmutableList.builder();
@@ -2118,8 +2156,13 @@ public class RelBuilder {
public RelBuilder semiJoin(Iterable<? extends RexNode> conditions) {
final Frame right = stack.pop();
final RelNode semiJoin =
- joinFactory.createJoin(peek(), right.rel,
- and(conditions), ImmutableSet.of(), JoinRelType.SEMI, false);
+ joinFactory.createJoin(peek(),
+ right.rel,
+ ImmutableList.of(),
+ and(conditions),
+ ImmutableSet.of(),
+ JoinRelType.SEMI,
+ false);
replaceTop(semiJoin);
return this;
}
@@ -2150,8 +2193,13 @@ public class RelBuilder {
public RelBuilder antiJoin(Iterable<? extends RexNode> conditions) {
final Frame right = stack.pop();
final RelNode antiJoin =
- joinFactory.createJoin(peek(), right.rel,
- and(conditions), ImmutableSet.of(), JoinRelType.ANTI, false);
+ joinFactory.createJoin(peek(),
+ right.rel,
+ ImmutableList.of(),
+ and(conditions),
+ ImmutableSet.of(),
+ JoinRelType.ANTI,
+ false);
replaceTop(antiJoin);
return this;
}
@@ -2431,6 +2479,7 @@ public class RelBuilder {
offsetNode, fetchNode);
replaceTop(
projectFactory.createProject(sort,
+ project.getHints(),
project.getProjects(),
Pair.right(project.getNamedProjects())));
return this;
@@ -2556,6 +2605,40 @@ public class RelBuilder {
return this;
}
+ /**
+ * Attaches an array of hints to the stack top relational expression.
+ *
+ * <p>The redundant hints would be eliminated.
+ *
+ * @param hints Hints
+ *
+ * @throws AssertionError if the top relational expression does not implement
+ * {@link org.apache.calcite.rel.hint.Hintable}
+ */
+ public RelBuilder hints(RelHint... hints) {
+ return hints(ImmutableList.copyOf(hints));
+ }
+
+ /**
+ * Attaches multiple hints to the stack top relational expression.
+ *
+ * <p>The redundant hints would be eliminated.
+ *
+ * @param hints Hints
+ *
+ * @throws AssertionError if the top relational expression does not implement
+ * {@link org.apache.calcite.rel.hint.Hintable}
+ */
+ public RelBuilder hints(Iterable<RelHint> hints) {
+ Objects.requireNonNull(hints);
+ final Frame frame = peek_();
+ assert frame != null : "There is no relational expression to attach the
hints";
+ assert frame.rel instanceof Hintable : "The top relational expression is
not a Hintable";
+ Hintable hintable = (Hintable) frame.rel;
+ replaceTop(hintable.attachHints(ImmutableList.copyOf(hints)));
+ return this;
+ }
+
/** Clears the stack.
*
* <p>The builder's state is now the same as when it was created. */
diff --git a/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java
b/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java
index bd49d78..e4dd6d0 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java
@@ -610,6 +610,7 @@ public class RelOptUtilTest {
.DEFAULT_PROJECT_FACTORY
.createProject(
agg,
+ ImmutableList.of(),
ImmutableList.of(
RexInputRef.of(0, agg.getRowType()),
RexInputRef.of(1, agg.getRowType()),
@@ -632,6 +633,7 @@ public class RelOptUtilTest {
.DEFAULT_PROJECT_FACTORY
.createProject(
agg,
+ ImmutableList.of(),
ImmutableList.of(
RexInputRef.of(0, agg.getRowType()),
RexInputRef.of(1, agg.getRowType()),
diff --git a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
index f0362f4..1714f2e 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
@@ -362,7 +362,8 @@ public class RelWriterTest {
LogicalTableScan scan =
LogicalTableScan.create(cluster,
relOptSchema.getTableForMember(
- Arrays.asList("hr", "emps")));
+ Arrays.asList("hr", "emps")),
+ ImmutableList.of());
final RexBuilder rexBuilder = cluster.getRexBuilder();
LogicalFilter filter =
LogicalFilter.create(scan,
@@ -376,7 +377,10 @@ public class RelWriterTest {
final RelDataType bigIntType =
cluster.getTypeFactory().createSqlType(SqlTypeName.BIGINT);
LogicalAggregate aggregate =
- LogicalAggregate.create(filter, ImmutableBitSet.of(0), null,
+ LogicalAggregate.create(filter,
+ ImmutableList.of(),
+ ImmutableBitSet.of(0),
+ null,
ImmutableList.of(
AggregateCall.create(SqlStdOperatorTable.COUNT,
true, false, false, ImmutableList.of(1), -1,
@@ -403,12 +407,14 @@ public class RelWriterTest {
LogicalTableScan scan =
LogicalTableScan.create(cluster,
relOptSchema.getTableForMember(
- Arrays.asList("hr", "emps")));
+ Arrays.asList("hr", "emps")),
+ ImmutableList.of());
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RelDataType bigIntType =
cluster.getTypeFactory().createSqlType(SqlTypeName.BIGINT);
LogicalProject project =
LogicalProject.create(scan,
+ ImmutableList.of(),
ImmutableList.of(
rexBuilder.makeInputRef(scan, 0),
rexBuilder.makeOver(bigIntType,
diff --git
a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
index 5394cd0..bb3918c 100644
---
a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
+++
b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
@@ -153,10 +153,11 @@ public class TraitPropagationTest {
}
};
- final RelNode rt1 = LogicalTableScan.create(cluster, t1);
+ final RelNode rt1 = LogicalTableScan.create(cluster, t1,
ImmutableList.of());
// project s column
RelNode project = LogicalProject.create(rt1,
+ ImmutableList.of(),
ImmutableList.of(
(RexNode) rexBuilder.makeInputRef(stringType, 0),
rexBuilder.makeInputRef(integerType, 1)),
diff --git a/core/src/test/java/org/apache/calcite/test/Matchers.java
b/core/src/test/java/org/apache/calcite/test/Matchers.java
index d22024c..2acd22a 100644
--- a/core/src/test/java/org/apache/calcite/test/Matchers.java
+++ b/core/src/test/java/org/apache/calcite/test/Matchers.java
@@ -18,6 +18,7 @@ package org.apache.calcite.test;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.hint.Hintable;
import org.apache.calcite.util.TestUtil;
import org.apache.calcite.util.Util;
@@ -205,6 +206,17 @@ public class Matchers {
}
/**
+ * Creates a Matcher that matches a {@link RelNode} if its hints string
+ * representation is equal to the given {@code value}.
+ */
+ public static Matcher<RelNode> hasHints(final String value) {
+ return compose(Is.is(value),
+ input -> input instanceof Hintable
+ ? ((Hintable) input).getHints().toString()
+ : "[]");
+ }
+
+ /**
* Creates a {@link Matcher} that matches execution plan and trims {@code ,
id=123} node ids.
* {@link RelNode#getId()} is not stable across runs, so this matcher
enables to trim those.
* @param value execpted execution plan
diff --git a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
index e5468dc..471152e 100644
--- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
@@ -33,6 +33,7 @@ import org.apache.calcite.rel.core.RelFactories;
import org.apache.calcite.rel.core.TableFunctionScan;
import org.apache.calcite.rel.core.TableModify;
import org.apache.calcite.rel.core.Window;
+import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
@@ -83,6 +84,7 @@ import java.util.TreeSet;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import static org.apache.calcite.test.Matchers.hasHints;
import static org.apache.calcite.test.Matchers.hasTree;
import static org.hamcrest.CoreMatchers.allOf;
@@ -3051,4 +3053,91 @@ public class RelBuilderTest {
+ " LogicalTableScan(table=[[scott, DEPT]])\n";
assertThat(root, hasTree(expected));
}
+
+ @Test public void testHints() {
+ final RelHint indexHint = RelHint.of(Collections.emptyList(),
+ "INDEX",
+ Arrays.asList("_idx1", "_idx2"));
+ final RelHint propsHint = RelHint.of(Collections.singletonList(0),
+ "PROPERTIES",
+ ImmutableMap.of("parallelism", "3", "mem", "20Mb"));
+ final RelHint noHashJoinHint = RelHint.of(Collections.singletonList(0),
+ "NO_HASH_JOIN");
+ final RelBuilder builder = RelBuilder.create(config().build());
+ // Equivalent SQL:
+ // SELECT *
+ // FROM emp /*+ INDEX(_idx1, _idx2) */
+ final RelNode root = builder
+ .scan("EMP")
+ .hints(indexHint)
+ .build();
+ assertThat(root,
+ hasHints("[[INDEX inheritPath:[] options:[_idx1, _idx2]]]"));
+ // Equivalent SQL:
+ // SELECT /*+ PROPERTIES(parallelism='3', mem='20Mb') */
+ // *
+ // FROM emp /*+ INDEX(_idx1, _idx2) */
+ final RelNode root1 = builder
+ .scan("EMP")
+ .hints(indexHint, propsHint)
+ .build();
+ assertThat(root1,
+ hasHints("[[INDEX inheritPath:[] options:[_idx1, _idx2]], "
+ + "[PROPERTIES inheritPath:[0] options:{parallelism=3,
mem=20Mb}]]"));
+ // Equivalent SQL:
+ // SELECT /*+ NO_HASH_JOIN */
+ // *
+ // FROM emp
+ // join dept
+ // on emp.deptno = dept.deptno
+ final RelNode root2 = builder
+ .scan("EMP")
+ .scan("DEPT")
+ .join(JoinRelType.INNER,
+ builder.equals(
+ builder.field(2, 0, "DEPTNO"),
+ builder.field(2, 1, "DEPTNO")))
+ .hints(noHashJoinHint)
+ .build();
+ assertThat(root2, hasHints("[[NO_HASH_JOIN inheritPath:[0]]]"));
+ }
+
+ @Test public void testHintsOnEmptyStack() {
+ final RelHint indexHint = RelHint.of(Collections.emptyList(),
+ "INDEX",
+ Arrays.asList("_idx1", "_idx2"));
+ // Attach hints on empty stack.
+ final AssertionError error = assertThrows(
+ AssertionError.class,
+ () -> RelBuilder.create(config().build()).hints(indexHint),
+ "hints() should fail on empty stack");
+ assertThat(error.getMessage(),
+ containsString("There is no relational expression to attach the
hints"));
+ }
+
+ @Test public void testHintsOnNonHintable() {
+ final RelHint indexHint = RelHint.of(Collections.emptyList(),
+ "INDEX",
+ Arrays.asList("_idx1", "_idx2"));
+ // Attach hints on non hintable.
+ final AssertionError error1 = assertThrows(
+ AssertionError.class,
+ () -> {
+ final RelBuilder builder = RelBuilder.create(config().build());
+ // Equivalent SQL:
+ // SELECT *
+ // FROM emp
+ // WHERE EMPNO = 124
+ builder
+ .scan("EMP")
+ .filter(
+ builder.equals(
+ builder.field("EMPNO"),
+ builder.literal(124)))
+ .hints(indexHint);
+ },
+ "hints() should fail on non Hintable relational expression");
+ assertThat(error1.getMessage(),
+ containsString("The top relational expression is not a Hintable"));
+ }
}
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 29ecb5d..2b84ae2 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -1468,7 +1468,7 @@ public class RelMetadataTest extends SqlToRelTestBase {
private void checkCollation(RelOptCluster cluster, RelOptTable empTable,
RelOptTable deptTable) {
final RexBuilder rexBuilder = cluster.getRexBuilder();
- final LogicalTableScan empScan = LogicalTableScan.create(cluster,
empTable);
+ final LogicalTableScan empScan = LogicalTableScan.create(cluster,
empTable, ImmutableList.of());
List<RelCollation> collations =
RelMdCollation.table(empScan.getTable());
@@ -1500,11 +1500,13 @@ public class RelMetadataTest extends SqlToRelTestBase {
assertThat(collations.get(0).getFieldCollations().get(1).getFieldIndex(),
equalTo(0));
- final LogicalProject project = LogicalProject.create(empSort, projects,
+ final LogicalProject project = LogicalProject.create(empSort,
+ ImmutableList.of(),
+ projects,
ImmutableList.of("a", "b", "c", "d"));
final LogicalTableScan deptScan =
- LogicalTableScan.create(cluster, deptTable);
+ LogicalTableScan.create(cluster, deptTable, ImmutableList.of());
final RelCollation deptCollation =
RelCollations.of(new RelFieldCollation(0), new RelFieldCollation(1));
@@ -1653,7 +1655,7 @@ public class RelMetadataTest extends SqlToRelTestBase {
RelOptTable deptTable) {
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RelMetadataQuery mq = cluster.getMetadataQuery();
- final LogicalTableScan empScan = LogicalTableScan.create(cluster,
empTable);
+ final LogicalTableScan empScan = LogicalTableScan.create(cluster,
empTable, ImmutableList.of());
Double rowSize = mq.getAverageRowSize(empScan);
List<Double> columnSizes = mq.getAverageColumnSizes(empScan);
@@ -1708,7 +1710,7 @@ public class RelMetadataTest extends SqlToRelTestBase {
// Filter
final LogicalTableScan deptScan =
- LogicalTableScan.create(cluster, deptTable);
+ LogicalTableScan.create(cluster, deptTable, ImmutableList.of());
final LogicalFilter filter =
LogicalFilter.create(deptScan,
rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN,
@@ -1723,6 +1725,7 @@ public class RelMetadataTest extends SqlToRelTestBase {
// Project
final LogicalProject deptProject =
LogicalProject.create(filter,
+ ImmutableList.of(),
ImmutableList.of(
rexBuilder.makeInputRef(filter, 0),
rexBuilder.makeInputRef(filter, 1),
@@ -1740,8 +1743,8 @@ public class RelMetadataTest extends SqlToRelTestBase {
// Join
final LogicalJoin join =
- LogicalJoin.create(empScan, deptProject, rexBuilder.makeLiteral(true),
- ImmutableSet.of(), JoinRelType.INNER);
+ LogicalJoin.create(empScan, deptProject, ImmutableList.of(),
+ rexBuilder.makeLiteral(true), ImmutableSet.of(),
JoinRelType.INNER);
rowSize = mq.getAverageRowSize(join);
columnSizes = mq.getAverageColumnSizes(join);
assertThat(columnSizes.size(), equalTo(13));
@@ -1753,7 +1756,9 @@ public class RelMetadataTest extends SqlToRelTestBase {
// Aggregate
final LogicalAggregate aggregate =
- LogicalAggregate.create(join, ImmutableBitSet.of(2, 0),
+ LogicalAggregate.create(join,
+ ImmutableList.of(),
+ ImmutableBitSet.of(2, 0),
ImmutableList.of(),
ImmutableList.of(
AggregateCall.create(SqlStdOperatorTable.COUNT,
@@ -1793,7 +1798,8 @@ public class RelMetadataTest extends SqlToRelTestBase {
final RelBuilder relBuilder = RelBuilder.proto().create(cluster, null);
final RelMetadataQuery mq = cluster.getMetadataQuery();
- final LogicalTableScan empScan = LogicalTableScan.create(cluster,
empTable);
+ final LogicalTableScan empScan = LogicalTableScan.create(cluster, empTable,
+ ImmutableList.of());
relBuilder.push(empScan);
RelOptPredicateList predicates =
@@ -1809,7 +1815,7 @@ public class RelMetadataTest extends SqlToRelTestBase {
assertThat(predicates.pulledUpPredicates, sortsAs("[=($0, 1)]"));
final LogicalTableScan deptScan =
- LogicalTableScan.create(cluster, deptTable);
+ LogicalTableScan.create(cluster, deptTable, ImmutableList.of());
relBuilder.push(deptScan);
relBuilder.semiJoin(
@@ -2396,7 +2402,8 @@ public class RelMetadataTest extends SqlToRelTestBase {
final RelBuilder relBuilder = RelBuilder.proto().create(cluster, null);
final RelMetadataQuery mq = cluster.getMetadataQuery();
- final LogicalTableScan empScan = LogicalTableScan.create(cluster,
empTable);
+ final LogicalTableScan empScan = LogicalTableScan.create(cluster, empTable,
+ ImmutableList.of());
relBuilder.push(empScan);
RelOptPredicateList predicates =
@@ -2417,7 +2424,7 @@ public class RelMetadataTest extends SqlToRelTestBase {
assertThat(inputRef1.getIndex(), is(0));
final LogicalTableScan deptScan =
- LogicalTableScan.create(cluster, deptTable);
+ LogicalTableScan.create(cluster, deptTable, ImmutableList.of());
relBuilder.push(deptScan);
relBuilder.join(JoinRelType.INNER,
@@ -2602,8 +2609,8 @@ public class RelMetadataTest extends SqlToRelTestBase {
final RexBuilder rexBuilder = node.getCluster().getRexBuilder();
// Join
final LogicalJoin join =
- LogicalJoin.create(nodeWithUnknown, node, rexBuilder.makeLiteral(true),
- ImmutableSet.of(), JoinRelType.INNER);
+ LogicalJoin.create(nodeWithUnknown, node, ImmutableList.of(),
+ rexBuilder.makeLiteral(true), ImmutableSet.of(),
JoinRelType.INNER);
final RelMetadataQuery mq = node.getCluster().getMetadataQuery();
final Set<RelTableRef> tableReferences = mq.getTableReferences(join);
assertNull(tableReferences);
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 48801d3..e94a271 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
@@ -90,6 +90,7 @@ import static org.hamcrest.collection.IsIn.in;
import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Unit test for {@link org.apache.calcite.rel.hint.RelHint}.
@@ -477,10 +478,11 @@ public class SqlHintsConverterTest extends
SqlToRelTestBase {
assertThat(1, is(join.getHints().size()));
call.transformTo(
LogicalJoin.create(join.getLeft(),
- join.getRight(),
- join.getCondition(),
- join.getVariablesSet(),
- join.getJoinType()));
+ join.getRight(),
+ ImmutableList.of(),
+ join.getCondition(),
+ join.getVariablesSet(),
+ join.getJoinType()));
}
}
@@ -599,6 +601,7 @@ public class SqlHintsConverterTest extends SqlToRelTestBase
{
void fails(String failedMsg) {
try {
tester.convertSqlToRel(sql);
+ fail("Unexpected exception");
} catch (AssertionError e) {
assertThat(e.getMessage(), is(failedMsg));
}
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
index edf6735..c79019c 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
@@ -411,7 +411,8 @@ public abstract class SqlToRelTestBase {
}
public RelNode toRel(ToRelContext context) {
- return LogicalTableScan.create(context.getCluster(), this);
+ return LogicalTableScan.create(context.getCluster(), this,
+ context.getTableHints());
}
public List<RelCollation> getCollationList() {
@@ -493,7 +494,8 @@ public abstract class SqlToRelTestBase {
}
public RelNode toRel(ToRelContext context) {
- return LogicalTableScan.create(context.getCluster(), this);
+ return LogicalTableScan.create(context.getCluster(), this,
+ context.getTableHints());
}
public List<RelCollation> getCollationList() {
diff --git
a/core/src/test/java/org/apache/calcite/test/catalog/MockCatalogReader.java
b/core/src/test/java/org/apache/calcite/test/catalog/MockCatalogReader.java
index 05b9b19..fcad4d1 100644
--- a/core/src/test/java/org/apache/calcite/test/catalog/MockCatalogReader.java
+++ b/core/src/test/java/org/apache/calcite/test/catalog/MockCatalogReader.java
@@ -493,7 +493,7 @@ public abstract class MockCatalogReader extends
CalciteCatalogReader {
}
public RelNode toRel(ToRelContext context) {
- return LogicalTableScan.create(context.getCluster(), this);
+ return LogicalTableScan.create(context.getCluster(), this,
context.getTableHints());
}
public List<RelCollation> getCollationList() {
@@ -864,7 +864,8 @@ public abstract class MockCatalogReader extends
CalciteCatalogReader {
}
@Override public RelNode toRel(ToRelContext context) {
- RelNode rel = LogicalTableScan.create(context.getCluster(), fromTable);
+ RelNode rel = LogicalTableScan.create(context.getCluster(), fromTable,
+ context.getTableHints());
final RexBuilder rexBuilder = context.getCluster().getRexBuilder();
rel = LogicalFilter.create(
rel, getConstraint(rexBuilder, rel.getRowType()));
@@ -880,7 +881,9 @@ public abstract class MockCatalogReader extends
CalciteCatalogReader {
return mapping.size();
}
};
- return LogicalProject.create(rel, Pair.left(projects),
+ return LogicalProject.create(rel,
+ ImmutableList.of(),
+ Pair.left(projects),
Pair.right(projects));
}
@@ -919,7 +922,7 @@ public abstract class MockCatalogReader extends
CalciteCatalogReader {
}
@Override public RelNode toRel(RelOptTable.ToRelContext context,
RelOptTable relOptTable) {
- return LogicalTableScan.create(context.getCluster(), relOptTable);
+ return LogicalTableScan.create(context.getCluster(), relOptTable,
context.getTableHints());
}
}
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 04f247d..d9eb8ef 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
@@ -23,7 +23,7 @@ from (select /*+ resource(mem='20Mb')*/ empno, ename from
emp)]]>
</Resource>
<Resource name="hints">
<![CDATA[
-Project:[[RESOURCE inheritPath:[] options:{PARALLELISM=3}], [REPARTITION
inheritPath:[] options:[10]]]
+Project:[[RESOURCE inheritPath:[] options:{MEM=20Mb}], [RESOURCE
inheritPath:[] options:{PARALLELISM=3}], [REPARTITION inheritPath:[]
options:[10]]]
]]>
</Resource>
</TestCase>
@@ -165,7 +165,7 @@ from emp left join dept on emp.deptno = dept.deptno)]]>
</Resource>
<Resource name="hints">
<![CDATA[
-Project:[[RESOURCE inheritPath:[] options:{PARALLELISM=3}], [NO_HASH_JOIN
inheritPath:[]]]
+Project:[[RESOURCE inheritPath:[] options:{MEM=20Mb}], [RESOURCE
inheritPath:[] options:{PARALLELISM=3}], [NO_HASH_JOIN inheritPath:[]]]
LogicalJoin:[[NO_HASH_JOIN inheritPath:[0]]]
]]>
</Resource>
diff --git
a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
index e7ef4b0..9c9f43c 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
@@ -242,7 +242,7 @@ public class DruidTable extends AbstractTable implements
TranslatableTable {
public RelNode toRel(RelOptTable.ToRelContext context,
RelOptTable relOptTable) {
final RelOptCluster cluster = context.getCluster();
- final TableScan scan = LogicalTableScan.create(cluster, relOptTable);
+ final TableScan scan = LogicalTableScan.create(cluster, relOptTable,
ImmutableList.of());
return DruidQuery.create(cluster,
cluster.traitSetOf(BindableConvention.INSTANCE), relOptTable, this,
ImmutableList.of(scan));
diff --git
a/pig/src/main/java/org/apache/calcite/adapter/pig/PigRelFactories.java
b/pig/src/main/java/org/apache/calcite/adapter/pig/PigRelFactories.java
index e1c3050..6cccb6a 100644
--- a/pig/src/main/java/org/apache/calcite/adapter/pig/PigRelFactories.java
+++ b/pig/src/main/java/org/apache/calcite/adapter/pig/PigRelFactories.java
@@ -26,8 +26,10 @@ import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Util;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -58,7 +60,9 @@ public class PigRelFactories {
public static final PigTableScanFactory INSTANCE = new
PigTableScanFactory();
- @Override public RelNode createScan(RelOptCluster cluster, RelOptTable
table) {
+ @Override public RelNode createScan(RelOptCluster cluster,
+ RelOptTable table, List<RelHint> hints) {
+ Util.discard(hints);
return new PigTableScan(cluster, cluster.traitSetOf(PigRel.CONVENTION),
table);
}
}
@@ -92,8 +96,10 @@ public class PigRelFactories {
public static final PigAggregateFactory INSTANCE = new
PigAggregateFactory();
@Override public RelNode createAggregate(RelNode input,
+ List<RelHint> hints,
ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
+ Util.discard(hints);
return new PigAggregate(input.getCluster(), input.getTraitSet(), input,
groupSet, groupSets, aggCalls);
}
@@ -108,8 +114,12 @@ public class PigRelFactories {
public static final PigJoinFactory INSTANCE = new PigJoinFactory();
- @Override public RelNode createJoin(RelNode left, RelNode right, RexNode
condition,
- Set<CorrelationId> variablesSet, JoinRelType joinType, boolean
semiJoinDone) {
+ @Override public RelNode createJoin(RelNode left, RelNode right,
List<RelHint> hints,
+ RexNode condition, Set<CorrelationId> variablesSet, JoinRelType
joinType,
+ boolean semiJoinDone) {
+ Util.discard(hints);
+ Util.discard(variablesSet);
+ Util.discard(semiJoinDone);
return new PigJoin(left.getCluster(), left.getTraitSet(), left, right,
condition, joinType);
}
diff --git a/piglet/src/main/java/org/apache/calcite/piglet/PigRelBuilder.java
b/piglet/src/main/java/org/apache/calcite/piglet/PigRelBuilder.java
index e85d5b3..96150af 100644
--- a/piglet/src/main/java/org/apache/calcite/piglet/PigRelBuilder.java
+++ b/piglet/src/main/java/org/apache/calcite/piglet/PigRelBuilder.java
@@ -78,7 +78,7 @@ public class PigRelBuilder extends RelBuilder {
/** Creates a PigRelBuilder. */
public static PigRelBuilder create(FrameworkConfig config) {
final RelBuilder relBuilder = RelBuilder.create(config);
- Hook.REL_BUILDER_SIMPLIFY.add(Hook.propertyJ(false));
+ Hook.REL_BUILDER_SIMPLIFY.addThread(Hook.propertyJ(false));
return new PigRelBuilder(config.getContext(), relBuilder.getCluster(),
relBuilder.getRelOptSchema());
}
@@ -253,7 +253,7 @@ public class PigRelBuilder extends RelBuilder {
* @return This builder
*/
private RelBuilder scan(RelOptTable tableSchema) {
- final RelNode scan = getScanFactory().createScan(cluster, tableSchema);
+ final RelNode scan = getScanFactory().createScan(cluster, tableSchema,
ImmutableList.of());
push(scan);
return this;
}
diff --git a/site/_docs/history.md b/site/_docs/history.md
index b24c767..cc842df 100644
--- a/site/_docs/history.md
+++ b/site/_docs/history.md
@@ -33,6 +33,7 @@ Downloads are available on the
#### Breaking Changes
* Constructors for `Project`, `TableScan`, `Calc`, `Aggregate` and `Join`
introduce new parameter named "hints";
+* Logical `RelNode`'s `create` method need to pass in hints explicitly;
* `Project` names will not represent in `RelNode` digest anymore;
* `RexCall`s are default to be normalized in the `RelNode` digest.
diff --git
a/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
b/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
index 2163d8e..10ca4f8 100644
---
a/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
+++
b/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
@@ -228,7 +228,7 @@ public class SplunkPushDownRule
// handle top projection (ie reordering and renaming)
List<RelDataTypeField> newFields = bottomFields;
if (topProj != null) {
- LOGGER.debug("topProj: {}", String.valueOf(topProj.getPermutation()));
+ LOGGER.debug("topProj: {}", topProj.getPermutation());
newFields = new ArrayList<>();
int i = 0;
for (RexNode rn : topProj.getProjects()) {
@@ -279,7 +279,8 @@ public class SplunkPushDownRule
if (proj == null) {
return rel;
}
- return LogicalProject.create(rel, proj.getProjects(), proj.getRowType());
+ return LogicalProject.create(rel, proj.getHints(),
+ proj.getProjects(), proj.getRowType());
}
// TODO: use StringBuilder instead of String