Search in sources :

Example 1 with ExpressionAnalysis

use of com.facebook.presto.sql.analyzer.ExpressionAnalysis in project presto by prestodb.

the class FunctionAssertions method createExpression.

public static Expression createExpression(String expression, Metadata metadata, Map<Symbol, Type> symbolTypes) {
    Expression parsedExpression = SQL_PARSER.createExpression(expression);
    parsedExpression = rewriteIdentifiersToSymbolReferences(parsedExpression);
    final ExpressionAnalysis analysis = analyzeExpressionsWithSymbols(TEST_SESSION, metadata, SQL_PARSER, symbolTypes, ImmutableList.of(parsedExpression), emptyList(), false);
    Expression rewrittenExpression = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Void>() {

        @Override
        public Expression rewriteExpression(Expression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
            Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context);
            // cast expression if coercion is registered
            Type coercion = analysis.getCoercion(node);
            if (coercion != null) {
                rewrittenExpression = new Cast(rewrittenExpression, coercion.getTypeSignature().toString(), false, analysis.isTypeOnlyCoercion(node));
            }
            return rewrittenExpression;
        }

        @Override
        public Expression rewriteDereferenceExpression(DereferenceExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
            if (analysis.getColumnReferences().contains(node)) {
                return rewriteExpression(node, context, treeRewriter);
            }
            Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context);
            // cast expression if coercion is registered
            Type coercion = analysis.getCoercion(node);
            if (coercion != null) {
                rewrittenExpression = new Cast(rewrittenExpression, coercion.getTypeSignature().toString());
            }
            return rewrittenExpression;
        }
    }, parsedExpression);
    return canonicalizeExpression(rewrittenExpression);
}
Also used : Cast(com.facebook.presto.sql.tree.Cast) Type(com.facebook.presto.spi.type.Type) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) RowExpression(com.facebook.presto.sql.relational.RowExpression) CanonicalizeExpressions.canonicalizeExpression(com.facebook.presto.sql.planner.optimizations.CanonicalizeExpressions.canonicalizeExpression) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) Expression(com.facebook.presto.sql.tree.Expression) ExpressionAnalysis(com.facebook.presto.sql.analyzer.ExpressionAnalysis)

Example 2 with ExpressionAnalysis

use of com.facebook.presto.sql.analyzer.ExpressionAnalysis in project presto by prestodb.

the class FunctionAssertions method createExpression.

public static Expression createExpression(Session session, String expression, Metadata metadata, TypeProvider symbolTypes) {
    Expression parsedExpression = SQL_PARSER.createExpression(expression, createParsingOptions(session));
    parsedExpression = rewriteIdentifiersToSymbolReferences(parsedExpression);
    final ExpressionAnalysis analysis = analyzeExpressions(session, metadata, SQL_PARSER, symbolTypes, ImmutableList.of(parsedExpression), ImmutableList.of(), WarningCollector.NOOP, false);
    Expression rewrittenExpression = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Void>() {

        @Override
        public Expression rewriteExpression(Expression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
            Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context);
            // cast expression if coercion is registered
            Type coercion = analysis.getCoercion(node);
            if (coercion != null) {
                rewrittenExpression = new Cast(rewrittenExpression, coercion.getTypeSignature().toString(), false, analysis.isTypeOnlyCoercion(node));
            }
            return rewrittenExpression;
        }

        @Override
        public Expression rewriteDereferenceExpression(DereferenceExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
            if (analysis.isColumnReference(node)) {
                return rewriteExpression(node, context, treeRewriter);
            }
            Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context);
            // cast expression if coercion is registered
            Type coercion = analysis.getCoercion(node);
            if (coercion != null) {
                rewrittenExpression = new Cast(rewrittenExpression, coercion.getTypeSignature().toString());
            }
            return rewrittenExpression;
        }
    }, parsedExpression);
    return canonicalizeExpression(rewrittenExpression);
}
Also used : Cast(com.facebook.presto.sql.tree.Cast) RowType(com.facebook.presto.common.type.RowType) Type(com.facebook.presto.common.type.Type) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) CanonicalizeExpressionRewriter.canonicalizeExpression(com.facebook.presto.sql.planner.iterative.rule.CanonicalizeExpressionRewriter.canonicalizeExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) Expression(com.facebook.presto.sql.tree.Expression) ExpressionAnalysis(com.facebook.presto.sql.analyzer.ExpressionAnalysis)

Example 3 with ExpressionAnalysis

use of com.facebook.presto.sql.analyzer.ExpressionAnalysis in project presto by prestodb.

the class SqlFunctionUtils method getSqlFunctionImplementationExpression.

private static Expression getSqlFunctionImplementationExpression(FunctionMetadata functionMetadata, SqlInvokedScalarFunctionImplementation implementation, Metadata metadata, PlanVariableAllocator variableAllocator, SqlFunctionProperties sqlFunctionProperties, Map<String, VariableReferenceExpression> argumentVariables) {
    checkArgument(functionMetadata.getImplementationType().equals(SQL), format("Expect SQL function, get %s", functionMetadata.getImplementationType()));
    checkArgument(functionMetadata.getArgumentNames().isPresent(), "ArgumentNames is missing");
    Expression expression = normalizeParameters(functionMetadata.getArgumentNames().get(), parseSqlFunctionExpression(implementation, sqlFunctionProperties));
    ExpressionAnalysis functionAnalysis = analyzeSqlFunctionExpression(metadata, sqlFunctionProperties, expression, argumentVariables.entrySet().stream().collect(toImmutableMap(Map.Entry::getKey, entry -> entry.getValue().getType())));
    expression = coerceIfNecessary(expression, functionAnalysis);
    return rewriteLambdaExpression(expression, argumentVariables, functionAnalysis, variableAllocator);
}
Also used : VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ExpressionAnalyzer.analyzeSqlFunctionExpression(com.facebook.presto.sql.analyzer.ExpressionAnalyzer.analyzeSqlFunctionExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) Expression(com.facebook.presto.sql.tree.Expression) ExpressionAnalysis(com.facebook.presto.sql.analyzer.ExpressionAnalysis)

Example 4 with ExpressionAnalysis

use of com.facebook.presto.sql.analyzer.ExpressionAnalysis in project presto by prestodb.

the class SqlFunctionUtils method rewriteLambdaExpression.

private static Expression rewriteLambdaExpression(Expression sqlFunction, Map<String, VariableReferenceExpression> arguments, ExpressionAnalysis functionAnalysis, PlanVariableAllocator variableAllocator) {
    Map<NodeRef<Identifier>, LambdaArgumentDeclaration> lambdaArgumentReferences = functionAnalysis.getLambdaArgumentReferences();
    Map<NodeRef<Expression>, Type> expressionTypes = functionAnalysis.getExpressionTypes();
    // Rewrite reference to LambdaArgumentDeclaration
    Map<NodeRef<LambdaArgumentDeclaration>, VariableReferenceExpression> variables = expressionTypes.entrySet().stream().filter(entry -> entry.getKey().getNode() instanceof LambdaArgumentDeclaration).distinct().collect(toImmutableMap(entry -> NodeRef.of((LambdaArgumentDeclaration) entry.getKey().getNode()), entry -> variableAllocator.newVariable(((LambdaArgumentDeclaration) entry.getKey().getNode()).getName(), entry.getValue(), "lambda")));
    Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Map<NodeRef<Identifier>, LambdaArgumentDeclaration>>() {

        @Override
        public Expression rewriteLambdaExpression(LambdaExpression node, Map<NodeRef<Identifier>, LambdaArgumentDeclaration> context, ExpressionTreeRewriter<Map<NodeRef<Identifier>, LambdaArgumentDeclaration>> treeRewriter) {
            return new LambdaExpression(node.getArguments().stream().map(argument -> new LambdaArgumentDeclaration(new Identifier(variables.get(NodeRef.of(argument)).getName()))).collect(toImmutableList()), treeRewriter.rewrite(node.getBody(), context));
        }

        @Override
        public Expression rewriteIdentifier(Identifier node, Map<NodeRef<Identifier>, LambdaArgumentDeclaration> context, ExpressionTreeRewriter<Map<NodeRef<Identifier>, LambdaArgumentDeclaration>> treeRewriter) {
            NodeRef<Identifier> ref = NodeRef.of(node);
            if (context.containsKey(ref)) {
                return createSymbolReference(variables.get(NodeRef.of(context.get(ref))));
            }
            return node;
        }
    }, sqlFunction, lambdaArgumentReferences);
    // Rewrite function input referenced in lambda
    rewritten = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Map<String, VariableReferenceExpression>>() {

        @Override
        public Expression rewriteIdentifier(Identifier node, Map<String, VariableReferenceExpression> context, ExpressionTreeRewriter<Map<String, VariableReferenceExpression>> treeRewriter) {
            if (context.containsKey(node.getValue())) {
                return createSymbolReference(context.get(node.getValue()));
            }
            return node;
        }
    }, rewritten, arguments);
    // Desugar lambda capture
    return LambdaCaptureDesugaringRewriter.rewrite(rewritten, variableAllocator);
}
Also used : ExpressionTreeRewriter(com.facebook.presto.sql.tree.ExpressionTreeRewriter) LambdaArgumentDeclaration(com.facebook.presto.sql.tree.LambdaArgumentDeclaration) RowExpressionRewriter(com.facebook.presto.expressions.RowExpressionRewriter) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ExpressionAnalyzer.analyzeSqlFunctionExpression(com.facebook.presto.sql.analyzer.ExpressionAnalyzer.analyzeSqlFunctionExpression) SqlInvokedFunction(com.facebook.presto.spi.function.SqlInvokedFunction) Identifier(com.facebook.presto.sql.tree.Identifier) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Map(java.util.Map) LambdaCaptureDesugaringRewriter(com.facebook.presto.sql.planner.iterative.rule.LambdaCaptureDesugaringRewriter) Cast(com.facebook.presto.sql.tree.Cast) SQL(com.facebook.presto.spi.function.FunctionImplementationType.SQL) ENGLISH(java.util.Locale.ENGLISH) Type(com.facebook.presto.common.type.Type) RowExpression(com.facebook.presto.spi.relation.RowExpression) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) RowExpressionTreeRewriter(com.facebook.presto.expressions.RowExpressionTreeRewriter) ImmutableMap(com.google.common.collect.ImmutableMap) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) SqlFunctionProperties(com.facebook.presto.common.function.SqlFunctionProperties) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) String.format(java.lang.String.format) SqlParser(com.facebook.presto.sql.parser.SqlParser) ExpressionRewriter(com.facebook.presto.sql.tree.ExpressionRewriter) Preconditions.checkState(com.google.common.base.Preconditions.checkState) NodeRef(com.facebook.presto.sql.tree.NodeRef) FunctionMetadata(com.facebook.presto.spi.function.FunctionMetadata) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) SqlFunctionId(com.facebook.presto.spi.function.SqlFunctionId) Expression(com.facebook.presto.sql.tree.Expression) AS_DOUBLE(com.facebook.presto.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DOUBLE) AS_DECIMAL(com.facebook.presto.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DECIMAL) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) Function.identity(java.util.function.Function.identity) Optional(java.util.Optional) ParsingOptions(com.facebook.presto.sql.parser.ParsingOptions) ExpressionAnalysis(com.facebook.presto.sql.analyzer.ExpressionAnalysis) Metadata(com.facebook.presto.metadata.Metadata) SqlInvokedScalarFunctionImplementation(com.facebook.presto.spi.function.SqlInvokedScalarFunctionImplementation) ExpressionTreeUtils.createSymbolReference(com.facebook.presto.sql.analyzer.ExpressionTreeUtils.createSymbolReference) ExpressionTreeRewriter(com.facebook.presto.sql.tree.ExpressionTreeRewriter) RowExpressionTreeRewriter(com.facebook.presto.expressions.RowExpressionTreeRewriter) NodeRef(com.facebook.presto.sql.tree.NodeRef) Type(com.facebook.presto.common.type.Type) LambdaArgumentDeclaration(com.facebook.presto.sql.tree.LambdaArgumentDeclaration) Identifier(com.facebook.presto.sql.tree.Identifier) RowExpressionRewriter(com.facebook.presto.expressions.RowExpressionRewriter) ExpressionRewriter(com.facebook.presto.sql.tree.ExpressionRewriter) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ExpressionAnalyzer.analyzeSqlFunctionExpression(com.facebook.presto.sql.analyzer.ExpressionAnalyzer.analyzeSqlFunctionExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) Expression(com.facebook.presto.sql.tree.Expression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression)

Aggregations

ExpressionAnalysis (com.facebook.presto.sql.analyzer.ExpressionAnalysis)4 Expression (com.facebook.presto.sql.tree.Expression)4 RowExpression (com.facebook.presto.spi.relation.RowExpression)3 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)3 Cast (com.facebook.presto.sql.tree.Cast)3 Type (com.facebook.presto.common.type.Type)2 ExpressionAnalyzer.analyzeSqlFunctionExpression (com.facebook.presto.sql.analyzer.ExpressionAnalyzer.analyzeSqlFunctionExpression)2 DereferenceExpression (com.facebook.presto.sql.tree.DereferenceExpression)2 LambdaExpression (com.facebook.presto.sql.tree.LambdaExpression)2 SqlFunctionProperties (com.facebook.presto.common.function.SqlFunctionProperties)1 RowType (com.facebook.presto.common.type.RowType)1 RowExpressionRewriter (com.facebook.presto.expressions.RowExpressionRewriter)1 RowExpressionTreeRewriter (com.facebook.presto.expressions.RowExpressionTreeRewriter)1 Metadata (com.facebook.presto.metadata.Metadata)1 SQL (com.facebook.presto.spi.function.FunctionImplementationType.SQL)1 FunctionMetadata (com.facebook.presto.spi.function.FunctionMetadata)1 SqlFunctionId (com.facebook.presto.spi.function.SqlFunctionId)1 SqlInvokedFunction (com.facebook.presto.spi.function.SqlInvokedFunction)1 SqlInvokedScalarFunctionImplementation (com.facebook.presto.spi.function.SqlInvokedScalarFunctionImplementation)1 Type (com.facebook.presto.spi.type.Type)1