throws Exception
{
Expression originalPredicate = or(
and(greaterThan(A, longLiteral(1L)), unprocessableExpression1(A)),
and(lessThan(A, longLiteral(5L)), unprocessableExpression2(A)));
ExtractionResult result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), originalPredicate);
Assert.assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(ACH, Domain.notNull(Long.class))));
originalPredicate = or(
and(equal(A, longLiteral(1L)), unprocessableExpression1(A)),
and(equal(A, longLiteral(2L)), unprocessableExpression2(A)));
result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), originalPredicate);
Assert.assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(ACH, Domain.create(SortedRangeSet.of(Range.equal(1L), Range.equal(2L)), false))));
// Same unprocessableExpression means that we can do more extraction
// If both sides are operating on the same single symbol
originalPredicate = or(
and(equal(A, longLiteral(1L)), unprocessableExpression1(A)),
and(equal(A, longLiteral(2L)), unprocessableExpression1(A)));
result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), unprocessableExpression1(A));
Assert.assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(ACH, Domain.create(SortedRangeSet.of(Range.equal(1L), Range.equal(2L)), false))));
// And not if they have different symbols
originalPredicate = or(
and(equal(A, longLiteral(1L)), unprocessableExpression1(A)),
and(equal(B, doubleLiteral(2.0)), unprocessableExpression1(A)));
result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), originalPredicate);
Assert.assertTrue(result.getTupleDomain().isAll());
// We can make another optimization if one side is the super set of the other side
originalPredicate = or(
and(greaterThan(A, longLiteral(1L)), greaterThan(B, doubleLiteral(1.0)), unprocessableExpression1(A)),
and(greaterThan(A, longLiteral(2L)), greaterThan(B, doubleLiteral(2.0)), unprocessableExpression1(A)));
result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), unprocessableExpression1(A));
Assert.assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(
ACH, Domain.create(SortedRangeSet.of(Range.greaterThan(1L)), false),
BCH, Domain.create(SortedRangeSet.of(Range.greaterThan(1.0)), false))));
// We can't make those inferences if the unprocessableExpressions are non-deterministic
originalPredicate = or(
and(equal(A, longLiteral(1L)), randPredicate(A)),
and(equal(A, longLiteral(2L)), randPredicate(A)));
result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), originalPredicate);
Assert.assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(ACH, Domain.create(SortedRangeSet.of(Range.equal(1L), Range.equal(2L)), false))));
// Test complements
originalPredicate = not(or(
and(greaterThan(A, longLiteral(1L)), unprocessableExpression1(A)),
and(lessThan(A, longLiteral(5L)), unprocessableExpression2(A))));
result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), and(
not(and(greaterThan(A, longLiteral(1L)), unprocessableExpression1(A))),
not(and(lessThan(A, longLiteral(5L)), unprocessableExpression2(A)))));
Assert.assertTrue(result.getTupleDomain().isAll());
originalPredicate = not(or(
not(and(greaterThan(A, longLiteral(1L)), unprocessableExpression1(A))),
not(and(lessThan(A, longLiteral(5L)), unprocessableExpression2(A)))));
result = fromPredicate(MANAGER, SESSION, originalPredicate, TYPES, COLUMN_HANDLES);
Assert.assertEquals(result.getRemainingExpression(), and(unprocessableExpression1(A), unprocessableExpression2(A)));
Assert.assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(ACH, Domain.create(SortedRangeSet.of(Range.range(1L, false, 5L, false)), false))));
}