public void analyzeWhere(Node node, Scope scope, Expression predicate) { Analyzer.verifyNoAggregateWindowOrGroupingFunctions(metadata.getFunctionRegistry(), predicate, "WHERE clause"); ExpressionAnalysis expressionAnalysis = analyzeExpression(predicate, scope); analysis.recordSubqueries(node, expressionAnalysis); Type predicateType = expressionAnalysis.getType(predicate); if (!predicateType.equals(BOOLEAN)) { if (!predicateType.equals(UNKNOWN)) { throw new SemanticException(TYPE_MISMATCH, predicate, "WHERE clause must evaluate to a boolean: actual type %s", predicateType); } // coerce null to boolean analysis.addCoercion(predicate, BOOLEAN, false); } analysis.setWhere(node, predicate); }
@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; }
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(); }
public void recordSubqueries(Node node, ExpressionAnalysis expressionAnalysis) { NodeRef<Node> key = NodeRef.of(node); this.inPredicatesSubqueries.putAll(key, dereference(expressionAnalysis.getSubqueryInPredicates())); this.scalarSubqueries.putAll(key, dereference(expressionAnalysis.getScalarSubqueries())); this.existsSubqueries.putAll(key, dereference(expressionAnalysis.getExistsSubqueries())); this.quantifiedComparisonSubqueries.putAll(key, dereference(expressionAnalysis.getQuantifiedComparisons())); }
private void analyzeHaving(QuerySpecification node, Scope scope) { if (node.getHaving().isPresent()) { Expression predicate = node.getHaving().get(); ExpressionAnalysis expressionAnalysis = analyzeExpression(predicate, scope); expressionAnalysis.getWindowFunctions().stream() .findFirst() .ifPresent(function -> { throw new SemanticException(NESTED_WINDOW, function.getNode(), "HAVING clause cannot contain window functions"); }); analysis.recordSubqueries(node, expressionAnalysis); Type predicateType = expressionAnalysis.getType(predicate); if (!predicateType.equals(BOOLEAN) && !predicateType.equals(UNKNOWN)) { throw new SemanticException(TYPE_MISMATCH, predicate, "HAVING clause must evaluate to a boolean: actual type %s", predicateType); } analysis.setHaving(node, predicate); } }
@Override public Expression rewriteExpression(Expression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context); // cast expression if coercion is registered Type type = analysis.getType(node); Type coercion = analysis.getCoercion(node); if (coercion != null) { rewrittenExpression = new Cast( rewrittenExpression, coercion.getTypeSignature().toString(), false, isTypeOnlyCoercion(type.getTypeSignature(), coercion.getTypeSignature())); } return rewrittenExpression; }
public void recordSubqueries(Node node, ExpressionAnalysis expressionAnalysis) { this.inPredicates.putAll(node, expressionAnalysis.getSubqueryInPredicates()); this.scalarSubqueries.putAll(node, expressionAnalysis.getScalarSubqueries()); }
@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);
@Override public Expression rewriteDereferenceExpression(DereferenceExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { if (analysis.getColumnReferences().contains(node)) { return rewriteExpression(node, context, treeRewriter); } // Rewrite all row field reference to function call. QualifiedName mangledName = QualifiedName.of(mangleFieldReference(node.getFieldName())); FunctionCall functionCall = new FunctionCall(mangledName, ImmutableList.of(node.getBase())); Expression rewrittenExpression = rewriteFunctionCall(functionCall, context, treeRewriter); // cast expression if coercion is registered Type coercion = analysis.getCoercion(node); if (coercion != null) { rewrittenExpression = new Cast(rewrittenExpression, coercion.getTypeSignature().toString()); } return rewrittenExpression; } }, parsedExpression);
checkState(leftExpressionAnalysis.getSubqueryInPredicates().isEmpty(), "INVARIANT"); checkState(rightExpressionAnalysis.getSubqueryInPredicates().isEmpty(), "INVARIANT"); ExpressionAnalysis leftExpressionAnalysis = analyzeExpression(leftExpression, left, context); ExpressionAnalysis rightExpressionAnalysis = analyzeExpression(rightExpression, right, context); leftJoinInPredicates.addAll(leftExpressionAnalysis.getSubqueryInPredicates()); rightJoinInPredicates.addAll(rightExpressionAnalysis.getSubqueryInPredicates()); addCoercionForJoinCriteria(node, leftExpression, rightExpression);
private static ExpressionAnalysis analyzeExpressions( Session session, Metadata metadata, SqlParser sqlParser, RelationType tupleDescriptor, Iterable<? extends Expression> expressions) { // 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 ExpressionAnalyzer analyzer = create(new Analysis(), session, metadata, sqlParser, new DenyAllAccessControl(), false); for (Expression expression : expressions) { analyzer.analyze(expression, tupleDescriptor, new AnalysisContext()); } return new ExpressionAnalysis( analyzer.getExpressionTypes(), analyzer.getExpressionCoercions(), analyzer.getSubqueryInPredicates(), analyzer.getScalarSubqueries(), analyzer.getResolvedNames().keySet()); }
public static ExpressionAnalysis analyzeExpression( Session session, Metadata metadata, AccessControl accessControl, SqlParser sqlParser, RelationType tupleDescriptor, Analysis analysis, boolean approximateQueriesEnabled, AnalysisContext context, Expression expression) { ExpressionAnalyzer analyzer = create(analysis, session, metadata, sqlParser, accessControl, approximateQueriesEnabled); analyzer.analyze(expression, tupleDescriptor, context); IdentityHashMap<Expression, Type> expressionTypes = analyzer.getExpressionTypes(); IdentityHashMap<Expression, Type> expressionCoercions = analyzer.getExpressionCoercions(); IdentityHashMap<FunctionCall, Signature> resolvedFunctions = analyzer.getResolvedFunctions(); analysis.addTypes(expressionTypes); analysis.addCoercions(expressionCoercions); analysis.addFunctionSignatures(resolvedFunctions); analysis.addResolvedNames(analyzer.getResolvedNames()); return new ExpressionAnalysis( expressionTypes, expressionCoercions, analyzer.getSubqueryInPredicates(), analyzer.getScalarSubqueries(), analyzer.getColumnReferences()); }
for (Expression expression : node.getExpressions()) { ExpressionAnalysis expressionAnalysis = analyzeExpression(expression, createScope(scope)); Type expressionType = expressionAnalysis.getType(expression); if (expressionType instanceof ArrayType) { Type elementType = ((ArrayType) expressionType).getElementType();
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(); }
.map(row -> analyzeExpression(row, createScope(scope)).getType(row)) .map(type -> { if (type instanceof RowType) {
public static IdentityHashMap<Expression, Type> getExpressionTypesFromInput( Session session, Metadata metadata, SqlParser sqlParser, Map<Integer, Type> types, Iterable<? extends Expression> expressions) { return analyzeExpressionsWithInputs(session, metadata, sqlParser, types, expressions).getExpressionTypes(); }
ExpressionAnalysis expressionAnalysis = analyzeExpression(expression, scope); Type type = expressionAnalysis.getType(expression); if (node.getSelect().isDistinct() && !type.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node.getSelect(), "DISTINCT can only be applied to comparable types (actual: %s)", type); outputExpressionBuilder.add(column.getExpression()); Type type = expressionAnalysis.getType(column.getExpression()); if (node.getSelect().isDistinct() && !type.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node.getSelect(), "DISTINCT can only be applied to comparable types (actual: %s): %s", type, column.getExpression());
public static IdentityHashMap<Expression, Type> getExpressionTypes( Session session, Metadata metadata, SqlParser sqlParser, Map<Symbol, Type> types, Iterable<? extends Expression> expressions) { return analyzeExpressionsWithSymbols(session, metadata, sqlParser, types, expressions).getExpressionTypes(); }
Type clauseType = expressionAnalysis.getType(expression); if (!clauseType.equals(BOOLEAN)) { if (!clauseType.equals(UNKNOWN)) {
private void analyzeHaving(QuerySpecification node, RelationType tupleDescriptor, AnalysisContext context) { if (node.getHaving().isPresent()) { Expression predicate = node.getHaving().get(); ExpressionAnalysis expressionAnalysis = analyzeExpression(predicate, tupleDescriptor, context); analysis.recordSubqueries(node, expressionAnalysis); Type predicateType = expressionAnalysis.getType(predicate); if (!predicateType.equals(BOOLEAN) && !predicateType.equals(UNKNOWN)) { throw new SemanticException(TYPE_MISMATCH, predicate, "HAVING clause must evaluate to a boolean: actual type %s", predicateType); } analysis.setHaving(node, predicate); } }