org.apache.calcite.rel.metadata.ChainedRelMetadataProvider Java Examples

The following examples show how to use org.apache.calcite.rel.metadata.ChainedRelMetadataProvider. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Programs.java    From Bats with Apache License 2.0 6 votes vote down vote up
/** Creates a program that executes a {@link HepProgram}. */
public static Program of(final HepProgram hepProgram, final boolean noDag,
    final RelMetadataProvider metadataProvider) {
  return (planner, rel, requiredOutputTraits, materializations, lattices) -> {
    final HepPlanner hepPlanner = new HepPlanner(hepProgram,
        null, noDag, null, RelOptCostImpl.FACTORY);

    List<RelMetadataProvider> list = new ArrayList<>();
    if (metadataProvider != null) {
      list.add(metadataProvider);
    }
    hepPlanner.registerMetadataProviders(list);
    RelMetadataProvider plannerChain =
        ChainedRelMetadataProvider.of(list);
    rel.getCluster().setMetadataProvider(plannerChain);

    hepPlanner.setRoot(rel);
    return hepPlanner.findBestExp();
  };
}
 
Example #2
Source File: Programs.java    From calcite with Apache License 2.0 6 votes vote down vote up
/** Creates a program that executes a {@link HepProgram}. */
public static Program of(final HepProgram hepProgram, final boolean noDag,
    final RelMetadataProvider metadataProvider) {
  return (planner, rel, requiredOutputTraits, materializations, lattices) -> {
    final HepPlanner hepPlanner = new HepPlanner(hepProgram,
        null, noDag, null, RelOptCostImpl.FACTORY);

    List<RelMetadataProvider> list = new ArrayList<>();
    if (metadataProvider != null) {
      list.add(metadataProvider);
    }
    hepPlanner.registerMetadataProviders(list);
    for (RelOptMaterialization materialization : materializations) {
      hepPlanner.addMaterialization(materialization);
    }
    for (RelOptLattice lattice : lattices) {
      hepPlanner.addLattice(lattice);
    }
    RelMetadataProvider plannerChain =
        ChainedRelMetadataProvider.of(list);
    rel.getCluster().setMetadataProvider(plannerChain);

    hepPlanner.setRoot(rel);
    return hepPlanner.findBestExp();
  };
}
 
Example #3
Source File: RelMetadataTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void testBrokenCustomProviderWithMetadataFactory() {
  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 RelRoot root = tester
      .withClusterFactory(cluster -> {
        cluster.setMetadataProvider(
            ChainedRelMetadataProvider.of(
                ImmutableList.of(BrokenColTypeImpl.SOURCE,
                    cluster.getMetadataProvider())));
        return cluster;
      })
      .convertSqlToRel(sql);

  final RelNode rel = root.rel;
  assertThat(rel, instanceOf(LogicalFilter.class));
  final MyRelMetadataQuery mq = new MyRelMetadataQuery();

  try {
    assertThat(colType(mq, rel, 0), equalTo("DEPTNO-rel"));
    fail("expected error");
  } catch (IllegalArgumentException e) {
    final String value = "No handler for method [public abstract java.lang.String "
        + "org.apache.calcite.test.RelMetadataTest$ColType.getColType(int)] "
        + "applied to argument of type [interface org.apache.calcite.rel.RelNode]; "
        + "we recommend you create a catch-all (RelNode) handler";
    assertThat(e.getMessage(), is(value));
  }
}
 
Example #4
Source File: RelMetadataTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void testBrokenCustomProviderWithMetadataQuery() {
  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 RelRoot root = tester
      .withClusterFactory(cluster -> {
        cluster.setMetadataProvider(
            ChainedRelMetadataProvider.of(
                ImmutableList.of(BrokenColTypeImpl.SOURCE,
                    cluster.getMetadataProvider())));
        cluster.setMetadataQuerySupplier(MyRelMetadataQuery::new);
        return cluster;
      })
      .convertSqlToRel(sql);

  final RelNode rel = root.rel;
  assertThat(rel, instanceOf(LogicalFilter.class));
  assertThat(rel.getCluster().getMetadataQuery(), instanceOf(MyRelMetadataQuery.class));
  final MyRelMetadataQuery mq = (MyRelMetadataQuery) rel.getCluster().getMetadataQuery();

  try {
    assertThat(colType(mq, rel, 0), equalTo("DEPTNO-rel"));
    fail("expected error");
  } catch (IllegalArgumentException e) {
    final String value = "No handler for method [public abstract java.lang.String "
        + "org.apache.calcite.test.RelMetadataTest$ColType.getColType(int)] "
        + "applied to argument of type [interface org.apache.calcite.rel.RelNode]; "
        + "we recommend you create a catch-all (RelNode) handler";
    assertThat(e.getMessage(), is(value));
  }
}
 
Example #5
Source File: RelMetadataTest.java    From calcite with Apache License 2.0 4 votes vote down vote up
@Test void testCustomProviderWithRelMetadataFactory() {
  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 RelRoot root = tester
      .withClusterFactory(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 = 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"));

  // 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));
}
 
Example #6
Source File: RelMetadataTest.java    From calcite with Apache License 2.0 4 votes vote down vote up
@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 RelRoot root = tester
      .withClusterFactory(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));
        cluster.setMetadataQuerySupplier(MyRelMetadataQuery::new);
        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));
  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"));

  // 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"));
  assertThat(buf.size(), equalTo(5));
  assertThat(colType(mq1, input, 0), equalTo("DEPTNO-agg"));
  assertThat(buf.size(), equalTo(5));
  // Resets the RelMetadataQuery to default.
  rel.getCluster().setMetadataQuerySupplier(RelMetadataQuery::instance);
}
 
Example #7
Source File: RelOptTestBase.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * 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
 */
private 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;

  assertNotNull(relInitial);

  List<RelMetadataProvider> list = new ArrayList<>();
  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);

  if (planner instanceof VolcanoPlanner) {
    relBefore = planner.changeTraits(relBefore,
        relBefore.getTraitSet().replace(EnumerableConvention.INSTANCE));
  }
  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 checkUnchanged");
    }
  }
  SqlToRelTestBase.assertValid(r);
}