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操作,
查询结果:
这个StatementQuery实在复杂,再慢慢搞懂吧