warningCollector, isDescribe); if (context.getContext().isInLambda()) { for (LambdaArgumentDeclaration argument : context.getContext().getFieldToLambdaArgumentDeclaration().values()) { innerExpressionAnalyzer.setExpressionType(argument, getExpressionType(argument)); return innerExpressionAnalyzer.analyze(expression, baseScope, context.getContext().expectingLambda(types)).getTypeSignature(); })); process(expression, new StackableAstVisitorContext<>(context.getContext().expectingLambda(expectedFunctionType.getArgumentTypes())));
@Override protected Type visitSubqueryExpression(SubqueryExpression node, StackableAstVisitorContext<Context> context) if (context.getContext().isInLambda()) { throw new SemanticException(NOT_SUPPORTED, node, "Lambda expression cannot contain subqueries"); .withParent(context.getContext().getScope()) .build(); Scope queryScope = analyzer.analyze(node.getQuery(), subqueryScope); Node previousNode = context.getPreviousNode().orElse(null); if (previousNode instanceof InPredicate && ((InPredicate) previousNode).getValue() != node) { subqueryInPredicates.add(NodeRef.of((InPredicate) previousNode));
function = functionRegistry.resolveFunction(node.getName(), argumentTypes.build(), context.getContext().isApproximate());
@Override protected Type visitSubqueryExpression(SubqueryExpression node, StackableAstVisitorContext<AnalysisContext> context) { StatementAnalyzer analyzer = statementAnalyzerFactory.apply(node); RelationType descriptor = analyzer.process(node.getQuery(), context.getContext()); // Subquery should only produce one column if (descriptor.getVisibleFieldCount() != 1) { throw new SemanticException(MULTIPLE_FIELDS_FROM_SUBQUERY, node, "Multiple columns returned by subquery are not yet supported. Found %s", descriptor.getVisibleFieldCount()); } Optional<Node> previousNode = context.getPreviousNode(); if (previousNode.isPresent() && previousNode.get() instanceof InPredicate && ((InPredicate) previousNode.get()).getValue() != node) { subqueryInPredicates.add((InPredicate) previousNode.get()); } else { scalarSubqueries.add(node); } Type type = Iterables.getOnlyElement(descriptor.getVisibleFields()).getType(); expressionTypes.put(node, type); return type; }
/** * @param tupleDescriptor the tuple descriptor to use to resolve QualifiedNames * @param context the namespace context of the surrounding query */ public Type analyze(Expression expression, RelationType tupleDescriptor, AnalysisContext context) { Visitor visitor = new Visitor(tupleDescriptor); return visitor.process(expression, new StackableAstVisitor.StackableAstVisitorContext<>(context)); }
public R process(Node node, StackableAstVisitorContext<C> context) { context.push(node); try { return node.accept(this, context); } finally { context.pop(); } }
public R process(Node node, StackableAstVisitorContext<C> context) { context.push(node); try { return node.accept(this, context); } finally { context.pop(); } }
Scope scope = context.getContext().getScope(); Optional<ResolvedField> resolvedField = scope.tryResolveField(node, qualifiedName); if (resolvedField.isPresent()) {
if (!context.getContext().isExpectingLambda()) { throw new SemanticException(STANDALONE_LAMBDA, node, "Lambda expression should always be used inside a function"); List<Type> types = context.getContext().getFunctionInputTypes(); List<LambdaArgumentDeclaration> lambdaArguments = node.getArguments(); .withParent(context.getContext().getScope()) .withRelationType(RelationId.of(node), new RelationType(fields.build())) .build(); if (context.getContext().isInLambda()) { fieldToLambdaArgumentDeclaration.putAll(context.getContext().getFieldToLambdaArgumentDeclaration()); Type returnType = process(node.getBody(), new StackableAstVisitorContext<>(Context.inLambda(lambdaScope, fieldToLambdaArgumentDeclaration.build()))); FunctionType functionType = new FunctionType(types, returnType); return setExpressionType(node, functionType);
@Override protected Type visitBindExpression(BindExpression node, StackableAstVisitorContext<Context> context) { verify(context.getContext().isExpectingLambda(), "bind expression found when lambda is not expected"); StackableAstVisitorContext<Context> innerContext = new StackableAstVisitorContext<>(context.getContext().notExpectingLambda()); ImmutableList.Builder<Type> functionInputTypesBuilder = ImmutableList.builder(); for (Expression value : node.getValues()) { functionInputTypesBuilder.add(process(value, innerContext)); } functionInputTypesBuilder.addAll(context.getContext().getFunctionInputTypes()); List<Type> functionInputTypes = functionInputTypesBuilder.build(); FunctionType functionType = (FunctionType) process(node.getFunction(), new StackableAstVisitorContext<>(context.getContext().expectingLambda(functionInputTypes))); List<Type> argumentTypes = functionType.getArgumentTypes(); int numCapturedValues = node.getValues().size(); verify(argumentTypes.size() == functionInputTypes.size()); for (int i = 0; i < numCapturedValues; i++) { verify(functionInputTypes.get(i).equals(argumentTypes.get(i))); } FunctionType result = new FunctionType(argumentTypes.subList(numCapturedValues, argumentTypes.size()), functionType.getReturnType()); return setExpressionType(node, result); }
private Type handleResolvedField(Expression node, FieldId fieldId, Field field, StackableAstVisitorContext<Context> context) { if (context.getContext().isInLambda()) { LambdaArgumentDeclaration lambdaArgumentDeclaration = context.getContext().getFieldToLambdaArgumentDeclaration().get(fieldId); if (lambdaArgumentDeclaration != null) { // Lambda argument reference is not a column reference lambdaArgumentReferences.put(NodeRef.of((Identifier) node), lambdaArgumentDeclaration); return setExpressionType(node, field.getType()); } } if (field.getOriginTable().isPresent() && field.getOriginColumnName().isPresent()) { tableColumnReferences.put(field.getOriginTable().get(), field.getOriginColumnName().get()); } FieldId previous = columnReferences.put(NodeRef.of(node), fieldId); checkState(previous == null, "%s already known to refer to %s", node, previous); return setExpressionType(node, field.getType()); }
@Override protected Type visitExists(ExistsPredicate node, StackableAstVisitorContext<Context> context) { StatementAnalyzer analyzer = statementAnalyzerFactory.apply(node); Scope subqueryScope = Scope.builder().withParent(context.getContext().getScope()).build(); analyzer.analyze(node.getSubquery(), subqueryScope); existsSubqueries.add(NodeRef.of(node)); return setExpressionType(node, BOOLEAN); }
@Override protected Type visitSymbolReference(SymbolReference node, StackableAstVisitorContext<Context> context) { if (context.getContext().isInLambda()) { Optional<ResolvedField> resolvedField = context.getContext().getScope().tryResolveField(node, QualifiedName.of(node.getName())); if (resolvedField.isPresent() && context.getContext().getFieldToLambdaArgumentDeclaration().containsKey(FieldId.from(resolvedField.get()))) { return setExpressionType(node, resolvedField.get().getType()); } } Type type = symbolTypes.get(Symbol.from(node)); return setExpressionType(node, type); }
public R process(Node node, StackableAstVisitorContext<C> context) { context.push(node); try { return node.accept(this, context); } finally { context.pop(); } }
@Override protected Type visitIdentifier(Identifier node, StackableAstVisitorContext<Context> context) { ResolvedField resolvedField = context.getContext().getScope().resolveField(node, QualifiedName.of(node.getValue())); return handleResolvedField(node, resolvedField, context); }
private Type analyze(Expression expression, Scope baseScope, Context context) { Visitor visitor = new Visitor(baseScope, warningCollector); return visitor.process(expression, new StackableAstVisitor.StackableAstVisitorContext<>(context)); }
public Type analyze(Expression expression, Scope scope) { Visitor visitor = new Visitor(scope, warningCollector); return visitor.process(expression, new StackableAstVisitor.StackableAstVisitorContext<>(Context.notInLambda(scope))); }