Search in sources :

Example 6 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)

Example 7 with RelMetadataProvider

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

the class Programs method of.

/**
 * Creates a program that executes a {@link HepProgram}.
 */
public static Program of(final HepProgram hepProgram, final boolean noDag, final RelMetadataProvider metadataProvider) {
    return new Program() {

        public RelNode run(RelOptPlanner planner, RelNode rel, RelTraitSet requiredOutputTraits, List<RelOptMaterialization> materializations, List<RelOptLattice> lattices) {
            final HepPlanner hepPlanner = new HepPlanner(hepProgram, null, noDag, null, RelOptCostImpl.FACTORY);
            List<RelMetadataProvider> list = Lists.newArrayList();
            if (metadataProvider != null) {
                list.add(metadataProvider);
            }
            hepPlanner.registerMetadataProviders(list);
            RelMetadataProvider plannerChain = ChainedRelMetadataProvider.of(list);
            rel.getCluster().setMetadataProvider(plannerChain);
            hepPlanner.setRoot(rel);
            return hepPlanner.findBestExp();
        }
    };
}
Also used : HepProgram(org.apache.calcite.plan.hep.HepProgram) 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) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) HepPlanner(org.apache.calcite.plan.hep.HepPlanner) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner)

Example 8 with RelMetadataProvider

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

the class RelOptFixture method checkPlanning.

/**
 * Checks the plan for a given {@link RelNode} supplier before/after executing
 * a given rule, with a pre-program to prepare the tree.
 *
 * @param unchanged Whether the rule is to have no effect
 */
private void checkPlanning(boolean unchanged) {
    final RelNode relInitial = toRel();
    assertNotNull(relInitial);
    List<RelMetadataProvider> list = new ArrayList<>();
    list.add(DefaultRelMetadataProvider.INSTANCE);
    RelMetadataProvider plannerChain = ChainedRelMetadataProvider.of(list);
    final RelOptCluster cluster = relInitial.getCluster();
    cluster.setMetadataProvider(plannerChain);
    // Rather than a single mutable 'RelNode r', this method uses lots of
    // final variables (relInitial, r1, relBefore, and so forth) so that the
    // intermediate states of planning are visible in the debugger.
    final RelNode r1;
    if (preProgram == null) {
        r1 = relInitial;
    } else {
        HepPlanner prePlanner = new HepPlanner(preProgram);
        prePlanner.setRoot(relInitial);
        r1 = prePlanner.findBestExp();
    }
    final RelNode relBefore = before.apply(this, r1);
    assertThat(relBefore, notNullValue());
    final String planBefore = NL + RelOptUtil.toString(relBefore);
    final DiffRepository diffRepos = diffRepos();
    diffRepos.assertEquals("planBefore", "${planBefore}", planBefore);
    assertThat(relBefore, relIsValid());
    final RelNode r2;
    if (planner instanceof VolcanoPlanner) {
        r2 = planner.changeTraits(relBefore, relBefore.getTraitSet().replace(EnumerableConvention.INSTANCE));
    } else {
        r2 = relBefore;
    }
    planner.setRoot(r2);
    final RelNode r3 = planner.findBestExp();
    final RelNode r4;
    if (lateDecorrelate) {
        final String planMid = NL + RelOptUtil.toString(r3);
        diffRepos.assertEquals("planMid", "${planMid}", planMid);
        assertThat(r3, relIsValid());
        final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(cluster, null);
        r4 = RelDecorrelator.decorrelateQuery(r3, relBuilder);
    } else {
        r4 = r3;
    }
    final RelNode relAfter = after.apply(this, r4);
    final String planAfter = NL + RelOptUtil.toString(relAfter);
    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 checkUnchanged");
        }
    }
    assertThat(relAfter, relIsValid());
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelBuilder(org.apache.calcite.tools.RelBuilder) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) DefaultRelMetadataProvider(org.apache.calcite.rel.metadata.DefaultRelMetadataProvider) ChainedRelMetadataProvider(org.apache.calcite.rel.metadata.ChainedRelMetadataProvider) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider) VolcanoPlanner(org.apache.calcite.plan.volcano.VolcanoPlanner) HepPlanner(org.apache.calcite.plan.hep.HepPlanner)

Example 9 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>.
 *
 * <p>Too slow to run every day, and it does not reproduce the issue.
 */
@Tag("slow")
@Test
void testMetadataHandlerCacheLimit() {
    assumeTrue(CalciteSystemProperty.METADATA_HANDLER_CACHE_MAXIMUM_SIZE.value() < 10_000, "If cache size is too large, this test may fail and the test won't be to blame");
    final int iterationCount = 2_000;
    final RelNode rel = sql("select * from emp").toRel();
    final RelMetadataProvider metadataProvider = rel.getCluster().getMetadataProvider();
    for (int i = 0; i < iterationCount; i++) {
        RelMetadataProvider wrappedProvider = new RelMetadataProvider() {

            // to be removed before 2.0
            @Deprecated
            @Override
            @Nullable
            public <M extends @Nullable Metadata> UnboundMetadata<M> apply(Class<? extends RelNode> relClass, Class<? extends M> metadataClass) {
                return metadataProvider.apply(relClass, metadataClass);
            }

            // to be removed before 2.0
            @Deprecated
            @Override
            public <M extends Metadata> Multimap<Method, MetadataHandler<M>> handlers(MetadataDef<M> def) {
                return metadataProvider.handlers(def);
            }

            @Override
            public List<MetadataHandler<?>> handlers(Class<? extends MetadataHandler<?>> handlerClass) {
                return metadataProvider.handlers(handlerClass);
            }
        };
        RelMetadataQuery.THREAD_PROVIDERS.set(JaninoRelMetadataProvider.of(wrappedProvider));
        final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
        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) BuiltInMetadata(org.apache.calcite.rel.metadata.BuiltInMetadata) Metadata(org.apache.calcite.rel.metadata.Metadata) UnboundMetadata(org.apache.calcite.rel.metadata.UnboundMetadata) 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) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider) MetadataDef(org.apache.calcite.rel.metadata.MetadataDef) Method(java.lang.reflect.Method) MetadataHandler(org.apache.calcite.rel.metadata.MetadataHandler) RelHint(org.apache.calcite.rel.hint.RelHint) Test(org.junit.jupiter.api.Test) Tag(org.junit.jupiter.api.Tag)

Example 10 with RelMetadataProvider

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

the class RelMetadataTest method testCustomProviderWithRelMetadataQuery.

@Test
void testCustomProviderWithRelMetadataQuery() {
    final List<String> buf = new ArrayList<>();
    ColTypeImpl.THREAD_LIST.set(buf);
    final String sql = "select deptno, count(*) from emp where deptno > 10 " + "group by deptno having count(*) = 0";
    final RelMetadataFixture.MetadataConfig metadataConfig = fixture().metadataConfig;
    final RelMetadataFixture fixture = sql(sql).withMetadataConfig(RelMetadataFixture.MetadataConfig.NOP).withCluster(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, requireNonNull(cluster.getMetadataProvider(), "cluster.metadataProvider"));
        metadataConfig.applyMetadata(cluster, ChainedRelMetadataProvider.of(list), MyRelMetadataQuery::new);
        return cluster;
    });
    final RelNode rel = fixture.toRel();
    // Top node is a filter. Its metadata uses getColType(RelNode, int).
    assertThat(rel, instanceOf(LogicalFilter.class));
    assertThat(rel.getCluster().getMetadataQuery(), instanceOf(MyRelMetadataQuery.class));
    final MyRelMetadataQuery mq = (MyRelMetadataQuery) rel.getCluster().getMetadataQuery();
    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"));
    if (metadataConfig.isCaching()) {
        // The metadata query is caching, only the first request for each piece of metadata
        // generates a new 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(3));
        assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
        assertThat(buf.size(), equalTo(3));
        assertThat(colType(mq, input, 1), equalTo("EXPR$1-agg"));
        assertThat(buf.size(), equalTo(4));
        assertThat(colType(mq, input, 1), equalTo("EXPR$1-agg"));
        assertThat(buf.size(), equalTo(4));
        assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
        assertThat(buf.size(), equalTo(4));
    }
    // Invalidate the metadata query triggers clearing of all the metadata.
    rel.getCluster().invalidateMetadataQuery();
    assertThat(rel.getCluster().getMetadataQuery(), instanceOf(MyRelMetadataQuery.class));
    final MyRelMetadataQuery mq1 = (MyRelMetadataQuery) rel.getCluster().getMetadataQuery();
    assertThat(colType(mq1, input, 0), equalTo("DEPTNO-agg"));
    if (metadataConfig.isCaching()) {
        assertThat(buf.size(), equalTo(5));
    }
    assertThat(colType(mq1, input, 0), equalTo("DEPTNO-agg"));
    if (metadataConfig.isCaching()) {
        assertThat(buf.size(), equalTo(5));
    }
    // Resets the RelMetadataQuery to default.
    metadataConfig.applyMetadata(rel.getCluster());
}
Also used : LogicalAggregate(org.apache.calcite.rel.logical.LogicalAggregate) RelNode(org.apache.calcite.rel.RelNode) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) ArrayList(java.util.ArrayList) 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) RelMetadataProvider(org.apache.calcite.rel.metadata.RelMetadataProvider) Test(org.junit.jupiter.api.Test)

Aggregations

RelMetadataProvider (org.apache.calcite.rel.metadata.RelMetadataProvider)11 RelNode (org.apache.calcite.rel.RelNode)10 ChainedRelMetadataProvider (org.apache.calcite.rel.metadata.ChainedRelMetadataProvider)9 DefaultRelMetadataProvider (org.apache.calcite.rel.metadata.DefaultRelMetadataProvider)9 HepPlanner (org.apache.calcite.plan.hep.HepPlanner)6 RelOptCluster (org.apache.calcite.plan.RelOptCluster)5 JaninoRelMetadataProvider (org.apache.calcite.rel.metadata.JaninoRelMetadataProvider)4 ReflectiveRelMetadataProvider (org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider)4 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)4 ArrayList (java.util.ArrayList)3 RelOptPlanner (org.apache.calcite.plan.RelOptPlanner)3 HepProgram (org.apache.calcite.plan.hep.HepProgram)3 HepProgramBuilder (org.apache.calcite.plan.hep.HepProgramBuilder)3 RelRoot (org.apache.calcite.rel.RelRoot)3 LogicalAggregate (org.apache.calcite.rel.logical.LogicalAggregate)3 LogicalFilter (org.apache.calcite.rel.logical.LogicalFilter)3 CachingRelMetadataProvider (org.apache.calcite.rel.metadata.CachingRelMetadataProvider)3 Test (org.junit.jupiter.api.Test)3 UnboundMetadata (org.apache.calcite.rel.metadata.UnboundMetadata)2 RelBuilder (org.apache.calcite.tools.RelBuilder)2