Search in sources :

Example 71 with Project

use of org.apache.calcite.rel.core.Project in project flink by apache.

the class FlinkRelDecorrelator method projectedLiteral.

/**
	 * Returns a literal output field, or null if it is not literal.
	 */
private static RexLiteral projectedLiteral(RelNode rel, int i) {
    if (rel instanceof Project) {
        final Project project = (Project) rel;
        final RexNode node = project.getProjects().get(i);
        if (node instanceof RexLiteral) {
            return (RexLiteral) node;
        }
    }
    return null;
}
Also used : Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexLiteral(org.apache.calcite.rex.RexLiteral) RexNode(org.apache.calcite.rex.RexNode)

Example 72 with Project

use of org.apache.calcite.rel.core.Project in project storm by apache.

the class TridentProjectRule method convert.

@Override
public RelNode convert(RelNode rel) {
    final Project project = (Project) rel;
    final RelNode input = project.getInput();
    return new TridentProjectRel(project.getCluster(), project.getTraitSet().replace(TridentLogicalConvention.INSTANCE), convert(input, input.getTraitSet().replace(TridentLogicalConvention.INSTANCE)), project.getProjects(), project.getRowType());
}
Also used : Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) TridentProjectRel(org.apache.storm.sql.planner.trident.rel.TridentProjectRel) RelNode(org.apache.calcite.rel.RelNode)

Example 73 with Project

use of org.apache.calcite.rel.core.Project in project druid by druid-io.

the class GroupByRules method applyAggregate.

/**
   * Applies a filter -> project -> aggregate chain to a druidRel. Do not call this method unless
   * {@link #canApplyAggregate(DruidRel, Filter, Project, Aggregate)} returns true.
   *
   * @return new rel, or null if the chain cannot be applied
   */
private static DruidRel applyAggregate(final DruidRel druidRel, final Filter filter0, final Project project0, final Aggregate aggregate, final DruidOperatorTable operatorTable, final boolean approximateCountDistinct) {
    Preconditions.checkState(canApplyAggregate(druidRel, filter0, project0, aggregate), "Cannot applyAggregate.");
    final RowSignature sourceRowSignature;
    final boolean isNestedQuery = druidRel.getQueryBuilder().getGrouping() != null;
    if (isNestedQuery) {
        // Nested groupBy; source row signature is the output signature of druidRel.
        sourceRowSignature = druidRel.getOutputRowSignature();
    } else {
        sourceRowSignature = druidRel.getSourceRowSignature();
    }
    // Filter that should be applied before aggregating.
    final DimFilter filter;
    if (filter0 != null) {
        filter = Expressions.toFilter(operatorTable, druidRel.getPlannerContext(), sourceRowSignature, filter0.getCondition());
        if (filter == null) {
            // Can't plan this filter.
            return null;
        }
    } else if (druidRel.getQueryBuilder().getFilter() != null && !isNestedQuery) {
        // We're going to replace the existing druidRel, so inherit its filter.
        filter = druidRel.getQueryBuilder().getFilter();
    } else {
        filter = null;
    }
    // Projection that should be applied before aggregating.
    final Project project;
    if (project0 != null) {
        project = project0;
    } else if (druidRel.getQueryBuilder().getSelectProjection() != null && !isNestedQuery) {
        // We're going to replace the existing druidRel, so inherit its projection.
        project = druidRel.getQueryBuilder().getSelectProjection().getProject();
    } else {
        project = null;
    }
    final List<DimensionSpec> dimensions = Lists.newArrayList();
    final List<Aggregation> aggregations = Lists.newArrayList();
    final List<String> rowOrder = Lists.newArrayList();
    // Translate groupSet.
    final ImmutableBitSet groupSet = aggregate.getGroupSet();
    int dimOutputNameCounter = 0;
    for (int i : groupSet) {
        if (project != null && project.getChildExps().get(i) instanceof RexLiteral) {
            // Ignore literals in GROUP BY, so a user can write e.g. "GROUP BY 'dummy'" to group everything into a single
            // row. Add dummy rowOrder entry so NULLs come out. This is not strictly correct but it works as long as
            // nobody actually expects to see the literal.
            rowOrder.add(dimOutputName(dimOutputNameCounter++));
        } else {
            final RexNode rexNode = Expressions.fromFieldAccess(sourceRowSignature, project, i);
            final RowExtraction rex = Expressions.toRowExtraction(operatorTable, druidRel.getPlannerContext(), sourceRowSignature.getRowOrder(), rexNode);
            if (rex == null) {
                return null;
            }
            final SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();
            final ValueType outputType = Calcites.getValueTypeForSqlTypeName(sqlTypeName);
            if (outputType == null) {
                throw new ISE("Cannot translate sqlTypeName[%s] to Druid type for field[%s]", sqlTypeName, rowOrder.get(i));
            }
            final DimensionSpec dimensionSpec = rex.toDimensionSpec(sourceRowSignature, dimOutputName(dimOutputNameCounter++), outputType);
            if (dimensionSpec == null) {
                return null;
            }
            dimensions.add(dimensionSpec);
            rowOrder.add(dimensionSpec.getOutputName());
        }
    }
    // Translate aggregates.
    for (int i = 0; i < aggregate.getAggCallList().size(); i++) {
        final AggregateCall aggCall = aggregate.getAggCallList().get(i);
        final Aggregation aggregation = translateAggregateCall(druidRel.getPlannerContext(), sourceRowSignature, project, aggCall, operatorTable, aggregations, i, approximateCountDistinct);
        if (aggregation == null) {
            return null;
        }
        aggregations.add(aggregation);
        rowOrder.add(aggregation.getOutputName());
    }
    if (isNestedQuery) {
        // Nested groupBy.
        return DruidNestedGroupBy.from(druidRel, filter, Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder);
    } else {
        // groupBy on a base dataSource.
        return druidRel.withQueryBuilder(druidRel.getQueryBuilder().withFilter(filter).withGrouping(Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder));
    }
}
Also used : DimensionSpec(io.druid.query.dimension.DimensionSpec) RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) ValueType(io.druid.segment.column.ValueType) RowExtraction(io.druid.sql.calcite.expression.RowExtraction) Aggregation(io.druid.sql.calcite.aggregation.Aggregation) AggregateCall(org.apache.calcite.rel.core.AggregateCall) Project(org.apache.calcite.rel.core.Project) ISE(io.druid.java.util.common.ISE) RowSignature(io.druid.sql.calcite.table.RowSignature) DimFilter(io.druid.query.filter.DimFilter) NotDimFilter(io.druid.query.filter.NotDimFilter) AndDimFilter(io.druid.query.filter.AndDimFilter) RexNode(org.apache.calcite.rex.RexNode)

Example 74 with Project

use of org.apache.calcite.rel.core.Project in project hive by apache.

the class HiveSubQRemoveRelBuilder method sortLimit.

/**
 * Creates a {@link Sort} by a list of expressions, with limit and offset.
 *
 * @param offset Number of rows to skip; non-positive means don't skip any
 * @param fetch Maximum number of rows to fetch; negative means no limit
 * @param nodes Sort expressions
 */
public HiveSubQRemoveRelBuilder sortLimit(int offset, int fetch, Iterable<? extends RexNode> nodes) {
    final List<RelFieldCollation> fieldCollations = new ArrayList<>();
    final RelDataType inputRowType = peek().getRowType();
    final List<RexNode> extraNodes = projects(inputRowType);
    final List<RexNode> originalExtraNodes = ImmutableList.copyOf(extraNodes);
    for (RexNode node : nodes) {
        fieldCollations.add(collation(node, RelFieldCollation.Direction.ASCENDING, null, extraNodes));
    }
    final RexNode offsetNode = offset <= 0 ? null : literal(offset);
    final RexNode fetchNode = fetch < 0 ? null : literal(fetch);
    if (offsetNode == null && fetch == 0) {
        return empty();
    }
    if (offsetNode == null && fetchNode == null && fieldCollations.isEmpty()) {
        // sort is trivial
        return this;
    }
    final boolean addedFields = extraNodes.size() > originalExtraNodes.size();
    if (fieldCollations.isEmpty()) {
        assert !addedFields;
        RelNode top = peek();
        if (top instanceof Sort) {
            final Sort sort2 = (Sort) top;
            if (sort2.offset == null && sort2.fetch == null) {
                stack.pop();
                push(sort2.getInput());
                final RelNode sort = sortFactory.createSort(build(), sort2.collation, offsetNode, fetchNode);
                push(sort);
                return this;
            }
        }
        if (top instanceof Project) {
            final Project project = (Project) top;
            if (project.getInput() instanceof Sort) {
                final Sort sort2 = (Sort) project.getInput();
                if (sort2.offset == null && sort2.fetch == null) {
                    stack.pop();
                    push(sort2.getInput());
                    final RelNode sort = sortFactory.createSort(build(), sort2.collation, offsetNode, fetchNode);
                    push(sort);
                    project(project.getProjects());
                    return this;
                }
            }
        }
    }
    if (addedFields) {
        project(extraNodes);
    }
    final RelNode sort = sortFactory.createSort(build(), RelCollations.of(fieldCollations), offsetNode, fetchNode);
    push(sort);
    if (addedFields) {
        project(originalExtraNodes);
    }
    return this;
}
Also used : Project(org.apache.calcite.rel.core.Project) RelNode(org.apache.calcite.rel.RelNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) ArrayList(java.util.ArrayList) Sort(org.apache.calcite.rel.core.Sort) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 75 with Project

use of org.apache.calcite.rel.core.Project in project drill by axbaretto.

the class DrillPushFilterPastProjectRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    Filter filterRel = call.rel(0);
    Project projRel = call.rel(1);
    // get a conjunctions of the filter condition. For each conjunction, if it refers to ITEM or FLATTEN expression
    // then we could not pushed down. Otherwise, it's qualified to be pushed down.
    final List<RexNode> predList = RelOptUtil.conjunctions(filterRel.getCondition());
    final List<RexNode> qualifiedPredList = Lists.newArrayList();
    final List<RexNode> unqualifiedPredList = Lists.newArrayList();
    for (final RexNode pred : predList) {
        if (DrillRelOptUtil.findOperators(pred, projRel.getProjects(), BANNED_OPERATORS) == null) {
            qualifiedPredList.add(pred);
        } else {
            unqualifiedPredList.add(pred);
        }
    }
    final RexNode qualifedPred = RexUtil.composeConjunction(filterRel.getCluster().getRexBuilder(), qualifiedPredList, true);
    if (qualifedPred == null) {
        return;
    }
    // convert the filter to one that references the child of the project
    RexNode newCondition = RelOptUtil.pushPastProject(qualifedPred, projRel);
    Filter newFilterRel = LogicalFilter.create(projRel.getInput(), newCondition);
    Project newProjRel = (Project) RelOptUtil.createProject(newFilterRel, Pair.left(projRel.getNamedProjects()), Pair.right(projRel.getNamedProjects()), false, relBuilderFactory.create(projRel.getCluster(), null));
    final RexNode unqualifiedPred = RexUtil.composeConjunction(filterRel.getCluster().getRexBuilder(), unqualifiedPredList, true);
    if (unqualifiedPred == null) {
        call.transformTo(newProjRel);
    } else {
        // if there are filters not qualified to be pushed down, then we have to put those filters on top of
        // the new Project operator.
        // Filter -- unqualified filters
        // \
        // Project
        // \
        // Filter  -- qualified filters
        Filter filterNotPushed = LogicalFilter.create(newProjRel, unqualifiedPred);
        call.transformTo(filterNotPushed);
    }
}
Also used : Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) Filter(org.apache.calcite.rel.core.Filter) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

Project (org.apache.calcite.rel.core.Project)143 RexNode (org.apache.calcite.rex.RexNode)77 RelNode (org.apache.calcite.rel.RelNode)71 ArrayList (java.util.ArrayList)46 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)35 RexBuilder (org.apache.calcite.rex.RexBuilder)28 RelDataType (org.apache.calcite.rel.type.RelDataType)26 Aggregate (org.apache.calcite.rel.core.Aggregate)22 Filter (org.apache.calcite.rel.core.Filter)22 Join (org.apache.calcite.rel.core.Join)22 List (java.util.List)19 RexLiteral (org.apache.calcite.rex.RexLiteral)19 AggregateCall (org.apache.calcite.rel.core.AggregateCall)18 Sort (org.apache.calcite.rel.core.Sort)18 Test (org.junit.Test)18 RelBuilder (org.apache.calcite.tools.RelBuilder)17 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)16 HiveProject (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject)16 Collectors (java.util.stream.Collectors)15 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)15