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

Fix DISTINCT ON with ORDER BY

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