Search in sources :

Example 1 with StarTable

use of org.apache.calcite.schema.impl.StarTable in project calcite by apache.

the class CalciteMaterializer method useStar.

/**
 * Converts a relational expression to use a
 * {@link org.apache.calcite.schema.impl.StarTable} defined in {@code schema}.
 * Uses the first star table that fits.
 */
private Iterable<Callback> useStar(CalciteSchema schema, RelNode queryRel) {
    List<CalciteSchema.TableEntry> starTables = Schemas.getStarTables(schema.root());
    if (starTables.isEmpty()) {
        // Don't waste effort converting to leaf-join form.
        return ImmutableList.of();
    }
    final List<Callback> list = Lists.newArrayList();
    final RelNode rel2 = RelOptMaterialization.toLeafJoinForm(queryRel);
    for (CalciteSchema.TableEntry starTable : starTables) {
        final Table table = starTable.getTable();
        assert table instanceof StarTable;
        RelOptTableImpl starRelOptTable = RelOptTableImpl.create(catalogReader, table.getRowType(typeFactory), starTable, null);
        final RelNode rel3 = RelOptMaterialization.tryUseStar(rel2, starRelOptTable);
        if (rel3 != null) {
            list.add(new Callback(rel3, starTable, starRelOptTable));
        }
    }
    return list;
}
Also used : RelOptTable(org.apache.calcite.plan.RelOptTable) SqlRexConvertletTable(org.apache.calcite.sql2rel.SqlRexConvertletTable) Table(org.apache.calcite.schema.Table) StarTable(org.apache.calcite.schema.impl.StarTable) RelNode(org.apache.calcite.rel.RelNode) StarTable(org.apache.calcite.schema.impl.StarTable) CalciteSchema(org.apache.calcite.jdbc.CalciteSchema)

Example 2 with StarTable

use of org.apache.calcite.schema.impl.StarTable in project calcite by apache.

the class RelOptMaterialization method tryUseStar.

/**
 * Converts a relational expression to one that uses a
 * {@link org.apache.calcite.schema.impl.StarTable}.
 *
 * <p>The relational expression is already in leaf-join-form, per
 * {@link #toLeafJoinForm(org.apache.calcite.rel.RelNode)}.
 *
 * @return Rewritten expression, or null if expression cannot be rewritten
 * to use the star
 */
public static RelNode tryUseStar(RelNode rel, final RelOptTable starRelOptTable) {
    final StarTable starTable = starRelOptTable.unwrap(StarTable.class);
    assert starTable != null;
    RelNode rel2 = rel.accept(new RelShuttleImpl() {

        @Override
        public RelNode visit(TableScan scan) {
            RelOptTable relOptTable = scan.getTable();
            final Table table = relOptTable.unwrap(Table.class);
            if (table.equals(starTable.tables.get(0))) {
                Mappings.TargetMapping mapping = Mappings.createShiftMapping(starRelOptTable.getRowType().getFieldCount(), 0, 0, relOptTable.getRowType().getFieldCount());
                final RelOptCluster cluster = scan.getCluster();
                final RelNode scan2 = starRelOptTable.toRel(RelOptUtil.getContext(cluster));
                return RelOptUtil.createProject(scan2, Mappings.asList(mapping.inverse()));
            }
            return scan;
        }

        @Override
        public RelNode visit(LogicalJoin join) {
            for (; ; ) {
                RelNode rel = super.visit(join);
                if (rel == join || !(rel instanceof LogicalJoin)) {
                    return rel;
                }
                join = (LogicalJoin) rel;
                final ProjectFilterTable left = ProjectFilterTable.of(join.getLeft());
                if (left != null) {
                    final ProjectFilterTable right = ProjectFilterTable.of(join.getRight());
                    if (right != null) {
                        try {
                            match(left, right, join.getCluster());
                        } catch (Util.FoundOne e) {
                            return (RelNode) e.getNode();
                        }
                    }
                }
            }
        }

        /**
         * Throws a {@link org.apache.calcite.util.Util.FoundOne} containing
         * a {@link org.apache.calcite.rel.logical.LogicalTableScan} on
         * success.  (Yes, an exception for normal operation.)
         */
        private void match(ProjectFilterTable left, ProjectFilterTable right, RelOptCluster cluster) {
            final Mappings.TargetMapping leftMapping = left.mapping();
            final Mappings.TargetMapping rightMapping = right.mapping();
            final RelOptTable leftRelOptTable = left.getTable();
            final Table leftTable = leftRelOptTable.unwrap(Table.class);
            final int leftCount = leftRelOptTable.getRowType().getFieldCount();
            final RelOptTable rightRelOptTable = right.getTable();
            final Table rightTable = rightRelOptTable.unwrap(Table.class);
            if (leftTable instanceof StarTable && ((StarTable) leftTable).tables.contains(rightTable)) {
                final int offset = ((StarTable) leftTable).columnOffset(rightTable);
                Mappings.TargetMapping mapping = Mappings.merge(leftMapping, Mappings.offsetTarget(Mappings.offsetSource(rightMapping, offset), leftMapping.getTargetCount()));
                final RelNode project = RelOptUtil.createProject(LogicalTableScan.create(cluster, leftRelOptTable), Mappings.asList(mapping.inverse()));
                final List<RexNode> conditions = Lists.newArrayList();
                if (left.condition != null) {
                    conditions.add(left.condition);
                }
                if (right.condition != null) {
                    conditions.add(RexUtil.apply(mapping, RexUtil.shift(right.condition, offset)));
                }
                final RelNode filter = RelOptUtil.createFilter(project, conditions);
                throw new Util.FoundOne(filter);
            }
            if (rightTable instanceof StarTable && ((StarTable) rightTable).tables.contains(leftTable)) {
                final int offset = ((StarTable) rightTable).columnOffset(leftTable);
                Mappings.TargetMapping mapping = Mappings.merge(Mappings.offsetSource(leftMapping, offset), Mappings.offsetTarget(rightMapping, leftCount));
                final RelNode project = RelOptUtil.createProject(LogicalTableScan.create(cluster, rightRelOptTable), Mappings.asList(mapping.inverse()));
                final List<RexNode> conditions = Lists.newArrayList();
                if (left.condition != null) {
                    conditions.add(RexUtil.apply(mapping, RexUtil.shift(left.condition, offset)));
                }
                if (right.condition != null) {
                    conditions.add(RexUtil.apply(mapping, right.condition));
                }
                final RelNode filter = RelOptUtil.createFilter(project, conditions);
                throw new Util.FoundOne(filter);
            }
        }
    });
    if (rel2 == rel) {
        // No rewrite happened.
        return null;
    }
    final Program program = Programs.hep(ImmutableList.of(ProjectFilterTransposeRule.INSTANCE, AggregateProjectMergeRule.INSTANCE, AggregateFilterTransposeRule.INSTANCE), false, DefaultRelMetadataProvider.INSTANCE);
    return program.run(null, rel2, null, ImmutableList.<RelOptMaterialization>of(), ImmutableList.<RelOptLattice>of());
}
Also used : TableScan(org.apache.calcite.rel.core.TableScan) LogicalTableScan(org.apache.calcite.rel.logical.LogicalTableScan) Table(org.apache.calcite.schema.Table) StarTable(org.apache.calcite.schema.impl.StarTable) Program(org.apache.calcite.tools.Program) RelShuttleImpl(org.apache.calcite.rel.RelShuttleImpl) RexUtil(org.apache.calcite.rex.RexUtil) Util(org.apache.calcite.util.Util) RelNode(org.apache.calcite.rel.RelNode) StarTable(org.apache.calcite.schema.impl.StarTable) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List)

Aggregations

RelNode (org.apache.calcite.rel.RelNode)2 Table (org.apache.calcite.schema.Table)2 StarTable (org.apache.calcite.schema.impl.StarTable)2 ImmutableList (com.google.common.collect.ImmutableList)1 List (java.util.List)1 CalciteSchema (org.apache.calcite.jdbc.CalciteSchema)1 RelOptTable (org.apache.calcite.plan.RelOptTable)1 RelShuttleImpl (org.apache.calcite.rel.RelShuttleImpl)1 TableScan (org.apache.calcite.rel.core.TableScan)1 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)1 LogicalTableScan (org.apache.calcite.rel.logical.LogicalTableScan)1 RexUtil (org.apache.calcite.rex.RexUtil)1 SqlRexConvertletTable (org.apache.calcite.sql2rel.SqlRexConvertletTable)1 Program (org.apache.calcite.tools.Program)1 Util (org.apache.calcite.util.Util)1