public static PredicateSplit splitPredicate(ScalarOperator predicate) {
        ScalarOperator normalPredicate = filterPredicate(predicate);
        if (normalPredicate == null) {
            return PredicateSplit.of(null, null, null);
        }

        PredicateExtractor extractor = new PredicateExtractor();
        RangePredicate rangePredicate =
                normalPredicate.accept(extractor, new PredicateExtractor.PredicateExtractorContext());
        ScalarOperator equalityConjunct = Utils.compoundAnd(extractor.getColumnEqualityPredicates());
        ScalarOperator rangeConjunct = null;
        ScalarOperator residualConjunct = Utils.compoundAnd(extractor.getResidualPredicates());
        if (rangePredicate != null) {
            // convert rangePredicate to rangeConjunct
            rangeConjunct = rangePredicate.toScalarOperator();
        } else if (extractor.getColumnEqualityPredicates().isEmpty() && extractor.getResidualPredicates().isEmpty()) {
            residualConjunct = Utils.compoundAnd(residualConjunct, normalPredicate);
        }
        return PredicateSplit.of(equalityConjunct, rangeConjunct, residualConjunct);
    }
@Test
    public void testSplitPredicate() {
        ScalarOperator predicate = null;
        PredicateSplit split = PredicateSplit.splitPredicate(predicate);
        Assert.assertNotNull(split);
        Assert.assertNull(split.getEqualPredicates());
        Assert.assertNull(split.getRangePredicates());
        Assert.assertNull(split.getResidualPredicates());

        ColumnRefFactory columnRefFactory = new ColumnRefFactory();
        ColumnRefOperator columnRef1 = columnRefFactory.create("col1", Type.INT, false);
        ColumnRefOperator columnRef2 = columnRefFactory.create("col2", Type.INT, false);
        BinaryPredicateOperator binaryPredicate = new BinaryPredicateOperator(
                BinaryType.EQ, columnRef1, columnRef2);
        BinaryPredicateOperator binaryPredicate2 = new BinaryPredicateOperator(
                BinaryType.GE, columnRef1, ConstantOperator.createInt(1));

        List<ScalarOperator> arguments = Lists.newArrayList();
        arguments.add(columnRef1);
        arguments.add(columnRef2);
        CallOperator callOperator = new CallOperator(FunctionSet.SUM, Type.INT, arguments);
        BinaryPredicateOperator binaryPredicate3 = new BinaryPredicateOperator(
                BinaryType.GE, callOperator, ConstantOperator.createInt(1));
        ScalarOperator andPredicate = Utils.compoundAnd(binaryPredicate, binaryPredicate2, binaryPredicate3);
        PredicateSplit result = PredicateSplit.splitPredicate(andPredicate);
        Assert.assertEquals(binaryPredicate, result.getEqualPredicates());
        Assert.assertEquals(binaryPredicate2, result.getRangePredicates());
        Assert.assertEquals(binaryPredicate3, result.getResidualPredicates());
    }