提交 f6f3a3d8 authored 作者: Noel Grandin's avatar Noel Grandin

address review comments

上级 c3deabaa
...@@ -187,9 +187,7 @@ public class Select extends Query { ...@@ -187,9 +187,7 @@ public class Select extends Query {
public void setCurrentGroupExprData(Expression expr, Object obj) { public void setCurrentGroupExprData(Expression expr, Object obj) {
Integer index = exprToIndexInGroupByData.get(expr); Integer index = exprToIndexInGroupByData.get(expr);
if (index != null) { if (index != null) {
if (currentGroupByExprData[index] != null) { assert currentGroupByExprData[index] != null;
throw DbException.throwInternalError();
}
currentGroupByExprData[index] = obj; currentGroupByExprData[index] = obj;
return; return;
} }
...@@ -368,73 +366,77 @@ public class Select extends Query { ...@@ -368,73 +366,77 @@ public class Select extends Query {
currentGroupByExprData = null; currentGroupByExprData = null;
currentGroupsKey = null; currentGroupsKey = null;
exprToIndexInGroupByData.clear(); exprToIndexInGroupByData.clear();
int rowNumber = 0; try {
setCurrentRowNumber(0); int rowNumber = 0;
ValueArray defaultGroup = ValueArray.get(new Value[0]); setCurrentRowNumber(0);
int sampleSize = getSampleSizeValue(session); ValueArray defaultGroup = ValueArray.get(new Value[0]);
while (topTableFilter.next()) { int sampleSize = getSampleSizeValue(session);
setCurrentRowNumber(rowNumber + 1); while (topTableFilter.next()) {
if (isConditionMet()) { setCurrentRowNumber(rowNumber + 1);
rowNumber++; if (isConditionMet()) {
if (groupIndex == null) { rowNumber++;
currentGroupsKey = defaultGroup; if (groupIndex == null) {
} else { currentGroupsKey = defaultGroup;
Value[] keyValues = new Value[groupIndex.length]; } else {
// update group Value[] keyValues = new Value[groupIndex.length];
for (int i = 0; i < groupIndex.length; i++) { // update group
int idx = groupIndex[i]; for (int i = 0; i < groupIndex.length; i++) {
Expression expr = expressions.get(idx); int idx = groupIndex[i];
keyValues[i] = expr.getValue(session); Expression expr = expressions.get(idx);
keyValues[i] = expr.getValue(session);
}
currentGroupsKey = ValueArray.get(keyValues);
}
Object[] values = groupByData.get(currentGroupsKey);
if (values == null) {
values = new Object[Math.max(exprToIndexInGroupByData.size(), expressions.size())];
groupByData.put(currentGroupsKey, values);
}
currentGroupByExprData = values;
currentGroupRowId++;
for (int i = 0; i < columnCount; i++) {
if (groupByExpression == null || !groupByExpression[i]) {
Expression expr = expressions.get(i);
expr.updateAggregate(session);
}
}
if (sampleSize > 0 && rowNumber >= sampleSize) {
break;
} }
currentGroupsKey = ValueArray.get(keyValues);
} }
Object[] values = groupByData.get(currentGroupsKey); }
if (values == null) { if (groupIndex == null && groupByData.size() == 0) {
values = new Object[Math.max(exprToIndexInGroupByData.size(), expressions.size())]; groupByData.put(defaultGroup,
groupByData.put(currentGroupsKey, values); new Object[Math.max(exprToIndexInGroupByData.size(), expressions.size())]);
}
ArrayList<Value> keys = groupByData.keys();
for (Value v : keys) {
currentGroupsKey = (ValueArray) v;
currentGroupByExprData = groupByData.get(currentGroupsKey);
Value[] keyValues = currentGroupsKey.getList();
Value[] row = new Value[columnCount];
for (int j = 0; groupIndex != null && j < groupIndex.length; j++) {
row[groupIndex[j]] = keyValues[j];
} }
currentGroupByExprData = values; for (int j = 0; j < columnCount; j++) {
currentGroupRowId++; if (groupByExpression != null && groupByExpression[j]) {
for (int i = 0; i < columnCount; i++) { continue;
if (groupByExpression == null || !groupByExpression[i]) {
Expression expr = expressions.get(i);
expr.updateAggregate(session);
} }
Expression expr = expressions.get(j);
row[j] = expr.getValue(session);
} }
if (sampleSize > 0 && rowNumber >= sampleSize) { if (isHavingNullOrFalse(row)) {
break;
}
}
}
if (groupIndex == null && groupByData.size() == 0) {
groupByData.put(defaultGroup, new Object[Math.max(exprToIndexInGroupByData.size(), expressions.size())]);
}
ArrayList<Value> keys = groupByData.keys();
for (Value v : keys) {
currentGroupsKey = (ValueArray) v;
currentGroupByExprData = groupByData.get(currentGroupsKey);
Value[] keyValues = currentGroupsKey.getList();
Value[] row = new Value[columnCount];
for (int j = 0; groupIndex != null && j < groupIndex.length; j++) {
row[groupIndex[j]] = keyValues[j];
}
for (int j = 0; j < columnCount; j++) {
if (groupByExpression != null && groupByExpression[j]) {
continue; continue;
} }
Expression expr = expressions.get(j); row = keepOnlyDistinct(row, columnCount);
row[j] = expr.getValue(session); result.addRow(row);
} }
if (isHavingNullOrFalse(row)) { } finally {
continue; groupByData = null;
} currentGroupsKey = null;
row = keepOnlyDistinct(row, columnCount); currentGroupByExprData = null;
result.addRow(row); exprToIndexInGroupByData.clear();
} }
groupByData = null;
currentGroupsKey = null;
currentGroupByExprData = null;
exprToIndexInGroupByData.clear();
} }
/** /**
......
...@@ -19,14 +19,13 @@ import org.h2.value.ValueNull; ...@@ -19,14 +19,13 @@ import org.h2.value.ValueNull;
* <p> * <p>
* HashMap in archaic versions of Java have some overhead for allocation of * HashMap in archaic versions of Java have some overhead for allocation of
* entries, but slightly better behaviour with limited number of collisions, * entries, but slightly better behaviour with limited number of collisions,
* because collisions have no impact on non-colliding entires. HashMap in modern * because collisions have no impact on non-colliding entries. HashMap in modern
* versions of Java also have the same overhead, but it builds a trees of keys * versions of Java also have the same overhead, but it builds a trees of keys
* with colliding hashes, that's why even if the all keys have exactly the same * with colliding hashes, that's why even if the all keys have exactly the same
* hash code it still offers a good performance similar to TreeMap. So * hash code it still offers a good performance similar to TreeMap. So
* ValueHashMap is faster in typical cases, but may behave really bad in some * ValueHashMap is faster in typical cases, but may behave really bad in some
* cases. HashMap is slower in typical cases, but its performance does not * cases. HashMap is slower in typical cases, but its performance does not
* degrade too much even in the worst possible case (if keys are comparable, * degrade too much even in the worst possible case (if keys are comparable).
* like our Value class).
* *
* @param <V> the value type * @param <V> the value type
*/ */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论