Search in sources :

Example 1 with RelMetadataProvider

use of org.apache.calcite.rel.metadata.RelMetadataProvider in project calcite by apache.

the class RelOptRulesTest method transitiveInference.

private void transitiveInference(RelOptRule... extraRules) throws Exception {
    final DiffRepository diffRepos = getDiffRepos();
    final String sql = diffRepos.expand(null, "${sql}");
    final HepProgram program = new HepProgramBuilder().addRuleInstance(FilterJoinRule.DUMB_FILTER_ON_JOIN).addRuleInstance(FilterJoinRule.JOIN).addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(FilterSetOpTransposeRule.INSTANCE).build();
    final HepPlanner planner = new HepPlanner(program);
    final RelRoot root = tester.convertSqlToRel(sql);
    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);
    relInitial.getCluster().setMetadataProvider(new CachingRelMetadataProvider(plannerChain, planner));
    planner.setRoot(relInitial);
    RelNode relBefore = planner.findBestExp();
    String planBefore = NL + RelOptUtil.toString(relBefore);
    diffRepos.assertEquals("planBefore", "${planBefore}", planBefore);
    HepProgram program2 = new HepProgramBuilder().addMatchOrder(HepMatchOrder.BOTTOM_UP).addRuleInstance(FilterJoinRule.DUMB_FILTER_ON_JOIN).addRuleInstance(FilterJoinRule.JOIN).addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(FilterSetOpTransposeRule.INSTANCE).addRuleInstance(JoinPushTransitivePredicatesRule.INSTANCE).addRuleCollection(Arrays.asList(extraRules)).build();
    final HepPlanner planner2 = new HepPlanner(program2);
    planner.registerMetadataProviders(list);
    planner2.setRoot(relBefore);
    RelNode relAfter = planner2.findBestExp();
    String planAfter = NL + RelOptUtil.toString(relAfter);
    diffRepos.assertEquals("planAfter", "${planAfter}", planAfter);
}
Also used : HepProgram(org.apache.calcite.plan.hep.HepProgram) RelNode(org.apache.calcite.rel.RelNode) CachingRelMetadataProvider(org.apache.calcite.rel.metadata.CachingRelMetadataProvider) HepProgramBuilder(org.apache.calcite.plan.hep.HepProgramBuilder) DefaultRelMetadataProvider(org.apache.calcite.rel.metadata.DefaultRelMetadataProvider) ChainedRelMetadataProvider(org.apache.calcite.rel.metadata.ChainedRelMetadataProvider) CachingRelMetadataProvider(org.apache.calcite.rel.metadata.CachingRelMetadataProvider) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider) RelRoot(org.apache.calcite.rel.RelRoot) HepPlanner(org.apache.calcite.plan.hep.HepPlanner)

Example 2 with RelMetadataProvider

use of org.apache.calcite.rel.metadata.RelMetadataProvider in project calcite by apache.

the class RelMetadataTest method testMetadataHandlerCacheLimit.

/**
 * Test case for
 * <a href="https://issues.apache.org/jira/browse/CALCITE-1808">[CALCITE-1808]
 * JaninoRelMetadataProvider loading cache might cause
 * OutOfMemoryError</a>.
 */
@Test
public void testMetadataHandlerCacheLimit() {
    Assume.assumeTrue("If cache size is too large, this test may fail and the " + "test won't be to blame", SaffronProperties.INSTANCE.metadataHandlerCacheMaximumSize().get() < 10_000);
    final int iterationCount = 2_000;
    final RelNode rel = convertSql("select * from emp");
    final RelMetadataProvider metadataProvider = rel.getCluster().getMetadataProvider();
    final RelOptPlanner planner = rel.getCluster().getPlanner();
    for (int i = 0; i < iterationCount; i++) {
        RelMetadataQuery.THREAD_PROVIDERS.set(JaninoRelMetadataProvider.of(new CachingRelMetadataProvider(metadataProvider, planner)));
        final RelMetadataQuery mq = RelMetadataQuery.instance();
        final Double result = mq.getRowCount(rel);
        assertThat(result, within(14d, 0.1d));
    }
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RelNode(org.apache.calcite.rel.RelNode) CachingRelMetadataProvider(org.apache.calcite.rel.metadata.CachingRelMetadataProvider) JaninoRelMetadataProvider(org.apache.calcite.rel.metadata.JaninoRelMetadataProvider) DefaultRelMetadataProvider(org.apache.calcite.rel.metadata.DefaultRelMetadataProvider) ChainedRelMetadataProvider(org.apache.calcite.rel.metadata.ChainedRelMetadataProvider) ReflectiveRelMetadataProvider(org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider) CachingRelMetadataProvider(org.apache.calcite.rel.metadata.CachingRelMetadataProvider) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner) Test(org.junit.Test)

Example 3 with RelMetadataProvider

use of org.apache.calcite.rel.metadata.RelMetadataProvider 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));
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) CachingRelMetadataProvider(org.apache.calcite.rel.metadata.CachingRelMetadataProvider) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) RelRoot(org.apache.calcite.rel.RelRoot) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner) Function(com.google.common.base.Function) LogicalAggregate(org.apache.calcite.rel.logical.LogicalAggregate) RelNode(org.apache.calcite.rel.RelNode) JaninoRelMetadataProvider(org.apache.calcite.rel.metadata.JaninoRelMetadataProvider) DefaultRelMetadataProvider(org.apache.calcite.rel.metadata.DefaultRelMetadataProvider) ChainedRelMetadataProvider(org.apache.calcite.rel.metadata.ChainedRelMetadataProvider) ReflectiveRelMetadataProvider(org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider) CachingRelMetadataProvider(org.apache.calcite.rel.metadata.CachingRelMetadataProvider) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider) Test(org.junit.Test)

Example 4 with RelMetadataProvider

use of org.apache.calcite.rel.metadata.RelMetadataProvider 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);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelBuilder(org.apache.calcite.tools.RelBuilder) RelNode(org.apache.calcite.rel.RelNode) DefaultRelMetadataProvider(org.apache.calcite.rel.metadata.DefaultRelMetadataProvider) ChainedRelMetadataProvider(org.apache.calcite.rel.metadata.ChainedRelMetadataProvider) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider) RelRoot(org.apache.calcite.rel.RelRoot) HepPlanner(org.apache.calcite.plan.hep.HepPlanner)

Example 5 with RelMetadataProvider

use of org.apache.calcite.rel.metadata.RelMetadataProvider in project calcite by apache.

the class VolcanoRelMetadataProvider method apply.

public <M extends Metadata> UnboundMetadata<M> apply(Class<? extends RelNode> relClass, final Class<? extends M> metadataClass) {
    if (relClass != RelSubset.class) {
        // let someone else further down the chain sort it out
        return null;
    }
    return new UnboundMetadata<M>() {

        public M bind(RelNode rel, RelMetadataQuery mq) {
            final RelSubset subset = (RelSubset) rel;
            final RelMetadataProvider provider = rel.getCluster().getMetadataProvider();
            // this query, treat it as the most reliable.
            if (subset.best != null) {
                final UnboundMetadata<M> function = provider.apply(subset.best.getClass(), metadataClass);
                if (function != null) {
                    final M metadata = function.bind(subset.best, mq);
                    if (metadata != null) {
                        return metadata;
                    }
                }
            }
            // granularity).
            if (subset.set.inMetadataQuery) {
                return null;
            }
            subset.set.inMetadataQuery = true;
            try {
                for (RelNode relCandidate : subset.set.rels) {
                    final UnboundMetadata<M> function = provider.apply(relCandidate.getClass(), metadataClass);
                    if (function != null) {
                        final M result = function.bind(relCandidate, mq);
                        if (result != null) {
                            return result;
                        }
                    }
                }
            } finally {
                subset.set.inMetadataQuery = false;
            }
            // Give up.
            return null;
        }
    };
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RelNode(org.apache.calcite.rel.RelNode) UnboundMetadata(org.apache.calcite.rel.metadata.UnboundMetadata) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider)

Aggregations

RelNode (org.apache.calcite.rel.RelNode)7 RelMetadataProvider (org.apache.calcite.rel.metadata.RelMetadataProvider)7 ChainedRelMetadataProvider (org.apache.calcite.rel.metadata.ChainedRelMetadataProvider)6 DefaultRelMetadataProvider (org.apache.calcite.rel.metadata.DefaultRelMetadataProvider)5 HepPlanner (org.apache.calcite.plan.hep.HepPlanner)4 CachingRelMetadataProvider (org.apache.calcite.rel.metadata.CachingRelMetadataProvider)4 RelOptCluster (org.apache.calcite.plan.RelOptCluster)3 RelOptPlanner (org.apache.calcite.plan.RelOptPlanner)3 RelRoot (org.apache.calcite.rel.RelRoot)3 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)3 Test (org.junit.Test)3 HepProgram (org.apache.calcite.plan.hep.HepProgram)2 HepProgramBuilder (org.apache.calcite.plan.hep.HepProgramBuilder)2 JaninoRelMetadataProvider (org.apache.calcite.rel.metadata.JaninoRelMetadataProvider)2 ReflectiveRelMetadataProvider (org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider)2 Function (com.google.common.base.Function)1 ImmutableList (com.google.common.collect.ImmutableList)1 List (java.util.List)1 JavaTypeFactoryImpl (org.apache.calcite.jdbc.JavaTypeFactoryImpl)1 RelOptRule (org.apache.calcite.plan.RelOptRule)1