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 testRewrite2() {
        ScalarOperator root = new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.OR,
                new BinaryPredicateOperator(BinaryType.EQ,
                        ConstantOperator.createInt(1),
                        new ColumnRefOperator(0, Type.VARCHAR, "test0", true)),
                new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.AND,
                        new BinaryPredicateOperator(BinaryType.EQ,
                                ConstantOperator.createInt(1),
                                new ColumnRefOperator(1, Type.BIGINT, "test1", true)),
                        new CastOperator(Type.BOOLEAN, ConstantOperator.createNull(Type.BIGINT))));

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

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

        assertEquals(Type.VARCHAR.getPrimitiveType(), result.getChild(0).getChild(0).getType().getPrimitiveType());
        assertEquals(Type.VARCHAR.getPrimitiveType(), result.getChild(0).getChild(1).getType().getPrimitiveType());

        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.CALL, result.getChild(1).getChild(1).getOpType());
        assertEquals(Type.BOOLEAN, result.getChild(1).getChild(1).getType());
    }