use of org.apache.calcite.rel.RelRoot in project calcite by apache.
the class RelMetadataTest method testCustomProvider.
@Test
public void testCustomProvider() {
final List<String> buf = Lists.newArrayList();
ColTypeImpl.THREAD_LIST.set(buf);
final String sql = "select deptno, count(*) from emp where deptno > 10 " + "group by deptno having count(*) = 0";
final RelRoot root = tester.withClusterFactory(new Function<RelOptCluster, RelOptCluster>() {
public RelOptCluster apply(RelOptCluster cluster) {
// Create a custom provider that includes ColType.
// Include the same provider twice just to be devious.
final ImmutableList<RelMetadataProvider> list = ImmutableList.of(ColTypeImpl.SOURCE, ColTypeImpl.SOURCE, cluster.getMetadataProvider());
cluster.setMetadataProvider(ChainedRelMetadataProvider.of(list));
return cluster;
}
}).convertSqlToRel(sql);
final RelNode rel = root.rel;
// Top node is a filter. Its metadata uses getColType(RelNode, int).
assertThat(rel, instanceOf(LogicalFilter.class));
final RelMetadataQuery mq = RelMetadataQuery.instance();
assertThat(colType(mq, rel, 0), equalTo("DEPTNO-rel"));
assertThat(colType(mq, rel, 1), equalTo("EXPR$1-rel"));
// Next node is an aggregate. Its metadata uses
// getColType(LogicalAggregate, int).
final RelNode input = rel.getInput(0);
assertThat(input, instanceOf(LogicalAggregate.class));
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
// There is no caching. Another request causes another call to the provider.
assertThat(buf.toString(), equalTo("[DEPTNO-rel, EXPR$1-rel, DEPTNO-agg]"));
assertThat(buf.size(), equalTo(3));
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(4));
// Now add a cache. Only the first request for each piece of metadata
// generates a new call to the provider.
final RelOptPlanner planner = rel.getCluster().getPlanner();
rel.getCluster().setMetadataProvider(new CachingRelMetadataProvider(rel.getCluster().getMetadataProvider(), planner));
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(5));
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(5));
assertThat(colType(mq, input, 1), equalTo("EXPR$1-agg"));
assertThat(buf.size(), equalTo(6));
assertThat(colType(mq, input, 1), equalTo("EXPR$1-agg"));
assertThat(buf.size(), equalTo(6));
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(6));
// With a different timestamp, a metadata item is re-computed on first call.
long timestamp = planner.getRelMetadataTimestamp(rel);
assertThat(timestamp, equalTo(0L));
((MockRelOptPlanner) planner).setRelMetadataTimestamp(timestamp + 1);
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(7));
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(7));
}
use of org.apache.calcite.rel.RelRoot in project calcite by apache.
the class RelOptRulesTest method testSemiJoinTrim.
@Test
public void testSemiJoinTrim() throws Exception {
final DiffRepository diffRepos = getDiffRepos();
String sql = diffRepos.expand(null, "${sql}");
TesterImpl t = (TesterImpl) tester;
final RelDataTypeFactory typeFactory = t.getTypeFactory();
final Prepare.CatalogReader catalogReader = t.createCatalogReader(typeFactory);
final SqlValidator validator = t.createValidator(catalogReader, typeFactory);
SqlToRelConverter converter = t.createSqlToRelConverter(validator, catalogReader, typeFactory, SqlToRelConverter.Config.DEFAULT);
final SqlNode sqlQuery = t.parseQuery(sql);
final SqlNode validatedQuery = validator.validate(sqlQuery);
RelRoot root = converter.convertQuery(validatedQuery, false, true);
root = root.withRel(converter.decorrelate(sqlQuery, root.rel));
final HepProgram program = HepProgram.builder().addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(FilterJoinRule.FILTER_ON_JOIN).addRuleInstance(ProjectMergeRule.INSTANCE).addRuleInstance(SemiJoinRule.PROJECT).build();
HepPlanner planner = new HepPlanner(program);
planner.setRoot(root.rel);
root = root.withRel(planner.findBestExp());
String planBefore = NL + RelOptUtil.toString(root.rel);
diffRepos.assertEquals("planBefore", "${planBefore}", planBefore);
converter = t.createSqlToRelConverter(validator, catalogReader, typeFactory, SqlToRelConverter.configBuilder().withTrimUnusedFields(true).build());
root = root.withRel(converter.trimUnusedFields(false, root.rel));
String planAfter = NL + RelOptUtil.toString(root.rel);
diffRepos.assertEquals("planAfter", "${planAfter}", planAfter);
}
use of org.apache.calcite.rel.RelRoot in project calcite by apache.
the class RelOptTestBase method checkPlanning.
/**
* Checks the plan for a SQL statement before/after executing a given rule,
* with a pre-program to prepare the tree.
*
* @param tester Tester
* @param preProgram Program to execute before comparing before state
* @param planner Planner
* @param sql SQL query
* @param unchanged Whether the rule is to have no effect
*/
protected void checkPlanning(Tester tester, HepProgram preProgram, RelOptPlanner planner, String sql, boolean unchanged) {
final DiffRepository diffRepos = getDiffRepos();
String sql2 = diffRepos.expand("sql", sql);
final RelRoot root = tester.convertSqlToRel(sql2);
final RelNode relInitial = root.rel;
assertTrue(relInitial != null);
List<RelMetadataProvider> list = Lists.newArrayList();
list.add(DefaultRelMetadataProvider.INSTANCE);
planner.registerMetadataProviders(list);
RelMetadataProvider plannerChain = ChainedRelMetadataProvider.of(list);
final RelOptCluster cluster = relInitial.getCluster();
cluster.setMetadataProvider(plannerChain);
RelNode relBefore;
if (preProgram == null) {
relBefore = relInitial;
} else {
HepPlanner prePlanner = new HepPlanner(preProgram);
prePlanner.setRoot(relInitial);
relBefore = prePlanner.findBestExp();
}
assertThat(relBefore, notNullValue());
final String planBefore = NL + RelOptUtil.toString(relBefore);
diffRepos.assertEquals("planBefore", "${planBefore}", planBefore);
SqlToRelTestBase.assertValid(relBefore);
planner.setRoot(relBefore);
RelNode r = planner.findBestExp();
if (tester.isLateDecorrelate()) {
final String planMid = NL + RelOptUtil.toString(r);
diffRepos.assertEquals("planMid", "${planMid}", planMid);
SqlToRelTestBase.assertValid(r);
final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(cluster, null);
r = RelDecorrelator.decorrelateQuery(r, relBuilder);
}
final String planAfter = NL + RelOptUtil.toString(r);
if (unchanged) {
assertThat(planAfter, is(planBefore));
} else {
diffRepos.assertEquals("planAfter", "${planAfter}", planAfter);
if (planBefore.equals(planAfter)) {
throw new AssertionError("Expected plan before and after is the same.\n" + "You must use unchanged=true or call checkPlanUnchanged");
}
}
SqlToRelTestBase.assertValid(r);
}
use of org.apache.calcite.rel.RelRoot in project calcite by apache.
the class PlannerTest method testConvertWithoutValidateFails.
/**
* Tests that planner throws an error if you pass to
* {@link Planner#rel(org.apache.calcite.sql.SqlNode)}
* a {@link org.apache.calcite.sql.SqlNode} that has been parsed but not
* validated.
*/
@Test
public void testConvertWithoutValidateFails() throws Exception {
Planner planner = getPlanner(null);
SqlNode parse = planner.parse("select * from \"emps\"");
try {
RelRoot rel = planner.rel(parse);
fail("expected error, got " + rel);
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), containsString("cannot move from STATE_3_PARSED to STATE_4_VALIDATED"));
}
}
use of org.apache.calcite.rel.RelRoot in project calcite by apache.
the class ViewTable method expandView.
private RelRoot expandView(RelOptTable.ToRelContext preparingStmt, RelDataType rowType, String queryString) {
try {
RelRoot root = preparingStmt.expandView(rowType, queryString, schemaPath, viewPath);
root = root.withRel(RelOptUtil.createCastRel(root.rel, rowType, true));
return root;
} catch (Exception e) {
throw new RuntimeException("Error while parsing view definition: " + queryString, e);
}
}
Aggregations