Search in sources :

Example 66 with RexCall

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

the class FlinkRelMdCollation method project.

/**
 * Helper method to determine a {@link Project}'s collation.
 */
public static List<RelCollation> project(RelMetadataQuery mq, RelNode input, List<? extends RexNode> projects) {
    final SortedSet<RelCollation> collations = new TreeSet<>();
    final List<RelCollation> inputCollations = mq.collations(input);
    if (inputCollations == null || inputCollations.isEmpty()) {
        return com.google.common.collect.ImmutableList.of();
    }
    final com.google.common.collect.Multimap<Integer, Integer> targets = com.google.common.collect.LinkedListMultimap.create();
    final Map<Integer, SqlMonotonicity> targetsWithMonotonicity = new HashMap<>();
    for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) {
        if (project.e instanceof RexInputRef) {
            targets.put(((RexInputRef) project.e).getIndex(), project.i);
        } else if (project.e instanceof RexCall) {
            final RexCall call = (RexCall) project.e;
            final RexCallBinding binding = RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
            targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
        }
    }
    final List<RelFieldCollation> fieldCollations = new ArrayList<>();
    loop: for (RelCollation ic : inputCollations) {
        if (ic.getFieldCollations().isEmpty()) {
            continue;
        }
        fieldCollations.clear();
        for (RelFieldCollation ifc : ic.getFieldCollations()) {
            final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
            if (integers.isEmpty()) {
                // cannot do this collation
                continue loop;
            }
            fieldCollations.add(ifc.withFieldIndex(integers.iterator().next()));
        }
        assert !fieldCollations.isEmpty();
        collations.add(RelCollations.of(fieldCollations));
    }
    final List<RelFieldCollation> fieldCollationsForRexCalls = new ArrayList<>();
    for (Map.Entry<Integer, SqlMonotonicity> entry : targetsWithMonotonicity.entrySet()) {
        final SqlMonotonicity value = entry.getValue();
        switch(value) {
            case NOT_MONOTONIC:
            case CONSTANT:
                break;
            default:
                fieldCollationsForRexCalls.add(new RelFieldCollation(entry.getKey(), RelFieldCollation.Direction.of(value)));
                break;
        }
    }
    if (!fieldCollationsForRexCalls.isEmpty()) {
        collations.add(RelCollations.of(fieldCollationsForRexCalls));
    }
    return com.google.common.collect.ImmutableList.copyOf(collations);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RexCall(org.apache.calcite.rex.RexCall) RexCallBinding(org.apache.calcite.rex.RexCallBinding) RelCollation(org.apache.calcite.rel.RelCollation) TreeSet(java.util.TreeSet) SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexInputRef(org.apache.calcite.rex.RexInputRef) Collection(java.util.Collection) Map(java.util.Map) HashMap(java.util.HashMap) RexNode(org.apache.calcite.rex.RexNode)

Example 67 with RexCall

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

the class PythonCorrelateSplitRule method matches.

@Override
public boolean matches(RelOptRuleCall call) {
    FlinkLogicalCorrelate correlate = call.rel(0);
    RelNode right = ((HepRelVertex) correlate.getRight()).getCurrentRel();
    FlinkLogicalTableFunctionScan tableFunctionScan;
    if (right instanceof FlinkLogicalTableFunctionScan) {
        tableFunctionScan = (FlinkLogicalTableFunctionScan) right;
    } else if (right instanceof FlinkLogicalCalc) {
        tableFunctionScan = StreamPhysicalCorrelateRule.getTableScan((FlinkLogicalCalc) right);
    } else {
        return false;
    }
    RexNode rexNode = tableFunctionScan.getCall();
    if (rexNode instanceof RexCall) {
        return PythonUtil.isPythonCall(rexNode, null) && PythonUtil.containsNonPythonCall(rexNode) || PythonUtil.isNonPythonCall(rexNode) && PythonUtil.containsPythonCall(rexNode, null) || (PythonUtil.isPythonCall(rexNode, null) && RexUtil.containsFieldAccess(rexNode));
    }
    return false;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) FlinkLogicalCorrelate(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCorrelate) HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex) RelNode(org.apache.calcite.rel.RelNode) FlinkLogicalCalc(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc) FlinkLogicalTableFunctionScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableFunctionScan) RexNode(org.apache.calcite.rex.RexNode)

Example 68 with RexCall

use of org.apache.calcite.rex.RexCall 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 69 with RexCall

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

the class RexNodeJsonSerializer method serialize.

@Override
public void serialize(RexNode rexNode, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
    final ReadableConfig config = SerdeContext.get(serializerProvider).getConfiguration();
    final CatalogPlanCompilation compilationStrategy = config.get(TableConfigOptions.PLAN_COMPILE_CATALOG_OBJECTS);
    switch(rexNode.getKind()) {
        case INPUT_REF:
        case TABLE_INPUT_REF:
            serializeInputRef((RexInputRef) rexNode, jsonGenerator, serializerProvider);
            break;
        case LITERAL:
            serializeLiteral((RexLiteral) rexNode, jsonGenerator, serializerProvider);
            break;
        case FIELD_ACCESS:
            serializeFieldAccess((RexFieldAccess) rexNode, jsonGenerator, serializerProvider);
            break;
        case CORREL_VARIABLE:
            serializeCorrelVariable((RexCorrelVariable) rexNode, jsonGenerator, serializerProvider);
            break;
        case PATTERN_INPUT_REF:
            serializePatternFieldRef((RexPatternFieldRef) rexNode, jsonGenerator, serializerProvider);
            break;
        default:
            if (rexNode instanceof RexCall) {
                serializeCall((RexCall) rexNode, jsonGenerator, serializerProvider, compilationStrategy);
            } else {
                throw new TableException("Unknown RexNode: " + rexNode);
            }
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) ReadableConfig(org.apache.flink.configuration.ReadableConfig) TableException(org.apache.flink.table.api.TableException) CatalogPlanCompilation(org.apache.flink.table.api.config.TableConfigOptions.CatalogPlanCompilation)

Example 70 with RexCall

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

the class TVFScanConverter method convert.

@Override
public RelNode convert(ResolvedTVFScan zetaNode, List<RelNode> inputs) {
    RelNode input = inputs.get(0);
    RexCall call = getExpressionConverter().convertTableValuedFunction(input, zetaNode.getTvf(), zetaNode.getArgumentList(), zetaNode.getArgumentList().size() > 0 && zetaNode.getArgumentList().get(0).getScan() != null ? zetaNode.getArgumentList().get(0).getScan().getColumnList() : Collections.emptyList());
    RelNode tableFunctionScan = LogicalTableFunctionScan.create(getCluster(), inputs, call, null, call.getType(), Collections.EMPTY_SET);
    // Pure SQL UDF's language body is built bottom up, so FunctionArgumentRefMapping should be
    // already consumed thus it can be cleared now.
    context.clearFunctionArgumentRefMapping();
    return tableFunctionScan;
}
Also used : RexCall(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall) RelNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode)

Aggregations

RexCall (org.apache.calcite.rex.RexCall)213 RexNode (org.apache.calcite.rex.RexNode)172 RexInputRef (org.apache.calcite.rex.RexInputRef)61 ArrayList (java.util.ArrayList)59 RexLiteral (org.apache.calcite.rex.RexLiteral)44 Nullable (javax.annotation.Nullable)35 RelNode (org.apache.calcite.rel.RelNode)26 RelDataType (org.apache.calcite.rel.type.RelDataType)24 SqlOperator (org.apache.calcite.sql.SqlOperator)23 List (java.util.List)22 RexBuilder (org.apache.calcite.rex.RexBuilder)22 DruidExpression (org.apache.druid.sql.calcite.expression.DruidExpression)19 SqlKind (org.apache.calcite.sql.SqlKind)14 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)14 RelOptUtil (org.apache.calcite.plan.RelOptUtil)11 PostAggregator (org.apache.druid.query.aggregation.PostAggregator)11 RexCall (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall)10 RexTableInputRef (org.apache.calcite.rex.RexTableInputRef)10 TimeUnitRange (org.apache.calcite.avatica.util.TimeUnitRange)9 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9