提交 acd95c24 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Convert results to distinct where needed in safe way

上级 edf9f2d7
......@@ -2535,7 +2535,7 @@ public class Parser {
}
currentSelect = temp;
if (readIf(DISTINCT)) {
command.setDistinct(true);
command.setDistinct();
} else {
readIf(ALL);
}
......
......@@ -255,13 +255,17 @@ public abstract class Query extends Prepared {
/**
* Set the distinct flag.
*
* @param b the new value
*/
public void setDistinct(boolean b) {
distinct = b;
public void setDistinct() {
distinct = true;
}
/**
* Set the distinct flag only if it is possible, may be used as a possible
* optimization only.
*/
public abstract void setDistinctIfPossible();
public boolean isDistinct() {
return distinct;
}
......
......@@ -247,6 +247,13 @@ public class Select extends Query {
return orderList != null || sort != null;
}
@Override
public void setDistinctIfPossible() {
if (!distinct && offsetExpr == null && limitExpr == null) {
setDistinct();
}
}
/**
* Add a condition to the list of conditions.
*
......@@ -667,9 +674,6 @@ public class Select extends Query {
result = createLocalResult(result);
result.setDistinct();
}
if (randomAccessResult) {
result = createLocalResult(result);
}
if (isGroupQuery && !isGroupSortedQuery) {
result = createLocalResult(result);
}
......@@ -724,8 +728,12 @@ public class Select extends Query {
if (limitRows > 0) {
lazyResult.setLimit(limitRows);
}
if (randomAccessResult) {
return convertToDistinct(lazyResult);
} else {
return lazyResult;
}
}
if (offsetExpr != null) {
result.setOffset(offsetExpr.getValue(session).getInt());
}
......@@ -734,6 +742,9 @@ public class Select extends Query {
}
if (result != null) {
result.done();
if (randomAccessResult && !distinct) {
result = convertToDistinct(result);
}
if (target != null) {
while (result.next()) {
target.addRow(result.currentRow());
......@@ -761,6 +772,18 @@ public class Select extends Query {
visibleColumnCount);
}
private LocalResult convertToDistinct(ResultInterface result) {
LocalResult distinctResult = new LocalResult(session, expressionArray, visibleColumnCount);
distinctResult.setDistinct();
result.reset();
while (result.next()) {
distinctResult.addRow(result.currentRow());
}
result.close();
distinctResult.done();
return distinctResult;
}
private void expandColumnList() {
Database db = session.getDatabase();
......
......@@ -125,6 +125,11 @@ public class SelectUnion extends Query {
return orderList != null || sort != null;
}
@Override
public void setDistinctIfPossible() {
setDistinct();
}
private Value[] convert(Value[] values, int columnCount) {
Value[] newValues;
if (columnCount == values.length) {
......@@ -210,8 +215,8 @@ public class SelectUnion extends Query {
result.setSortOrder(sort);
}
if (distinct) {
left.setDistinct(true);
right.setDistinct(true);
left.setDistinctIfPossible();
right.setDistinctIfPossible();
result.setDistinct();
}
if (randomAccessResult) {
......@@ -220,15 +225,15 @@ public class SelectUnion extends Query {
switch (unionType) {
case UNION:
case EXCEPT:
left.setDistinct(true);
right.setDistinct(true);
left.setDistinctIfPossible();
right.setDistinctIfPossible();
result.setDistinct();
break;
case UNION_ALL:
break;
case INTERSECT:
left.setDistinct(true);
right.setDistinct(true);
left.setDistinctIfPossible();
right.setDistinctIfPossible();
break;
default:
DbException.throwInternalError("type=" + unionType);
......
......@@ -43,9 +43,7 @@ public class ConditionInSelect extends Condition {
@Override
public Value getValue(Session session) {
query.setSession(session);
if (!query.hasOrder()) {
query.setDistinct(true);
}
query.setDistinctIfPossible();
ResultInterface rows = query.query(0);
Value l = left.getValue(session);
if (!rows.hasNext()) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论