Search in sources :

Example 46 with Expression

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.linq4j.tree.Expression in project storm by apache.

the class RexNodeToJavaCodeCompiler method compileToBlock.

private BlockBuilder compileToBlock(final RexProgram program, ParameterExpression context, ParameterExpression outputValues) {
    RelDataType inputRowType = program.getInputRowType();
    final BlockBuilder builder = new BlockBuilder();
    final JavaTypeFactoryImpl javaTypeFactory = new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
    final RexToLixTranslator.InputGetter inputGetter = new RexToLixTranslator.InputGetterImpl(ImmutableList.of(Pair.<Expression, PhysType>of(Expressions.field(context, BuiltInMethod.CONTEXT_VALUES.field), PhysTypeImpl.of(javaTypeFactory, inputRowType, JavaRowFormat.ARRAY, false))));
    final Function1<String, RexToLixTranslator.InputGetter> correlates = new Function1<String, RexToLixTranslator.InputGetter>() {

        @Override
        public RexToLixTranslator.InputGetter apply(String a0) {
            throw new UnsupportedOperationException();
        }
    };
    final Expression root = Expressions.field(context, BuiltInMethod.CONTEXT_ROOT.field);
    final List<Expression> list = RexToLixTranslator.translateProjects(program, javaTypeFactory, builder, null, root, inputGetter, correlates);
    for (int i = 0; i < list.size(); i++) {
        builder.add(Expressions.statement(Expressions.assign(Expressions.arrayIndex(outputValues, Expressions.constant(i)), list.get(i))));
    }
    return builder;
}
Also used : Function1(org.apache.calcite.linq4j.function.Function1) RelDataType(org.apache.calcite.rel.type.RelDataType) PhysType(org.apache.calcite.adapter.enumerable.PhysType) Expression(org.apache.calcite.linq4j.tree.Expression) ExecutableExpression(org.apache.storm.sql.runtime.calcite.ExecutableExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) JavaTypeFactoryImpl(org.apache.calcite.jdbc.JavaTypeFactoryImpl) RexToLixTranslator(org.apache.calcite.adapter.enumerable.RexToLixTranslator) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

Example 47 with Expression

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.linq4j.tree.Expression in project storm by apache.

the class RexNodeToJavaCodeCompiler method baz.

/**
 * Given a method that implements {@link ExecutableExpression#execute(Context, Object[])}, adds a bridge method that
 * implements {@link ExecutableExpression#execute(Context)}, and compiles.
 */
static String baz(ParameterExpression context, ParameterExpression outputValues, BlockStatement block, String className) {
    final List<MemberDeclaration> declarations = Lists.newArrayList();
    // public void execute(Context, Object[] outputValues)
    declarations.add(Expressions.methodDecl(Modifier.PUBLIC, void.class, StormBuiltInMethod.EXPR_EXECUTE2.method.getName(), ImmutableList.of(context, outputValues), block));
    // public Object execute(Context)
    final BlockBuilder builder = new BlockBuilder();
    final Expression values_ = builder.append("values", Expressions.newArrayBounds(Object.class, 1, Expressions.constant(1)));
    builder.add(Expressions.statement(Expressions.call(Expressions.parameter(ExecutableExpression.class, "this"), StormBuiltInMethod.EXPR_EXECUTE2.method, context, values_)));
    builder.add(Expressions.return_(null, Expressions.arrayIndex(values_, Expressions.constant(0))));
    declarations.add(Expressions.methodDecl(Modifier.PUBLIC, Object.class, StormBuiltInMethod.EXPR_EXECUTE1.method.getName(), ImmutableList.of(context), builder.toBlock()));
    final ClassDeclaration classDeclaration = Expressions.classDecl(Modifier.PUBLIC, className, null, ImmutableList.<Type>of(ExecutableExpression.class), declarations);
    return Expressions.toString(Lists.newArrayList(classDeclaration), "\n", false);
}
Also used : ClassDeclaration(org.apache.calcite.linq4j.tree.ClassDeclaration) Expression(org.apache.calcite.linq4j.tree.Expression) ExecutableExpression(org.apache.storm.sql.runtime.calcite.ExecutableExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) MemberDeclaration(org.apache.calcite.linq4j.tree.MemberDeclaration) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder) ExecutableExpression(org.apache.storm.sql.runtime.calcite.ExecutableExpression)

Example 48 with Expression

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.linq4j.tree.Expression in project beam by apache.

the class CalcRelSplitter method chooseLevels.

/**
 * Figures out which expressions to calculate at which level.
 *
 * @param exprs Array of expressions
 * @param conditionOrdinal Ordinal of the condition expression, or -1 if no condition
 * @param exprLevels Level ordinal for each expression (output)
 * @param levelTypeOrdinals The type of each level (output)
 * @return Number of levels required
 */
private int chooseLevels(final RexNode[] exprs, int conditionOrdinal, int[] exprLevels, int[] levelTypeOrdinals) {
    final int inputFieldCount = program.getInputRowType().getFieldCount();
    int levelCount = 0;
    final MaxInputFinder maxInputFinder = new MaxInputFinder(exprLevels);
    boolean[] relTypesPossibleForTopLevel = new boolean[relTypes.length];
    Arrays.fill(relTypesPossibleForTopLevel, true);
    // Compute the order in which to visit expressions.
    final List<Set<Integer>> cohorts = getCohorts();
    final List<Integer> permutation = computeTopologicalOrdering(exprs, cohorts);
    for (int i : permutation) {
        RexNode expr = exprs[i];
        final boolean condition = i == conditionOrdinal;
        if (i < inputFieldCount) {
            assert expr instanceof RexInputRef;
            exprLevels[i] = -1;
            continue;
        }
        // Deduce the minimum level of the expression. An expression must
        // be at a level greater than or equal to all of its inputs.
        int level = maxInputFinder.maxInputFor(expr);
        // If the expression is in a cohort, it can occur no lower than the
        // levels of other expressions in the same cohort.
        Set<Integer> cohort = findCohort(cohorts, i);
        if (cohort != null) {
            for (Integer exprOrdinal : cohort) {
                if (exprOrdinal == i) {
                    // of effort to repeat.
                    continue;
                }
                final RexNode cohortExpr = exprs[exprOrdinal];
                int cohortLevel = maxInputFinder.maxInputFor(cohortExpr);
                if (cohortLevel > level) {
                    level = cohortLevel;
                }
            }
        }
        // If that is not possible, try to implement it at higher levels.
        levelLoop: for (; ; ++level) {
            if (level >= levelCount) {
                // This is a new level. We can use any type we like.
                for (int relTypeOrdinal = 0; relTypeOrdinal < relTypes.length; relTypeOrdinal++) {
                    if (!relTypesPossibleForTopLevel[relTypeOrdinal]) {
                        continue;
                    }
                    if (relTypes[relTypeOrdinal].canImplement(expr, condition)) {
                        // Success. We have found a type where we can
                        // implement this expression.
                        exprLevels[i] = level;
                        levelTypeOrdinals[level] = relTypeOrdinal;
                        assert (level == 0) || (levelTypeOrdinals[level - 1] != levelTypeOrdinals[level]) : "successive levels of same type";
                        // Previous reltypes are not possible.
                        for (int j = 0; j < relTypeOrdinal; ++j) {
                            relTypesPossibleForTopLevel[j] = false;
                        }
                        // Successive reltypes may be possible.
                        for (int j = relTypeOrdinal + 1; j < relTypes.length; ++j) {
                            if (relTypesPossibleForTopLevel[j]) {
                                relTypesPossibleForTopLevel[j] = relTypes[j].canImplement(expr, condition);
                            }
                        }
                        // Move to next level.
                        levelTypeOrdinals[levelCount] = firstSet(relTypesPossibleForTopLevel);
                        ++levelCount;
                        Arrays.fill(relTypesPossibleForTopLevel, true);
                        break levelLoop;
                    }
                }
                // level, with all options open?
                if (count(relTypesPossibleForTopLevel) >= relTypes.length) {
                    // Cannot implement for any type.
                    throw new AssertionError("cannot implement " + expr);
                }
                levelTypeOrdinals[levelCount] = firstSet(relTypesPossibleForTopLevel);
                ++levelCount;
                Arrays.fill(relTypesPossibleForTopLevel, true);
            } else {
                final int levelTypeOrdinal = levelTypeOrdinals[level];
                if (!relTypes[levelTypeOrdinal].canImplement(expr, condition)) {
                    // continue to next level.
                    continue;
                }
                exprLevels[i] = level;
                break;
            }
        }
    }
    if (levelCount == 0) {
        // At least one level is always required.
        levelCount = 1;
    }
    return levelCount;
}
Also used : Set(java.util.Set) RelTraitSet(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelTraitSet) RexInputRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 49 with Expression

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.linq4j.tree.Expression in project beam by apache.

the class CalcRelSplitter method execute.

// ~ Methods ----------------------------------------------------------------
public RelNode execute() {
    // expressions to the left.
    assert program.isValid(Litmus.THROW, null);
    final List<RexNode> exprList = program.getExprList();
    final RexNode[] exprs = exprList.toArray(new RexNode[0]);
    assert !RexUtil.containComplexExprs(exprList);
    // Figure out what level each expression belongs to.
    int[] exprLevels = new int[exprs.length];
    // The type of a level is given by
    // relTypes[levelTypeOrdinals[level]].
    int[] levelTypeOrdinals = new int[exprs.length];
    int levelCount = chooseLevels(exprs, -1, exprLevels, levelTypeOrdinals);
    // For each expression, figure out which is the highest level where it
    // is used.
    int[] exprMaxUsingLevelOrdinals = new HighestUsageFinder(exprs, exprLevels).getMaxUsingLevelOrdinals();
    // If expressions are used as outputs, mark them as higher than that.
    final List<RexLocalRef> projectRefList = program.getProjectList();
    final RexLocalRef conditionRef = program.getCondition();
    for (RexLocalRef projectRef : projectRefList) {
        exprMaxUsingLevelOrdinals[projectRef.getIndex()] = levelCount;
    }
    if (conditionRef != null) {
        exprMaxUsingLevelOrdinals[conditionRef.getIndex()] = levelCount;
    }
    // Print out what we've got.
    if (RULE_LOGGER.isTraceEnabled()) {
        traceLevelExpressions(exprs, exprLevels, levelTypeOrdinals, levelCount);
    }
    // Now build the calcs.
    RelNode rel = child;
    final int inputFieldCount = program.getInputRowType().getFieldCount();
    int[] inputExprOrdinals = identityArray(inputFieldCount);
    boolean doneCondition = false;
    for (int level = 0; level < levelCount; level++) {
        final int[] projectExprOrdinals;
        final RelDataType outputRowType;
        if (level == (levelCount - 1)) {
            outputRowType = program.getOutputRowType();
            projectExprOrdinals = new int[projectRefList.size()];
            for (int i = 0; i < projectExprOrdinals.length; i++) {
                projectExprOrdinals[i] = projectRefList.get(i).getIndex();
            }
        } else {
            outputRowType = null;
            // Project the expressions which are computed at this level or
            // before, and will be used at later levels.
            List<Integer> projectExprOrdinalList = new ArrayList<>();
            for (int i = 0; i < exprs.length; i++) {
                RexNode expr = exprs[i];
                if (expr instanceof RexLiteral) {
                    // Don't project literals. They are always created in
                    // the level where they are used.
                    exprLevels[i] = -1;
                    continue;
                }
                if ((exprLevels[i] <= level) && (exprMaxUsingLevelOrdinals[i] > level)) {
                    projectExprOrdinalList.add(i);
                }
            }
            projectExprOrdinals = Ints.toArray(projectExprOrdinalList);
        }
        final RelType relType = relTypes[levelTypeOrdinals[level]];
        // Can we do the condition this level?
        int conditionExprOrdinal = -1;
        if ((conditionRef != null) && !doneCondition) {
            conditionExprOrdinal = conditionRef.getIndex();
            if ((exprLevels[conditionExprOrdinal] > level) || !relType.supportsCondition()) {
                // stand down -- we're not ready to do the condition yet
                conditionExprOrdinal = -1;
            } else {
                doneCondition = true;
            }
        }
        RexProgram program1 = createProgramForLevel(level, levelCount, rel.getRowType(), exprs, exprLevels, inputExprOrdinals, projectExprOrdinals, conditionExprOrdinal, outputRowType);
        rel = relType.makeRel(cluster, traits, relBuilder, rel, program1);
        rel = handle(rel);
        // The outputs of this level will be the inputs to the next level.
        inputExprOrdinals = projectExprOrdinals;
    }
    Preconditions.checkArgument(doneCondition || (conditionRef == null), "unhandled condition");
    return rel;
}
Also used : RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) RexProgram(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexProgram) ArrayList(java.util.ArrayList) RelDataType(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataType) RelNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode) RexLocalRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLocalRef) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 50 with Expression

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.linq4j.tree.Expression in project beam by apache.

the class CalcRelSplitter method computeTopologicalOrdering.

/**
 * Computes the order in which to visit expressions, so that we decide the level of an expression
 * only after the levels of lower expressions have been decided.
 *
 * <p>First, we need to ensure that an expression is visited after all of its inputs.
 *
 * <p>Further, if the expression is a member of a cohort, we need to visit it after the inputs of
 * all other expressions in that cohort. With this condition, expressions in the same cohort will
 * very likely end up in the same level.
 *
 * <p>Note that if there are no cohorts, the expressions from the {@link RexProgram} are already
 * in a suitable order. We perform the topological sort just to ensure that the code path is
 * well-trodden.
 *
 * @param exprs Expressions
 * @param cohorts List of cohorts, each of which is a set of expr ordinals
 * @return Expression ordinals in topological order
 */
private static List<Integer> computeTopologicalOrdering(RexNode[] exprs, List<Set<Integer>> cohorts) {
    final DirectedGraph<Integer, DefaultEdge> graph = DefaultDirectedGraph.create();
    for (int i = 0; i < exprs.length; i++) {
        graph.addVertex(i);
    }
    for (int i = 0; i < exprs.length; i++) {
        final RexNode expr = exprs[i];
        final Set<Integer> cohort = findCohort(cohorts, i);
        final Set<Integer> targets;
        if (cohort == null) {
            targets = Collections.singleton(i);
        } else {
            targets = cohort;
        }
        expr.accept(new RexVisitorImpl<Void>(true) {

            @Override
            public Void visitLocalRef(RexLocalRef localRef) {
                for (Integer target : targets) {
                    graph.addEdge(localRef.getIndex(), target);
                }
                return null;
            }
        });
    }
    TopologicalOrderIterator<Integer, DefaultEdge> iter = new TopologicalOrderIterator<>(graph);
    final List<Integer> permutation = new ArrayList<>();
    while (iter.hasNext()) {
        permutation.add(iter.next());
    }
    return permutation;
}
Also used : ArrayList(java.util.ArrayList) DefaultEdge(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.graph.DefaultEdge) TopologicalOrderIterator(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.graph.TopologicalOrderIterator) RexLocalRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLocalRef) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Aggregations

Expression (org.apache.calcite.linq4j.tree.Expression)91 ParameterExpression (org.apache.calcite.linq4j.tree.ParameterExpression)64 BlockBuilder (org.apache.calcite.linq4j.tree.BlockBuilder)56 ArrayList (java.util.ArrayList)26 MethodCallExpression (org.apache.calcite.linq4j.tree.MethodCallExpression)19 RelDataType (org.apache.calcite.rel.type.RelDataType)19 ConstantExpression (org.apache.calcite.linq4j.tree.ConstantExpression)16 Test (org.junit.Test)16 Type (java.lang.reflect.Type)11 PhysType (org.apache.calcite.adapter.enumerable.PhysType)11 UnaryExpression (org.apache.calcite.linq4j.tree.UnaryExpression)11 RexNode (org.apache.calcite.rex.RexNode)10 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)9 JavaTypeFactory (org.apache.calcite.adapter.java.JavaTypeFactory)9 BinaryExpression (org.apache.calcite.linq4j.tree.BinaryExpression)8 BlockStatement (org.apache.calcite.linq4j.tree.BlockStatement)8 NewExpression (org.apache.calcite.linq4j.tree.NewExpression)8 FunctionExpression (org.apache.calcite.linq4j.tree.FunctionExpression)7 MemberDeclaration (org.apache.calcite.linq4j.tree.MemberDeclaration)7 ImmutableList (com.google.common.collect.ImmutableList)5