提交 734243cd authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Fix DISTINCT ON with ORDER BY

上级 f5c5d3a1
......@@ -1825,7 +1825,7 @@ public class Select extends Query {
@Override
public boolean allowGlobalConditions() {
return offsetExpr == null && (limitExpr == null || sort == null);
return offsetExpr == null && (limitExpr == null && distinctExpressions == null || sort == null);
}
public SortOrder getSortOrder() {
......
......@@ -56,7 +56,12 @@ class MVSortedTempResult extends MVTempResult {
* {@link #contains(Value[])} method is invoked. Only the root result should
* have an index if required.
*/
private MVMap<ValueRow, Boolean> index;
private MVMap<ValueRow, Object> index;
/**
* Used for DISTINCT ON in presence of ORDER BY.
*/
private ValueDataType orderedDistinctOnType;
/**
* Cursor for the {@link #next()} method.
......@@ -172,7 +177,11 @@ class MVSortedTempResult extends MVTempResult {
if (distinct && length != visibleColumnCount || distinctIndexes != null) {
int count = distinctIndexes != null ? distinctIndexes.length : visibleColumnCount;
ValueDataType distinctType = new ValueDataType(database, new int[count]);
Builder<ValueRow, Boolean> indexBuilder = new MVMap.Builder<ValueRow, Boolean>().keyType(distinctType);
Builder<ValueRow, Object> indexBuilder = new MVMap.Builder<ValueRow, Object>().keyType(distinctType);
if (distinctIndexes != null && sort != null) {
indexBuilder.valueType(keyType);
orderedDistinctOnType = keyType;
}
index = store.openMap("idx", indexBuilder);
}
}
......@@ -189,8 +198,21 @@ class MVSortedTempResult extends MVTempResult {
newValues[i] = values[distinctIndexes[i]];
}
ValueRow distinctRow = ValueRow.get(newValues);
if (index.putIfAbsent(distinctRow, true) != null) {
return rowCount;
if (orderedDistinctOnType == null) {
if (index.putIfAbsent(distinctRow, true) != null) {
return rowCount;
}
} else {
ValueRow previous = (ValueRow) index.get(distinctRow);
if (previous == null) {
index.put(distinctRow, key);
} else if (orderedDistinctOnType.compare(previous, key) > 0) {
map.remove(previous);
rowCount--;
index.put(distinctRow, key);
} else {
return rowCount;
}
}
} else if (expressions.length != visibleColumnCount) {
ValueRow distinctRow = ValueRow.get(Arrays.copyOf(values, visibleColumnCount));
......
......@@ -316,7 +316,8 @@ public class LocalResultImpl implements LocalResult {
if (isAnyDistinct()) {
if (distinctRows != null) {
ValueRow array = getDistinctRow(values);
if (!distinctRows.containsKey(array)) {
Value[] previous = distinctRows.get(array);
if (previous == null || sort != null && sort.compare(previous, values) > 0) {
distinctRows.put(array, values);
}
rowCount = distinctRows.size();
......
......@@ -144,6 +144,42 @@ SELECT DISTINCT ON(C1) C2 FROM TEST ORDER BY C1;
> 4
> rows (ordered): 3
SELECT DISTINCT ON(C1) C1, C4, C5 FROM TEST ORDER BY C1, C5;
> C1 C4 C5
> -- -- --
> 1 4 5
> 2 8 9
> 3 1 1
> rows (ordered): 3
SELECT DISTINCT ON(C1) C1, C4, C5 FROM TEST ORDER BY C1, C5 DESC;
> C1 C4 C5
> -- -- --
> 1 6 7
> 2 8 9
> 3 1 1
> rows (ordered): 3
SELECT T1.C1, T2.C5 FROM TEST T1 JOIN (
SELECT DISTINCT ON(C1) C1, C4, C5 FROM TEST ORDER BY C1, C5
) T2 ON T1.C4 = T2.C4 ORDER BY T1.C1;
> C1 C5
> -- --
> 1 5
> 2 9
> 3 1
> rows (ordered): 3
SELECT T1.C1, T2.C5 FROM TEST T1 JOIN (
SELECT DISTINCT ON(C1) C1, C4, C5 FROM TEST ORDER BY C1, C5 DESC
) T2 ON T1.C4 = T2.C4 ORDER BY T1.C1;
> C1 C5
> -- --
> 1 7
> 2 9
> 3 1
> rows (ordered): 3
EXPLAIN SELECT DISTINCT ON(C1) C2 FROM TEST ORDER BY C1;
>> SELECT DISTINCT ON(C1) C2 FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */ ORDER BY =C1
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论