use of org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class EnumerableLimit method create.
/**
* Creates an EnumerableLimit.
*/
public static EnumerableLimit create(final RelNode input, RexNode offset, RexNode fetch) {
final RelOptCluster cluster = input.getCluster();
final RelMetadataQuery mq = cluster.getMetadataQuery();
final RelTraitSet traitSet = cluster.traitSetOf(EnumerableConvention.INSTANCE).replaceIfs(RelCollationTraitDef.INSTANCE, new Supplier<List<RelCollation>>() {
public List<RelCollation> get() {
return RelMdCollation.limit(mq, input);
}
}).replaceIf(RelDistributionTraitDef.INSTANCE, new Supplier<RelDistribution>() {
public RelDistribution get() {
return RelMdDistribution.limit(mq, input);
}
});
return new EnumerableLimit(cluster, traitSet, input, offset, fetch);
}
use of org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class EnumerableMergeJoin method create.
public static EnumerableMergeJoin create(RelNode left, RelNode right, RexLiteral condition, ImmutableIntList leftKeys, ImmutableIntList rightKeys, JoinRelType joinType) throws InvalidRelException {
final RelOptCluster cluster = right.getCluster();
RelTraitSet traitSet = cluster.traitSet();
if (traitSet.isEnabled(RelCollationTraitDef.INSTANCE)) {
final RelMetadataQuery mq = cluster.getMetadataQuery();
final List<RelCollation> collations = RelMdCollation.mergeJoin(mq, left, right, leftKeys, rightKeys);
traitSet = traitSet.replace(collations);
}
return new EnumerableMergeJoin(cluster, traitSet, left, right, condition, leftKeys, rightKeys, ImmutableSet.<CorrelationId>of(), joinType);
}
use of org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class EnumerableMergeJoinRule method convert.
@Override
public RelNode convert(RelNode rel) {
LogicalJoin join = (LogicalJoin) rel;
final JoinInfo info = JoinInfo.of(join.getLeft(), join.getRight(), join.getCondition());
if (join.getJoinType() != JoinRelType.INNER) {
// (It supports non-equi join, using a post-filter; see below.)
return null;
}
if (info.pairs().size() == 0) {
// EnumerableMergeJoin CAN support cartesian join, but disable it for now.
return null;
}
final List<RelNode> newInputs = Lists.newArrayList();
final List<RelCollation> collations = Lists.newArrayList();
int offset = 0;
for (Ord<RelNode> ord : Ord.zip(join.getInputs())) {
RelTraitSet traits = ord.e.getTraitSet().replace(EnumerableConvention.INSTANCE);
if (!info.pairs().isEmpty()) {
final List<RelFieldCollation> fieldCollations = Lists.newArrayList();
for (int key : info.keys().get(ord.i)) {
fieldCollations.add(new RelFieldCollation(key, RelFieldCollation.Direction.ASCENDING, RelFieldCollation.NullDirection.LAST));
}
final RelCollation collation = RelCollations.of(fieldCollations);
collations.add(RelCollations.shift(collation, offset));
traits = traits.replace(collation);
}
newInputs.add(convert(ord.e, traits));
offset += ord.e.getRowType().getFieldCount();
}
final RelNode left = newInputs.get(0);
final RelNode right = newInputs.get(1);
final RelOptCluster cluster = join.getCluster();
RelNode newRel;
try {
RelTraitSet traits = join.getTraitSet().replace(EnumerableConvention.INSTANCE);
if (!collations.isEmpty()) {
traits = traits.replace(collations);
}
newRel = new EnumerableMergeJoin(cluster, traits, left, right, info.getEquiCondition(left, right, cluster.getRexBuilder()), info.leftKeys, info.rightKeys, join.getVariablesSet(), join.getJoinType());
} catch (InvalidRelException e) {
EnumerableRules.LOGGER.debug(e.toString());
return null;
}
if (!info.isEqui()) {
newRel = new EnumerableFilter(cluster, newRel.getTraitSet(), newRel, info.getRemaining(cluster.getRexBuilder()));
}
return newRel;
}
use of org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class Prepare method optimize.
/**
* Optimizes a query plan.
*
* @param root Root of relational expression tree
* @param materializations Tables known to be populated with a given query
* @param lattices Lattices
* @return an equivalent optimized relational expression
*/
protected RelRoot optimize(RelRoot root, final List<Materialization> materializations, final List<CalciteSchema.LatticeEntry> lattices) {
final RelOptPlanner planner = root.rel.getCluster().getPlanner();
final DataContext dataContext = context.getDataContext();
planner.setExecutor(new RexExecutorImpl(dataContext));
final List<RelOptMaterialization> materializationList = new ArrayList<>();
for (Materialization materialization : materializations) {
List<String> qualifiedTableName = materialization.materializedTable.path();
materializationList.add(new RelOptMaterialization(materialization.tableRel, materialization.queryRel, materialization.starRelOptTable, qualifiedTableName));
}
final List<RelOptLattice> latticeList = new ArrayList<>();
for (CalciteSchema.LatticeEntry lattice : lattices) {
final CalciteSchema.TableEntry starTable = lattice.getStarTable();
final JavaTypeFactory typeFactory = context.getTypeFactory();
final RelOptTableImpl starRelOptTable = RelOptTableImpl.create(catalogReader, starTable.getTable().getRowType(typeFactory), starTable, null);
latticeList.add(new RelOptLattice(lattice.getLattice(), starRelOptTable));
}
final RelTraitSet desiredTraits = getDesiredRootTraitSet(root);
// Work around
// [CALCITE-1774] Allow rules to be registered during planning process
// by briefly creating each kind of physical table to let it register its
// rules. The problem occurs when plans are created via RelBuilder, not
// the usual process (SQL and SqlToRelConverter.Config.isConvertTableAccess
// = true).
final RelVisitor visitor = new RelVisitor() {
@Override
public void visit(RelNode node, int ordinal, RelNode parent) {
if (node instanceof TableScan) {
final RelOptCluster cluster = node.getCluster();
final RelOptTable.ToRelContext context = RelOptUtil.getContext(cluster);
final RelNode r = node.getTable().toRel(context);
planner.registerClass(r);
}
super.visit(node, ordinal, parent);
}
};
visitor.go(root.rel);
final Program program = getProgram();
final RelNode rootRel4 = program.run(planner, root.rel, desiredTraits, materializationList, latticeList);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Plan after physical tweaks: {}", RelOptUtil.toString(rootRel4, SqlExplainLevel.ALL_ATTRIBUTES));
}
return root.withRel(rootRel4);
}
use of org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class RelOptTableImpl method toRel.
public RelNode toRel(ToRelContext context) {
// RelOptTable by replacing with immutable RelRecordType using the same field list.
if (this.getRowType().isDynamicStruct()) {
final RelDataType staticRowType = new RelRecordType(getRowType().getFieldList());
final RelOptTable relOptTable = this.copy(staticRowType);
return relOptTable.toRel(context);
}
// If there are any virtual columns, create a copy of this table without
// those virtual columns.
final List<ColumnStrategy> strategies = getColumnStrategies();
if (strategies.contains(ColumnStrategy.VIRTUAL)) {
final RelDataTypeFactory.Builder b = context.getCluster().getTypeFactory().builder();
for (RelDataTypeField field : rowType.getFieldList()) {
if (strategies.get(field.getIndex()) != ColumnStrategy.VIRTUAL) {
b.add(field.getName(), field.getType());
}
}
final RelOptTable relOptTable = new RelOptTableImpl(this.schema, b.build(), this.names, this.table, this.expressionFunction, this.rowCount) {
@Override
public <T> T unwrap(Class<T> clazz) {
if (clazz.isAssignableFrom(InitializerExpressionFactory.class)) {
return clazz.cast(NullInitializerExpressionFactory.INSTANCE);
}
return super.unwrap(clazz);
}
};
return relOptTable.toRel(context);
}
if (table instanceof TranslatableTable) {
return ((TranslatableTable) table).toRel(context, this);
}
final RelOptCluster cluster = context.getCluster();
if (Hook.ENABLE_BINDABLE.get(false)) {
return LogicalTableScan.create(cluster, this);
}
if (CalcitePrepareImpl.ENABLE_ENUMERABLE && table instanceof QueryableTable) {
return EnumerableTableScan.create(cluster, this);
}
if (table instanceof ScannableTable || table instanceof FilterableTable || table instanceof ProjectableFilterableTable) {
return LogicalTableScan.create(cluster, this);
}
if (CalcitePrepareImpl.ENABLE_ENUMERABLE) {
return EnumerableTableScan.create(cluster, this);
}
throw new AssertionError();
}
Aggregations