Search in sources :

Example 1 with ComparisonExpression

use of com.facebook.presto.sql.tree.ComparisonExpression in project presto by prestodb.

the class EqualityInference method generateEqualitiesPartitionedBy.

/**
     * Dumps the inference equalities as equality expressions that are partitioned by the symbolScope.
     * All stored equalities are returned in a compact set and will be classified into three groups as determined by the symbol scope:
     * <ol>
     * <li>equalities that fit entirely within the symbol scope</li>
     * <li>equalities that fit entirely outside of the symbol scope</li>
     * <li>equalities that straddle the symbol scope</li>
     * </ol>
     * <pre>
     * Example:
     *   Stored Equalities:
     *     a = b = c
     *     d = e = f = g
     *
     *   Symbol Scope:
     *     a, b, d, e
     *
     *   Output EqualityPartition:
     *     Scope Equalities:
     *       a = b
     *       d = e
     *     Complement Scope Equalities
     *       f = g
     *     Scope Straddling Equalities
     *       a = c
     *       d = f
     * </pre>
     */
public EqualityPartition generateEqualitiesPartitionedBy(Predicate<Symbol> symbolScope) {
    Set<Expression> scopeEqualities = new HashSet<>();
    Set<Expression> scopeComplementEqualities = new HashSet<>();
    Set<Expression> scopeStraddlingEqualities = new HashSet<>();
    for (Collection<Expression> equalitySet : equalitySets.asMap().values()) {
        Set<Expression> scopeExpressions = new HashSet<>();
        Set<Expression> scopeComplementExpressions = new HashSet<>();
        Set<Expression> scopeStraddlingExpressions = new HashSet<>();
        // Try to push each non-derived expression into one side of the scope
        for (Expression expression : filter(equalitySet, not(derivedExpressions::contains))) {
            Expression scopeRewritten = rewriteExpression(expression, symbolScope, false);
            if (scopeRewritten != null) {
                scopeExpressions.add(scopeRewritten);
            }
            Expression scopeComplementRewritten = rewriteExpression(expression, not(symbolScope), false);
            if (scopeComplementRewritten != null) {
                scopeComplementExpressions.add(scopeComplementRewritten);
            }
            if (scopeRewritten == null && scopeComplementRewritten == null) {
                scopeStraddlingExpressions.add(expression);
            }
        }
        // Compile the equality expressions on each side of the scope
        Expression matchingCanonical = getCanonical(scopeExpressions);
        if (scopeExpressions.size() >= 2) {
            for (Expression expression : filter(scopeExpressions, not(equalTo(matchingCanonical)))) {
                scopeEqualities.add(new ComparisonExpression(ComparisonExpressionType.EQUAL, matchingCanonical, expression));
            }
        }
        Expression complementCanonical = getCanonical(scopeComplementExpressions);
        if (scopeComplementExpressions.size() >= 2) {
            for (Expression expression : filter(scopeComplementExpressions, not(equalTo(complementCanonical)))) {
                scopeComplementEqualities.add(new ComparisonExpression(ComparisonExpressionType.EQUAL, complementCanonical, expression));
            }
        }
        // Compile the scope straddling equality expressions
        List<Expression> connectingExpressions = new ArrayList<>();
        connectingExpressions.add(matchingCanonical);
        connectingExpressions.add(complementCanonical);
        connectingExpressions.addAll(scopeStraddlingExpressions);
        connectingExpressions = ImmutableList.copyOf(filter(connectingExpressions, Predicates.notNull()));
        Expression connectingCanonical = getCanonical(connectingExpressions);
        if (connectingCanonical != null) {
            for (Expression expression : filter(connectingExpressions, not(equalTo(connectingCanonical)))) {
                scopeStraddlingEqualities.add(new ComparisonExpression(ComparisonExpressionType.EQUAL, connectingCanonical, expression));
            }
        }
    }
    return new EqualityPartition(scopeEqualities, scopeComplementEqualities, scopeStraddlingEqualities);
}
Also used : ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) InListExpression(com.facebook.presto.sql.tree.InListExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) Expression(com.facebook.presto.sql.tree.Expression) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 2 with ComparisonExpression

use of com.facebook.presto.sql.tree.ComparisonExpression in project presto by prestodb.

the class DomainTranslator method extractDisjuncts.

private static List<Expression> extractDisjuncts(Type type, DiscreteValues discreteValues, SymbolReference reference) {
    List<Expression> values = discreteValues.getValues().stream().map(object -> toExpression(object, type)).collect(toList());
    // If values is empty, then the equatableValues was either ALL or NONE, both of which should already have been checked for
    checkState(!values.isEmpty());
    Expression predicate;
    if (values.size() == 1) {
        predicate = new ComparisonExpression(EQUAL, reference, getOnlyElement(values));
    } else {
        predicate = new InPredicate(reference, new InListExpression(values));
    }
    if (!discreteValues.isWhiteList()) {
        predicate = new NotExpression(predicate);
    }
    return ImmutableList.of(predicate);
}
Also used : ComparisonExpressionType(com.facebook.presto.sql.tree.ComparisonExpressionType) Block(com.facebook.presto.spi.block.Block) GREATER_THAN(com.facebook.presto.sql.tree.ComparisonExpressionType.GREATER_THAN) GREATER_THAN_OR_EQUAL(com.facebook.presto.sql.tree.ComparisonExpressionType.GREATER_THAN_OR_EQUAL) IsNullPredicate(com.facebook.presto.sql.tree.IsNullPredicate) PeekingIterator(com.google.common.collect.PeekingIterator) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Map(java.util.Map) NullableValue(com.facebook.presto.spi.predicate.NullableValue) BetweenPredicate(com.facebook.presto.sql.tree.BetweenPredicate) NotExpression(com.facebook.presto.sql.tree.NotExpression) EQUAL(com.facebook.presto.sql.tree.ComparisonExpressionType.EQUAL) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) ImmutableMap(com.google.common.collect.ImmutableMap) Collections.emptyList(java.util.Collections.emptyList) SortedRangeSet(com.facebook.presto.spi.predicate.SortedRangeSet) Marker(com.facebook.presto.spi.predicate.Marker) SqlParser(com.facebook.presto.sql.parser.SqlParser) Preconditions.checkState(com.google.common.base.Preconditions.checkState) TRUE_LITERAL(com.facebook.presto.sql.tree.BooleanLiteral.TRUE_LITERAL) LESS_THAN(com.facebook.presto.sql.tree.ComparisonExpressionType.LESS_THAN) TupleDomain(com.facebook.presto.spi.predicate.TupleDomain) BooleanLiteral(com.facebook.presto.sql.tree.BooleanLiteral) NullLiteral(com.facebook.presto.sql.tree.NullLiteral) ExpressionUtils.combineDisjunctsWithDefault(com.facebook.presto.sql.ExpressionUtils.combineDisjunctsWithDefault) Domain(com.facebook.presto.spi.predicate.Domain) LogicalBinaryExpression(com.facebook.presto.sql.tree.LogicalBinaryExpression) List(java.util.List) Utils(com.facebook.presto.spi.predicate.Utils) InPredicate(com.facebook.presto.sql.tree.InPredicate) Optional(java.util.Optional) Ranges(com.facebook.presto.spi.predicate.Ranges) ExpressionUtils.combineConjuncts(com.facebook.presto.sql.ExpressionUtils.combineConjuncts) ExpressionUtils.and(com.facebook.presto.sql.ExpressionUtils.and) ArrayList(java.util.ArrayList) InListExpression(com.facebook.presto.sql.tree.InListExpression) ImmutableList(com.google.common.collect.ImmutableList) ValueSet(com.facebook.presto.spi.predicate.ValueSet) Type(com.facebook.presto.spi.type.Type) Objects.requireNonNull(java.util.Objects.requireNonNull) Cast(com.facebook.presto.sql.tree.Cast) Iterators.peekingIterator(com.google.common.collect.Iterators.peekingIterator) Nullable(javax.annotation.Nullable) ExpressionUtils.or(com.facebook.presto.sql.ExpressionUtils.or) FALSE_LITERAL(com.facebook.presto.sql.tree.BooleanLiteral.FALSE_LITERAL) Session(com.facebook.presto.Session) Signature(com.facebook.presto.metadata.Signature) AstVisitor(com.facebook.presto.sql.tree.AstVisitor) Signature.internalOperator(com.facebook.presto.metadata.Signature.internalOperator) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) IsNotNullPredicate(com.facebook.presto.sql.tree.IsNotNullPredicate) SATURATED_FLOOR_CAST(com.facebook.presto.spi.function.OperatorType.SATURATED_FLOOR_CAST) DiscreteValues(com.facebook.presto.spi.predicate.DiscreteValues) Range(com.facebook.presto.spi.predicate.Range) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) LiteralInterpreter.toExpression(com.facebook.presto.sql.planner.LiteralInterpreter.toExpression) LESS_THAN_OR_EQUAL(com.facebook.presto.sql.tree.ComparisonExpressionType.LESS_THAN_OR_EQUAL) NOT_EQUAL(com.facebook.presto.sql.tree.ComparisonExpressionType.NOT_EQUAL) Collectors.toList(java.util.stream.Collectors.toList) ExpressionAnalyzer(com.facebook.presto.sql.analyzer.ExpressionAnalyzer) Expression(com.facebook.presto.sql.tree.Expression) FunctionInvoker(com.facebook.presto.sql.FunctionInvoker) IdentityLinkedHashMap(com.facebook.presto.util.maps.IdentityLinkedHashMap) Metadata(com.facebook.presto.metadata.Metadata) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) NotExpression(com.facebook.presto.sql.tree.NotExpression) LogicalBinaryExpression(com.facebook.presto.sql.tree.LogicalBinaryExpression) InListExpression(com.facebook.presto.sql.tree.InListExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) LiteralInterpreter.toExpression(com.facebook.presto.sql.planner.LiteralInterpreter.toExpression) Expression(com.facebook.presto.sql.tree.Expression) InListExpression(com.facebook.presto.sql.tree.InListExpression) NotExpression(com.facebook.presto.sql.tree.NotExpression) InPredicate(com.facebook.presto.sql.tree.InPredicate)

Example 3 with ComparisonExpression

use of com.facebook.presto.sql.tree.ComparisonExpression in project presto by prestodb.

the class DomainTranslator method processRange.

private static Expression processRange(Type type, Range range, SymbolReference reference) {
    if (range.isAll()) {
        return TRUE_LITERAL;
    }
    if (isBetween(range)) {
        // specialize the range with BETWEEN expression if possible b/c it is currently more efficient
        return new BetweenPredicate(reference, toExpression(range.getLow().getValue(), type), toExpression(range.getHigh().getValue(), type));
    }
    List<Expression> rangeConjuncts = new ArrayList<>();
    if (!range.getLow().isLowerUnbounded()) {
        switch(range.getLow().getBound()) {
            case ABOVE:
                rangeConjuncts.add(new ComparisonExpression(GREATER_THAN, reference, toExpression(range.getLow().getValue(), type)));
                break;
            case EXACTLY:
                rangeConjuncts.add(new ComparisonExpression(GREATER_THAN_OR_EQUAL, reference, toExpression(range.getLow().getValue(), type)));
                break;
            case BELOW:
                throw new IllegalStateException("Low Marker should never use BELOW bound: " + range);
            default:
                throw new AssertionError("Unhandled bound: " + range.getLow().getBound());
        }
    }
    if (!range.getHigh().isUpperUnbounded()) {
        switch(range.getHigh().getBound()) {
            case ABOVE:
                throw new IllegalStateException("High Marker should never use ABOVE bound: " + range);
            case EXACTLY:
                rangeConjuncts.add(new ComparisonExpression(LESS_THAN_OR_EQUAL, reference, toExpression(range.getHigh().getValue(), type)));
                break;
            case BELOW:
                rangeConjuncts.add(new ComparisonExpression(LESS_THAN, reference, toExpression(range.getHigh().getValue(), type)));
                break;
            default:
                throw new AssertionError("Unhandled bound: " + range.getHigh().getBound());
        }
    }
    // If rangeConjuncts is null, then the range was ALL, which should already have been checked for
    checkState(!rangeConjuncts.isEmpty());
    return combineConjuncts(rangeConjuncts);
}
Also used : ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) BetweenPredicate(com.facebook.presto.sql.tree.BetweenPredicate) NotExpression(com.facebook.presto.sql.tree.NotExpression) LogicalBinaryExpression(com.facebook.presto.sql.tree.LogicalBinaryExpression) InListExpression(com.facebook.presto.sql.tree.InListExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) LiteralInterpreter.toExpression(com.facebook.presto.sql.planner.LiteralInterpreter.toExpression) Expression(com.facebook.presto.sql.tree.Expression) ArrayList(java.util.ArrayList)

Example 4 with ComparisonExpression

use of com.facebook.presto.sql.tree.ComparisonExpression in project presto by prestodb.

the class TransformExistsApplyToScalarApply method apply.

@Override
public Optional<PlanNode> apply(PlanNode node, Lookup lookup, PlanNodeIdAllocator idAllocator, SymbolAllocator symbolAllocator) {
    if (!(node instanceof ApplyNode)) {
        return Optional.empty();
    }
    ApplyNode parent = (ApplyNode) node;
    if (parent.getSubqueryAssignments().size() != 1) {
        return Optional.empty();
    }
    Expression expression = getOnlyElement(parent.getSubqueryAssignments().getExpressions());
    if (!(expression instanceof ExistsPredicate)) {
        return Optional.empty();
    }
    Symbol count = symbolAllocator.newSymbol(COUNT.toString(), BIGINT);
    Symbol exists = getOnlyElement(parent.getSubqueryAssignments().getSymbols());
    return Optional.of(new ApplyNode(node.getId(), parent.getInput(), new ProjectNode(idAllocator.getNextId(), new AggregationNode(idAllocator.getNextId(), new LimitNode(idAllocator.getNextId(), parent.getSubquery(), 1, false), ImmutableMap.of(count, COUNT_CALL), ImmutableMap.of(count, countSignature), ImmutableMap.of(), ImmutableList.of(ImmutableList.of()), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty()), Assignments.of(exists, new ComparisonExpression(GREATER_THAN, count.toSymbolReference(), new Cast(new LongLiteral("0"), BIGINT.toString())))), Assignments.of(exists, exists.toSymbolReference()), parent.getCorrelation()));
}
Also used : Cast(com.facebook.presto.sql.tree.Cast) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) Expression(com.facebook.presto.sql.tree.Expression) LimitNode(com.facebook.presto.sql.planner.plan.LimitNode) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) Symbol(com.facebook.presto.sql.planner.Symbol) ApplyNode(com.facebook.presto.sql.planner.plan.ApplyNode) ExistsPredicate(com.facebook.presto.sql.tree.ExistsPredicate) ProjectNode(com.facebook.presto.sql.planner.plan.ProjectNode) AggregationNode(com.facebook.presto.sql.planner.plan.AggregationNode)

Example 5 with ComparisonExpression

use of com.facebook.presto.sql.tree.ComparisonExpression in project presto by prestodb.

the class TestSqlParser method testShowStatsForQuery.

@Test
public void testShowStatsForQuery() {
    final String[] tableNames = { "t", "s.t", "c.s.t" };
    for (String fullName : tableNames) {
        QualifiedName qualifiedName = makeQualifiedName(fullName);
        assertStatement(format("SHOW STATS FOR (SELECT * FROM %s)", qualifiedName), createShowStats(qualifiedName, ImmutableList.of(new AllColumns()), Optional.empty()));
        assertStatement(format("SHOW STATS FOR (SELECT * FROM %s WHERE field > 0)", qualifiedName), createShowStats(qualifiedName, ImmutableList.of(new AllColumns()), Optional.of(new ComparisonExpression(GREATER_THAN, new Identifier("field"), new LongLiteral("0")))));
        assertStatement(format("SHOW STATS FOR (SELECT * FROM %s WHERE field > 0 or field < 0)", qualifiedName), createShowStats(qualifiedName, ImmutableList.of(new AllColumns()), Optional.of(new LogicalBinaryExpression(LogicalBinaryExpression.Operator.OR, new ComparisonExpression(GREATER_THAN, new Identifier("field"), new LongLiteral("0")), new ComparisonExpression(LESS_THAN, new Identifier("field"), new LongLiteral("0"))))));
    }
}
Also used : LogicalBinaryExpression(com.facebook.presto.sql.tree.LogicalBinaryExpression) QuantifiedComparisonExpression(com.facebook.presto.sql.tree.QuantifiedComparisonExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) Identifier(com.facebook.presto.sql.tree.Identifier) QueryUtil.quotedIdentifier(com.facebook.presto.sql.QueryUtil.quotedIdentifier) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) QualifiedName(com.facebook.presto.sql.tree.QualifiedName) AllColumns(com.facebook.presto.sql.tree.AllColumns) Test(org.testng.annotations.Test)

Aggregations

ComparisonExpression (com.facebook.presto.sql.tree.ComparisonExpression)34 Test (org.testng.annotations.Test)16 Expression (com.facebook.presto.sql.tree.Expression)15 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)12 SymbolReference (com.facebook.presto.sql.tree.SymbolReference)12 LongLiteral (com.facebook.presto.sql.tree.LongLiteral)10 ArrayList (java.util.ArrayList)10 LogicalBinaryExpression (com.facebook.presto.sql.tree.LogicalBinaryExpression)9 NotExpression (com.facebook.presto.sql.tree.NotExpression)9 InListExpression (com.facebook.presto.sql.tree.InListExpression)7 Cast (com.facebook.presto.sql.tree.Cast)6 StringLiteral (com.facebook.presto.sql.tree.StringLiteral)6 DoubleLiteral (com.facebook.presto.sql.tree.DoubleLiteral)5 ImmutableList (com.google.common.collect.ImmutableList)5 InPredicate (com.facebook.presto.sql.tree.InPredicate)4 IsNullPredicate (com.facebook.presto.sql.tree.IsNullPredicate)4 Session (com.facebook.presto.Session)3 ProjectNode (com.facebook.presto.spi.plan.ProjectNode)3 JoinNode (com.facebook.presto.sql.planner.plan.JoinNode)3 BetweenPredicate (com.facebook.presto.sql.tree.BetweenPredicate)3