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 @@ -59,10 +59,8 @@ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
intersectExp =
Expressions.call(
intersectExp,
all
? BuiltInMethod.CONCAT.method
: BuiltInMethod.INTERSECT.method,
childExp);
BuiltInMethod.INTERSECT.method,
Expressions.list(childExp).appendIfNotNull(result.physType.comparer()));
}

// Once the first input has chosen its format, ask for the same for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
Expressions.call(
minusExp,
BuiltInMethod.EXCEPT.method,
childExp);
Expressions.list(childExp).appendIfNotNull(result.physType.comparer()));
}

// Once the first input has chosen its format, ask for the same for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,12 @@ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
if (unionExp == null) {
unionExp = childExp;
} else {
unionExp =
Expressions.call(
unionExp = all
? Expressions.call(unionExp, BuiltInMethod.CONCAT.method, childExp)
: Expressions.call(
unionExp,
all
? BuiltInMethod.CONCAT.method
: BuiltInMethod.UNION.method,
childExp);
BuiltInMethod.UNION.method,
Expressions.list(childExp).appendIfNotNull(result.physType.comparer()));
}

// Once the first input has chosen its format, ask for the same for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,9 @@ public void removeRule(RelOptRule rule) {
}
});
}

Hook.PLANNER.run(planner); // allow test to add or remove rules

return planner;
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/apache/calcite/prepare/Prepare.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ protected RelRoot optimize(final RelRoot root,
}

private Program getProgram() {
// Allow a test to override the planner.
// Allow a test to override the default program.
final List<Materialization> materializations = ImmutableList.of();
final Holder<Program> holder = Holder.of(null);
Hook.PROGRAM.run(Pair.of(materializations, holder));
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/org/apache/calcite/runtime/Hook.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public enum Hook {
/** Called with the output of sql-to-rel-converter. */
CONVERTED,

/** Called with the created planner. */
PLANNER,

/** Called after de-correlation and field trimming, but before
* optimization. */
TRIMMED,
Expand Down
60 changes: 60 additions & 0 deletions core/src/test/java/org/apache/calcite/test/JdbcTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@
import org.apache.calcite.linq4j.Queryable;
import org.apache.calcite.linq4j.function.Function0;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.prepare.CalcitePrepareImpl;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.TableModify;
import org.apache.calcite.rel.logical.LogicalTableModify;
import org.apache.calcite.rel.rules.IntersectToDistinctRule;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.runtime.FlatLists;
Expand Down Expand Up @@ -3456,6 +3458,64 @@ public Void apply(ResultSet resultSet) {
"C=0");
}

@Test public void testUnionAll() {
CalciteAssert.hr()
.query("select \"empid\", \"name\" from \"hr\".\"emps\" where \"deptno\"=10\n"
+ " union all\n"
+ " select \"empid\", \"name\" from \"hr\".\"emps\" where \"empid\">=150")
.explainContains(""
+ "PLAN=EnumerableUnion(all=[true])")
.returnsUnordered(""
+ "empid=100; name=Bill\n"
+ "empid=110; name=Theodore\n"
+ "empid=150; name=Sebastian\n"
+ "empid=150; name=Sebastian\n"
+ "empid=200; name=Eric");
}

@Test public void testUnion() {
CalciteAssert.hr()
.query("select \"empid\", \"name\" from \"hr\".\"emps\" where \"deptno\"=10\n"
+ " union \n"
+ " select \"empid\", \"name\" from \"hr\".\"emps\" where \"empid\">=150")
.explainContains(""
+ "PLAN=EnumerableUnion(all=[false])")
.returnsUnordered(""
+ "empid=100; name=Bill\n"
+ "empid=110; name=Theodore\n"
+ "empid=150; name=Sebastian\n"
+ "empid=200; name=Eric");
}

@Test public void testIntersect() {
CalciteAssert.hr()
.query("select \"empid\", \"name\" from \"hr\".\"emps\" where \"deptno\"=10\n"
+ " intersect \n"
+ " select \"empid\", \"name\" from \"hr\".\"emps\" where \"empid\">=150")
.withHook(Hook.PLANNER, new Function<RelOptPlanner, Void>() {
@Override public Void apply(RelOptPlanner planner) {
planner.removeRule(IntersectToDistinctRule.INSTANCE);
return null;
}
})
.explainContains(""
+ "PLAN=EnumerableIntersect(all=[false])")
.returns(""
+ "empid=150; name=Sebastian\n");
}

@Test public void testExcept() {
CalciteAssert.hr()
.query("select \"empid\", \"name\" from \"hr\".\"emps\" where \"deptno\"=10\n"
+ " except \n"
+ " select \"empid\", \"name\" from \"hr\".\"emps\" where \"empid\">=150")
.explainContains(""
+ "PLAN=EnumerableMinus(all=[false])")
.returnsUnordered(""
+ "empid=100; name=Bill\n"
+ "empid=110; name=Theodore");
}

/** Tests that SUM and AVG over empty set return null. COUNT returns 0. */
@Test public void testAggregateEmpty() {
CalciteAssert.hr()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.plan.SubstitutionVisitor;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.rel.RelNode;
Expand All @@ -37,13 +36,9 @@
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.tools.Program;
import org.apache.calcite.tools.Programs;
import org.apache.calcite.tools.RuleSet;
import org.apache.calcite.tools.RuleSets;
import org.apache.calcite.util.Holder;
import org.apache.calcite.util.JsonBuilder;
import org.apache.calcite.util.Pair;
import org.apache.calcite.util.TryThreadLocal;
import org.apache.calcite.util.Util;

Expand Down Expand Up @@ -187,22 +182,14 @@ private void checkMaterialize(String materialize, String query, String model,

// Add any additional rules required for the test
if (rules.iterator().hasNext()) {
that.withHook(Hook.PROGRAM,
new Function<Pair<List<Prepare.Materialization>, Holder<Program>>,
Void>() {
public Void apply(Pair<List<Prepare.Materialization>, Holder<Program>> pair) {
pair.right.set(new Program() {
public RelNode run(RelOptPlanner planner, RelNode rel,
RelTraitSet requiredOutputTraits) {
for (RelOptRule rule : rules) {
planner.addRule(rule);
}
return Programs.standard().run(planner, rel, requiredOutputTraits);
}
});
return null;
that.withHook(Hook.PLANNER, new Function<RelOptPlanner, Void>() {
public Void apply(RelOptPlanner planner) {
for (RelOptRule rule : rules) {
planner.addRule(rule);
}
});
return null;
}
});
}

that.explainMatches("", explainChecker)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,9 @@ public static <TSource> Enumerable<TSource> except(
public static <TSource> Enumerable<TSource> except(
Enumerable<TSource> source0, Enumerable<TSource> source1,
EqualityComparer<TSource> comparer) {
if (comparer == Functions.identityComparer()) {
return except(source0, source1);
}
Set<Wrapped<TSource>> set = new HashSet<>();
Function1<TSource, Wrapped<TSource>> wrapper = wrapperFor(comparer);
source0.select(wrapper).into(set);
Expand Down Expand Up @@ -994,6 +997,9 @@ public static <TSource> Enumerable<TSource> intersect(
public static <TSource> Enumerable<TSource> intersect(
Enumerable<TSource> source0, Enumerable<TSource> source1,
EqualityComparer<TSource> comparer) {
if (comparer == Functions.identityComparer()) {
return intersect(source0, source1);
}
Set<Wrapped<TSource>> set0 = new HashSet<>();
Function1<TSource, Wrapped<TSource>> wrapper = wrapperFor(comparer);
source0.select(wrapper).into(set0);
Expand Down