Search in sources :

Example 41 with CallExpression

use of com.facebook.presto.spi.relation.CallExpression in project presto by prestodb.

the class TestRowExpressionTranslator method testEndToEndFunctionTranslation.

@Test
public void testEndToEndFunctionTranslation() {
    String untranslated = "LN(bitwise_and(1, col1))";
    TypeProvider typeProvider = TypeProvider.copyOf(ImmutableMap.of("col1", BIGINT));
    CallExpression callExpression = (CallExpression) sqlToRowExpressionTranslator.translate(expression(untranslated), typeProvider);
    TranslatedExpression translatedExpression = translateWith(callExpression, new TestFunctionTranslator(functionAndTypeManager, buildFunctionTranslator(ImmutableSet.of(TestFunctions.class))), emptyMap());
    assertTrue(translatedExpression.getTranslated().isPresent());
    assertEquals(translatedExpression.getTranslated().get(), "LNof(1 BITWISE_AND col1)");
}
Also used : TypeProvider(com.facebook.presto.sql.planner.TypeProvider) TranslatedExpression(com.facebook.presto.expressions.translator.TranslatedExpression) CallExpression(com.facebook.presto.spi.relation.CallExpression) Test(org.testng.annotations.Test)

Example 42 with CallExpression

use of com.facebook.presto.spi.relation.CallExpression in project presto by prestodb.

the class RowExpressionRewriteRuleSet method rewriteAggregation.

private AggregationNode.Aggregation rewriteAggregation(AggregationNode.Aggregation aggregation, Rule.Context context) {
    RowExpression rewrittenCall = rewriter.rewrite(aggregation.getCall(), context);
    checkArgument(rewrittenCall instanceof CallExpression, "Aggregation CallExpression must be rewritten to CallExpression");
    return new AggregationNode.Aggregation((CallExpression) rewrittenCall, aggregation.getFilter().map(filter -> rewriter.rewrite(filter, context)), aggregation.getOrderBy(), aggregation.isDistinct(), aggregation.getMask());
}
Also used : AggregationNode(com.facebook.presto.spi.plan.AggregationNode) SpatialJoinNode(com.facebook.presto.sql.planner.plan.SpatialJoinNode) Patterns.values(com.facebook.presto.sql.planner.plan.Patterns.values) Captures(com.facebook.presto.matching.Captures) Assignments(com.facebook.presto.spi.plan.Assignments) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Patterns.tableFinish(com.facebook.presto.sql.planner.plan.Patterns.tableFinish) Patterns.join(com.facebook.presto.sql.planner.plan.Patterns.join) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode) Expressions.call(com.facebook.presto.sql.relational.Expressions.call) Patterns.filter(com.facebook.presto.sql.planner.plan.Patterns.filter) Pattern(com.facebook.presto.matching.Pattern) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) FilterNode(com.facebook.presto.spi.plan.FilterNode) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ImmutableList(com.google.common.collect.ImmutableList) StatisticAggregations(com.facebook.presto.sql.planner.plan.StatisticAggregations) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) CallExpression(com.facebook.presto.spi.relation.CallExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) Patterns.applyNode(com.facebook.presto.sql.planner.plan.Patterns.applyNode) ImmutableSet(com.google.common.collect.ImmutableSet) Patterns.aggregation(com.facebook.presto.sql.planner.plan.Patterns.aggregation) WindowNode(com.facebook.presto.sql.planner.plan.WindowNode) ImmutableMap(com.google.common.collect.ImmutableMap) Rule(com.facebook.presto.sql.planner.iterative.Rule) Patterns.project(com.facebook.presto.sql.planner.plan.Patterns.project) Set(java.util.Set) Patterns.window(com.facebook.presto.sql.planner.plan.Patterns.window) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Patterns.tableWriterNode(com.facebook.presto.sql.planner.plan.Patterns.tableWriterNode) List(java.util.List) Patterns.spatialJoin(com.facebook.presto.sql.planner.plan.Patterns.spatialJoin) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) ImmutableMap.builder(com.google.common.collect.ImmutableMap.builder) Optional(java.util.Optional) ApplyNode(com.facebook.presto.sql.planner.plan.ApplyNode) TableFinishNode(com.facebook.presto.sql.planner.plan.TableFinishNode) RowExpression(com.facebook.presto.spi.relation.RowExpression) CallExpression(com.facebook.presto.spi.relation.CallExpression)

Example 43 with CallExpression

use of com.facebook.presto.spi.relation.CallExpression in project presto by prestodb.

the class SimplifyCountOverConstant method apply.

@Override
public Result apply(AggregationNode parent, Captures captures, Context context) {
    ProjectNode child = captures.get(CHILD);
    boolean changed = false;
    Map<VariableReferenceExpression, AggregationNode.Aggregation> aggregations = new LinkedHashMap<>(parent.getAggregations());
    for (Entry<VariableReferenceExpression, AggregationNode.Aggregation> entry : parent.getAggregations().entrySet()) {
        VariableReferenceExpression variable = entry.getKey();
        AggregationNode.Aggregation aggregation = entry.getValue();
        if (isCountOverConstant(aggregation, child.getAssignments())) {
            changed = true;
            aggregations.put(variable, new AggregationNode.Aggregation(new CallExpression(aggregation.getCall().getSourceLocation(), "count", functionResolution.countFunction(), BIGINT, ImmutableList.of()), Optional.empty(), Optional.empty(), false, aggregation.getMask()));
        }
    }
    if (!changed) {
        return Result.empty();
    }
    return Result.ofPlanNode(new AggregationNode(parent.getSourceLocation(), parent.getId(), child, aggregations, parent.getGroupingSets(), ImmutableList.of(), parent.getStep(), parent.getHashVariable(), parent.getGroupIdVariable()));
}
Also used : VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) CallExpression(com.facebook.presto.spi.relation.CallExpression) LinkedHashMap(java.util.LinkedHashMap)

Example 44 with CallExpression

use of com.facebook.presto.spi.relation.CallExpression in project presto by prestodb.

the class TranslateExpressions method createRewriter.

private static PlanRowExpressionRewriter createRewriter(Metadata metadata, SqlParser sqlParser) {
    return new PlanRowExpressionRewriter() {

        @Override
        public RowExpression rewrite(RowExpression expression, Rule.Context context) {
            // special treatment of the CallExpression in Aggregation
            if (expression instanceof CallExpression && ((CallExpression) expression).getArguments().stream().anyMatch(OriginalExpressionUtils::isExpression)) {
                return removeOriginalExpressionArguments((CallExpression) expression, context.getSession(), context.getVariableAllocator());
            }
            return removeOriginalExpression(expression, context);
        }

        private RowExpression removeOriginalExpressionArguments(CallExpression callExpression, Session session, PlanVariableAllocator variableAllocator) {
            Map<NodeRef<Expression>, Type> types = analyzeCallExpressionTypes(callExpression, session, variableAllocator.getTypes());
            return new CallExpression(callExpression.getSourceLocation(), callExpression.getDisplayName(), callExpression.getFunctionHandle(), callExpression.getType(), callExpression.getArguments().stream().map(expression -> removeOriginalExpression(expression, session, types)).collect(toImmutableList()));
        }

        private Map<NodeRef<Expression>, Type> analyzeCallExpressionTypes(CallExpression callExpression, Session session, TypeProvider typeProvider) {
            List<LambdaExpression> lambdaExpressions = callExpression.getArguments().stream().filter(OriginalExpressionUtils::isExpression).map(OriginalExpressionUtils::castToExpression).filter(LambdaExpression.class::isInstance).map(LambdaExpression.class::cast).collect(toImmutableList());
            ImmutableMap.Builder<NodeRef<Expression>, Type> builder = ImmutableMap.<NodeRef<Expression>, Type>builder();
            if (!lambdaExpressions.isEmpty()) {
                List<FunctionType> functionTypes = metadata.getFunctionAndTypeManager().getFunctionMetadata(callExpression.getFunctionHandle()).getArgumentTypes().stream().filter(typeSignature -> typeSignature.getBase().equals(FunctionType.NAME)).map(typeSignature -> (FunctionType) (metadata.getFunctionAndTypeManager().getType(typeSignature))).collect(toImmutableList());
                InternalAggregationFunction internalAggregationFunction = metadata.getFunctionAndTypeManager().getAggregateFunctionImplementation(callExpression.getFunctionHandle());
                List<Class> lambdaInterfaces = internalAggregationFunction.getLambdaInterfaces();
                verify(lambdaExpressions.size() == functionTypes.size());
                verify(lambdaExpressions.size() == lambdaInterfaces.size());
                for (int i = 0; i < lambdaExpressions.size(); i++) {
                    LambdaExpression lambdaExpression = lambdaExpressions.get(i);
                    FunctionType functionType = functionTypes.get(i);
                    // To compile lambda, LambdaDefinitionExpression needs to be generated from LambdaExpression,
                    // which requires the types of all sub-expressions.
                    // 
                    // In project and filter expression compilation, ExpressionAnalyzer.getExpressionTypesFromInput
                    // is used to generate the types of all sub-expressions. (see visitScanFilterAndProject and visitFilter)
                    // 
                    // This does not work here since the function call representation in final aggregation node
                    // is currently a hack: it takes intermediate type as input, and may not be a valid
                    // function call in Presto.
                    // 
                    // TODO: Once the final aggregation function call representation is fixed,
                    // the same mechanism in project and filter expression should be used here.
                    verify(lambdaExpression.getArguments().size() == functionType.getArgumentTypes().size());
                    Map<NodeRef<Expression>, Type> lambdaArgumentExpressionTypes = new HashMap<>();
                    Map<String, Type> lambdaArgumentSymbolTypes = new HashMap<>();
                    for (int j = 0; j < lambdaExpression.getArguments().size(); j++) {
                        LambdaArgumentDeclaration argument = lambdaExpression.getArguments().get(j);
                        Type type = functionType.getArgumentTypes().get(j);
                        lambdaArgumentExpressionTypes.put(NodeRef.of(argument), type);
                        lambdaArgumentSymbolTypes.put(argument.getName().getValue(), type);
                    }
                    // the lambda expression itself
                    builder.put(NodeRef.of(lambdaExpression), functionType).putAll(lambdaArgumentExpressionTypes).putAll(getExpressionTypes(session, metadata, sqlParser, TypeProvider.copyOf(lambdaArgumentSymbolTypes), lambdaExpression.getBody(), emptyList(), NOOP));
                }
            }
            for (RowExpression argument : callExpression.getArguments()) {
                if (!isExpression(argument) || castToExpression(argument) instanceof LambdaExpression) {
                    continue;
                }
                builder.putAll(analyze(castToExpression(argument), session, typeProvider));
            }
            return builder.build();
        }

        private Map<NodeRef<Expression>, Type> analyze(Expression expression, Session session, TypeProvider typeProvider) {
            return getExpressionTypes(session, metadata, sqlParser, typeProvider, expression, emptyList(), NOOP);
        }

        private RowExpression toRowExpression(Expression expression, Session session, Map<NodeRef<Expression>, Type> types) {
            return SqlToRowExpressionTranslator.translate(expression, types, ImmutableMap.of(), metadata.getFunctionAndTypeManager(), session);
        }

        private RowExpression removeOriginalExpression(RowExpression expression, Rule.Context context) {
            if (isExpression(expression)) {
                return toRowExpression(castToExpression(expression), context.getSession(), analyze(castToExpression(expression), context.getSession(), context.getVariableAllocator().getTypes()));
            }
            return expression;
        }

        private RowExpression removeOriginalExpression(RowExpression rowExpression, Session session, Map<NodeRef<Expression>, Type> types) {
            if (isExpression(rowExpression)) {
                Expression expression = castToExpression(rowExpression);
                return toRowExpression(expression, session, types);
            }
            return rowExpression;
        }
    };
}
Also used : LambdaArgumentDeclaration(com.facebook.presto.sql.tree.LambdaArgumentDeclaration) OriginalExpressionUtils(com.facebook.presto.sql.relational.OriginalExpressionUtils) SqlToRowExpressionTranslator(com.facebook.presto.sql.relational.SqlToRowExpressionTranslator) OriginalExpressionUtils.isExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.isExpression) HashMap(java.util.HashMap) OriginalExpressionUtils.castToExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToExpression) Verify.verify(com.google.common.base.Verify.verify) TypeProvider(com.facebook.presto.sql.planner.TypeProvider) Map(java.util.Map) CallExpression(com.facebook.presto.spi.relation.CallExpression) Type(com.facebook.presto.common.type.Type) RowExpression(com.facebook.presto.spi.relation.RowExpression) ImmutableMap(com.google.common.collect.ImmutableMap) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) Collections.emptyList(java.util.Collections.emptyList) Session(com.facebook.presto.Session) Rule(com.facebook.presto.sql.planner.iterative.Rule) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) InternalAggregationFunction(com.facebook.presto.operator.aggregation.InternalAggregationFunction) FunctionType(com.facebook.presto.common.type.FunctionType) SqlParser(com.facebook.presto.sql.parser.SqlParser) NodeRef(com.facebook.presto.sql.tree.NodeRef) List(java.util.List) Expression(com.facebook.presto.sql.tree.Expression) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) NOOP(com.facebook.presto.spi.WarningCollector.NOOP) ExpressionAnalyzer.getExpressionTypes(com.facebook.presto.sql.analyzer.ExpressionAnalyzer.getExpressionTypes) Metadata(com.facebook.presto.metadata.Metadata) HashMap(java.util.HashMap) InternalAggregationFunction(com.facebook.presto.operator.aggregation.InternalAggregationFunction) NodeRef(com.facebook.presto.sql.tree.NodeRef) LambdaArgumentDeclaration(com.facebook.presto.sql.tree.LambdaArgumentDeclaration) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) CallExpression(com.facebook.presto.spi.relation.CallExpression) FunctionType(com.facebook.presto.common.type.FunctionType) RowExpression(com.facebook.presto.spi.relation.RowExpression) TypeProvider(com.facebook.presto.sql.planner.TypeProvider) ImmutableMap(com.google.common.collect.ImmutableMap) Type(com.facebook.presto.common.type.Type) FunctionType(com.facebook.presto.common.type.FunctionType) OriginalExpressionUtils.isExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.isExpression) OriginalExpressionUtils.castToExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToExpression) CallExpression(com.facebook.presto.spi.relation.CallExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) Expression(com.facebook.presto.sql.tree.Expression) OriginalExpressionUtils(com.facebook.presto.sql.relational.OriginalExpressionUtils) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) HashMap(java.util.HashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) Session(com.facebook.presto.Session)

Example 45 with CallExpression

use of com.facebook.presto.spi.relation.CallExpression in project presto by prestodb.

the class TestCursorProcessorCompiler method testRewriteRowExpressionWithCSE.

@Test
public void testRewriteRowExpressionWithCSE() {
    CursorProcessorCompiler cseCursorCompiler = new CursorProcessorCompiler(METADATA, true, emptyMap());
    ClassDefinition cursorProcessorClassDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(CursorProcessor.class.getSimpleName()), type(Object.class), type(CursorProcessor.class));
    RowExpression filter = new SpecialFormExpression(AND, BIGINT, ADD_X_Y_GREATER_THAN_2);
    List<RowExpression> projections = ImmutableList.of(ADD_X_Y_Z);
    List<RowExpression> rowExpressions = ImmutableList.<RowExpression>builder().addAll(projections).add(filter).build();
    Map<Integer, Map<RowExpression, VariableReferenceExpression>> commonSubExpressionsByLevel = collectCSEByLevel(rowExpressions);
    Map<VariableReferenceExpression, CommonSubExpressionRewriter.CommonSubExpressionFields> cseFields = declareCommonSubExpressionFields(cursorProcessorClassDefinition, commonSubExpressionsByLevel);
    Map<RowExpression, VariableReferenceExpression> commonSubExpressions = commonSubExpressionsByLevel.values().stream().flatMap(m -> m.entrySet().stream()).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
    // X+Y as CSE
    assertEquals(1, cseFields.size());
    VariableReferenceExpression cseVariable = cseFields.keySet().iterator().next();
    RowExpression rewrittenFilter = cseCursorCompiler.rewriteRowExpressionsWithCSE(ImmutableList.of(filter), commonSubExpressions).get(0);
    List<RowExpression> rewrittenProjections = cseCursorCompiler.rewriteRowExpressionsWithCSE(projections, commonSubExpressions);
    // X+Y+Z contains CSE X+Y
    assertTrue(((CallExpression) rewrittenProjections.get(0)).getArguments().contains(cseVariable));
    // X+Y > 2 consists CSE X+Y
    assertTrue(((CallExpression) ((SpecialFormExpression) rewrittenFilter).getArguments().get(0)).getArguments().contains(cseVariable));
}
Also used : FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) Page(com.facebook.presto.common.Page) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) Expressions.constant(com.facebook.presto.sql.relational.Expressions.constant) PageBuilder(com.facebook.presto.common.PageBuilder) Expressions.field(com.facebook.presto.sql.relational.Expressions.field) ADD(com.facebook.presto.common.function.OperatorType.ADD) Access.a(com.facebook.presto.bytecode.Access.a) CursorProcessor(com.facebook.presto.operator.project.CursorProcessor) ParameterizedType.type(com.facebook.presto.bytecode.ParameterizedType.type) IF(com.facebook.presto.spi.relation.SpecialFormExpression.Form.IF) CommonSubExpressionRewriter.collectCSEByLevel(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.collectCSEByLevel) SESSION(com.facebook.presto.testing.TestingConnectorSession.SESSION) Map(java.util.Map) AND(com.facebook.presto.spi.relation.SpecialFormExpression.Form.AND) LESS_THAN(com.facebook.presto.common.function.OperatorType.LESS_THAN) CompilerUtils.makeClassName(com.facebook.presto.util.CompilerUtils.makeClassName) CallExpression(com.facebook.presto.spi.relation.CallExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) BlockBuilder(com.facebook.presto.common.block.BlockBuilder) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) FINAL(com.facebook.presto.bytecode.Access.FINAL) Optional(java.util.Optional) IntStream(java.util.stream.IntStream) DriverYieldSignal(com.facebook.presto.operator.DriverYieldSignal) Assert.assertEquals(org.testng.Assert.assertEquals) PageRecordSet(com.facebook.presto.operator.index.PageRecordSet) Supplier(java.util.function.Supplier) TypeSignatureProvider.fromTypes(com.facebook.presto.sql.analyzer.TypeSignatureProvider.fromTypes) Expressions.call(com.facebook.presto.sql.relational.Expressions.call) ImmutableList(com.google.common.collect.ImmutableList) BOOLEAN(com.facebook.presto.common.type.BooleanType.BOOLEAN) CommonSubExpressionFields.declareCommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields.declareCommonSubExpressionFields) Type(com.facebook.presto.common.type.Type) RowExpression(com.facebook.presto.spi.relation.RowExpression) PUBLIC(com.facebook.presto.bytecode.Access.PUBLIC) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) Collections.emptyMap(java.util.Collections.emptyMap) RecordSet(com.facebook.presto.spi.RecordSet) GREATER_THAN(com.facebook.presto.common.function.OperatorType.GREATER_THAN) Collectors.toList(java.util.stream.Collectors.toList) MetadataManager.createTestMetadataManager(com.facebook.presto.metadata.MetadataManager.createTestMetadataManager) Assert.assertTrue(org.testng.Assert.assertTrue) Block(com.facebook.presto.common.block.Block) Metadata(com.facebook.presto.metadata.Metadata) CursorProcessor(com.facebook.presto.operator.project.CursorProcessor) RowExpression(com.facebook.presto.spi.relation.RowExpression) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) CommonSubExpressionFields.declareCommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields.declareCommonSubExpressionFields) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) Map(java.util.Map) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Collections.emptyMap(java.util.Collections.emptyMap) CallExpression(com.facebook.presto.spi.relation.CallExpression) Test(org.testng.annotations.Test)

Aggregations

CallExpression (com.facebook.presto.spi.relation.CallExpression)64 RowExpression (com.facebook.presto.spi.relation.RowExpression)33 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)33 Test (org.testng.annotations.Test)22 AggregationNode (com.facebook.presto.spi.plan.AggregationNode)20 FunctionHandle (com.facebook.presto.spi.function.FunctionHandle)19 ImmutableList (com.google.common.collect.ImmutableList)18 FunctionAndTypeManager (com.facebook.presto.metadata.FunctionAndTypeManager)16 Type (com.facebook.presto.common.type.Type)14 Map (java.util.Map)14 ConstantExpression (com.facebook.presto.spi.relation.ConstantExpression)13 ImmutableMap (com.google.common.collect.ImmutableMap)13 Optional (java.util.Optional)12 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)11 OperatorType (com.facebook.presto.common.function.OperatorType)10 Aggregation (com.facebook.presto.spi.plan.AggregationNode.Aggregation)10 PlanNode (com.facebook.presto.spi.plan.PlanNode)10 ProjectNode (com.facebook.presto.spi.plan.ProjectNode)10 SpecialFormExpression (com.facebook.presto.spi.relation.SpecialFormExpression)10 Page (com.facebook.presto.common.Page)8