Search in sources :

Example 11 with ComparisonExpression

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

the class TestRemoveUnreferencedScalarSubqueries method testDoNotRemoveInputOfLeftOrFullJoinWhenSubqueryPotentiallyEmpty.

@Test
public void testDoNotRemoveInputOfLeftOrFullJoinWhenSubqueryPotentiallyEmpty() {
    tester().assertThat(new RemoveUnreferencedScalarSubqueries()).on(p -> {
        Symbol b = p.symbol("b");
        return p.correlatedJoin(emptyList(), p.values(emptyList(), ImmutableList.of(emptyList())), LEFT, TRUE_LITERAL, p.filter(new ComparisonExpression(LESS_THAN, b.toSymbolReference(), new LongLiteral("3")), p.values(2, b)));
    }).doesNotFire();
    tester().assertThat(new RemoveUnreferencedScalarSubqueries()).on(p -> {
        Symbol b = p.symbol("b");
        return p.correlatedJoin(emptyList(), p.values(emptyList(), ImmutableList.of(emptyList())), FULL, TRUE_LITERAL, p.filter(new ComparisonExpression(LESS_THAN, b.toSymbolReference(), new LongLiteral("3")), p.values(2, b)));
    }).doesNotFire();
}
Also used : Symbol(io.trino.sql.planner.Symbol) LEFT(io.trino.sql.planner.plan.CorrelatedJoinNode.Type.LEFT) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) RIGHT(io.trino.sql.planner.plan.CorrelatedJoinNode.Type.RIGHT) Collections.emptyList(java.util.Collections.emptyList) Test(org.testng.annotations.Test) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) TRUE_LITERAL(io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL) LESS_THAN(io.trino.sql.tree.ComparisonExpression.Operator.LESS_THAN) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) BigintType(io.trino.spi.type.BigintType) FULL(io.trino.sql.planner.plan.CorrelatedJoinNode.Type.FULL) ImmutableList(com.google.common.collect.ImmutableList) LongLiteral(io.trino.sql.tree.LongLiteral) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) LongLiteral(io.trino.sql.tree.LongLiteral) Symbol(io.trino.sql.planner.Symbol) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Test(org.testng.annotations.Test)

Example 12 with ComparisonExpression

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

the class TestSimplifyFilterPredicate method testSimplifyIfExpression.

@Test
public void testSimplifyIfExpression() {
    // true result iff the condition is true
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, true, false)"), p.values(p.symbol("a")))).matches(filter("a", values("a")));
    // true result iff the condition is true
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, true)"), p.values(p.symbol("a")))).matches(filter("a", values("a")));
    // true result iff the condition is null or false
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, false, true)"), p.values(p.symbol("a")))).matches(filter("a IS NULL OR NOT a", values("a")));
    // true result iff the condition is null or false
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, null, true)"), p.values(p.symbol("a")))).matches(filter("a IS NULL OR NOT a", values("a")));
    // always true
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, true, true)"), p.values(p.symbol("a")))).matches(filter("true", values("a")));
    // always false
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, false, false)"), p.values(p.symbol("a")))).matches(filter("false", values("a")));
    // both results equal
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, b > 0, b > 0)"), p.values(p.symbol("a"), p.symbol("b")))).matches(filter("b > 0", values("a", "b")));
    // both results are equal non-deterministic expressions
    FunctionCall randomFunction = new FunctionCall(tester().getMetadata().resolveFunction(tester().getSession(), QualifiedName.of("random"), ImmutableList.of()).toQualifiedName(), ImmutableList.of());
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(new IfExpression(expression("a"), new ComparisonExpression(EQUAL, randomFunction, new LongLiteral("0")), new ComparisonExpression(EQUAL, randomFunction, new LongLiteral("0"))), p.values(p.symbol("a")))).doesNotFire();
    // always null (including the default) -> simplified to FALSE
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, null)"), p.values(p.symbol("a")))).matches(filter("false", values("a")));
    // condition is true -> first branch
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(true, a, NOT a)"), p.values(p.symbol("a")))).matches(filter("a", values("a")));
    // condition is true -> second branch
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(false, a, NOT a)"), p.values(p.symbol("a")))).matches(filter("NOT a", values("a")));
    // condition is true, no second branch -> the result is null, simplified to FALSE
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(false, a)"), p.values(p.symbol("a")))).matches(filter("false", values("a")));
    // not known result (`b`) - cannot optimize
    tester().assertThat(new SimplifyFilterPredicate(tester().getMetadata())).on(p -> p.filter(expression("IF(a, true, b)"), p.values(p.symbol("a"), p.symbol("b")))).doesNotFire();
}
Also used : QualifiedName(io.trino.sql.tree.QualifiedName) EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.EQUAL) IfExpression(io.trino.sql.tree.IfExpression) ImmutableList(com.google.common.collect.ImmutableList) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) LongLiteral(io.trino.sql.tree.LongLiteral) Test(org.testng.annotations.Test) PlanMatchPattern.filter(io.trino.sql.planner.assertions.PlanMatchPattern.filter) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) FunctionCall(io.trino.sql.tree.FunctionCall) PlanBuilder.expression(io.trino.sql.planner.iterative.rule.test.PlanBuilder.expression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) IfExpression(io.trino.sql.tree.IfExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) LongLiteral(io.trino.sql.tree.LongLiteral) FunctionCall(io.trino.sql.tree.FunctionCall) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Test(org.testng.annotations.Test)

Example 13 with ComparisonExpression

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

the class TestTransformCorrelatedJoinToJoin method testRewriteInnerCorrelatedJoin.

@Test
public void testRewriteInnerCorrelatedJoin() {
    tester().assertThat(new TransformCorrelatedJoinToJoin(tester().getPlannerContext())).on(p -> {
        Symbol a = p.symbol("a");
        Symbol b = p.symbol("b");
        return p.correlatedJoin(ImmutableList.of(a), p.values(a), p.filter(new ComparisonExpression(GREATER_THAN, b.toSymbolReference(), a.toSymbolReference()), p.values(b)));
    }).matches(join(JoinNode.Type.INNER, ImmutableList.of(), Optional.of("b > a"), values("a"), filter(TRUE_LITERAL, values("b"))));
    tester().assertThat(new TransformCorrelatedJoinToJoin(tester().getPlannerContext())).on(p -> {
        Symbol a = p.symbol("a");
        Symbol b = p.symbol("b");
        return p.correlatedJoin(ImmutableList.of(a), p.values(a), INNER, new ComparisonExpression(LESS_THAN, b.toSymbolReference(), new LongLiteral("3")), p.filter(new ComparisonExpression(GREATER_THAN, b.toSymbolReference(), a.toSymbolReference()), p.values(b)));
    }).matches(join(JoinNode.Type.INNER, ImmutableList.of(), Optional.of("b > a AND b < 3"), values("a"), filter(TRUE_LITERAL, values("b"))));
}
Also used : Symbol(io.trino.sql.planner.Symbol) INNER(io.trino.sql.planner.plan.CorrelatedJoinNode.Type.INNER) LEFT(io.trino.sql.planner.plan.CorrelatedJoinNode.Type.LEFT) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Test(org.testng.annotations.Test) PlanMatchPattern.filter(io.trino.sql.planner.assertions.PlanMatchPattern.filter) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) TRUE_LITERAL(io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL) LESS_THAN(io.trino.sql.tree.ComparisonExpression.Operator.LESS_THAN) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) ImmutableList(com.google.common.collect.ImmutableList) LongLiteral(io.trino.sql.tree.LongLiteral) GREATER_THAN(io.trino.sql.tree.ComparisonExpression.Operator.GREATER_THAN) Optional(java.util.Optional) JoinNode(io.trino.sql.planner.plan.JoinNode) PlanMatchPattern.join(io.trino.sql.planner.assertions.PlanMatchPattern.join) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) LongLiteral(io.trino.sql.tree.LongLiteral) Symbol(io.trino.sql.planner.Symbol) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Test(org.testng.annotations.Test)

Example 14 with ComparisonExpression

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

the class LogicalPlanner method noTruncationCast.

/*
    According to the standard, for the purpose of store assignment (INSERT),
    no non-space characters of a character string, and no non-zero octets
    of a binary string must be lost when the inserted value is truncated to
    fit in the target column type.
    The following method returns a cast from source type to target type
    with a guarantee of no illegal truncation.
    TODO Once BINARY and parametric VARBINARY types are supported, they should be handled here.
    TODO This workaround is insufficient to handle structural types
     */
private Expression noTruncationCast(Expression expression, Type fromType, Type toType) {
    if (fromType instanceof UnknownType || (!(toType instanceof VarcharType) && !(toType instanceof CharType))) {
        return new Cast(expression, toSqlType(toType));
    }
    int targetLength;
    if (toType instanceof VarcharType) {
        if (((VarcharType) toType).isUnbounded()) {
            return new Cast(expression, toSqlType(toType));
        }
        targetLength = ((VarcharType) toType).getBoundedLength();
    } else {
        targetLength = ((CharType) toType).getLength();
    }
    checkState(fromType instanceof VarcharType || fromType instanceof CharType, "inserting non-character value to column of character type");
    ResolvedFunction spaceTrimmedLength = metadata.resolveFunction(session, QualifiedName.of("$space_trimmed_length"), fromTypes(VARCHAR));
    ResolvedFunction fail = metadata.resolveFunction(session, QualifiedName.of("fail"), fromTypes(VARCHAR));
    return new IfExpression(// check if the trimmed value fits in the target type
    new ComparisonExpression(GREATER_THAN_OR_EQUAL, new GenericLiteral("BIGINT", Integer.toString(targetLength)), new CoalesceExpression(new FunctionCall(spaceTrimmedLength.toQualifiedName(), ImmutableList.of(new Cast(expression, toSqlType(VARCHAR)))), new GenericLiteral("BIGINT", "0"))), new Cast(expression, toSqlType(toType)), new Cast(new FunctionCall(fail.toQualifiedName(), ImmutableList.of(new Cast(new StringLiteral(format("Cannot truncate non-space characters when casting from %s to %s on INSERT", fromType.getDisplayName(), toType.getDisplayName())), toSqlType(VARCHAR)))), toSqlType(toType)));
}
Also used : UnknownType(io.trino.type.UnknownType) Cast(io.trino.sql.tree.Cast) IfExpression(io.trino.sql.tree.IfExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) StringLiteral(io.trino.sql.tree.StringLiteral) VarcharType(io.trino.spi.type.VarcharType) ResolvedFunction(io.trino.metadata.ResolvedFunction) CharType(io.trino.spi.type.CharType) FunctionCall(io.trino.sql.tree.FunctionCall) CoalesceExpression(io.trino.sql.tree.CoalesceExpression) GenericLiteral(io.trino.sql.tree.GenericLiteral)

Example 15 with ComparisonExpression

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

the class TestFilterStatsRule method testUnestimatableFunction.

@Test
public void testUnestimatableFunction() {
    // can't estimate function and default filter factor is turned off
    ComparisonExpression unestimatableExpression = new ComparisonExpression(Operator.EQUAL, new TestingFunctionResolution().functionCallBuilder(QualifiedName.of("sin")).addArgument(DOUBLE, new SymbolReference("i1")).build(), new DoubleLiteral("1"));
    tester().assertStatsFor(pb -> pb.filter(unestimatableExpression, pb.values(pb.symbol("i1"), pb.symbol("i2"), pb.symbol("i3")))).withSourceStats(0, PlanNodeStatsEstimate.builder().setOutputRowCount(10).addSymbolStatistics(new Symbol("i1"), SymbolStatsEstimate.builder().setLowValue(1).setHighValue(10).setDistinctValuesCount(5).setNullsFraction(0).build()).addSymbolStatistics(new Symbol("i2"), SymbolStatsEstimate.builder().setLowValue(0).setHighValue(3).setDistinctValuesCount(4).setNullsFraction(0).build()).addSymbolStatistics(new Symbol("i3"), SymbolStatsEstimate.builder().setLowValue(10).setHighValue(15).setDistinctValuesCount(4).setNullsFraction(0.1).build()).build()).check(PlanNodeStatsAssertion::outputRowsCountUnknown);
    // can't estimate function, but default filter factor is turned on
    defaultFilterTester.assertStatsFor(pb -> pb.filter(unestimatableExpression, pb.values(pb.symbol("i1"), pb.symbol("i2"), pb.symbol("i3")))).withSourceStats(0, PlanNodeStatsEstimate.builder().setOutputRowCount(10).addSymbolStatistics(new Symbol("i1"), SymbolStatsEstimate.builder().setLowValue(1).setHighValue(10).setDistinctValuesCount(5).setNullsFraction(0).build()).addSymbolStatistics(new Symbol("i2"), SymbolStatsEstimate.builder().setLowValue(0).setHighValue(3).setDistinctValuesCount(4).setNullsFraction(0).build()).addSymbolStatistics(new Symbol("i3"), SymbolStatsEstimate.builder().setLowValue(10).setHighValue(15).setDistinctValuesCount(4).setNullsFraction(0.1).build()).build()).check(check -> check.outputRowsCount(9).symbolStats("i1", assertion -> assertion.lowValue(1).highValue(10).dataSizeUnknown().distinctValuesCount(5).nullsFraction(0)).symbolStats("i2", assertion -> assertion.lowValue(0).highValue(3).dataSizeUnknown().distinctValuesCount(4).nullsFraction(0)).symbolStats("i3", assertion -> assertion.lowValue(10).highValue(15).dataSizeUnknown().distinctValuesCount(4).nullsFraction(0.1)));
}
Also used : TestingFunctionResolution(io.trino.metadata.TestingFunctionResolution) Symbol(io.trino.sql.planner.Symbol) AfterClass(org.testng.annotations.AfterClass) BeforeClass(org.testng.annotations.BeforeClass) TestingFunctionResolution(io.trino.metadata.TestingFunctionResolution) Test(org.testng.annotations.Test) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) DoubleLiteral(io.trino.sql.tree.DoubleLiteral) QualifiedName(io.trino.sql.tree.QualifiedName) DOUBLE(io.trino.spi.type.DoubleType.DOUBLE) TestingSession.testSessionBuilder(io.trino.testing.TestingSession.testSessionBuilder) SymbolReference(io.trino.sql.tree.SymbolReference) Operator(io.trino.sql.tree.ComparisonExpression.Operator) PlanBuilder.expression(io.trino.sql.planner.iterative.rule.test.PlanBuilder.expression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) SymbolReference(io.trino.sql.tree.SymbolReference) Symbol(io.trino.sql.planner.Symbol) DoubleLiteral(io.trino.sql.tree.DoubleLiteral) Test(org.testng.annotations.Test)

Aggregations

ComparisonExpression (io.trino.sql.tree.ComparisonExpression)58 Test (org.testng.annotations.Test)30 ImmutableList (com.google.common.collect.ImmutableList)24 Expression (io.trino.sql.tree.Expression)23 Symbol (io.trino.sql.planner.Symbol)22 SymbolReference (io.trino.sql.tree.SymbolReference)21 ImmutableMap (com.google.common.collect.ImmutableMap)18 LongLiteral (io.trino.sql.tree.LongLiteral)17 BaseRuleTest (io.trino.sql.planner.iterative.rule.test.BaseRuleTest)15 FunctionCall (io.trino.sql.tree.FunctionCall)15 GenericLiteral (io.trino.sql.tree.GenericLiteral)15 QualifiedName (io.trino.sql.tree.QualifiedName)15 Optional (java.util.Optional)15 StringLiteral (io.trino.sql.tree.StringLiteral)14 PlanMatchPattern.values (io.trino.sql.planner.assertions.PlanMatchPattern.values)13 Type (io.trino.spi.type.Type)12 BIGINT (io.trino.spi.type.BigintType.BIGINT)11 FilterNode (io.trino.sql.planner.plan.FilterNode)11 ResolvedFunction (io.trino.metadata.ResolvedFunction)10 GREATER_THAN (io.trino.sql.tree.ComparisonExpression.Operator.GREATER_THAN)10