public Range canonicalize(boolean removeSafeConstants)
    {
        if (!removeSafeConstants) {
            return this;
        }

        boolean removeConstants = low.getBound().equals(Marker.Bound.EXACTLY) && high.getBound().equals(Marker.Bound.EXACTLY);
        Marker newLow = low.canonicalize(removeConstants);
        Marker newHigh = high.canonicalize(removeConstants);
        if (low == newLow && high == newHigh) {
            return this;
        }
        // After removing constants, newLow and newHigh cannot be compared, and will fail the
        // low <= high check. So we skip this check.
        return new Range(newLow, newHigh, () -> {});
    }
@Test
    public void testCanonicalize()
            throws Exception
    {
        assertSameRange(Range.greaterThan(BIGINT, 0L), Range.greaterThan(BIGINT, 0L), false);
        assertSameRange(Range.equal(BIGINT, 0L), Range.equal(BIGINT, 0L), false);
        assertSameRange(Range.lessThanOrEqual(BIGINT, 0L), Range.lessThanOrEqual(BIGINT, 0L), false);
        assertSameRange(Range.range(BIGINT, 0L, false, 2L, false), Range.range(BIGINT, 0L, false, 2L, false), false);
        assertSameRange(Range.all(VARCHAR), Range.all(VARCHAR), false);

        assertDifferentRange(Range.greaterThan(BIGINT, 0L), Range.greaterThan(BIGINT, 3L), false);
        assertDifferentRange(Range.equal(BIGINT, 0L), Range.equal(BIGINT, 1L), false);
        assertDifferentRange(Range.lessThanOrEqual(BIGINT, 0L), Range.lessThanOrEqual(BIGINT, 6L), false);
        assertDifferentRange(Range.range(BIGINT, 0L, false, 2L, false), Range.range(BIGINT, 0L, false, 3L, false), false);
        assertDifferentRange(Range.all(VARCHAR), Range.all(BIGINT), false);

        assertDifferentRange(Range.greaterThan(BIGINT, 0L), Range.lessThan(BIGINT, 0L), false);
        assertDifferentRange(Range.equal(BIGINT, 0L), Range.equal(BIGINT, 1L), false);
        assertDifferentRange(Range.greaterThanOrEqual(BIGINT, 0L), Range.greaterThan(BIGINT, 0L), false);
        assertDifferentRange(Range.range(BIGINT, 0L, false, 2L, false), Range.range(BIGINT, 0L, true, 2L, false), false);
        assertDifferentRange(Range.all(VARCHAR), Range.all(BIGINT), false);

        assertSameRange(Range.equal(BIGINT, 10L), Range.equal(BIGINT, 3L), true);
        assertSameRange(Range.range(BIGINT, 0L, true, 0L, true), Range.range(BIGINT, 1L, true, 1L, true), true);

        assertDifferentRange(Range.greaterThan(BIGINT, 0L), Range.greaterThan(BIGINT, 1L), true);
        assertDifferentRange(Range.greaterThanOrEqual(BIGINT, 0L), Range.greaterThanOrEqual(BIGINT, 1L), true);
        assertDifferentRange(Range.range(BIGINT, 0L, false, 2L, false), Range.range(BIGINT, 0L, false, 3L, false), true);

        assertDifferentRange(Range.greaterThan(BIGINT, 0L), Range.lessThan(BIGINT, 0L), true);
        assertDifferentRange(Range.greaterThanOrEqual(BIGINT, 0L), Range.greaterThan(BIGINT, 0L), true);
        assertDifferentRange(Range.range(BIGINT, 0L, false, 2L, false), Range.range(BIGINT, 0L, false, 2L, true), true);
        assertDifferentRange(Range.all(VARCHAR), Range.all(BIGINT), true);
    }