Search in sources :

Example 1 with RelShuttleImpl

use of org.apache.calcite.rel.RelShuttleImpl in project samza by apache.

the class QueryTranslator method translate.

/**
 * Translate Calcite plan to Samza stream operators.
 * @param relRoot Calcite plan in the form of {@link RelRoot}. RelRoot should not include the sink ({@link TableModify})
 * @param outputSystemStream Sink associated with the Calcite plan.
 * @param translatorContext Context maintained across translations.
 * @param queryId query index of the sql statement corresponding to the Calcite plan in multi SQL statement scenario
 *                starting with index 0.
 */
public void translate(RelRoot relRoot, String outputSystemStream, TranslatorContext translatorContext, int queryId) {
    final RelNode node = relRoot.project();
    ScanTranslator scanTranslator = new ScanTranslator(sqlConfig.getSamzaRelConverters(), sqlConfig.getInputSystemStreamConfigBySource(), queryId);
    /* update input metrics */
    String queryLogicalId = String.format(TranslatorConstants.LOGSQLID_TEMPLATE, queryId);
    opId = 0;
    node.accept(new RelShuttleImpl() {

        @Override
        public RelNode visit(RelNode relNode) {
            // There should never be a TableModify in the calcite plan.
            Validate.isTrue(!(relNode instanceof TableModify));
            return super.visit(relNode);
        }

        @Override
        public RelNode visit(TableScan scan) {
            RelNode node = super.visit(scan);
            String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "scan", opId++);
            scanTranslator.translate(scan, queryLogicalId, logicalOpId, translatorContext, systemDescriptors, inputMsgStreams);
            return node;
        }

        @Override
        public RelNode visit(LogicalFilter filter) {
            RelNode node = visitChild(filter, 0, filter.getInput());
            String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "filter", opId++);
            new FilterTranslator(queryId).translate(filter, logicalOpId, translatorContext);
            return node;
        }

        @Override
        public RelNode visit(LogicalProject project) {
            RelNode node = super.visit(project);
            String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "project", opId++);
            new ProjectTranslator(queryId).translate(project, logicalOpId, translatorContext);
            return node;
        }

        @Override
        public RelNode visit(LogicalJoin join) {
            RelNode node = super.visit(join);
            String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "join", opId++);
            new JoinTranslator(logicalOpId, sqlConfig.getMetadataTopicPrefix(), queryId).translate(join, translatorContext);
            return node;
        }

        @Override
        public RelNode visit(LogicalAggregate aggregate) {
            RelNode node = super.visit(aggregate);
            String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "window", opId++);
            new LogicalAggregateTranslator(logicalOpId, sqlConfig.getMetadataTopicPrefix()).translate(aggregate, translatorContext);
            return node;
        }
    });
    String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "insert", opId);
    sendToOutputStream(queryLogicalId, logicalOpId, outputSystemStream, streamAppDescriptor, translatorContext, node, queryId);
}
Also used : TableScan(org.apache.calcite.rel.core.TableScan) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) RelShuttleImpl(org.apache.calcite.rel.RelShuttleImpl) LogicalAggregate(org.apache.calcite.rel.logical.LogicalAggregate) RelNode(org.apache.calcite.rel.RelNode) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) TableModify(org.apache.calcite.rel.core.TableModify)

Example 2 with RelShuttleImpl

use of org.apache.calcite.rel.RelShuttleImpl in project calcite by apache.

the class SqlToRelConverterExtendedTest method foo.

public static void foo(RelNode rel) {
    // Convert rel tree to JSON.
    final RelJsonWriter writer = new RelJsonWriter();
    rel.explain(writer);
    final String json = writer.asString();
    // Find the schema. If there are no tables in the plan, we won't need one.
    final RelOptSchema[] schemas = { null };
    rel.accept(new RelShuttleImpl() {

        @Override
        public RelNode visit(TableScan scan) {
            schemas[0] = scan.getTable().getRelOptSchema();
            return super.visit(scan);
        }
    });
    // Convert JSON back to rel tree.
    Frameworks.withPlanner(new Frameworks.PlannerAction<Object>() {

        public Object apply(RelOptCluster cluster, RelOptSchema relOptSchema, SchemaPlus rootSchema) {
            final RelJsonReader reader = new RelJsonReader(cluster, schemas[0], rootSchema);
            try {
                RelNode x = reader.read(json);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return null;
        }
    });
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) TableScan(org.apache.calcite.rel.core.TableScan) RelOptSchema(org.apache.calcite.plan.RelOptSchema) SchemaPlus(org.apache.calcite.schema.SchemaPlus) RelShuttleImpl(org.apache.calcite.rel.RelShuttleImpl) RelJsonWriter(org.apache.calcite.rel.externalize.RelJsonWriter) IOException(java.io.IOException) RelNode(org.apache.calcite.rel.RelNode) Frameworks(org.apache.calcite.tools.Frameworks) RelJsonReader(org.apache.calcite.rel.externalize.RelJsonReader)

Example 3 with RelShuttleImpl

use of org.apache.calcite.rel.RelShuttleImpl 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)

Example 4 with RelShuttleImpl

use of org.apache.calcite.rel.RelShuttleImpl in project drill by apache.

the class FindLimit0Visitor method addLimitOnTopOfLeafNodes.

public static DrillRel addLimitOnTopOfLeafNodes(final DrillRel rel) {
    final Pointer<Boolean> isUnsupported = new Pointer<>(false);
    // to visit unsupported functions
    final RexShuttle unsupportedFunctionsVisitor = new RexShuttle() {

        @Override
        public RexNode visitCall(RexCall call) {
            final SqlOperator operator = call.getOperator();
            if (isUnsupportedScalarFunction(operator)) {
                isUnsupported.value = true;
                return call;
            }
            return super.visitCall(call);
        }
    };
    // to visit unsupported operators
    final RelShuttle unsupportedOperationsVisitor = new RelShuttleImpl() {

        @Override
        public RelNode visit(RelNode other) {
            if (other instanceof DrillUnionRelBase) {
                isUnsupported.value = true;
                return other;
            } else if (other instanceof DrillProjectRelBase) {
                if (!isUnsupported.value) {
                    other.accept(unsupportedFunctionsVisitor);
                }
                if (isUnsupported.value) {
                    return other;
                }
            }
            return super.visit(other);
        }
    };
    rel.accept(unsupportedOperationsVisitor);
    if (isUnsupported.value) {
        return rel;
    }
    // to add LIMIT (0) on top of leaf nodes
    final RelShuttle addLimitOnScanVisitor = new RelShuttleImpl() {

        private RelNode addLimitAsParent(RelNode node) {
            final RexBuilder builder = node.getCluster().getRexBuilder();
            final RexLiteral offset = builder.makeExactLiteral(BigDecimal.ZERO);
            final RexLiteral fetch = builder.makeExactLiteral(BigDecimal.ZERO);
            return new DrillLimitRel(node.getCluster(), node.getTraitSet(), node, offset, fetch);
        }

        @Override
        public RelNode visit(LogicalValues values) {
            return addLimitAsParent(values);
        }

        @Override
        public RelNode visit(TableScan scan) {
            return addLimitAsParent(scan);
        }

        @Override
        public RelNode visit(RelNode other) {
            if (other.getInputs().isEmpty()) {
                // leaf operator
                return addLimitAsParent(other);
            }
            return super.visit(other);
        }
    };
    return (DrillRel) rel.accept(addLimitOnScanVisitor);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) TableScan(org.apache.calcite.rel.core.TableScan) RexShuttle(org.apache.calcite.rex.RexShuttle) DrillSqlOperator(org.apache.drill.exec.planner.sql.DrillSqlOperator) SqlOperator(org.apache.calcite.sql.SqlOperator) RelShuttle(org.apache.calcite.rel.RelShuttle) RelShuttleImpl(org.apache.calcite.rel.RelShuttleImpl) Pointer(org.apache.drill.exec.util.Pointer) DrillProjectRelBase(org.apache.drill.exec.planner.common.DrillProjectRelBase) DrillLimitRel(org.apache.drill.exec.planner.logical.DrillLimitRel) LogicalValues(org.apache.calcite.rel.logical.LogicalValues) RexCall(org.apache.calcite.rex.RexCall) RelNode(org.apache.calcite.rel.RelNode) DrillUnionRelBase(org.apache.drill.exec.planner.common.DrillUnionRelBase) RexBuilder(org.apache.calcite.rex.RexBuilder) DrillRel(org.apache.drill.exec.planner.logical.DrillRel)

Example 5 with RelShuttleImpl

use of org.apache.calcite.rel.RelShuttleImpl in project hazelcast by hazelcast.

the class CalciteSqlOptimizer method extractPermissions.

private List<Permission> extractPermissions(PhysicalRel physicalRel) {
    List<Permission> permissions = new ArrayList<>();
    physicalRel.accept(new RelShuttleImpl() {

        @Override
        public RelNode visit(TableScan scan) {
            addPermissionForTable(scan.getTable(), ActionConstants.ACTION_READ);
            return super.visit(scan);
        }

        @Override
        public RelNode visit(RelNode other) {
            addPermissionForTable(other.getTable(), ActionConstants.ACTION_PUT);
            return super.visit(other);
        }

        private void addPermissionForTable(RelOptTable t, String action) {
            if (t == null) {
                return;
            }
            HazelcastTable table = t.unwrap(HazelcastTable.class);
            if (table != null && table.getTarget() instanceof AbstractMapTable) {
                String mapName = ((AbstractMapTable) table.getTarget()).getMapName();
                permissions.add(new MapPermission(mapName, action));
            }
        }
    });
    return permissions;
}
Also used : TableScan(org.apache.calcite.rel.core.TableScan) AbstractMapTable(com.hazelcast.sql.impl.schema.map.AbstractMapTable) RelNode(org.apache.calcite.rel.RelNode) MapPermission(com.hazelcast.security.permission.MapPermission) Permission(java.security.Permission) MapPermission(com.hazelcast.security.permission.MapPermission) ArrayList(java.util.ArrayList) RelShuttleImpl(org.apache.calcite.rel.RelShuttleImpl) RelOptTable(org.apache.calcite.plan.RelOptTable) SqlString(org.apache.calcite.sql.util.SqlString) HazelcastTable(com.hazelcast.jet.sql.impl.schema.HazelcastTable)

Aggregations

RelNode (org.apache.calcite.rel.RelNode)5 RelShuttleImpl (org.apache.calcite.rel.RelShuttleImpl)5 TableScan (org.apache.calcite.rel.core.TableScan)5 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)2 ImmutableList (com.google.common.collect.ImmutableList)1 HazelcastTable (com.hazelcast.jet.sql.impl.schema.HazelcastTable)1 MapPermission (com.hazelcast.security.permission.MapPermission)1 AbstractMapTable (com.hazelcast.sql.impl.schema.map.AbstractMapTable)1 IOException (java.io.IOException)1 Permission (java.security.Permission)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 RelOptCluster (org.apache.calcite.plan.RelOptCluster)1 RelOptSchema (org.apache.calcite.plan.RelOptSchema)1 RelOptTable (org.apache.calcite.plan.RelOptTable)1 RelShuttle (org.apache.calcite.rel.RelShuttle)1 TableModify (org.apache.calcite.rel.core.TableModify)1 RelJsonReader (org.apache.calcite.rel.externalize.RelJsonReader)1 RelJsonWriter (org.apache.calcite.rel.externalize.RelJsonWriter)1 LogicalAggregate (org.apache.calcite.rel.logical.LogicalAggregate)1