Search in sources :

Example 1 with ExpressionAnalyzer

use of io.trino.sql.analyzer.ExpressionAnalyzer in project trino by trinodb.

the class ExpressionInterpreter method evaluateConstantExpression.

public static Object evaluateConstantExpression(Expression expression, Type expectedType, PlannerContext plannerContext, Session session, AccessControl accessControl, Map<NodeRef<Parameter>, Expression> parameters) {
    ExpressionAnalyzer analyzer = createConstantAnalyzer(plannerContext, accessControl, session, parameters, WarningCollector.NOOP);
    analyzer.analyze(expression, Scope.create());
    Type actualType = analyzer.getExpressionTypes().get(NodeRef.of(expression));
    if (!new TypeCoercion(plannerContext.getTypeManager()::getType).canCoerce(actualType, expectedType)) {
        throw semanticException(TYPE_MISMATCH, expression, "Cannot cast type %s to %s", actualType.getDisplayName(), expectedType.getDisplayName());
    }
    Map<NodeRef<Expression>, Type> coercions = ImmutableMap.<NodeRef<Expression>, Type>builder().putAll(analyzer.getExpressionCoercions()).put(NodeRef.of(expression), expectedType).buildOrThrow();
    return evaluateConstantExpression(expression, coercions, analyzer.getTypeOnlyCoercions(), plannerContext, session, accessControl, ImmutableSet.of(), parameters);
}
Also used : NodeRef(io.trino.sql.tree.NodeRef) FunctionType(io.trino.type.FunctionType) OperatorType(io.trino.spi.function.OperatorType) CharType(io.trino.spi.type.CharType) VarcharType.createVarcharType(io.trino.spi.type.VarcharType.createVarcharType) RowType(io.trino.spi.type.RowType) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) ArrayType(io.trino.spi.type.ArrayType) Type(io.trino.spi.type.Type) VarcharType(io.trino.spi.type.VarcharType) NullIfExpression(io.trino.sql.tree.NullIfExpression) ArithmeticUnaryExpression(io.trino.sql.tree.ArithmeticUnaryExpression) DereferenceExpression(io.trino.sql.tree.DereferenceExpression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) ArithmeticBinaryExpression(io.trino.sql.tree.ArithmeticBinaryExpression) LogicalExpression(io.trino.sql.tree.LogicalExpression) SearchedCaseExpression(io.trino.sql.tree.SearchedCaseExpression) BindExpression(io.trino.sql.tree.BindExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) CoalesceExpression(io.trino.sql.tree.CoalesceExpression) IfExpression(io.trino.sql.tree.IfExpression) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Expression(io.trino.sql.tree.Expression) SimpleCaseExpression(io.trino.sql.tree.SimpleCaseExpression) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) LambdaExpression(io.trino.sql.tree.LambdaExpression) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) CanonicalizeExpressionRewriter.canonicalizeExpression(io.trino.sql.planner.iterative.rule.CanonicalizeExpressionRewriter.canonicalizeExpression) ExpressionAnalyzer(io.trino.sql.analyzer.ExpressionAnalyzer) TypeCoercion(io.trino.type.TypeCoercion)

Example 2 with ExpressionAnalyzer

use of io.trino.sql.analyzer.ExpressionAnalyzer in project trino by trinodb.

the class ExpressionInterpreter method evaluateConstantExpression.

public static Object evaluateConstantExpression(Expression expression, Map<NodeRef<Expression>, Type> coercions, Set<NodeRef<Expression>> typeOnlyCoercions, PlannerContext plannerContext, Session session, AccessControl accessControl, Set<NodeRef<Expression>> columnReferences, Map<NodeRef<Parameter>, Expression> parameters) {
    requireNonNull(columnReferences, "columnReferences is null");
    verifyExpressionIsConstant(columnReferences, expression);
    // add coercions
    Expression rewrite = Coercer.addCoercions(expression, coercions, typeOnlyCoercions);
    // redo the analysis since above expression rewriter might create new expressions which do not have entries in the type map
    ExpressionAnalyzer analyzer = createConstantAnalyzer(plannerContext, accessControl, session, parameters, WarningCollector.NOOP);
    analyzer.analyze(rewrite, Scope.create());
    // remove syntax sugar
    rewrite = DesugarAtTimeZoneRewriter.rewrite(rewrite, analyzer.getExpressionTypes(), plannerContext.getMetadata(), session);
    // The optimization above may have rewritten the expression tree which breaks all the identity maps, so redo the analysis
    // to re-analyze coercions that might be necessary
    analyzer = createConstantAnalyzer(plannerContext, accessControl, session, parameters, WarningCollector.NOOP);
    analyzer.analyze(rewrite, Scope.create());
    // expressionInterpreter/optimizer only understands a subset of expression types
    // TODO: remove this when the new expression tree is implemented
    Expression canonicalized = canonicalizeExpression(rewrite, analyzer.getExpressionTypes(), plannerContext, session);
    // The optimization above may have rewritten the expression tree which breaks all the identity maps, so redo the analysis
    // to re-analyze coercions that might be necessary
    analyzer = createConstantAnalyzer(plannerContext, accessControl, session, parameters, WarningCollector.NOOP);
    analyzer.analyze(canonicalized, Scope.create());
    // resolve functions
    Expression resolved = rewriteResolvedFunctions(canonicalized, analyzer.getResolvedFunctions());
    // The optimization above may have rewritten the expression tree which breaks all the identity maps, so redo the analysis
    // to re-analyze coercions that might be necessary
    analyzer = createConstantAnalyzer(plannerContext, accessControl, session, parameters, WarningCollector.NOOP);
    analyzer.analyze(resolved, Scope.create());
    // evaluate the expression
    return new ExpressionInterpreter(resolved, plannerContext, session, analyzer.getExpressionTypes()).evaluate();
}
Also used : NullIfExpression(io.trino.sql.tree.NullIfExpression) ArithmeticUnaryExpression(io.trino.sql.tree.ArithmeticUnaryExpression) DereferenceExpression(io.trino.sql.tree.DereferenceExpression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) ArithmeticBinaryExpression(io.trino.sql.tree.ArithmeticBinaryExpression) LogicalExpression(io.trino.sql.tree.LogicalExpression) SearchedCaseExpression(io.trino.sql.tree.SearchedCaseExpression) BindExpression(io.trino.sql.tree.BindExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) CoalesceExpression(io.trino.sql.tree.CoalesceExpression) IfExpression(io.trino.sql.tree.IfExpression) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Expression(io.trino.sql.tree.Expression) SimpleCaseExpression(io.trino.sql.tree.SimpleCaseExpression) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) LambdaExpression(io.trino.sql.tree.LambdaExpression) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) CanonicalizeExpressionRewriter.canonicalizeExpression(io.trino.sql.planner.iterative.rule.CanonicalizeExpressionRewriter.canonicalizeExpression) ExpressionAnalyzer(io.trino.sql.analyzer.ExpressionAnalyzer)

Example 3 with ExpressionAnalyzer

use of io.trino.sql.analyzer.ExpressionAnalyzer in project trino by trinodb.

the class ExpressionTestUtils method resolveFunctionCalls.

public static Expression resolveFunctionCalls(PlannerContext plannerContext, Session session, TypeProvider typeProvider, Expression expression, Scope scope) {
    ExpressionAnalyzer analyzer = ExpressionAnalyzer.createWithoutSubqueries(plannerContext, new AllowAllAccessControl(), session, typeProvider, ImmutableMap.of(), node -> semanticException(EXPRESSION_NOT_CONSTANT, node, "Constant expression cannot contain a subquery"), WarningCollector.NOOP, false);
    analyzer.analyze(expression, scope);
    return ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<>() {

        @Override
        public Expression rewriteFunctionCall(FunctionCall node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
            ResolvedFunction resolvedFunction = analyzer.getResolvedFunctions().get(NodeRef.of(node));
            checkArgument(resolvedFunction != null, "Function has not been analyzed: %s", node);
            FunctionCall rewritten = treeRewriter.defaultRewrite(node, context);
            FunctionCall newFunctionCall = new FunctionCall(rewritten.getLocation(), resolvedFunction.toQualifiedName(), rewritten.getWindow(), rewritten.getFilter(), rewritten.getOrderBy(), rewritten.isDistinct(), rewritten.getNullTreatment(), rewritten.getProcessingMode(), rewritten.getArguments());
            return coerceIfNecessary(node, newFunctionCall);
        }

        @Override
        protected Expression rewriteExpression(Expression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
            Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context);
            rewrittenExpression = coerceIfNecessary(node, rewrittenExpression);
            return rewrittenExpression;
        }

        private Expression coerceIfNecessary(Expression originalExpression, Expression rewrittenExpression) {
            // cast expression if coercion is registered
            Type coercion = analyzer.getExpressionCoercions().get(NodeRef.of(originalExpression));
            if (coercion != null) {
                rewrittenExpression = new Cast(rewrittenExpression, toSqlType(coercion), false, analyzer.getTypeOnlyCoercions().contains(NodeRef.of(originalExpression)));
            }
            return rewrittenExpression;
        }
    }, expression);
}
Also used : Cast(io.trino.sql.tree.Cast) Type(io.trino.spi.type.Type) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) Expression(io.trino.sql.tree.Expression) AllowAllAccessControl(io.trino.security.AllowAllAccessControl) ResolvedFunction(io.trino.metadata.ResolvedFunction) ExpressionAnalyzer(io.trino.sql.analyzer.ExpressionAnalyzer) FunctionCall(io.trino.sql.tree.FunctionCall)

Example 4 with ExpressionAnalyzer

use of io.trino.sql.analyzer.ExpressionAnalyzer in project trino by trinodb.

the class ExpressionUtils method getExpressionTypes.

/**
 * @deprecated Use {@link io.trino.sql.planner.TypeAnalyzer#getTypes(Session, TypeProvider, Expression)}.
 */
@Deprecated
public static Map<NodeRef<Expression>, Type> getExpressionTypes(PlannerContext plannerContext, Session session, Expression expression, TypeProvider types) {
    ExpressionAnalyzer expressionAnalyzer = ExpressionAnalyzer.createWithoutSubqueries(plannerContext, new AllowAllAccessControl(), session, types, ImmutableMap.of(), node -> new IllegalStateException("Unexpected node: " + node), WarningCollector.NOOP, false);
    expressionAnalyzer.analyze(expression, Scope.create());
    return expressionAnalyzer.getExpressionTypes();
}
Also used : AllowAllAccessControl(io.trino.security.AllowAllAccessControl) ExpressionAnalyzer(io.trino.sql.analyzer.ExpressionAnalyzer)

Example 5 with ExpressionAnalyzer

use of io.trino.sql.analyzer.ExpressionAnalyzer in project trino by trinodb.

the class SetTimeZoneTask method getTimeZoneId.

private String getTimeZoneId(Expression expression, SetTimeZone statement, QueryStateMachine stateMachine, List<Expression> parameters, WarningCollector warningCollector) {
    Map<NodeRef<Parameter>, Expression> parameterLookup = parameterExtractor(statement, parameters);
    ExpressionAnalyzer analyzer = createConstantAnalyzer(plannerContext, accessControl, stateMachine.getSession(), parameterLookup, warningCollector);
    Type type = analyzer.analyze(expression, Scope.create());
    if (!(type instanceof VarcharType || type instanceof IntervalDayTimeType)) {
        throw new TrinoException(TYPE_MISMATCH, format("Expected expression of varchar or interval day-time type, but '%s' has %s type", expression, type.getDisplayName()));
    }
    Object timeZoneValue = evaluateConstantExpression(expression, analyzer.getExpressionCoercions(), analyzer.getTypeOnlyCoercions(), plannerContext, stateMachine.getSession(), accessControl, ImmutableSet.of(), parameterLookup);
    TimeZoneKey timeZoneKey;
    if (timeZoneValue instanceof Slice) {
        timeZoneKey = getTimeZoneKey(((Slice) timeZoneValue).toStringUtf8());
    } else if (timeZoneValue instanceof Long) {
        timeZoneKey = getTimeZoneKeyForOffset(getZoneOffsetMinutes((Long) timeZoneValue));
    } else {
        throw new IllegalStateException(format("Time Zone expression '%s' not supported", expression));
    }
    return timeZoneKey.getId();
}
Also used : VarcharType(io.trino.spi.type.VarcharType) ExpressionAnalyzer(io.trino.sql.analyzer.ExpressionAnalyzer) NodeRef(io.trino.sql.tree.NodeRef) Type(io.trino.spi.type.Type) VarcharType(io.trino.spi.type.VarcharType) IntervalDayTimeType(io.trino.type.IntervalDayTimeType) ExpressionInterpreter.evaluateConstantExpression(io.trino.sql.planner.ExpressionInterpreter.evaluateConstantExpression) Expression(io.trino.sql.tree.Expression) Slice(io.airlift.slice.Slice) IntervalDayTimeType(io.trino.type.IntervalDayTimeType) TrinoException(io.trino.spi.TrinoException) TimeZoneKey(io.trino.spi.type.TimeZoneKey) TimeZoneKey.getTimeZoneKey(io.trino.spi.type.TimeZoneKey.getTimeZoneKey)

Aggregations

ExpressionAnalyzer (io.trino.sql.analyzer.ExpressionAnalyzer)5 Expression (io.trino.sql.tree.Expression)4 Type (io.trino.spi.type.Type)3 AllowAllAccessControl (io.trino.security.AllowAllAccessControl)2 VarcharType (io.trino.spi.type.VarcharType)2 TypeSignatureTranslator.toSqlType (io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType)2 CanonicalizeExpressionRewriter.canonicalizeExpression (io.trino.sql.planner.iterative.rule.CanonicalizeExpressionRewriter.canonicalizeExpression)2 ArithmeticBinaryExpression (io.trino.sql.tree.ArithmeticBinaryExpression)2 ArithmeticUnaryExpression (io.trino.sql.tree.ArithmeticUnaryExpression)2 BindExpression (io.trino.sql.tree.BindExpression)2 CoalesceExpression (io.trino.sql.tree.CoalesceExpression)2 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)2 DereferenceExpression (io.trino.sql.tree.DereferenceExpression)2 IfExpression (io.trino.sql.tree.IfExpression)2 InListExpression (io.trino.sql.tree.InListExpression)2 LambdaExpression (io.trino.sql.tree.LambdaExpression)2 LogicalExpression (io.trino.sql.tree.LogicalExpression)2 NodeRef (io.trino.sql.tree.NodeRef)2 NotExpression (io.trino.sql.tree.NotExpression)2 NullIfExpression (io.trino.sql.tree.NullIfExpression)2