Skip to content

Commit

Permalink
[OPTIQ-392] RelFieldTrimmer should use factory to create new rel nodes
Browse files Browse the repository at this point in the history
Add SetOpRel.kind, to distinguish between UNION, INTERSECT, MINUS (aka EXCEPT).

Close apache/calcite#9
  • Loading branch information
ashutoshc authored and julianhyde committed Aug 29, 2014
1 parent e60fa76 commit d30a76b
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 72 deletions.
3 changes: 2 additions & 1 deletion core/src/main/java/org/eigenbase/rel/IntersectRelBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eigenbase.rel.metadata.RelMetadataQuery;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelTraitSet;
import org.eigenbase.sql.SqlKind;

/**
* Abstract base class for implementations of
Expand All @@ -36,7 +37,7 @@ public IntersectRelBase(
RelTraitSet traits,
List<RelNode> inputs,
boolean all) {
super(cluster, traits, inputs, all);
super(cluster, traits, inputs, SqlKind.INTERSECT, all);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/org/eigenbase/rel/MinusRelBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eigenbase.rel.metadata.RelMetadataQuery;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelTraitSet;
import org.eigenbase.sql.SqlKind;

/**
* Abstract base class for implementations of
Expand All @@ -33,7 +34,7 @@ public MinusRelBase(
RelTraitSet traits,
List<RelNode> inputs,
boolean all) {
super(cluster, traits, inputs, all);
super(cluster, traits, inputs, SqlKind.EXCEPT, all);
}

/**
Expand Down
98 changes: 98 additions & 0 deletions core/src/main/java/org/eigenbase/rel/RelFactories.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@
package org.eigenbase.rel;

import java.util.AbstractList;
import java.util.BitSet;
import java.util.List;
import java.util.Set;

import org.eigenbase.rel.rules.SemiJoinRel;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelTraitSet;
import org.eigenbase.reltype.RelDataTypeField;
import org.eigenbase.rex.RexBuilder;
import org.eigenbase.rex.RexNode;
import org.eigenbase.sql.SqlKind;
import org.eigenbase.util.mapping.Mappings;

import com.google.common.collect.ImmutableList;
Expand All @@ -42,6 +46,15 @@ public class RelFactories {

public static final JoinFactory DEFAULT_JOIN_FACTORY = new JoinFactoryImpl();

public static final SortFactory DEFAULT_SORT_FACTORY =
new SortFactoryImpl();

public static final AggregateFactory DEFAULT_AGGREGATE_FACTORY =
new AggregateFactoryImpl();

public static final SetOpFactory DEFAULT_SET_OP_FACTORY =
new SetOpFactoryImpl();

private RelFactories() {
}

Expand Down Expand Up @@ -69,6 +82,79 @@ public RelNode createProject(RelNode child, List<RexNode> childExprs,
}
}

/**
* Can create a {@link org.eigenbase.rel.SortRel} of the appropriate type
* for this rule's calling convention.
*/
public interface SortFactory {
RelNode createSort(RelTraitSet traits, RelNode child,
RelCollation collation, RexNode offset, RexNode fetch);
}

/**
* Implementation of {@link org.eigenbase.rel.RelFactories.SortFactory} that
* returns vanilla {@link SortRel}.
*/
private static class SortFactoryImpl implements SortFactory {
public RelNode createSort(RelTraitSet traits, RelNode child,
RelCollation collation, RexNode offset, RexNode fetch) {
return new SortRel(child.getCluster(), traits, child, collation,
offset, fetch);
}
}

/**
* Can create a {@link org.eigenbase.rel.SetOpRel} for a particular kind of
* set operation (UNION, EXCEPT, INTERSECT) and of the appropriate type
* for this rule's calling convention.
*/
public interface SetOpFactory {
RelNode createSetOp(SqlKind kind, List<RelNode> inputs, boolean all);
}

/**
* Implementation of {@link org.eigenbase.rel.RelFactories.SetOpFactory} that
* returns a vanilla {@link SetOpRel} for the particular kind of set
* operation (UNION, EXCEPT, INTERSECT).
*/
private static class SetOpFactoryImpl implements SetOpFactory {
public RelNode createSetOp(SqlKind kind, List<RelNode> inputs,
boolean all) {
final RelOptCluster cluster = inputs.get(0).getCluster();
switch (kind) {
case UNION:
return new UnionRel(cluster, inputs, all);
case EXCEPT:
return new MinusRel(cluster, inputs, all);
case INTERSECT:
return new IntersectRel(cluster, inputs, all);
default:
throw new AssertionError("not a set op: " + kind);
}
}
}

/**
* Can create a {@link org.eigenbase.rel.AggregateRel} of the appropriate type
* for this rule's calling convention.
*/
public interface AggregateFactory {
RelNode createAggrRelNode(RelNode child, BitSet groupSet,
List<AggregateCall> aggCalls);
}

/**
* Implementation of {@link org.eigenbase.rel.RelFactories.AggregateFactory} that
* returns vanilla {@link AggregateRel}.
*/
private static class AggregateFactoryImpl implements AggregateFactory {

public RelNode createAggrRelNode(RelNode child, BitSet groupSet,
List<AggregateCall> aggCalls) {
return new AggregateRel(child.getCluster(), child, groupSet, aggCalls);
}
}

/**
* Can create a {@link org.eigenbase.rel.FilterRel} of the appropriate type
* for this rule's calling convention.
Expand Down Expand Up @@ -112,6 +198,9 @@ public interface JoinFactory {
RelNode createJoin(RelNode left, RelNode right, RexNode condition,
JoinRelType joinType, Set<String> variablesStopped,
boolean semiJoinDone);

SemiJoinRel createSemiJoinRel(RelTraitSet traitSet, RelNode left,
RelNode right, RexNode condition);
}

/**
Expand All @@ -126,6 +215,13 @@ public RelNode createJoin(RelNode left, RelNode right, RexNode condition,
return new JoinRel(cluster, left, right, condition, joinType,
variablesStopped, semiJoinDone, ImmutableList.<RelDataTypeField>of());
}

public SemiJoinRel createSemiJoinRel(RelTraitSet traitSet, RelNode left,
RelNode right, RexNode condition) {
final JoinInfo joinInfo = JoinInfo.of(left, right, condition);
return new SemiJoinRel(left.getCluster(), traitSet, left, right,
condition, joinInfo.leftKeys, joinInfo.rightKeys);
}
}

/**
Expand All @@ -150,10 +246,12 @@ public static RelNode createProject(final ProjectFactory factory,
final RexBuilder rexBuilder = child.getCluster().getRexBuilder();
return factory.createProject(child,
new AbstractList<RexNode>() {
@Override
public int size() {
return posList.size();
}

@Override
public RexNode get(int index) {
final int pos = posList.get(index);
return rexBuilder.makeInputRef(child, pos);
Expand Down
19 changes: 16 additions & 3 deletions core/src/main/java/org/eigenbase/rel/SetOpRel.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@

import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.sql.SqlKind;

import net.hydromatic.linq4j.Ord;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

/**
Expand All @@ -33,6 +35,7 @@ public abstract class SetOpRel extends AbstractRelNode {
//~ Instance fields --------------------------------------------------------

protected ImmutableList<RelNode> inputs;
public final SqlKind kind;
public final boolean all;

//~ Constructors -----------------------------------------------------------
Expand All @@ -44,8 +47,13 @@ protected SetOpRel(
RelOptCluster cluster,
RelTraitSet traits,
List<RelNode> inputs,
SqlKind kind,
boolean all) {
super(cluster, traits);
Preconditions.checkArgument(kind == SqlKind.UNION
|| kind == SqlKind.INTERSECT
|| kind == SqlKind.EXCEPT);
this.kind = kind;
this.inputs = ImmutableList.copyOf(inputs);
this.all = all;
}
Expand All @@ -54,9 +62,8 @@ protected SetOpRel(
* Creates a SetOpRel by parsing serialized output.
*/
protected SetOpRel(RelInput input) {
this(
input.getCluster(), input.getTraitSet(), input.getInputs(),
input.getBoolean("all"));
this(input.getCluster(), input.getTraitSet(), input.getInputs(),
SqlKind.UNION, input.getBoolean("all"));
}

//~ Methods ----------------------------------------------------------------
Expand All @@ -66,6 +73,7 @@ public abstract SetOpRel copy(
List<RelNode> inputs,
boolean all);

@Override
public SetOpRel copy(
RelTraitSet traitSet,
List<RelNode> inputs) {
Expand All @@ -87,10 +95,12 @@ public boolean isKey(BitSet columns) {
return !all && columns.nextClearBit(0) >= getRowType().getFieldCount();
}

@Override
public List<RelNode> getInputs() {
return inputs;
}

@Override
public RelWriter explainTerms(RelWriter pw) {
super.explainTerms(pw);
for (Ord<RelNode> ord : Ord.zip(inputs)) {
Expand All @@ -99,13 +109,16 @@ public RelWriter explainTerms(RelWriter pw) {
return pw.item("all", all);
}

@Override
protected RelDataType deriveRowType() {
return getCluster().getTypeFactory().leastRestrictive(
new AbstractList<RelDataType>() {
@Override
public RelDataType get(int index) {
return inputs.get(index).getRowType();
}

@Override
public int size() {
return inputs.size();
}
Expand Down
27 changes: 10 additions & 17 deletions core/src/main/java/org/eigenbase/rel/TableAccessRelBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,35 +59,34 @@ protected TableAccessRelBase(RelInput input) {

//~ Methods ----------------------------------------------------------------

public double getRows() {
@Override public double getRows() {
return table.getRowCount();
}

public RelOptTable getTable() {
@Override public RelOptTable getTable() {
return table;
}

public List<RelCollation> getCollationList() {
@Override public List<RelCollation> getCollationList() {
return table.getCollationList();
}

@Override
public boolean isKey(BitSet columns) {
@Override public boolean isKey(BitSet columns) {
return table.isKey(columns);
}

public RelOptCost computeSelfCost(RelOptPlanner planner) {
@Override public RelOptCost computeSelfCost(RelOptPlanner planner) {
double dRows = table.getRowCount();
double dCpu = dRows + 1; // ensure non-zero cost
double dIo = 0;
return planner.getCostFactory().makeCost(dRows, dCpu, dIo);
}

public RelDataType deriveRowType() {
@Override public RelDataType deriveRowType() {
return table.getRowType();
}

public RelWriter explainTerms(RelWriter pw) {
@Override public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw)
.item("table", table.getQualifiedName());
}
Expand All @@ -108,9 +107,8 @@ public RelWriter explainTerms(RelWriter pw) {
* wanted by the consumer
* @return Relational expression that projects the desired fields
*/
public RelNode project(
BitSet fieldsUsed,
Set<RelDataTypeField> extraFields) {
public RelNode project(BitSet fieldsUsed, Set<RelDataTypeField> extraFields,
RelFactories.ProjectFactory projectFactory) {
final int fieldCount = getRowType().getFieldCount();
if (fieldsUsed.equals(BitSets.range(fieldCount))
&& extraFields.isEmpty()) {
Expand Down Expand Up @@ -139,12 +137,7 @@ public RelNode project(
nameList.add(extraField.getName());
}

return new ProjectRel(
getCluster(),
this,
exprList,
nameList,
ProjectRel.Flags.BOXED);
return projectFactory.createProject(this, exprList, nameList);
}

@Override
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/org/eigenbase/rel/UnionRelBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;
import org.eigenbase.sql.SqlKind;

/**
* <code>UnionRelBase</code> is an abstract base class for implementations of
Expand All @@ -33,7 +34,7 @@ protected UnionRelBase(
RelTraitSet traits,
List<RelNode> inputs,
boolean all) {
super(cluster, traits, inputs, all);
super(cluster, traits, inputs, SqlKind.UNION, all);
}

/**
Expand Down
Loading

0 comments on commit d30a76b

Please sign in to comment.