private static ExpressionAnalysis analyzeExpressions( Session session, Metadata metadata, SqlParser sqlParser, RelationType tupleDescriptor, TypeProvider types, Iterable<? extends Expression> expressions, List<Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { // expressions at this point can not have sub queries so deny all access checks // in the future, we will need a full access controller here to verify access to functions Analysis analysis = new Analysis(null, parameters, isDescribe); ExpressionAnalyzer analyzer = create(analysis, session, metadata, sqlParser, new DenyAllAccessControl(), types, warningCollector); for (Expression expression : expressions) { analyzer.analyze(expression, Scope.builder().withRelationType(RelationId.anonymous(), tupleDescriptor).build()); } return new ExpressionAnalysis( analyzer.getExpressionTypes(), analyzer.getExpressionCoercions(), analyzer.getSubqueryInPredicates(), analyzer.getScalarSubqueries(), analyzer.getExistsSubqueries(), analyzer.getColumnReferences(), analyzer.getTypeOnlyCoercions(), analyzer.getQuantifiedComparisons(), analyzer.getLambdaArgumentReferences(), analyzer.getWindowFunctions()); }
public static Map<NodeRef<Expression>, Type> getExpressionTypes( Session session, Metadata metadata, SqlParser sqlParser, TypeProvider types, Iterable<Expression> expressions, List<Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { return analyzeExpressionsWithSymbols(session, metadata, sqlParser, types, expressions, parameters, warningCollector, isDescribe).getExpressionTypes(); }
private Map<NodeRef<Expression>, Type> getExpressionTypes(Session session, Expression expression, TypeProvider types) { ExpressionAnalyzer expressionAnalyzer = ExpressionAnalyzer.createWithoutSubqueries( metadata.getFunctionRegistry(), metadata.getTypeManager(), session, types, emptyList(), node -> new IllegalStateException("Unexpected node: %s" + node), WarningCollector.NOOP, false); expressionAnalyzer.analyze(expression, Scope.create()); return expressionAnalyzer.getExpressionTypes(); }
private static class Context { private final Scope scope; // functionInputTypes and nameToLambdaDeclarationMap can be null or non-null independently. All 4 combinations are possible. // The list of types when expecting a lambda (i.e. processing lambda parameters of a function); null otherwise. // Empty list represents expecting a lambda with no arguments. private final List<Type> functionInputTypes; // The mapping from names to corresponding lambda argument declarations when inside a lambda; null otherwise. // Empty map means that the all lambda expressions surrounding the current node has no arguments. private final Map<FieldId, LambdaArgumentDeclaration> fieldToLambdaArgumentDeclaration; private Context( Scope scope, List<Type> functionInputTypes, Map<FieldId, LambdaArgumentDeclaration> fieldToLambdaArgumentDeclaration) { this.scope = requireNonNull(scope, "scope is null"); this.functionInputTypes = functionInputTypes; this.fieldToLambdaArgumentDeclaration = fieldToLambdaArgumentDeclaration; } public static Context notInLambda(Scope scope) { return new Context(scope, null, null); } public static Context inLambda(Scope scope, Map<FieldId, LambdaArgumentDeclaration> fieldToLambdaArgumentDeclaration) {
public static Map<NodeRef<Expression>, Type> getExpressionTypes( Session session, Metadata metadata, SqlParser sqlParser, TypeProvider types, Expression expression, List<Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { return getExpressionTypes(session, metadata, sqlParser, types, ImmutableList.of(expression), parameters, warningCollector, isDescribe); }
public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, List<Expression> parameters) { ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters, WarningCollector.NOOP); analyzer.analyze(expression, Scope.create()); Type actualType = analyzer.getExpressionTypes().get(NodeRef.of(expression)); if (!metadata.getTypeManager().canCoerce(actualType, expectedType)) { throw new SemanticException(SemanticErrorCode.TYPE_MISMATCH, expression, format("Cannot cast type %s to %s", actualType.getTypeSignature(), expectedType.getTypeSignature())); } Map<NodeRef<Expression>, Type> coercions = ImmutableMap.<NodeRef<Expression>, Type>builder() .putAll(analyzer.getExpressionCoercions()) .put(NodeRef.of(expression), expectedType) .build(); return evaluateConstantExpression(expression, coercions, analyzer.getTypeOnlyCoercions(), metadata, session, ImmutableSet.of(), parameters); }
public InterpretedPageFilter( Expression expression, TypeProvider symbolTypes, Map<Symbol, Integer> symbolToInputMappings, Metadata metadata, SqlParser sqlParser, Session session) { SymbolToInputParameterRewriter rewriter = new SymbolToInputParameterRewriter(symbolTypes, symbolToInputMappings); Expression rewritten = rewriter.rewrite(expression); this.inputChannels = new InputChannels(rewriter.getInputChannels()); this.deterministic = DeterminismEvaluator.isDeterministic(expression); // analyze rewritten expression so we can know the type of every expression in the tree List<Type> inputTypes = rewriter.getInputTypes(); ImmutableMap.Builder<Integer, Type> parameterTypes = ImmutableMap.builder(); for (int parameter = 0; parameter < inputTypes.size(); parameter++) { Type type = inputTypes.get(parameter); parameterTypes.put(parameter, type); } Map<NodeRef<Expression>, Type> expressionTypes = getExpressionTypesFromInput(session, metadata, sqlParser, parameterTypes.build(), rewritten, emptyList(), WarningCollector.NOOP); this.evaluator = ExpressionInterpreter.expressionInterpreter(rewritten, metadata, session, expressionTypes); }
ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters, WarningCollector.NOOP); analyzer.analyze(rewrite, Scope.create()); rewrite = DesugarAtTimeZoneRewriter.rewrite(rewrite, analyzer.getExpressionTypes()); analyzer = createConstantAnalyzer(metadata, session, parameters, WarningCollector.NOOP); analyzer.analyze(canonicalized, Scope.create()); Object result = expressionInterpreter(canonicalized, metadata, session, analyzer.getExpressionTypes()).evaluate(); verify(!(result instanceof Expression), "Expression interpreter returned an unresolved expression"); return result;
@Override protected Scope visitProperty(Property node, Optional<Scope> scope) { // Property value expressions must be constant createConstantAnalyzer(metadata, session, analysis.getParameters(), WarningCollector.NOOP, analysis.isDescribe()) .analyze(node.getValue(), createScope(scope)); return createAndAssignScope(node, scope); }
private Type getType(Expression expression) { if (expression instanceof SymbolReference) { Symbol symbol = Symbol.from(expression); return requireNonNull(types.get(symbol), () -> format("No type for symbol %s", symbol)); } ExpressionAnalyzer expressionAnalyzer = ExpressionAnalyzer.createWithoutSubqueries( metadata.getFunctionRegistry(), metadata.getTypeManager(), session, types, ImmutableList.of(), // At this stage, there should be no subqueries in the plan. node -> new VerifyException("Unexpected subquery"), WarningCollector.NOOP, false); return expressionAnalyzer.analyze(expression, Scope.create()); }
argumentTypesBuilder.add(new TypeSignatureProvider( types -> { ExpressionAnalyzer innerExpressionAnalyzer = new ExpressionAnalyzer( functionRegistry, typeManager, if (context.getContext().isInLambda()) { for (LambdaArgumentDeclaration argument : context.getContext().getFieldToLambdaArgumentDeclaration().values()) { innerExpressionAnalyzer.setExpressionType(argument, getExpressionType(argument)); Signature function = resolveFunction(node, argumentTypes, functionRegistry); return setExpressionType(node, type);
public static ExpressionAnalyzer createConstantAnalyzer(Metadata metadata, Session session, List<Expression> parameters, WarningCollector warningCollector) { return createWithoutSubqueries( metadata.getFunctionRegistry(), metadata.getTypeManager(), session, parameters, EXPRESSION_NOT_CONSTANT, "Constant expression cannot contain a subquery", warningCollector, false); }
private ExpressionAnalysis analyzeExpression(Expression expression, Scope scope) { return ExpressionAnalyzer.analyzeExpression( session, metadata, accessControl, sqlParser, scope, analysis, expression, WarningCollector.NOOP); }
public static ExpressionAnalysis analyzeExpressionsWithSymbols( Session session, Metadata metadata, SqlParser sqlParser, TypeProvider types, Iterable<Expression> expressions, List<Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { return analyzeExpressions(session, metadata, sqlParser, new RelationType(), types, expressions, parameters, warningCollector, isDescribe); }
public static Map<NodeRef<Expression>, Type> getExpressionTypesFromInput( Session session, Metadata metadata, SqlParser sqlParser, Map<Integer, Type> types, Iterable<Expression> expressions, List<Expression> parameters, WarningCollector warningCollector) { return analyzeExpressionsWithInputs(session, metadata, sqlParser, types, expressions, parameters, warningCollector).getExpressionTypes(); }
public static ExpressionAnalyzer create( Analysis analysis, Session session, Metadata metadata, SqlParser sqlParser, AccessControl accessControl, TypeProvider types, WarningCollector warningCollector) { return new ExpressionAnalyzer( metadata.getFunctionRegistry(), metadata.getTypeManager(), node -> new StatementAnalyzer(analysis, metadata, sqlParser, accessControl, session, warningCollector), session, types, analysis.getParameters(), warningCollector, analysis.isDescribe()); }
public static Map<NodeRef<Expression>, Type> getExpressionTypes( Session session, Metadata metadata, SqlParser sqlParser, TypeProvider types, Expression expression, List<Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { return getExpressionTypes(session, metadata, sqlParser, types, ImmutableList.of(expression), parameters, warningCollector, isDescribe); }
private static class Context { private final Scope scope; // functionInputTypes and nameToLambdaDeclarationMap can be null or non-null independently. All 4 combinations are possible. // The list of types when expecting a lambda (i.e. processing lambda parameters of a function); null otherwise. // Empty list represents expecting a lambda with no arguments. private final List<Type> functionInputTypes; // The mapping from names to corresponding lambda argument declarations when inside a lambda; null otherwise. // Empty map means that the all lambda expressions surrounding the current node has no arguments. private final Map<FieldId, LambdaArgumentDeclaration> fieldToLambdaArgumentDeclaration; private Context( Scope scope, List<Type> functionInputTypes, Map<FieldId, LambdaArgumentDeclaration> fieldToLambdaArgumentDeclaration) { this.scope = requireNonNull(scope, "scope is null"); this.functionInputTypes = functionInputTypes; this.fieldToLambdaArgumentDeclaration = fieldToLambdaArgumentDeclaration; } public static Context notInLambda(Scope scope) { return new Context(scope, null, null); } public static Context inLambda(Scope scope, Map<FieldId, LambdaArgumentDeclaration> fieldToLambdaArgumentDeclaration) {
public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, List<Expression> parameters) { ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters, WarningCollector.NOOP); analyzer.analyze(expression, Scope.create()); Type actualType = analyzer.getExpressionTypes().get(NodeRef.of(expression)); if (!metadata.getTypeManager().canCoerce(actualType, expectedType)) { throw new SemanticException(SemanticErrorCode.TYPE_MISMATCH, expression, format("Cannot cast type %s to %s", actualType.getTypeSignature(), expectedType.getTypeSignature())); } Map<NodeRef<Expression>, Type> coercions = ImmutableMap.<NodeRef<Expression>, Type>builder() .putAll(analyzer.getExpressionCoercions()) .put(NodeRef.of(expression), expectedType) .build(); return evaluateConstantExpression(expression, coercions, analyzer.getTypeOnlyCoercions(), metadata, session, ImmutableSet.of(), parameters); }
private JoinFilterFunctionFactory compileJoinFilterFunction( Expression filterExpression, Map<Symbol, Integer> probeLayout, Map<Symbol, Integer> buildLayout, TypeProvider types, Session session) { Map<Symbol, Integer> joinSourcesLayout = createJoinSourcesLayout(buildLayout, probeLayout); Map<Integer, Type> sourceTypes = joinSourcesLayout.entrySet().stream() .collect(toImmutableMap(Map.Entry::getValue, entry -> types.get(entry.getKey()))); Expression rewrittenFilter = new SymbolToInputRewriter(joinSourcesLayout).rewrite(filterExpression); Map<NodeRef<Expression>, Type> expressionTypes = getExpressionTypesFromInput( session, metadata, sqlParser, sourceTypes, rewrittenFilter, emptyList(), /* parameters have already been replaced */ NOOP); RowExpression translatedFilter = toRowExpression(rewrittenFilter, expressionTypes); return joinFilterFunctionCompiler.compileJoinFilterFunction(translatedFilter, buildLayout.size()); }