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)))); Expressions.methodDecl(Modifier.PUBLIC, Object.class, StormBuiltInMethod.EXPR_EXECUTE1.method.getName(), ImmutableList.of(context), builder.toBlock()));
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()); null, root, inputGetter, correlates); for (int i = 0; i < list.size(); i++) { builder.add( Expressions.statement( Expressions.assign(
private static Object coerce(Object o, RelDataType type) { if (o == null) { return null; } if (!(type instanceof RelDataTypeFactoryImpl.JavaType)) { return null; } final RelDataTypeFactoryImpl.JavaType javaType = (RelDataTypeFactoryImpl.JavaType) type; final Class clazz = javaType.getJavaClass(); //noinspection unchecked if (clazz.isAssignableFrom(o.getClass())) { return o; } if (clazz == String.class && o instanceof NlsString) { return ((NlsString) o).getValue(); } // We need optimization here for constant folding. // Not all the expressions can be interpreted (e.g. ternary), so // we rely on optimization capabilities to fold non-interpretable // expressions. BlockBuilder bb = new BlockBuilder(); final Expression expr = RexToLixTranslator.convert(Expressions.constant(o), clazz); bb.add(Expressions.return_(null, expr)); final FunctionExpression convert = Expressions.lambda(bb.toBlock(), Collections.emptyList()); return convert.compile().dynamicInvoke(); }
public Expression implementResult(AggContext info, AggResultContext result) { WinAggResultContext winResult = (WinAggResultContext) result; List<RexNode> rexArgs = winResult.rexArguments(); ParameterExpression res = Expressions.parameter(0, info.returnType(), result.currentBlock().newName("nth")); RexToLixTranslator currentRowTranslator = winResult.rowTranslator( winResult.computeIndex(Expressions.constant(0), SeekType.START)); Expression dstIndex = winResult.computeIndex( Expressions.subtract( currentRowTranslator.translate(rexArgs.get(1), int.class), Expressions.constant(1)), SeekType.START); Expression rowInRange = winResult.rowInPartition(dstIndex); BlockBuilder thenBlock = result.nestBlock(); Expression nthValue = winResult.rowTranslator(dstIndex) .translate(rexArgs.get(0), res.type); thenBlock.add(Expressions.statement(Expressions.assign(res, nthValue))); result.exitBlock(); BlockStatement thenBranch = thenBlock.toBlock(); Expression defaultValue = getDefaultValue(res.type); result.currentBlock().add(Expressions.declare(0, res, null)); result.currentBlock().add( Expressions.ifThenElse(rowInRange, thenBranch, Expressions.statement(Expressions.assign(res, defaultValue)))); return res; } }
public Result implement(EnumerableRelImplementor implementor, Prefer pref) { BlockBuilder builder = new BlockBuilder(); final Result leftResult = implementor.visitChild(this, 0, (EnumerableRel) left, pref); Expression leftExpression = builder.append( "left", leftResult.block); final Result rightResult = implementor.visitChild(this, 1, (EnumerableRel) right, pref); Expression rightExpression = builder.append( "right", rightResult.block); final PhysType physType = leftResult.physType; return implementor.result( physType, builder.append( Expressions.call( BuiltInMethod.SEMI_JOIN.method, Expressions.list( leftExpression, rightExpression, leftResult.physType.generateAccessor(leftKeys), rightResult.physType.generateAccessor(rightKeys)))) .toBlock()); } }
public BlockBuilder append(Expression expression) { add(expression); return this; }
Expression predicate(EnumerableRelImplementor implementor, BlockBuilder builder, PhysType leftPhysType, PhysType rightPhysType, RexNode condition) { final ParameterExpression left_ = Expressions.parameter(leftPhysType.getJavaRowType(), "left"); final ParameterExpression right_ = Expressions.parameter(rightPhysType.getJavaRowType(), "right"); final RexProgramBuilder program = new RexProgramBuilder( implementor.getTypeFactory().builder() .addAll(left.getRowType().getFieldList()) .addAll(right.getRowType().getFieldList()) .build(), getCluster().getRexBuilder()); program.addCondition(condition); builder.add( Expressions.return_(null, RexToLixTranslator.translateCondition(program.getProgram(), implementor.getTypeFactory(), builder, new RexToLixTranslator.InputGetterImpl( ImmutableList.of(Pair.of((Expression) left_, leftPhysType), Pair.of((Expression) right_, rightPhysType))), implementor.allCorrelateVariables, implementor.getConformance()))); return Expressions.lambda(Predicate2.class, builder.toBlock(), left_, right_); } }
/** * Appends a block to a list of statements and returns an expression * (possibly a variable) that represents the result of the newly added * block. */ public Expression append(String name, BlockStatement block) { return append(name, block, true); }
DeclarationStatement declaration = (DeclarationStatement) statement; if (!variables.contains(declaration.parameter.name)) { add(statement); } else { String newName = newName(declaration.parameter.name, optimize); Expression x; if (declaration.initializer != null && isSafeForReuse(declaration)) { x = append(newName, declaration.initializer); } else { ParameterExpression pe = Expressions.parameter( declaration.modifiers, pe, declaration.initializer); x = pe; add(newDeclaration); add(statement); } else if (statement instanceof GotoStatement) { statements.remove(statements.size() - 1); result = append_(name, ((GotoStatement) statement).expression, optimize); if (isSimpleExpression(result)) { newName(name, optimize), result); add(declare); result = declare.parameter;
public BlockStatement compileToBlock(final RexProgram program) { final ParameterExpression context_ = Expressions.parameter(Context.class, "context"); final ParameterExpression outputValues_ = Expressions.parameter(Object[].class, "outputValues"); return compileToBlock(program, context_, outputValues_).toBlock(); }
/** * Starts nested code block. The resulting block can optimize expressions * and reuse already calculated values from the parent blocks. * @return new code block that can optimize expressions and reuse already * calculated values from the parent blocks. */ public final BlockBuilder nestBlock() { BlockBuilder block = new BlockBuilder(true, currentBlock()); nestBlock(block, Collections.emptyMap()); return block; }
private Expression append_(String name, Expression expression, boolean optimize) { if (isSimpleExpression(expression)) { // already simple; no need to declare a variable or // even to evaluate the expression return expression; } if (optimizing && optimize) { DeclarationStatement decl = getComputedExpression(expression); if (decl != null) { return decl.parameter; } } DeclarationStatement declare = Expressions.declare(Modifier.FINAL, newName(name, optimize), expression); add(declare); return declare.parameter; }
/** * Creates a name for a new variable, unique within this block, controlling * whether the variable can be inlined later. */ private String newName(String suggestion, boolean optimize) { if (!optimize && !suggestion.startsWith("_")) { // "_" prefix reminds us not to consider the variable for inlining suggestion = '_' + suggestion; } return newName(suggestion); }
private static Object coerce(Object o, RelDataType type) { if (o == null) { return null; } if (!(type instanceof RelDataTypeFactoryImpl.JavaType)) { return null; } final RelDataTypeFactoryImpl.JavaType javaType = (RelDataTypeFactoryImpl.JavaType) type; final Class clazz = javaType.getJavaClass(); //noinspection unchecked if (clazz.isAssignableFrom(o.getClass())) { return o; } if (clazz == String.class && o instanceof NlsString) { return ((NlsString) o).getValue(); } // We need optimization here for constant folding. // Not all the expressions can be interpreted (e.g. ternary), so // we rely on optimization capabilities to fold non-interpretable // expressions. BlockBuilder bb = new BlockBuilder(); final Expression expr = RexToLixTranslator.convert(Expressions.constant(o), clazz); bb.add(Expressions.return_(null, expr)); final FunctionExpression convert = Expressions.lambda(bb.toBlock(), Collections.emptyList()); return convert.compile().dynamicInvoke(); }
public Expression implementResult(AggContext info, AggResultContext result) { WinAggResultContext winResult = (WinAggResultContext) result; List<RexNode> rexArgs = winResult.rexArguments(); ParameterExpression res = Expressions.parameter(0, info.returnType(), result.currentBlock().newName("nth")); RexToLixTranslator currentRowTranslator = winResult.rowTranslator( winResult.computeIndex(Expressions.constant(0), SeekType.START)); Expression dstIndex = winResult.computeIndex( Expressions.subtract( currentRowTranslator.translate(rexArgs.get(1), int.class), Expressions.constant(1)), SeekType.START); Expression rowInRange = winResult.rowInPartition(dstIndex); BlockBuilder thenBlock = result.nestBlock(); Expression nthValue = winResult.rowTranslator(dstIndex) .translate(rexArgs.get(0), res.type); thenBlock.add(Expressions.statement(Expressions.assign(res, nthValue))); result.exitBlock(); BlockStatement thenBranch = thenBlock.toBlock(); Expression defaultValue = getDefaultValue(res.type); result.currentBlock().add(Expressions.declare(0, res, null)); result.currentBlock().add( Expressions.ifThenElse(rowInRange, thenBranch, Expressions.statement(Expressions.assign(res, defaultValue)))); return res; } }
public Result implement(EnumerableRelImplementor implementor, Prefer pref) { BlockBuilder builder = new BlockBuilder(); final Result leftResult = implementor.visitChild(this, 0, (EnumerableRel) left, pref); Expression leftExpression = builder.append( "left", leftResult.block); final Result rightResult = implementor.visitChild(this, 1, (EnumerableRel) right, pref); Expression rightExpression = builder.append( "right", rightResult.block); final PhysType physType = leftResult.physType; return implementor.result( physType, builder.append( Expressions.call( BuiltInMethod.SEMI_JOIN.method, Expressions.list( leftExpression, rightExpression, leftResult.physType.generateAccessor(leftKeys), rightResult.physType.generateAccessor(rightKeys)))) .toBlock()); } }
@Override protected void implementNotNullAdd(AggContext info, AggAddContext add) { List<Expression> acc = add.accumulator(); List<Expression> aggArgs = add.arguments(); List<Expression> args = new ArrayList<>(aggArgs.size() + 1); args.add(acc.get(0)); args.addAll(aggArgs); add.currentBlock().add( Expressions.statement( Expressions.assign(acc.get(0), Expressions.call(afi.isStatic ? null : acc.get(1), afi.addMethod, args)))); }
Expression predicate(EnumerableRelImplementor implementor, BlockBuilder builder, PhysType leftPhysType, PhysType rightPhysType, RexNode condition) { final ParameterExpression left_ = Expressions.parameter(leftPhysType.getJavaRowType(), "left"); final ParameterExpression right_ = Expressions.parameter(rightPhysType.getJavaRowType(), "right"); final RexProgramBuilder program = new RexProgramBuilder( implementor.getTypeFactory().builder() .addAll(left.getRowType().getFieldList()) .addAll(right.getRowType().getFieldList()) .build(), getCluster().getRexBuilder()); program.addCondition(condition); builder.add( Expressions.return_(null, RexToLixTranslator.translateCondition(program.getProgram(), implementor.getTypeFactory(), builder, new RexToLixTranslator.InputGetterImpl( ImmutableList.of(Pair.of((Expression) left_, leftPhysType), Pair.of((Expression) right_, rightPhysType))), implementor.allCorrelateVariables, implementor.getConformance()))); return Expressions.lambda(Predicate2.class, builder.toBlock(), left_, right_); } }