Search in sources :

Example 6 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess in project flink by apache.

the class SubQueryDecorrelator method analyzeCorConditions.

private static void analyzeCorConditions(final Set<CorrelationId> variableSet, final RexNode condition, final RexBuilder rexBuilder, final int maxCnfNodeCount, final List<RexNode> corConditions, final List<RexNode> nonCorConditions, final List<RexNode> unsupportedCorConditions) {
    // converts the expanded expression to conjunctive normal form,
    // like "(a AND b) OR c" will be converted to "(a OR c) AND (b OR c)"
    final RexNode cnf = FlinkRexUtil.toCnf(rexBuilder, maxCnfNodeCount, condition);
    // converts the cnf condition to a list of AND conditions
    final List<RexNode> conjunctions = RelOptUtil.conjunctions(cnf);
    // `true` for RexNode is supported correlation condition,
    // `false` for RexNode is unsupported correlation condition,
    // `null` for RexNode is not a correlation condition.
    final RexVisitorImpl<Boolean> visitor = new RexVisitorImpl<Boolean>(true) {

        @Override
        public Boolean visitFieldAccess(RexFieldAccess fieldAccess) {
            final RexNode ref = fieldAccess.getReferenceExpr();
            if (ref instanceof RexCorrelVariable) {
                return visitCorrelVariable((RexCorrelVariable) ref);
            } else {
                return super.visitFieldAccess(fieldAccess);
            }
        }

        @Override
        public Boolean visitCorrelVariable(RexCorrelVariable correlVariable) {
            return variableSet.contains(correlVariable.id);
        }

        @Override
        public Boolean visitSubQuery(RexSubQuery subQuery) {
            final List<Boolean> result = new ArrayList<>();
            for (RexNode operand : subQuery.operands) {
                result.add(operand.accept(this));
            }
            // in (select t3.d from t3)
            if (result.contains(true) || result.contains(false)) {
                return false;
            } else {
                return null;
            }
        }

        @Override
        public Boolean visitCall(RexCall call) {
            final List<Boolean> result = new ArrayList<>();
            for (RexNode operand : call.operands) {
                result.add(operand.accept(this));
            }
            if (result.contains(false)) {
                return false;
            } else if (result.contains(true)) {
                // return call.op.getKind() != SqlKind.OR || !result.contains(null);
                return call.op.getKind() != SqlKind.OR;
            } else {
                return null;
            }
        }
    };
    for (RexNode c : conjunctions) {
        Boolean r = c.accept(visitor);
        if (r == null) {
            nonCorConditions.add(c);
        } else if (r) {
            corConditions.add(c);
        } else {
            unsupportedCorConditions.add(c);
        }
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) ArrayList(java.util.ArrayList) RexVisitorImpl(org.apache.calcite.rex.RexVisitorImpl) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexSubQuery(org.apache.calcite.rex.RexSubQuery) RexNode(org.apache.calcite.rex.RexNode)

Example 7 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess in project beam by apache.

the class BeamZetaSqlUnnestRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    LogicalCorrelate correlate = call.rel(0);
    RelNode outer = call.rel(1);
    RelNode uncollect = call.rel(2);
    if (correlate.getRequiredColumns().cardinality() != 1) {
        // can only unnest a single column
        return;
    }
    if (correlate.getJoinType() != JoinRelType.INNER) {
        return;
    }
    if (!(uncollect instanceof ZetaSqlUnnest)) {
        // Drop projection
        uncollect = ((SingleRel) uncollect).getInput();
        if (uncollect instanceof RelSubset) {
            uncollect = ((RelSubset) uncollect).getOriginal();
        }
        if (!(uncollect instanceof ZetaSqlUnnest)) {
            return;
        }
    }
    RelNode project = ((ZetaSqlUnnest) uncollect).getInput();
    if (project instanceof RelSubset) {
        project = ((RelSubset) project).getOriginal();
    }
    if (!(project instanceof LogicalProject)) {
        return;
    }
    if (((LogicalProject) project).getProjects().size() != 1) {
        // can only unnest a single column
        return;
    }
    RexNode exp = ((LogicalProject) project).getProjects().get(0);
    if (!(exp instanceof RexFieldAccess)) {
        return;
    }
    RexFieldAccess fieldAccess = (RexFieldAccess) exp;
    // Innermost field index comes first (e.g. struct.field1.field2 => [2, 1])
    ImmutableList.Builder<Integer> fieldAccessIndices = ImmutableList.builder();
    while (true) {
        fieldAccessIndices.add(fieldAccess.getField().getIndex());
        if (!(fieldAccess.getReferenceExpr() instanceof RexFieldAccess)) {
            break;
        }
        fieldAccess = (RexFieldAccess) fieldAccess.getReferenceExpr();
    }
    call.transformTo(new BeamZetaSqlUnnestRel(correlate.getCluster(), correlate.getTraitSet().replace(BeamLogicalConvention.INSTANCE), convert(outer, outer.getTraitSet().replace(BeamLogicalConvention.INSTANCE)), call.rel(2).getRowType(), fieldAccessIndices.build()));
}
Also used : RelNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode) ImmutableList(org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableList) LogicalCorrelate(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate) LogicalProject(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject) RexFieldAccess(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexFieldAccess) RelSubset(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.volcano.RelSubset) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 8 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess in project hive by apache.

the class HiveRelOptUtil method splitCorrelatedFilterCondition.

private static void splitCorrelatedFilterCondition(Filter filter, RexNode condition, List<RexNode> joinKeys, List<RexNode> correlatedJoinKeys, List<RexNode> nonEquiList, boolean extractCorrelatedFieldAccess) {
    if (condition instanceof RexCall) {
        RexCall call = (RexCall) condition;
        if (call.getOperator().getKind() == SqlKind.AND) {
            for (RexNode operand : call.getOperands()) {
                splitCorrelatedFilterCondition(filter, operand, joinKeys, correlatedJoinKeys, nonEquiList, extractCorrelatedFieldAccess);
            }
            return;
        }
        if (call.getOperator().getKind() == SqlKind.EQUALS) {
            final List<RexNode> operands = call.getOperands();
            RexNode op0 = operands.get(0);
            RexNode op1 = operands.get(1);
            if (extractCorrelatedFieldAccess) {
                if (!RexUtil.containsFieldAccess(op0) && (op1 instanceof RexFieldAccess)) {
                    joinKeys.add(op0);
                    correlatedJoinKeys.add(op1);
                    return;
                } else if ((op0 instanceof RexFieldAccess) && !RexUtil.containsFieldAccess(op1)) {
                    correlatedJoinKeys.add(op0);
                    joinKeys.add(op1);
                    return;
                }
            } else {
                if (!(RexUtil.containsInputRef(op0)) && (op1 instanceof RexInputRef)) {
                    correlatedJoinKeys.add(op0);
                    joinKeys.add(op1);
                    return;
                } else if ((op0 instanceof RexInputRef) && !(RexUtil.containsInputRef(op1))) {
                    joinKeys.add(op0);
                    correlatedJoinKeys.add(op1);
                    return;
                }
            }
        }
    }
    // The operator is not of RexCall type
    // So we fail. Fall through.
    // Add this condition to the list of non-equi-join conditions.
    nonEquiList.add(condition);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Example 9 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess in project hive by apache.

the class RelFieldTrimmer method trimChild.

/**
 * Trims the fields of an input relational expression.
 *
 * @param rel        Relational expression
 * @param input      Input relational expression, whose fields to trim
 * @param fieldsUsed Bitmap of fields needed by the consumer
 * @return New relational expression and its field mapping
 */
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();
    // Fields that define the collation cannot be discarded.
    final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
    final ImmutableList<RelCollation> collations = mq.collations(input);
    if (collations != null) {
        for (RelCollation collation : collations) {
            for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
                fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
            }
        }
    }
    // fields.
    for (final CorrelationId correlation : rel.getVariablesSet()) {
        rel.accept(new CorrelationReferenceFinder() {

            protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.id.equals(correlation)) {
                    fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
                }
                return fieldAccess;
            }
        });
    }
    return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) RelCollation(org.apache.calcite.rel.RelCollation) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) CorrelationReferenceFinder(org.apache.calcite.sql2rel.CorrelationReferenceFinder) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Example 10 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess in project hive by apache.

the class RelFieldTrimmer method result.

protected TrimResult result(RelNode r, final Mapping mapping) {
    final RelBuilder relBuilder = REL_BUILDER.get();
    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
    for (final CorrelationId correlation : r.getVariablesSet()) {
        r = r.accept(new CorrelationReferenceFinder() {

            protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.id.equals(correlation) && v.getType().getFieldCount() == mapping.getSourceCount()) {
                    final int old = fieldAccess.getField().getIndex();
                    final int new_ = mapping.getTarget(old);
                    final RelDataTypeFactory.Builder typeBuilder = relBuilder.getTypeFactory().builder();
                    for (int target : Util.range(mapping.getTargetCount())) {
                        typeBuilder.add(v.getType().getFieldList().get(mapping.getSource(target)));
                    }
                    final RexNode newV = rexBuilder.makeCorrel(typeBuilder.build(), v.id);
                    if (old != new_) {
                        return rexBuilder.makeFieldAccess(newV, new_);
                    }
                }
                return fieldAccess;
            }
        });
    }
    return new TrimResult(r, mapping);
}
Also used : RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) RelBuilder(org.apache.calcite.tools.RelBuilder) CorrelationReferenceFinder(org.apache.calcite.sql2rel.CorrelationReferenceFinder) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)21 RexNode (org.apache.calcite.rex.RexNode)15 RexCorrelVariable (org.apache.calcite.rex.RexCorrelVariable)9 RexInputRef (org.apache.calcite.rex.RexInputRef)8 RexCall (org.apache.calcite.rex.RexCall)7 CorrelationId (org.apache.calcite.rel.core.CorrelationId)5 ArrayList (java.util.ArrayList)4 RexBuilder (org.apache.calcite.rex.RexBuilder)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 RelNode (org.apache.calcite.rel.RelNode)3 NlsString (org.apache.calcite.util.NlsString)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 List (java.util.List)2 RelSubset (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.volcano.RelSubset)2 RelNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode)2 LogicalCorrelate (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate)2 LogicalProject (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject)2 RexFieldAccess (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexFieldAccess)2 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)2