public static InputReferenceExpression field(int field, Type type) { return new InputReferenceExpression(field, type); }
@Override public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) { int field = node.getField(); Type type = node.getType(); BytecodeExpression block = blockResolver.apply(scope, field); BytecodeExpression position = positionResolver.apply(scope, field); return generateInputReference(callSiteBinder, scope, type, block, position); }
@Override public RowExpression visitInputReference(InputReferenceExpression reference, Void context) { return new InputReferenceExpression(reference.getField(), targetType); }
private Integer getParameterForField(InputReferenceExpression reference) { return fieldToParameter.computeIfAbsent(reference.getField(), field -> { inputChannels.add(field); return nextParameter++; }); }
@Override public RowExpression visitInputReference(InputReferenceExpression reference, Void context) { int parameter = getParameterForField(reference); return field(parameter, reference.getType()); }
private static List<Integer> getInputChannels(Iterable<RowExpression> expressions) { TreeSet<Integer> channels = new TreeSet<>(); for (RowExpression expression : Expressions.subExpressions(expressions)) { if (expression instanceof InputReferenceExpression) { channels.add(((InputReferenceExpression) expression).getField()); } } return ImmutableList.copyOf(channels); }
@Override public BytecodeNode visitInputReference(InputReferenceExpression node, Context context) { BytecodeNode inputReferenceBytecode = fieldReferenceCompiler.visitInputReference(node, context.getScope()); if (!context.getOutputBlockVariable().isPresent()) { return inputReferenceBytecode; } return new BytecodeBlock() .append(inputReferenceBytecode) .append(generateWrite( callSiteBinder, context.getScope(), context.getScope().getVariable("wasNull"), node.getType(), context.getOutputBlockVariable().get())); }
@Setup public void setup() { MetadataManager metadata = MetadataManager.createTestMetadataManager(); ExpressionCompiler compiler = new ExpressionCompiler(metadata, new PageFunctionCompiler(metadata, 0)); ImmutableList.Builder<RowExpression> projectionsBuilder = ImmutableList.builder(); Block[] blocks = new Block[TYPES.size()]; Type returnType = new ArrayType(BOOLEAN); for (int i = 0; i < TYPES.size(); i++) { Type elementType = TYPES.get(i); ArrayType arrayType = new ArrayType(elementType); Signature signature = new Signature("transform", FunctionKind.SCALAR, returnType.getTypeSignature(), arrayType.getTypeSignature(), parseTypeSignature("function(bigint,boolean)")); Signature greaterThan = new Signature("$operator$" + GREATER_THAN.name(), FunctionKind.SCALAR, BOOLEAN.getTypeSignature(), BIGINT.getTypeSignature(), BIGINT.getTypeSignature()); projectionsBuilder.add(new CallExpression(signature, returnType, ImmutableList.of( new InputReferenceExpression(0, arrayType), new LambdaDefinitionExpression( ImmutableList.of(BIGINT), ImmutableList.of("x"), new CallExpression(greaterThan, BOOLEAN, ImmutableList.of(new VariableReferenceExpression("x", BIGINT), new ConstantExpression(0L, BIGINT))))))); blocks[i] = createChannel(POSITIONS, ARRAY_SIZE, arrayType); } ImmutableList<RowExpression> projections = projectionsBuilder.build(); pageProcessor = compiler.compilePageProcessor(Optional.empty(), projections).get(); pageBuilder = new PageBuilder(projections.stream().map(RowExpression::getType).collect(Collectors.toList())); page = new Page(blocks); }
@Override public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) { int field = node.getField(); Type type = node.getType(); Variable wasNullVariable = scope.getVariable("wasNull"); Class<?> javaType = type.getJavaType(); if (!javaType.isPrimitive() && javaType != Slice.class) { javaType = Object.class; } IfStatement ifStatement = new IfStatement(); ifStatement.condition() .setDescription(format("cursor.get%s(%d)", type, field)) .getVariable(cursorVariable) .push(field) .invokeInterface(RecordCursor.class, "isNull", boolean.class, int.class); ifStatement.ifTrue() .putVariable(wasNullVariable, true) .pushJavaDefault(javaType); ifStatement.ifFalse() .getVariable(cursorVariable) .push(field) .invokeInterface(RecordCursor.class, "get" + Primitives.wrap(javaType).getSimpleName(), javaType, int.class); return ifStatement; }
@Override public RowExpression visitInputReference(InputReferenceExpression reference, Void context) { return field(reference.getField(), targetType); }
public static InputReferenceExpression field(int field, Type type) { return new InputReferenceExpression(field, type); }
private Supplier<PageProjection> compileProjectionInternal(RowExpression projection, Optional<String> classNameSuffix) { requireNonNull(projection, "projection is null"); if (projection instanceof InputReferenceExpression) { InputReferenceExpression input = (InputReferenceExpression) projection; InputPageProjection projectionFunction = new InputPageProjection(input.getField(), input.getType()); return () -> projectionFunction; } if (projection instanceof ConstantExpression) { ConstantExpression constant = (ConstantExpression) projection; ConstantPageProjection projectionFunction = new ConstantPageProjection(constant.getValue(), constant.getType()); return () -> projectionFunction; } PageFieldsToInputParametersRewriter.Result result = rewritePageFieldsToInputParameters(projection); CallSiteBinder callSiteBinder = new CallSiteBinder(); // generate Work ClassDefinition pageProjectionWorkDefinition = definePageProjectWorkClass(result.getRewrittenExpression(), callSiteBinder, classNameSuffix); Class<? extends Work> pageProjectionWorkClass; try { pageProjectionWorkClass = defineClass(pageProjectionWorkDefinition, Work.class, callSiteBinder.getBindings(), getClass().getClassLoader()); } catch (Exception e) { throw new PrestoException(COMPILER_ERROR, e); } return () -> new GeneratedPageProjection( result.getRewrittenExpression(), determinismEvaluator.isDeterministic(result.getRewrittenExpression()), result.getInputChannels(), constructorMethodHandle(pageProjectionWorkClass, BlockBuilder.class, ConnectorSession.class, Page.class, SelectedPositions.class)); }
private static IdentityProjectionInfo computeIdentityProjectionInfo(List<Symbol> symbols, Map<Symbol, Integer> inputLayout, Map<Symbol, Type> types) { Map<Symbol, Integer> outputMappings = new HashMap<>(); List<RowExpression> projections = new ArrayList<>(); int channel = 0; for (Symbol symbol : symbols) { Type type = types.get(symbol); RowExpression expression = new InputReferenceExpression(inputLayout.get(symbol), type); projections.add(expression); if (!outputMappings.containsKey(symbol)) { outputMappings.put(symbol, channel); channel++; } } return new IdentityProjectionInfo(projections, outputMappings); }
@Override public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) { int field = node.getField(); Type type = node.getType(); Class<?> javaType = type.getJavaType(); if (!javaType.isPrimitive() && javaType != Slice.class) { javaType = Object.class; } IfStatement ifStatement = new IfStatement(); ifStatement.condition() .setDescription(format("cursor.get%s(%d)", type, field)) .getVariable(cursorVariable) .push(field) .invokeInterface(RecordCursor.class, "isNull", boolean.class, int.class); ifStatement.ifTrue() .putVariable(wasNullVariable, true) .pushJavaDefault(javaType); ifStatement.ifFalse() .getVariable(cursorVariable) .push(field) .invokeInterface(RecordCursor.class, "get" + Primitives.wrap(javaType).getSimpleName(), javaType, int.class); return ifStatement; }
private static List<Integer> getInputChannels(Iterable<RowExpression> expressions) { TreeSet<Integer> channels = new TreeSet<>(); for (RowExpression expression : Expressions.subExpressions(expressions)) { if (expression instanceof InputReferenceExpression) { channels.add(((InputReferenceExpression) expression).getField()); } } return ImmutableList.copyOf(channels); }
@Test public void testNoCaching() throws Throwable { MetadataManager metadata = METADATA_MANAGER; ExpressionCompiler compiler = new ExpressionCompiler(metadata); ImmutableList.Builder<RowExpression> projectionsBuilder = ImmutableList.builder(); ArrayType arrayType = new ArrayType(VARCHAR); Signature signature = new Signature("concat", SCALAR, arrayType.getTypeSignature(), arrayType.getTypeSignature(), arrayType.getTypeSignature()); projectionsBuilder.add(new CallExpression(signature, arrayType, ImmutableList.of(new InputReferenceExpression(0, arrayType), new InputReferenceExpression(1, arrayType)))); ImmutableList<RowExpression> projections = projectionsBuilder.build(); PageProcessor pageProcessor = compiler.compilePageProcessor(new ConstantExpression(true, BOOLEAN), projections).get(); PageProcessor pageProcessor2 = compiler.compilePageProcessor(new ConstantExpression(true, BOOLEAN), projections).get(); assertTrue(pageProcessor != pageProcessor2); }
@Override public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) { int field = node.getField(); Type type = node.getType(); Variable block = scope.getVariable("block_" + field); Class<?> javaType = type.getJavaType(); if (!javaType.isPrimitive() && javaType != Slice.class) { javaType = Object.class; } IfStatement ifStatement = new IfStatement(); ifStatement.condition() .setDescription(format("block_%d.get%s()", field, type)) .append(block) .getVariable(positionVariable) .invokeInterface(Block.class, "isNull", boolean.class, int.class); ifStatement.ifTrue() .putVariable(wasNullVariable, true) .pushJavaDefault(javaType); String methodName = "get" + Primitives.wrap(javaType).getSimpleName(); ifStatement.ifFalse() .append(loadConstant(callSiteBinder.bind(type, Type.class))) .append(block) .getVariable(positionVariable) .invokeInterface(Type.class, methodName, javaType, Block.class, int.class); return ifStatement; }
@Test public void testSanityFilterOnRLE() throws Exception { Signature lessThan = internalOperator(LESS_THAN, BOOLEAN, ImmutableList.of(BIGINT, BIGINT)); CallExpression filter = new CallExpression(lessThan, BOOLEAN, ImmutableList.of(new InputReferenceExpression(0, BIGINT), new ConstantExpression(10L, BIGINT))); PageProcessor processor = new ExpressionCompiler(createTestMetadataManager()) .compilePageProcessor(filter, ImmutableList.of(new InputReferenceExpression(0, BIGINT))).get(); Page page = new Page(createRLEBlock(5L, 100)); Page outputPage = processor.processColumnarDictionary(null, page, ImmutableList.of(BIGINT)); assertEquals(outputPage.getPositionCount(), 100); assertTrue(outputPage.getBlock(0) instanceof RunLengthEncodedBlock); RunLengthEncodedBlock rle = (RunLengthEncodedBlock) outputPage.getBlock(0); assertEquals(BIGINT.getLong(rle.getValue(), 0), 5L); }