public ProcResult fetchResultByFilter(HashMap<String, Expr> filter, ArrayList<OrderByPair> orderByPairs,
                                          LimitElement limitElement) throws AnalysisException {
        Preconditions.checkNotNull(db);
        Preconditions.checkNotNull(schemaChangeHandler);

        List<List<Comparable>> schemaChangeJobInfos = getOptimizeJobInfos();

        //where
        List<List<Comparable>> jobInfos;
        if (filter == null || filter.size() == 0) {
            jobInfos = schemaChangeJobInfos;
        } else {
            jobInfos = Lists.newArrayList();
            for (List<Comparable> infoStr : schemaChangeJobInfos) {
                if (infoStr.size() != TITLE_NAMES.size()) {
                    LOG.warn("SchemaChangeJobInfos.size() " + schemaChangeJobInfos.size()
                            + " not equal TITLE_NAMES.size() " + TITLE_NAMES.size());
                    continue;
                }
                boolean isNeed = true;
                for (int i = 0; i < infoStr.size(); i++) {
                    isNeed = filterResult(TITLE_NAMES.get(i), infoStr.get(i), filter);
                    if (!isNeed) {
                        break;
                    }
                }
                if (isNeed) {
                    jobInfos.add(infoStr);
                }
            }
        }

        // order by
        if (orderByPairs != null) {
            ListComparator<List<Comparable>> comparator = null;
            OrderByPair[] orderByPairArr = new OrderByPair[orderByPairs.size()];
            comparator = new ListComparator<List<Comparable>>(orderByPairs.toArray(orderByPairArr));
            Collections.sort(jobInfos, comparator);
        }

        //limit
        if (limitElement != null && limitElement.hasLimit()) {
            int beginIndex = (int) limitElement.getOffset();
            int endIndex = (int) (beginIndex + limitElement.getLimit());
            if (endIndex > jobInfos.size()) {
                endIndex = jobInfos.size();
            }
            jobInfos = jobInfos.subList(beginIndex, endIndex);
        }

        BaseProcResult result = new BaseProcResult();
        result.setNames(TITLE_NAMES);
        for (List<Comparable> jobInfo : jobInfos) {
            List<String> oneResult = new ArrayList<String>(jobInfos.size());
            for (Comparable column : jobInfo) {
                oneResult.add(column.toString());
            }
            result.addRow(oneResult);
        }
        return result;
    }
@Test
    public void testFetchResultByFilterNull() throws AnalysisException {
        BaseProcResult result = (BaseProcResult) optimizeProcDir.fetchResultByFilter(null, null, null);
        List<List<String>> rows = result.getRows();
        List<String> list1 = rows.get(0);
        Assert.assertEquals(list1.size(), OptimizeProcDir.TITLE_NAMES.size());
        // JobId
        Assert.assertEquals("1", list1.get(0));
        // TableName
        Assert.assertEquals("tb1", list1.get(1));
        // CreateTime
        Assert.assertEquals("2020-01-01", list1.get(2));
        // FinishTime
        Assert.assertEquals("2020-01-01", list1.get(3));
        // Operation
        Assert.assertEquals("ALTER", list1.get(4));
        // TransactionId
        Assert.assertEquals("0", list1.get(5));
        // State
        Assert.assertEquals("FINISHED", list1.get(6));
        // Msg
        Assert.assertEquals("", list1.get(7));
        // Progress
        Assert.assertEquals("100", list1.get(8));
        // Timeout
        Assert.assertEquals("10000", list1.get(9));

        List<String> list2 = rows.get(1);
        Assert.assertEquals(list2.size(), OptimizeProcDir.TITLE_NAMES.size());
        // JobId
        Assert.assertEquals("1", list2.get(0));
        // TableName
        Assert.assertEquals("tb1", list2.get(1));
        // CreateTime
        Assert.assertEquals("2020-01-01", list2.get(2));
        // FinishTime
        Assert.assertEquals("2020-01-01", list2.get(3));
        // Operation
        Assert.assertEquals("ALTER", list2.get(4));
        // TransactionId
        Assert.assertEquals("0", list2.get(5));
        // State
        Assert.assertEquals("FINISHED", list2.get(6));
        // Msg
        Assert.assertEquals("", list2.get(7));
        // Progress
        Assert.assertEquals("100", list2.get(8));
        // Timeout
        Assert.assertEquals("10000", list2.get(9));

    }