Search in sources :

Example 1 with NodeRef

use of com.facebook.presto.sql.tree.NodeRef in project presto by prestodb.

the class SimplifyExpressions method rewrite.

@VisibleForTesting
static Expression rewrite(Expression expression, Session session, PlanVariableAllocator variableAllocator, Metadata metadata, LiteralEncoder literalEncoder, SqlParser sqlParser) {
    requireNonNull(metadata, "metadata is null");
    requireNonNull(sqlParser, "sqlParser is null");
    if (expression instanceof SymbolReference) {
        return expression;
    }
    expression = pushDownNegations(expression);
    expression = extractCommonPredicates(expression);
    Map<NodeRef<Expression>, Type> expressionTypes = getExpressionTypes(session, metadata, sqlParser, variableAllocator.getTypes(), expression, emptyList(), WarningCollector.NOOP);
    ExpressionInterpreter interpreter = ExpressionInterpreter.expressionOptimizer(expression, metadata, session, expressionTypes);
    return literalEncoder.toExpression(interpreter.optimize(NoOpVariableResolver.INSTANCE), expressionTypes.get(NodeRef.of(expression)));
}
Also used : NodeRef(com.facebook.presto.sql.tree.NodeRef) Type(com.facebook.presto.common.type.Type) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) ExpressionInterpreter(com.facebook.presto.sql.planner.ExpressionInterpreter) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with NodeRef

use of com.facebook.presto.sql.tree.NodeRef in project presto by prestodb.

the class FilterStatsCalculator method simplifyExpression.

private Expression simplifyExpression(Session session, Expression predicate, TypeProvider types) {
    // TODO reuse com.facebook.presto.sql.planner.iterative.rule.SimplifyExpressions.rewrite
    Map<NodeRef<Expression>, Type> expressionTypes = getExpressionTypes(session, predicate, types);
    ExpressionInterpreter interpreter = ExpressionInterpreter.expressionOptimizer(predicate, metadata, session, expressionTypes);
    Object value = interpreter.optimize(NoOpVariableResolver.INSTANCE);
    if (value == null) {
        // Expression evaluates to SQL null, which in Filter is equivalent to false. This assumes the expression is a top-level expression (eg. not in NOT).
        value = false;
    }
    return literalEncoder.toExpression(value, BOOLEAN);
}
Also used : NodeRef(com.facebook.presto.sql.tree.NodeRef) Type(com.facebook.presto.common.type.Type) OperatorType(com.facebook.presto.common.function.OperatorType) RowExpressionInterpreter(com.facebook.presto.sql.planner.RowExpressionInterpreter) ExpressionInterpreter(com.facebook.presto.sql.planner.ExpressionInterpreter)

Example 3 with NodeRef

use of com.facebook.presto.sql.tree.NodeRef in project presto by prestodb.

the class FunctionAssertions method interpret.

private Object interpret(Expression expression, Type expectedType, Session session) {
    Map<NodeRef<Expression>, Type> expressionTypes = getExpressionTypes(session, metadata, SQL_PARSER, SYMBOL_TYPES, expression, emptyList(), WarningCollector.NOOP);
    ExpressionInterpreter evaluator = ExpressionInterpreter.expressionInterpreter(expression, metadata, session, expressionTypes);
    Object result = evaluator.evaluate(variable -> {
        Symbol symbol = new Symbol(variable.getName());
        int position = 0;
        int channel = INPUT_MAPPING.get(new VariableReferenceExpression(Optional.empty(), symbol.getName(), SYMBOL_TYPES.get(symbol.toSymbolReference())));
        Type type = SYMBOL_TYPES.get(symbol.toSymbolReference());
        Block block = SOURCE_PAGE.getBlock(channel);
        if (block.isNull(position)) {
            return null;
        }
        Class<?> javaType = type.getJavaType();
        if (javaType == boolean.class) {
            return type.getBoolean(block, position);
        } else if (javaType == long.class) {
            return type.getLong(block, position);
        } else if (javaType == double.class) {
            return type.getDouble(block, position);
        } else if (javaType == Slice.class) {
            return type.getSlice(block, position);
        } else if (javaType == Block.class) {
            return type.getObject(block, position);
        } else {
            throw new UnsupportedOperationException("not yet implemented");
        }
    });
    // convert result from stack type to Type ObjectValue
    Block block = Utils.nativeValueToBlock(expectedType, result);
    return expectedType.getObjectValue(session.getSqlFunctionProperties(), block, 0);
}
Also used : NodeRef(com.facebook.presto.sql.tree.NodeRef) RowType(com.facebook.presto.common.type.RowType) Type(com.facebook.presto.common.type.Type) Symbol(com.facebook.presto.sql.planner.Symbol) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Slice(io.airlift.slice.Slice) ExpressionInterpreter(com.facebook.presto.sql.planner.ExpressionInterpreter) BlockAssertions.createIntsBlock(com.facebook.presto.block.BlockAssertions.createIntsBlock) BlockAssertions.createRowBlock(com.facebook.presto.block.BlockAssertions.createRowBlock) BlockAssertions.createBooleansBlock(com.facebook.presto.block.BlockAssertions.createBooleansBlock) BlockAssertions.createDoublesBlock(com.facebook.presto.block.BlockAssertions.createDoublesBlock) BlockAssertions.createLongsBlock(com.facebook.presto.block.BlockAssertions.createLongsBlock) BlockAssertions.createSlicesBlock(com.facebook.presto.block.BlockAssertions.createSlicesBlock) BlockAssertions.createTimestampsWithTimezoneBlock(com.facebook.presto.block.BlockAssertions.createTimestampsWithTimezoneBlock) BlockAssertions.createStringsBlock(com.facebook.presto.block.BlockAssertions.createStringsBlock) Block(com.facebook.presto.common.block.Block)

Example 4 with NodeRef

use of com.facebook.presto.sql.tree.NodeRef in project presto by prestodb.

the class TestInlineSqlFunctions method assertInlined.

private void assertInlined(RuleTester tester, String inputSql, String expected, Map<String, Type> variableTypes) {
    Session session = TestingSession.testSessionBuilder().setSystemProperty("inline_sql_functions", "true").build();
    Metadata metadata = tester.getMetadata();
    Expression inputSqlExpression = PlanBuilder.expression(inputSql);
    Map<NodeRef<Expression>, Type> expressionTypes = getExpressionTypes(session, metadata, tester.getSqlParser(), viewOf(variableTypes), inputSqlExpression, ImmutableList.of(), WarningCollector.NOOP);
    Expression inlinedExpression = InlineSqlFunctions.InlineSqlFunctionsRewriter.rewrite(inputSqlExpression, session, metadata, new PlanVariableAllocator(variableTypes.entrySet().stream().map(entry -> new VariableReferenceExpression(Optional.empty(), entry.getKey(), entry.getValue())).collect(toImmutableList())), expressionTypes);
    inlinedExpression = ExpressionUtils.rewriteIdentifiersToSymbolReferences(inlinedExpression);
    Expression expectedExpression = PlanBuilder.expression(expected);
    assertEquals(inlinedExpression, expectedExpression);
}
Also used : FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) WarningCollector(com.facebook.presto.spi.WarningCollector) Parameter(com.facebook.presto.spi.function.Parameter) SqlInvokedFunctionNamespaceManagerConfig(com.facebook.presto.functionNamespace.SqlInvokedFunctionNamespaceManagerConfig) SQL(com.facebook.presto.spi.function.RoutineCharacteristics.Language.SQL) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) SqlInvokedFunction(com.facebook.presto.spi.function.SqlInvokedFunction) Map(java.util.Map) PlanBuilder.assignment(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder.assignment) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) PlanMatchPattern.expression(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.expression) FunctionCall(com.facebook.presto.sql.tree.FunctionCall) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) PlanMatchPattern.project(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.project) ImmutableMap(com.google.common.collect.ImmutableMap) FunctionImplementationType(com.facebook.presto.spi.function.FunctionImplementationType) BigintType(com.facebook.presto.common.type.BigintType) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) DETERMINISTIC(com.facebook.presto.spi.function.RoutineCharacteristics.Determinism.DETERMINISTIC) InMemoryFunctionNamespaceManager(com.facebook.presto.functionNamespace.testing.InMemoryFunctionNamespaceManager) RETURNS_NULL_ON_NULL_INPUT(com.facebook.presto.spi.function.RoutineCharacteristics.NullCallClause.RETURNS_NULL_ON_NULL_INPUT) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) ExpressionAnalyzer.getExpressionTypes(com.facebook.presto.sql.analyzer.ExpressionAnalyzer.getExpressionTypes) Optional(java.util.Optional) TypeProvider.viewOf(com.facebook.presto.sql.planner.TypeProvider.viewOf) QualifiedName(com.facebook.presto.sql.tree.QualifiedName) Assert.assertEquals(org.testng.Assert.assertEquals) ExpressionUtils(com.facebook.presto.sql.ExpressionUtils) TestingSession(com.facebook.presto.testing.TestingSession) BeforeTest(org.testng.annotations.BeforeTest) IntegerType(com.facebook.presto.common.type.IntegerType) ImmutableList(com.google.common.collect.ImmutableList) PlanBuilder(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder) ArrayType(com.facebook.presto.common.type.ArrayType) THRIFT(com.facebook.presto.spi.function.FunctionImplementationType.THRIFT) Type(com.facebook.presto.common.type.Type) RoutineCharacteristics(com.facebook.presto.spi.function.RoutineCharacteristics) Session(com.facebook.presto.Session) INTEGER(com.facebook.presto.common.type.StandardTypes.INTEGER) NodeRef(com.facebook.presto.sql.tree.NodeRef) SqlFunctionExecutors(com.facebook.presto.functionNamespace.execution.SqlFunctionExecutors) TypeSignature.parseTypeSignature(com.facebook.presto.common.type.TypeSignature.parseTypeSignature) Expression(com.facebook.presto.sql.tree.Expression) FunctionVersion.notVersioned(com.facebook.presto.spi.function.FunctionVersion.notVersioned) CatalogSchemaName(com.facebook.presto.common.CatalogSchemaName) PlanMatchPattern.values(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.values) NoopSqlFunctionExecutor(com.facebook.presto.functionNamespace.execution.NoopSqlFunctionExecutor) RuleTester(com.facebook.presto.sql.planner.iterative.rule.test.RuleTester) Metadata(com.facebook.presto.metadata.Metadata) NodeRef(com.facebook.presto.sql.tree.NodeRef) FunctionImplementationType(com.facebook.presto.spi.function.FunctionImplementationType) BigintType(com.facebook.presto.common.type.BigintType) IntegerType(com.facebook.presto.common.type.IntegerType) ArrayType(com.facebook.presto.common.type.ArrayType) Type(com.facebook.presto.common.type.Type) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Expression(com.facebook.presto.sql.tree.Expression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Metadata(com.facebook.presto.metadata.Metadata) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) TestingSession(com.facebook.presto.testing.TestingSession) Session(com.facebook.presto.Session)

Example 5 with NodeRef

use of com.facebook.presto.sql.tree.NodeRef 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)

Aggregations

NodeRef (com.facebook.presto.sql.tree.NodeRef)15 Type (com.facebook.presto.common.type.Type)14 Expression (com.facebook.presto.sql.tree.Expression)9 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)8 RowExpression (com.facebook.presto.spi.relation.RowExpression)6 ExpressionInterpreter (com.facebook.presto.sql.planner.ExpressionInterpreter)5 SqlParser (com.facebook.presto.sql.parser.SqlParser)4 OperatorType (com.facebook.presto.common.function.OperatorType)3 ArrayType (com.facebook.presto.common.type.ArrayType)3 Metadata (com.facebook.presto.metadata.Metadata)3 LambdaExpression (com.facebook.presto.sql.tree.LambdaExpression)3 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 List (java.util.List)3 Session (com.facebook.presto.Session)2 DecimalType.createDecimalType (com.facebook.presto.common.type.DecimalType.createDecimalType)2 FunctionType (com.facebook.presto.common.type.FunctionType)2 RowType (com.facebook.presto.common.type.RowType)2 VarcharType.createVarcharType (com.facebook.presto.common.type.VarcharType.createVarcharType)2 FunctionAssertions.createExpression (com.facebook.presto.operator.scalar.FunctionAssertions.createExpression)2