读书人

hsqldb源码分析系列四 查询引擎之查询

发布时间: 2013-01-23 10:44:49 作者: rapoo

hsqldb源码分析系列4 查询引擎之查询操作

查询过程前面解析类似insert,最终调用是在下面这个QuerySpecification类的getSingleResult方法,RangeVariable是查询条件相关

  private Result getSingleResult(Session session, int maxRows) {        int[] limits = sortAndSlice.getLimits(session, this, maxRows);        Result              r         = buildResult(session, limits);        RowSetNavigatorData navigator = (RowSetNavigatorData) r.getNavigator();        if (isDistinctSelect) {            navigator.removeDuplicates(session);        }        if (sortAndSlice.hasOrder()) {            navigator.sortOrder(session);        }        if (limits != SortAndSlice.defaultLimits                && !sortAndSlice.skipFullResult) {            navigator.trim(limits[0], limits[1]);        }        return r;    }    private Result buildResult(Session session, int[] limits) {        RowSetNavigatorData navigator = new RowSetNavigatorData(session,            (QuerySpecification) this);        Result result = Result.newResult(navigator);        result.metaData = resultMetaData;        if (isUpdatable) {            result.rsProperties = ResultProperties.updatablePropsValue;        }        int skipCount  = 0;        int limitCount = limits[2];        if (sortAndSlice.skipFullResult) {            skipCount  = limits[0];            limitCount = limits[1];        }        if (this.isSimpleCount) {            Object[] data  = new Object[indexLimitData];            Table    table = rangeVariables[0].getTable();            table.materialise(session);            PersistentStore store = table.getRowStore(session);            long            count = store.elementCount(session);            data[0] = data[indexStartAggregates] = ValuePool.getLong(count);            navigator.add(data);            return result;        }        int fullJoinIndex = 0;        RangeIterator[] rangeIterators =            new RangeIterator[rangeVariables.length];        for (int i = 0; i < rangeVariables.length; i++) {            rangeIterators[i] = rangeVariables[i].getIterator(session);        }        session.sessionContext.rownum = 1;        for (int currentIndex = 0; ; ) {            if (currentIndex < fullJoinIndex) {                // finished current span                // or finished outer rows on right navigator                boolean end = true;                for (int i = fullJoinIndex + 1; i < rangeVariables.length;                        i++) {                    if (rangeVariables[i].isRightJoin) {                        fullJoinIndex = i;                        currentIndex  = i;                        end           = false;                        ((RangeIteratorRight) rangeIterators[i])                            .setOnOuterRows();                        break;                    }                }                if (end) {                    break;                }            }            RangeIterator it = rangeIterators[currentIndex];            if (it.next()) {                if (currentIndex < rangeVariables.length - 1) {                    currentIndex++;                    continue;                }            } else {                it.reset();                currentIndex--;                continue;            }            if (limitCount == 0) {                break;            }            session.sessionData.startRowProcessing();            Object[] data = new Object[indexLimitData];            for (int i = 0; i < indexStartAggregates; i++) {                if (isAggregated && aggregateCheck[i]) {                    continue;                } else {                    data[i] = exprColumns[i].getValue(session);                }            }            for (int i = indexLimitVisible; i < indexLimitRowId; i++) {                if (i == indexLimitVisible) {                    data[i] = it.getRowidObject();                } else {                    data[i] = it.getCurrentRow();                }            }            session.sessionContext.rownum++;            if (skipCount > 0) {                skipCount--;                continue;            }            Object[] groupData = null;            if (isAggregated || isGrouped) {                groupData = navigator.getGroupData(data);                if (groupData != null) {                    data = groupData;                }            }            for (int i = indexStartAggregates; i < indexLimitExpressions;                    i++) {                data[i] = exprColumns[i].updateAggregatingValue(session,                        data[i]);            }            if (groupData == null) {                navigator.add(data);            } else if (isAggregated) {                navigator.update(groupData, data);            }            int rowCount = navigator.getSize();            if (rowCount == session.resultMaxMemoryRows && !isAggregated                    && !isSingleMemoryTable) {                navigator = new RowSetNavigatorDataTable(session, this,                        navigator);                result.setNavigator(navigator);            }            if (isAggregated || isGrouped) {                if (!sortAndSlice.isGenerated) {                    continue;                }            }            if (rowCount >= limitCount) {                break;            }        }        navigator.reset();        for (int i = 0; i < rangeVariables.length; i++) {            rangeIterators[i].reset();        }        if (!isGrouped && !isAggregated) {            return result;        }        if (isAggregated) {            if (!isGrouped && navigator.getSize() == 0) {                Object[] data = new Object[exprColumns.length];                for (int i = 0; i < indexStartAggregates; i++) {                    if (!aggregateCheck[i]) {                        data[i] = exprColumns[i].getValue(session);                    }                }                navigator.add(data);            }            navigator.reset();            session.sessionContext.setRangeIterator(navigator);            while (navigator.next()) {                Object[] data = navigator.getCurrent();                for (int i = indexStartAggregates; i < indexLimitExpressions;                        i++) {                    data[i] = exprColumns[i].getAggregatedValue(session,                            data[i]);                }                for (int i = 0; i < indexStartAggregates; i++) {                    if (aggregateCheck[i]) {                        data[i] = exprColumns[i].getValue(session);                    }                }            }            session.sessionContext.unsetRangeIterator(navigator);        }        navigator.reset();        if (havingCondition != null) {            while (navigator.hasNext()) {                Object[] data = (Object[]) navigator.getNext();                if (!Boolean.TRUE.equals(                        data[indexLimitVisible + groupByColumnCount])) {                    navigator.remove();                }            }            navigator.reset();        }        return result;    }

比如一个like操作,


hsqldb源码分析系列四 查询引擎之查询操作


hsqldb源码分析系列四 查询引擎之查询操作

查询结果:


hsqldb源码分析系列四 查询引擎之查询操作

这个StatementQuery实在复杂,再慢慢搞懂吧


hsqldb源码分析系列四 查询引擎之查询操作

读书人网 >其他数据库

热点推荐