Search in sources :

Example 36 with TableScan

use of org.apache.calcite.rel.core.TableScan in project samza by apache.

the class JoinTranslator method isValidRemoteJoinRef.

/**
 * Helper method to check if the join condition can be evaluated by the remote table.
 * It does follow single path  using the index ref path checking if it is a simple reference all the way to table scan.
 * In case any RexCall is encountered will stop an return null as a marker otherwise will return Column Name.
 *
 * @param inputRexIndex rex ref index
 * @param relNode current Rel Node
 * @return false if any Relational Expression is encountered on the path, true if is simple ref to __key__ column.
 */
private static boolean isValidRemoteJoinRef(int inputRexIndex, RelNode relNode) {
    if (relNode instanceof TableScan) {
        return relNode.getRowType().getFieldList().get(inputRexIndex).getName().equals(SamzaSqlRelMessage.KEY_NAME);
    }
    // has to be a single rel kind filter/project/table scan
    Preconditions.checkState(relNode.getInputs().size() == 1, "Has to be single input RelNode and got " + relNode.getDigest());
    if (relNode instanceof LogicalFilter) {
        return isValidRemoteJoinRef(inputRexIndex, relNode.getInput(0));
    }
    RexNode inputRef = ((LogicalProject) relNode).getProjects().get(inputRexIndex);
    if (inputRef instanceof RexCall) {
        // we can not push any expression as of now stop and return null.
        return false;
    }
    return isValidRemoteJoinRef(((RexInputRef) inputRef).getIndex(), relNode.getInput(0));
}
Also used : RexCall(org.apache.calcite.rex.RexCall) TableScan(org.apache.calcite.rel.core.TableScan) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) RexNode(org.apache.calcite.rex.RexNode)

Example 37 with TableScan

use of org.apache.calcite.rel.core.TableScan in project samza by apache.

the class JoinTranslator method resolveSQlIOForTable.

static SqlIOConfig resolveSQlIOForTable(RelNode relNode, Map<String, SqlIOConfig> systemStreamConfigBySource) {
    if (relNode instanceof HepRelVertex) {
        return resolveSQlIOForTable(((HepRelVertex) relNode).getCurrentRel(), systemStreamConfigBySource);
    }
    if (relNode instanceof LogicalProject) {
        return resolveSQlIOForTable(((LogicalProject) relNode).getInput(), systemStreamConfigBySource);
    }
    if (relNode instanceof LogicalFilter) {
        return resolveSQlIOForTable(((LogicalFilter) relNode).getInput(), systemStreamConfigBySource);
    }
    // is considered a stream. Hence, we return null for the table.
    if (relNode instanceof LogicalJoin && relNode.getInputs().size() > 1) {
        return null;
    }
    if (!(relNode instanceof TableScan)) {
        throw new SamzaException(String.format("Unsupported query. relNode %s is not of type TableScan.", relNode.toString()));
    }
    String sourceName = SqlIOConfig.getSourceFromSourceParts(relNode.getTable().getQualifiedName());
    SqlIOConfig sourceConfig = systemStreamConfigBySource.get(sourceName);
    if (sourceConfig == null) {
        throw new SamzaException("Unsupported source found in join statement: " + sourceName);
    }
    return sourceConfig;
}
Also used : SqlIOConfig(org.apache.samza.sql.interfaces.SqlIOConfig) HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex) TableScan(org.apache.calcite.rel.core.TableScan) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) SamzaException(org.apache.samza.SamzaException)

Example 38 with TableScan

use of org.apache.calcite.rel.core.TableScan 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 39 with TableScan

use of org.apache.calcite.rel.core.TableScan in project calcite by apache.

the class CalcitePrepareImpl method analyze_.

private AnalyzeViewResult analyze_(SqlValidator validator, String sql, SqlNode sqlNode, RelRoot root, boolean fail) {
    final RexBuilder rexBuilder = root.rel.getCluster().getRexBuilder();
    RelNode rel = root.rel;
    final RelNode viewRel = rel;
    Project project;
    if (rel instanceof Project) {
        project = (Project) rel;
        rel = project.getInput();
    } else {
        project = null;
    }
    Filter filter;
    if (rel instanceof Filter) {
        filter = (Filter) rel;
        rel = filter.getInput();
    } else {
        filter = null;
    }
    TableScan scan;
    if (rel instanceof TableScan) {
        scan = (TableScan) rel;
    } else {
        scan = null;
    }
    if (scan == null) {
        if (fail) {
            throw validator.newValidationError(sqlNode, RESOURCE.modifiableViewMustBeBasedOnSingleTable());
        }
        return new AnalyzeViewResult(this, validator, sql, sqlNode, validator.getValidatedNodeType(sqlNode), root, null, null, null, null, false);
    }
    final RelOptTable targetRelTable = scan.getTable();
    final RelDataType targetRowType = targetRelTable.getRowType();
    final Table table = targetRelTable.unwrap(Table.class);
    final List<String> tablePath = targetRelTable.getQualifiedName();
    assert table != null;
    List<Integer> columnMapping;
    final Map<Integer, RexNode> projectMap = new HashMap<>();
    if (project == null) {
        columnMapping = ImmutableIntList.range(0, targetRowType.getFieldCount());
    } else {
        columnMapping = new ArrayList<>();
        for (Ord<RexNode> node : Ord.zip(project.getProjects())) {
            if (node.e instanceof RexInputRef) {
                RexInputRef rexInputRef = (RexInputRef) node.e;
                int index = rexInputRef.getIndex();
                if (projectMap.get(index) != null) {
                    if (fail) {
                        throw validator.newValidationError(sqlNode, RESOURCE.moreThanOneMappedColumn(targetRowType.getFieldList().get(index).getName(), Util.last(tablePath)));
                    }
                    return new AnalyzeViewResult(this, validator, sql, sqlNode, validator.getValidatedNodeType(sqlNode), root, null, null, null, null, false);
                }
                projectMap.put(index, rexBuilder.makeInputRef(viewRel, node.i));
                columnMapping.add(index);
            } else {
                columnMapping.add(-1);
            }
        }
    }
    final RexNode constraint;
    if (filter != null) {
        constraint = filter.getCondition();
    } else {
        constraint = rexBuilder.makeLiteral(true);
    }
    final List<RexNode> filters = new ArrayList<>();
    // If we put a constraint in projectMap above, then filters will not be empty despite
    // being a modifiable view.
    final List<RexNode> filters2 = new ArrayList<>();
    boolean retry = false;
    RelOptUtil.inferViewPredicates(projectMap, filters, constraint);
    if (fail && !filters.isEmpty()) {
        final Map<Integer, RexNode> projectMap2 = new HashMap<>();
        RelOptUtil.inferViewPredicates(projectMap2, filters2, constraint);
        if (!filters2.isEmpty()) {
            throw validator.newValidationError(sqlNode, RESOURCE.modifiableViewMustHaveOnlyEqualityPredicates());
        }
        retry = true;
    }
    // Check that all columns that are not projected have a constant value
    for (RelDataTypeField field : targetRowType.getFieldList()) {
        final int x = columnMapping.indexOf(field.getIndex());
        if (x >= 0) {
            assert Util.skip(columnMapping, x + 1).indexOf(field.getIndex()) < 0 : "column projected more than once; should have checked above";
            // target column is projected
            continue;
        }
        if (projectMap.get(field.getIndex()) != null) {
            // constant expression
            continue;
        }
        if (field.getType().isNullable()) {
            // don't need expression for nullable columns; NULL suffices
            continue;
        }
        if (fail) {
            throw validator.newValidationError(sqlNode, RESOURCE.noValueSuppliedForViewColumn(field.getName(), Util.last(tablePath)));
        }
        return new AnalyzeViewResult(this, validator, sql, sqlNode, validator.getValidatedNodeType(sqlNode), root, null, null, null, null, false);
    }
    final boolean modifiable = filters.isEmpty() || retry && filters2.isEmpty();
    return new AnalyzeViewResult(this, validator, sql, sqlNode, validator.getValidatedNodeType(sqlNode), root, modifiable ? table : null, ImmutableList.copyOf(tablePath), constraint, ImmutableIntList.copyOf(columnMapping), modifiable);
}
Also used : TableScan(org.apache.calcite.rel.core.TableScan) Table(org.apache.calcite.schema.Table) StandardConvertletTable(org.apache.calcite.sql2rel.StandardConvertletTable) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) RelOptTable(org.apache.calcite.plan.RelOptTable) ChainedSqlOperatorTable(org.apache.calcite.sql.util.ChainedSqlOperatorTable) SqlOperatorTable(org.apache.calcite.sql.SqlOperatorTable) SqlRexConvertletTable(org.apache.calcite.sql2rel.SqlRexConvertletTable) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) Project(org.apache.calcite.rel.core.Project) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) Filter(org.apache.calcite.rel.core.Filter) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) RelOptTable(org.apache.calcite.plan.RelOptTable) RexNode(org.apache.calcite.rex.RexNode)

Example 40 with TableScan

use of org.apache.calcite.rel.core.TableScan in project calcite by apache.

the class Prepare method optimize.

/**
 * Optimizes a query plan.
 *
 * @param root Root of relational expression tree
 * @param materializations Tables known to be populated with a given query
 * @param lattices Lattices
 * @return an equivalent optimized relational expression
 */
protected RelRoot optimize(RelRoot root, final List<Materialization> materializations, final List<CalciteSchema.LatticeEntry> lattices) {
    final RelOptPlanner planner = root.rel.getCluster().getPlanner();
    final DataContext dataContext = context.getDataContext();
    planner.setExecutor(new RexExecutorImpl(dataContext));
    final List<RelOptMaterialization> materializationList = new ArrayList<>();
    for (Materialization materialization : materializations) {
        List<String> qualifiedTableName = materialization.materializedTable.path();
        materializationList.add(new RelOptMaterialization(materialization.tableRel, materialization.queryRel, materialization.starRelOptTable, qualifiedTableName));
    }
    final List<RelOptLattice> latticeList = new ArrayList<>();
    for (CalciteSchema.LatticeEntry lattice : lattices) {
        final CalciteSchema.TableEntry starTable = lattice.getStarTable();
        final JavaTypeFactory typeFactory = context.getTypeFactory();
        final RelOptTableImpl starRelOptTable = RelOptTableImpl.create(catalogReader, starTable.getTable().getRowType(typeFactory), starTable, null);
        latticeList.add(new RelOptLattice(lattice.getLattice(), starRelOptTable));
    }
    final RelTraitSet desiredTraits = getDesiredRootTraitSet(root);
    // Work around
    // [CALCITE-1774] Allow rules to be registered during planning process
    // by briefly creating each kind of physical table to let it register its
    // rules. The problem occurs when plans are created via RelBuilder, not
    // the usual process (SQL and SqlToRelConverter.Config.isConvertTableAccess
    // = true).
    final RelVisitor visitor = new RelVisitor() {

        @Override
        public void visit(RelNode node, int ordinal, RelNode parent) {
            if (node instanceof TableScan) {
                final RelOptCluster cluster = node.getCluster();
                final RelOptTable.ToRelContext context = RelOptUtil.getContext(cluster);
                final RelNode r = node.getTable().toRel(context);
                planner.registerClass(r);
            }
            super.visit(node, ordinal, parent);
        }
    };
    visitor.go(root.rel);
    final Program program = getProgram();
    final RelNode rootRel4 = program.run(planner, root.rel, desiredTraits, materializationList, latticeList);
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Plan after physical tweaks: {}", RelOptUtil.toString(rootRel4, SqlExplainLevel.ALL_ATTRIBUTES));
    }
    return root.withRel(rootRel4);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) TableScan(org.apache.calcite.rel.core.TableScan) Program(org.apache.calcite.tools.Program) ArrayList(java.util.ArrayList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner) LatticeEntry(org.apache.calcite.jdbc.CalciteSchema.LatticeEntry) RexExecutorImpl(org.apache.calcite.rex.RexExecutorImpl) RelOptMaterialization(org.apache.calcite.plan.RelOptMaterialization) DataContext(org.apache.calcite.DataContext) RelNode(org.apache.calcite.rel.RelNode) RelOptMaterialization(org.apache.calcite.plan.RelOptMaterialization) CalciteSchema(org.apache.calcite.jdbc.CalciteSchema) JavaTypeFactory(org.apache.calcite.adapter.java.JavaTypeFactory) RelOptLattice(org.apache.calcite.plan.RelOptLattice) RelVisitor(org.apache.calcite.rel.RelVisitor) RelOptTable(org.apache.calcite.plan.RelOptTable)

Aggregations

TableScan (org.apache.calcite.rel.core.TableScan)51 RelNode (org.apache.calcite.rel.RelNode)19 ArrayList (java.util.ArrayList)13 PlannerSettings (org.apache.drill.exec.planner.physical.PlannerSettings)13 Project (org.apache.calcite.rel.core.Project)12 DrillScanRel (org.apache.drill.exec.planner.logical.DrillScanRel)11 Filter (org.apache.calcite.rel.core.Filter)10 IOException (java.io.IOException)9 RexNode (org.apache.calcite.rex.RexNode)9 GroupScan (org.apache.drill.exec.physical.base.GroupScan)9 RelOptRuleCall (org.apache.calcite.plan.RelOptRuleCall)8 DrillFilterRel (org.apache.drill.exec.planner.logical.DrillFilterRel)8 Aggregate (org.apache.calcite.rel.core.Aggregate)7 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)7 RexBuilder (org.apache.calcite.rex.RexBuilder)6 RelOptCluster (org.apache.calcite.plan.RelOptCluster)5 RelShuttleImpl (org.apache.calcite.rel.RelShuttleImpl)5 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)5 RelDataType (org.apache.calcite.rel.type.RelDataType)5 SchemaPath (org.apache.drill.common.expression.SchemaPath)5