Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.calcite.rel.mutable.MutableAggregate;
import org.apache.calcite.rel.mutable.MutableCalc;
import org.apache.calcite.rel.mutable.MutableFilter;
import org.apache.calcite.rel.mutable.MutableIntersect;
import org.apache.calcite.rel.mutable.MutableJoin;
import org.apache.calcite.rel.mutable.MutableRel;
import org.apache.calcite.rel.mutable.MutableRelVisitor;
Expand Down Expand Up @@ -134,7 +135,8 @@ public class SubstitutionVisitor {
AggregateToAggregateUnifyRule.INSTANCE,
AggregateOnCalcToAggregateUnifyRule.INSTANCE,
UnionToUnionUnifyRule.INSTANCE,
UnionOnCalcsToUnionUnifyRule.INSTANCE);
UnionOnCalcsToUnionUnifyRule.INSTANCE,
IntersectToIntersectUnifyRule.INSTANCE);

/**
* Factory for a builder for relational expressions.
Expand Down Expand Up @@ -1630,6 +1632,32 @@ && sameRelCollectionNoOrderConsidered(queryGrandInputs, targetInputs)) {
}
}

/**
* A {@link SubstitutionVisitor.UnifyRule} that matches a
* {@link MutableIntersect} to a {@link MutableIntersect} where the query and target
* have the same inputs but might not have the same order.
*/
private static class IntersectToIntersectUnifyRule extends AbstractUnifyRule {
public static final IntersectToIntersectUnifyRule INSTANCE =
new IntersectToIntersectUnifyRule();

private IntersectToIntersectUnifyRule() {
super(any(MutableIntersect.class), any(MutableIntersect.class), 0);
}

public UnifyResult apply(UnifyRuleCall call) {
final MutableIntersect query = (MutableIntersect) call.query;
final MutableIntersect target = (MutableIntersect) call.target;
final List<MutableRel> queryInputs = new ArrayList<>(query.getInputs());
final List<MutableRel> targetInputs = new ArrayList<>(target.getInputs());
if (query.isAll() == target.isAll()
&& sameRelCollectionNoOrderConsidered(queryInputs, targetInputs)) {
return call.result(target);
}
return null;
}
}

/** Check if list0 and list1 contains the same nodes -- order is not considered. */
private static boolean sameRelCollectionNoOrderConsidered(
List<MutableRel> list0, List<MutableRel> list1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2837,6 +2837,7 @@ private void checkSatisfiable(RexNode e, String s) {
checkNoMaterialize(sql0 + " union " + sql1, sql0 + " union all " + sql1,
HR_FKUK_MODEL);
}

@Test public void testUnionOnCalcsToUnion() {
String mv = ""
+ "select \"deptno\", \"salary\"\n"
Expand All @@ -2857,6 +2858,30 @@ private void checkSatisfiable(RexNode e, String s) {
checkMaterialize(mv, query);
}

@Test public void testIntersectToIntersect0() {
final String mv = ""
+ "select \"deptno\" from \"emps\"\n"
+ "intersect\n"
+ "select \"deptno\" from \"depts\"";
final String query = ""
+ "select \"deptno\" from \"depts\"\n"
+ "intersect\n"
+ "select \"deptno\" from \"emps\"";
checkMaterialize(mv, query, true);
}

@Test public void testIntersectToIntersect1() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about format like below:

select deptno from emps
intersect
select deptno  from depts;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, update code.

final String mv = ""
+ "select \"deptno\" from \"emps\"\n"
+ "intersect all\n"
+ "select \"deptno\" from \"depts\"";
final String query = ""
+ "select \"deptno\" from \"depts\"\n"
+ "intersect all\n"
+ "select \"deptno\" from \"emps\"";
checkMaterialize(mv, query, true);
}

private static <E> List<List<List<E>>> list3(E[][][] as) {
final ImmutableList.Builder<List<List<E>>> builder =
ImmutableList.builder();
Expand Down