public ScalarOperator rewrite(ScalarOperator root, List<ScalarOperatorRewriteRule> ruleList) {
        ScalarOperator result = root;

        context.reset();
        int changeNums;
        do {
            changeNums = context.changeNum();
            for (ScalarOperatorRewriteRule rule : ruleList) {
                result = rewriteByRule(result, rule);
            }

            if (changeNums > Config.max_planner_scalar_rewrite_num) {
                throw new StarRocksPlannerException("Planner rewrite scalar operator over limit",
                        ErrorType.INTERNAL_ERROR);
            }
        } while (changeNums != context.changeNum());

        return result;
    }
@Test
    public void testRewrite() {
        ScalarOperator root = new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.OR,
                new BetweenPredicateOperator(false, new ColumnRefOperator(3, Type.INT, "test3", true),
                        new ColumnRefOperator(4, Type.INT, "test4", true),
                        new ColumnRefOperator(5, Type.INT, "test5", true)),
                new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.AND,
                        new BinaryPredicateOperator(BinaryType.EQ,
                                ConstantOperator.createInt(1),
                                new ColumnRefOperator(1, Type.INT, "test1", true)),
                        new BinaryPredicateOperator(BinaryType.EQ,
                                ConstantOperator.createInt(1),
                                new ColumnRefOperator(2, Type.INT, "test2", true))
                ));

        ScalarOperatorRewriter operatorRewriter = new ScalarOperatorRewriter();
        ScalarOperator result = operatorRewriter
                .rewrite(root, Lists.newArrayList(new NormalizePredicateRule(), new SimplifiedPredicateRule()));

        assertEquals(root, result);
        assertEquals(OperatorType.COMPOUND, result.getChild(0).getOpType());
        assertTrue(result.getChild(0) instanceof CompoundPredicateOperator);
        assertEquals(CompoundPredicateOperator.CompoundType.AND,
                ((CompoundPredicateOperator) result.getChild(0)).getCompoundType());

        assertEquals(OperatorType.BINARY, result.getChild(0).getChild(0).getOpType());
        assertEquals(OperatorType.BINARY, result.getChild(0).getChild(1).getOpType());

        assertEquals(OperatorType.COMPOUND, result.getChild(1).getOpType());
        assertEquals(OperatorType.BINARY, result.getChild(1).getChild(0).getOpType());
        assertEquals(OperatorType.VARIABLE, result.getChild(1).getChild(0).getChild(0).getOpType());
        assertEquals(OperatorType.CONSTANT, result.getChild(1).getChild(0).getChild(1).getOpType());

        assertEquals(OperatorType.BINARY, result.getChild(1).getChild(1).getOpType());
        assertEquals(OperatorType.VARIABLE, result.getChild(1).getChild(1).getChild(0).getOpType());
        assertEquals(OperatorType.CONSTANT, result.getChild(1).getChild(1).getChild(1).getOpType());
    }