use of com.facebook.presto.sql.tree.Expression in project presto by prestodb.
the class EffectivePredicateExtractor method pullExpressionThroughSymbols.
private static Expression pullExpressionThroughSymbols(Expression expression, Collection<Symbol> symbols) {
EqualityInference equalityInference = createEqualityInference(expression);
ImmutableList.Builder<Expression> effectiveConjuncts = ImmutableList.builder();
for (Expression conjunct : EqualityInference.nonInferrableConjuncts(expression)) {
if (DeterminismEvaluator.isDeterministic(conjunct)) {
Expression rewritten = equalityInference.rewriteExpression(conjunct, in(symbols));
if (rewritten != null) {
effectiveConjuncts.add(rewritten);
}
}
}
effectiveConjuncts.addAll(equalityInference.generateEqualitiesPartitionedBy(in(symbols)).getScopeEqualities());
return combineConjuncts(effectiveConjuncts.build());
}
use of com.facebook.presto.sql.tree.Expression in project presto by prestodb.
the class EffectivePredicateExtractor method visitJoin.
@Override
public Expression visitJoin(JoinNode node, Void context) {
Expression leftPredicate = node.getLeft().accept(this, context);
Expression rightPredicate = node.getRight().accept(this, context);
List<Expression> joinConjuncts = new ArrayList<>();
for (JoinNode.EquiJoinClause clause : node.getCriteria()) {
joinConjuncts.add(new ComparisonExpression(ComparisonExpressionType.EQUAL, clause.getLeft().toSymbolReference(), clause.getRight().toSymbolReference()));
}
switch(node.getType()) {
case INNER:
return combineConjuncts(ImmutableList.<Expression>builder().add(pullExpressionThroughSymbols(leftPredicate, node.getOutputSymbols())).add(pullExpressionThroughSymbols(rightPredicate, node.getOutputSymbols())).addAll(pullExpressionsThroughSymbols(joinConjuncts, node.getOutputSymbols())).build());
case LEFT:
return combineConjuncts(ImmutableList.<Expression>builder().add(pullExpressionThroughSymbols(leftPredicate, node.getOutputSymbols())).addAll(pullNullableConjunctsThroughOuterJoin(extractConjuncts(rightPredicate), node.getOutputSymbols(), node.getRight().getOutputSymbols()::contains)).addAll(pullNullableConjunctsThroughOuterJoin(joinConjuncts, node.getOutputSymbols(), node.getRight().getOutputSymbols()::contains)).build());
case RIGHT:
return combineConjuncts(ImmutableList.<Expression>builder().add(pullExpressionThroughSymbols(rightPredicate, node.getOutputSymbols())).addAll(pullNullableConjunctsThroughOuterJoin(extractConjuncts(leftPredicate), node.getOutputSymbols(), node.getLeft().getOutputSymbols()::contains)).addAll(pullNullableConjunctsThroughOuterJoin(joinConjuncts, node.getOutputSymbols(), node.getLeft().getOutputSymbols()::contains)).build());
case FULL:
return combineConjuncts(ImmutableList.<Expression>builder().addAll(pullNullableConjunctsThroughOuterJoin(extractConjuncts(leftPredicate), node.getOutputSymbols(), node.getLeft().getOutputSymbols()::contains)).addAll(pullNullableConjunctsThroughOuterJoin(extractConjuncts(rightPredicate), node.getOutputSymbols(), node.getRight().getOutputSymbols()::contains)).addAll(pullNullableConjunctsThroughOuterJoin(joinConjuncts, node.getOutputSymbols(), node.getLeft().getOutputSymbols()::contains, node.getRight().getOutputSymbols()::contains)).build());
default:
throw new UnsupportedOperationException("Unknown join type: " + node.getType());
}
}
use of com.facebook.presto.sql.tree.Expression in project presto by prestodb.
the class EffectivePredicateExtractor method visitFilter.
@Override
public Expression visitFilter(FilterNode node, Void context) {
Expression underlyingPredicate = node.getSource().accept(this, context);
Expression predicate = node.getPredicate();
// Remove non-deterministic conjuncts
predicate = stripNonDeterministicConjuncts(predicate);
return combineConjuncts(predicate, underlyingPredicate);
}
use of com.facebook.presto.sql.tree.Expression in project presto by prestodb.
the class EqualityInference method rewriteExpression.
private Expression rewriteExpression(Expression expression, Predicate<Symbol> symbolScope, boolean allowFullReplacement) {
Iterable<Expression> subExpressions = SubExpressionExtractor.extract(expression);
if (!allowFullReplacement) {
subExpressions = filter(subExpressions, not(equalTo(expression)));
}
ImmutableMap.Builder<Expression, Expression> expressionRemap = ImmutableMap.builder();
for (Expression subExpression : subExpressions) {
Expression canonical = getScopedCanonical(subExpression, symbolScope);
if (canonical != null) {
expressionRemap.put(subExpression, canonical);
}
}
// Perform a naive single-pass traversal to try to rewrite non-compliant portions of the tree. Prefers to replace
// larger subtrees over smaller subtrees
// TODO: this rewrite can probably be made more sophisticated
Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ExpressionNodeInliner(expressionRemap.build()), expression);
if (!symbolToExpressionPredicate(symbolScope).apply(rewritten)) {
// If the rewritten is still not compliant with the symbol scope, just give up
return null;
}
return rewritten;
}
use of com.facebook.presto.sql.tree.Expression in project presto by prestodb.
the class ExpressionInterpreter method evaluateConstantExpression.
public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, List<Expression> parameters) {
ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters);
analyzer.analyze(expression, Scope.builder().build());
Type actualType = analyzer.getExpressionTypes().get(expression);
if (!metadata.getTypeManager().canCoerce(actualType, expectedType)) {
throw new SemanticException(SemanticErrorCode.TYPE_MISMATCH, expression, String.format("Cannot cast type %s to %s", expectedType.getTypeSignature(), actualType.getTypeSignature()));
}
IdentityLinkedHashMap<Expression, Type> coercions = new IdentityLinkedHashMap<>();
coercions.putAll(analyzer.getExpressionCoercions());
coercions.put(expression, expectedType);
return evaluateConstantExpression(expression, coercions, metadata, session, ImmutableSet.of(), parameters);
}
Aggregations