Search in sources :

Example 6 with InListExpression

use of io.trino.sql.tree.InListExpression in project trino by trinodb.

the class TestEffectivePredicateExtractor method testValues.

@Test
public void testValues() {
    TypeProvider types = TypeProvider.copyOf(ImmutableMap.<Symbol, Type>builder().put(A, BIGINT).put(B, BIGINT).put(D, DOUBLE).put(R, RowType.anonymous(ImmutableList.of(BIGINT, BIGINT))).buildOrThrow());
    // one column
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(A), ImmutableList.of(new Row(ImmutableList.of(bigintLiteral(1))), new Row(ImmutableList.of(bigintLiteral(2))))), types, typeAnalyzer), new InPredicate(AE, new InListExpression(ImmutableList.of(bigintLiteral(1), bigintLiteral(2)))));
    // one column with null
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(A), ImmutableList.of(new Row(ImmutableList.of(bigintLiteral(1))), new Row(ImmutableList.of(bigintLiteral(2))), new Row(ImmutableList.of(new Cast(new NullLiteral(), toSqlType(BIGINT)))))), types, typeAnalyzer), or(new InPredicate(AE, new InListExpression(ImmutableList.of(bigintLiteral(1), bigintLiteral(2)))), new IsNullPredicate(AE)));
    // all nulls
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(A), ImmutableList.of(new Row(ImmutableList.of(new Cast(new NullLiteral(), toSqlType(BIGINT)))))), types, typeAnalyzer), new IsNullPredicate(AE));
    // nested row
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(R), ImmutableList.of(new Row(ImmutableList.of(new Row(ImmutableList.of(bigintLiteral(1), new NullLiteral())))))), types, typeAnalyzer), TRUE_LITERAL);
    // many rows
    List<Expression> rows = IntStream.range(0, 500).mapToObj(TestEffectivePredicateExtractor::bigintLiteral).map(ImmutableList::of).map(Row::new).collect(toImmutableList());
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(A), rows), types, typeAnalyzer), new BetweenPredicate(AE, bigintLiteral(0), bigintLiteral(499)));
    // NaN
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(D), ImmutableList.of(new Row(ImmutableList.of(doubleLiteral(Double.NaN))))), types, typeAnalyzer), new NotExpression(new IsNullPredicate(DE)));
    // NaN and NULL
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(D), ImmutableList.of(new Row(ImmutableList.of(new Cast(new NullLiteral(), toSqlType(DOUBLE)))), new Row(ImmutableList.of(doubleLiteral(Double.NaN))))), types, typeAnalyzer), TRUE_LITERAL);
    // NaN and value
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(D), ImmutableList.of(new Row(ImmutableList.of(doubleLiteral(42.))), new Row(ImmutableList.of(doubleLiteral(Double.NaN))))), types, typeAnalyzer), new NotExpression(new IsNullPredicate(DE)));
    // Real NaN
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(D), ImmutableList.of(new Row(ImmutableList.of(new Cast(doubleLiteral(Double.NaN), toSqlType(REAL)))))), TypeProvider.copyOf(ImmutableMap.of(D, REAL)), typeAnalyzer), new NotExpression(new IsNullPredicate(DE)));
    // multiple columns
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(A, B), ImmutableList.of(new Row(ImmutableList.of(bigintLiteral(1), bigintLiteral(100))), new Row(ImmutableList.of(bigintLiteral(2), bigintLiteral(200))))), types, typeAnalyzer), and(new InPredicate(AE, new InListExpression(ImmutableList.of(bigintLiteral(1), bigintLiteral(2)))), new InPredicate(BE, new InListExpression(ImmutableList.of(bigintLiteral(100), bigintLiteral(200))))));
    // multiple columns with null
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(A, B), ImmutableList.of(new Row(ImmutableList.of(bigintLiteral(1), new Cast(new NullLiteral(), toSqlType(BIGINT)))), new Row(ImmutableList.of(new Cast(new NullLiteral(), toSqlType(BIGINT)), bigintLiteral(200))))), types, typeAnalyzer), and(or(new ComparisonExpression(EQUAL, AE, bigintLiteral(1)), new IsNullPredicate(AE)), or(new ComparisonExpression(EQUAL, BE, bigintLiteral(200)), new IsNullPredicate(BE))));
    // non-deterministic
    ResolvedFunction rand = functionResolution.resolveFunction(QualifiedName.of("rand"), ImmutableList.of());
    ValuesNode node = new ValuesNode(newId(), ImmutableList.of(A, B), ImmutableList.of(new Row(ImmutableList.of(bigintLiteral(1), new FunctionCall(rand.toQualifiedName(), ImmutableList.of())))));
    assertEquals(extract(types, node), new ComparisonExpression(EQUAL, AE, bigintLiteral(1)));
    // non-constant
    assertEquals(effectivePredicateExtractor.extract(SESSION, new ValuesNode(newId(), ImmutableList.of(A), ImmutableList.of(new Row(ImmutableList.of(bigintLiteral(1))), new Row(ImmutableList.of(BE)))), types, typeAnalyzer), TRUE_LITERAL);
}
Also used : Cast(io.trino.sql.tree.Cast) ValuesNode(io.trino.sql.planner.plan.ValuesNode) BetweenPredicate(io.trino.sql.tree.BetweenPredicate) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) ResolvedFunction(io.trino.metadata.ResolvedFunction) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) InPredicate(io.trino.sql.tree.InPredicate) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) RowType(io.trino.spi.type.RowType) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) Type(io.trino.spi.type.Type) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) IsNullPredicate(io.trino.sql.tree.IsNullPredicate) Row(io.trino.sql.tree.Row) FunctionCall(io.trino.sql.tree.FunctionCall) NullLiteral(io.trino.sql.tree.NullLiteral) Test(org.testng.annotations.Test)

Example 7 with InListExpression

use of io.trino.sql.tree.InListExpression in project trino by trinodb.

the class TestDomainTranslator method in.

private InPredicate in(Expression expression, Type expressisonType, List<?> values) {
    List<Type> types = nCopies(values.size(), expressisonType);
    List<Expression> expressions = literalEncoder.toExpressions(TEST_SESSION, values, types);
    return new InPredicate(expression, new InListExpression(expressions));
}
Also used : CharType.createCharType(io.trino.spi.type.CharType.createCharType) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) DecimalType(io.trino.spi.type.DecimalType) DoubleType(io.trino.spi.type.DoubleType) Type(io.trino.spi.type.Type) VarcharType.createUnboundedVarcharType(io.trino.spi.type.VarcharType.createUnboundedVarcharType) DecimalType.createDecimalType(io.trino.spi.type.DecimalType.createDecimalType) RealType(io.trino.spi.type.RealType) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) InListExpression(io.trino.sql.tree.InListExpression) InPredicate(io.trino.sql.tree.InPredicate)

Example 8 with InListExpression

use of io.trino.sql.tree.InListExpression in project trino by trinodb.

the class DomainTranslator method extractDisjuncts.

private List<Expression> extractDisjuncts(Session session, Type type, DiscreteValues discreteValues, SymbolReference reference) {
    List<Expression> values = discreteValues.getValues().stream().map(object -> literalEncoder.toExpression(session, 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.isInclusive()) {
        predicate = new NotExpression(predicate);
    }
    return ImmutableList.of(predicate);
}
Also used : IsNullPredicate(io.trino.sql.tree.IsNullPredicate) TableProceduresPropertyManager(io.trino.metadata.TableProceduresPropertyManager) FAIL_ON_NULL(io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL) ExpressionUtils.combineDisjunctsWithDefault(io.trino.sql.ExpressionUtils.combineDisjunctsWithDefault) InvocationConvention.simpleConvention(io.trino.spi.function.InvocationConvention.simpleConvention) PeekingIterator(com.google.common.collect.PeekingIterator) InterpretedFunctionInvoker(io.trino.sql.InterpretedFunctionInvoker) TypeUtils.isFloatingPointNaN(io.trino.spi.type.TypeUtils.isFloatingPointNaN) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BooleanLiteral(io.trino.sql.tree.BooleanLiteral) ExpressionUtils.or(io.trino.sql.ExpressionUtils.or) Slices(io.airlift.slice.Slices) Map(java.util.Map) GREATER_THAN(io.trino.sql.tree.ComparisonExpression.Operator.GREATER_THAN) DiscreteValues(io.trino.spi.predicate.DiscreteValues) SqlParser(io.trino.sql.parser.SqlParser) FunctionCall(io.trino.sql.tree.FunctionCall) BetweenPredicate(io.trino.sql.tree.BetweenPredicate) SliceUtf8.getCodePointAt(io.airlift.slice.SliceUtf8.getCodePointAt) SATURATED_FLOOR_CAST(io.trino.spi.function.OperatorType.SATURATED_FLOOR_CAST) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Range(io.trino.spi.predicate.Range) Ranges(io.trino.spi.predicate.Ranges) ResolvedFunction(io.trino.metadata.ResolvedFunction) Domain(io.trino.spi.predicate.Domain) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) FALSE_LITERAL(io.trino.sql.tree.BooleanLiteral.FALSE_LITERAL) Set(java.util.Set) TrinoException(io.trino.spi.TrinoException) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) ValueSet(io.trino.spi.predicate.ValueSet) InPredicate(io.trino.sql.tree.InPredicate) Preconditions.checkState(com.google.common.base.Preconditions.checkState) LESS_THAN_OR_EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.LESS_THAN_OR_EQUAL) SessionPropertyManager(io.trino.metadata.SessionPropertyManager) EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.EQUAL) NOT_EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.NOT_EQUAL) List(java.util.List) SymbolReference(io.trino.sql.tree.SymbolReference) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) InListExpression(io.trino.sql.tree.InListExpression) ExpressionUtils.combineConjuncts(io.trino.sql.ExpressionUtils.combineConjuncts) NEVER_NULL(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL) Session(io.trino.Session) PlannerContext(io.trino.sql.PlannerContext) MethodHandle(java.lang.invoke.MethodHandle) Slice(io.airlift.slice.Slice) AllowAllAccessControl(io.trino.security.AllowAllAccessControl) NullableValue(io.trino.spi.predicate.NullableValue) DoubleType(io.trino.spi.type.DoubleType) LikePredicate(io.trino.sql.tree.LikePredicate) Type(io.trino.spi.type.Type) TypeCoercion(io.trino.type.TypeCoercion) BOOLEAN(io.trino.spi.type.BooleanType.BOOLEAN) Collectors.collectingAndThen(java.util.stream.Collectors.collectingAndThen) ArrayList(java.util.ArrayList) Cast(io.trino.sql.tree.Cast) VarcharType(io.trino.spi.type.VarcharType) ImmutableList(com.google.common.collect.ImmutableList) IsNotNullPredicate(io.trino.sql.tree.IsNotNullPredicate) NodeRef(io.trino.sql.tree.NodeRef) NotExpression(io.trino.sql.tree.NotExpression) Objects.requireNonNull(java.util.Objects.requireNonNull) NullLiteral(io.trino.sql.tree.NullLiteral) TableProceduresRegistry(io.trino.metadata.TableProceduresRegistry) Iterators.peekingIterator(com.google.common.collect.Iterators.peekingIterator) GREATER_THAN_OR_EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.GREATER_THAN_OR_EQUAL) Nullable(javax.annotation.Nullable) AstVisitor(io.trino.sql.tree.AstVisitor) SliceUtf8.lengthOfCodePoint(io.airlift.slice.SliceUtf8.lengthOfCodePoint) StringLiteral(io.trino.sql.tree.StringLiteral) OperatorNotFoundException(io.trino.metadata.OperatorNotFoundException) Throwables(com.google.common.base.Throwables) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) TRUE_LITERAL(io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL) LESS_THAN(io.trino.sql.tree.ComparisonExpression.Operator.LESS_THAN) TupleDomain(io.trino.spi.predicate.TupleDomain) SliceUtf8.setCodePointAt(io.airlift.slice.SliceUtf8.setCodePointAt) GENERIC_INTERNAL_ERROR(io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR) LikeFunctions(io.trino.type.LikeFunctions) Collectors.toList(java.util.stream.Collectors.toList) ExpressionUtils.and(io.trino.sql.ExpressionUtils.and) StatementAnalyzerFactory(io.trino.sql.analyzer.StatementAnalyzerFactory) TablePropertyManager(io.trino.metadata.TablePropertyManager) RealType(io.trino.spi.type.RealType) LogicalExpression(io.trino.sql.tree.LogicalExpression) SliceUtf8.countCodePoints(io.airlift.slice.SliceUtf8.countCodePoints) AnalyzePropertyManager(io.trino.metadata.AnalyzePropertyManager) SortedRangeSet(io.trino.spi.predicate.SortedRangeSet) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) LogicalExpression(io.trino.sql.tree.LogicalExpression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) InPredicate(io.trino.sql.tree.InPredicate)

Example 9 with InListExpression

use of io.trino.sql.tree.InListExpression in project trino by trinodb.

the class DomainTranslator method extractDisjuncts.

private List<Expression> extractDisjuncts(Session session, Type type, Ranges ranges, SymbolReference reference) {
    List<Expression> disjuncts = new ArrayList<>();
    List<Expression> singleValues = new ArrayList<>();
    List<Range> orderedRanges = ranges.getOrderedRanges();
    SortedRangeSet sortedRangeSet = SortedRangeSet.copyOf(type, orderedRanges);
    SortedRangeSet complement = sortedRangeSet.complement();
    List<Range> singleValueExclusionsList = complement.getOrderedRanges().stream().filter(Range::isSingleValue).collect(toList());
    List<Range> originalUnionSingleValues = SortedRangeSet.copyOf(type, singleValueExclusionsList).union(sortedRangeSet).getOrderedRanges();
    PeekingIterator<Range> singleValueExclusions = peekingIterator(singleValueExclusionsList.iterator());
    /*
        For types including NaN, it is incorrect to introduce range "all" while processing a set of ranges,
        even if the component ranges cover the entire value set.
        This is because partial ranges don't include NaN, while range "all" does.
        Example: ranges (unbounded , 1.0) and (1.0, unbounded) should not be coalesced to (unbounded, unbounded) with excluded point 1.0.
        That result would be further translated to expression "xxx <> 1.0", which is satisfied by NaN.
        To avoid error, in such case the ranges are not optimised.
         */
    if (type instanceof RealType || type instanceof DoubleType) {
        boolean originalRangeIsAll = orderedRanges.stream().anyMatch(Range::isAll);
        boolean coalescedRangeIsAll = originalUnionSingleValues.stream().anyMatch(Range::isAll);
        if (!originalRangeIsAll && coalescedRangeIsAll) {
            for (Range range : orderedRanges) {
                disjuncts.add(processRange(session, type, range, reference));
            }
            return disjuncts;
        }
    }
    for (Range range : originalUnionSingleValues) {
        if (range.isSingleValue()) {
            singleValues.add(literalEncoder.toExpression(session, range.getSingleValue(), type));
            continue;
        }
        // attempt to optimize ranges that can be coalesced as long as single value points are excluded
        List<Expression> singleValuesInRange = new ArrayList<>();
        while (singleValueExclusions.hasNext() && range.contains(singleValueExclusions.peek())) {
            singleValuesInRange.add(literalEncoder.toExpression(session, singleValueExclusions.next().getSingleValue(), type));
        }
        if (!singleValuesInRange.isEmpty()) {
            disjuncts.add(combineRangeWithExcludedPoints(session, type, reference, range, singleValuesInRange));
            continue;
        }
        disjuncts.add(processRange(session, type, range, reference));
    }
    // Add back all of the possible single values either as an equality or an IN predicate
    if (singleValues.size() == 1) {
        disjuncts.add(new ComparisonExpression(EQUAL, reference, getOnlyElement(singleValues)));
    } else if (singleValues.size() > 1) {
        disjuncts.add(new InPredicate(reference, new InListExpression(singleValues)));
    }
    return disjuncts;
}
Also used : ArrayList(java.util.ArrayList) InListExpression(io.trino.sql.tree.InListExpression) Range(io.trino.spi.predicate.Range) InPredicate(io.trino.sql.tree.InPredicate) RealType(io.trino.spi.type.RealType) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) SortedRangeSet(io.trino.spi.predicate.SortedRangeSet) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) LogicalExpression(io.trino.sql.tree.LogicalExpression) DoubleType(io.trino.spi.type.DoubleType)

Aggregations

InListExpression (io.trino.sql.tree.InListExpression)9 InPredicate (io.trino.sql.tree.InPredicate)9 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)6 Expression (io.trino.sql.tree.Expression)6 NotExpression (io.trino.sql.tree.NotExpression)5 Test (org.testng.annotations.Test)5 DoubleType (io.trino.spi.type.DoubleType)3 RealType (io.trino.spi.type.RealType)3 Type (io.trino.spi.type.Type)3 Cast (io.trino.sql.tree.Cast)3 LogicalExpression (io.trino.sql.tree.LogicalExpression)3 NullLiteral (io.trino.sql.tree.NullLiteral)3 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)2 ResolvedFunction (io.trino.metadata.ResolvedFunction)2 Range (io.trino.spi.predicate.Range)2 SortedRangeSet (io.trino.spi.predicate.SortedRangeSet)2 TypeSignatureTranslator.toSqlType (io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType)2 BetweenPredicate (io.trino.sql.tree.BetweenPredicate)2 FunctionCall (io.trino.sql.tree.FunctionCall)2