提交 6ae17fc2 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Use TreeMap in LocalResultImpl

上级 21ffff1a
......@@ -26,14 +26,13 @@ import org.h2.value.ValueNull;
/**
* Used for optimised IN(...) queries where the contents of the IN list are all
* constant and of the same type.
* <p>
* Checking using a HashSet is has time complexity O(1), instead of O(n) for
* checking using an array.
*/
public class ConditionInConstantSet extends Condition {
private Expression left;
private final ArrayList<Expression> valueList;
// HashSet cannot be used here, because we need to compare values of
// different type or scale properly.
private final TreeSet<Value> valueSet;
private boolean hasNull;
private final TypeInfo type;
......
......@@ -7,7 +7,7 @@ package org.h2.mvstore.db;
import java.io.IOException;
import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.Collection;
import org.h2.engine.Constants;
import org.h2.engine.Database;
......@@ -178,7 +178,7 @@ public abstract class MVTempResult implements ResultExternal {
}
@Override
public int addRows(ArrayList<Value[]> rows) {
public int addRows(Collection<Value[]> rows) {
for (Value[] row : rows) {
addRow(row);
}
......
......@@ -7,6 +7,7 @@ package org.h2.result;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeMap;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.engine.SessionInterface;
......@@ -14,7 +15,6 @@ import org.h2.expression.Expression;
import org.h2.message.DbException;
import org.h2.mvstore.db.MVTempResult;
import org.h2.util.Utils;
import org.h2.util.ValueHashMap;
import org.h2.value.TypeInfo;
import org.h2.value.Value;
import org.h2.value.ValueRow;
......@@ -34,7 +34,9 @@ public class LocalResultImpl implements LocalResult {
private int rowId, rowCount;
private ArrayList<Value[]> rows;
private SortOrder sort;
private ValueHashMap<Value[]> distinctRows;
// HashSet cannot be used here, because we need to compare values of
// different type or scale properly.
private TreeMap<Value, Value[]> distinctRows;
private Value[] currentRow;
private int offset;
private int limit = -1;
......@@ -145,7 +147,7 @@ public class LocalResultImpl implements LocalResult {
public void setDistinct() {
assert distinctIndexes == null;
distinct = true;
distinctRows = new ValueHashMap<>();
distinctRows = new TreeMap<>(session.getDatabase().getCompareMode());
}
/**
......@@ -157,7 +159,7 @@ public class LocalResultImpl implements LocalResult {
public void setDistinct(int[] distinctIndexes) {
assert !distinct;
this.distinctIndexes = distinctIndexes;
distinctRows = new ValueHashMap<>();
distinctRows = new TreeMap<>(session.getDatabase().getCompareMode());
}
/**
......@@ -200,7 +202,7 @@ public class LocalResultImpl implements LocalResult {
return external.contains(values);
}
if (distinctRows == null) {
distinctRows = new ValueHashMap<>();
distinctRows = new TreeMap<>(session.getDatabase().getCompareMode());
for (Value[] row : rows) {
ValueRow array = getDistinctRow(row);
distinctRows.put(array, array.getList());
......@@ -359,7 +361,7 @@ public class LocalResultImpl implements LocalResult {
addRowsToDisk();
} else {
if (isAnyDistinct()) {
rows = distinctRows.values();
rows = new ArrayList<>(distinctRows.values());
}
if (sort != null && limit != 0 && !limitsWereApplied) {
boolean withLimit = limit > 0 && withTiesSortOrder == null;
......
......@@ -5,7 +5,7 @@
*/
package org.h2.result;
import java.util.ArrayList;
import java.util.Collection;
import org.h2.value.Value;
/**
......@@ -40,7 +40,7 @@ public interface ResultExternal {
* @param rows the list of rows to add
* @return the new number of rows in this object
*/
int addRows(ArrayList<Value[]> rows);
int addRows(Collection<Value[]> rows);
/**
* Close this object and delete the temporary file.
......
......@@ -6,9 +6,9 @@
package org.h2.result;
import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import org.h2.command.ddl.CreateTableData;
import org.h2.engine.Constants;
......@@ -263,11 +263,7 @@ public class ResultTempTable implements ResultExternal {
}
@Override
public int addRows(ArrayList<Value[]> rows) {
// speeds up inserting, but not really needed:
if (sort != null) {
sort.sort(rows);
}
public int addRows(Collection<Value[]> rows) {
for (Value[] values : rows) {
addRow(values);
}
......
......@@ -8,3 +8,24 @@ CREATE TABLE TEST(I NUMERIC(-1));
CREATE TABLE TEST(I NUMERIC(-1, -1));
> exception INVALID_VALUE_2
CREATE TABLE TEST (N NUMERIC) AS VALUES (0), (0.0), (NULL);
> ok
SELECT * FROM TEST;
> N
> ----
> 0
> 0.0
> null
> rows: 3
SELECT DISTINCT * FROM TEST;
> N
> ----
> 0
> null
> rows: 2
DROP TABLE TEST;
> ok
......@@ -550,3 +550,62 @@ VALUES 1, 2;
> 1
> 2
> rows: 2
SELECT * FROM (VALUES (1::BIGINT, 2)) T (A, B) WHERE (A, B) IN (VALUES(1, 2));
> A B
> - -
> 1 2
> rows: 1
SELECT * FROM (VALUES (1000000000000, 2)) T (A, B) WHERE (A, B) IN (VALUES(1, 2));
> A B
> - -
> rows: 0
SELECT * FROM (VALUES (1, 2)) T (A, B) WHERE (A, B) IN (VALUES(1::BIGINT, 2));
> A B
> - -
> 1 2
> rows: 1
SELECT * FROM (VALUES (1, 2)) T (A, B) WHERE (A, B) IN (VALUES(1000000000000, 2));
> A B
> - -
> rows: 0
CREATE TABLE TEST(A BIGINT, B INT) AS VALUES (1::BIGINT, 2);
> ok
SELECT * FROM TEST WHERE (A, B) IN ((1, 2), (3, 4));
> A B
> - -
> 1 2
> rows: 1
UPDATE TEST SET A = 1000000000000;
> update count: 1
SELECT * FROM TEST WHERE (A, B) IN ((1, 2), (3, 4));
> A B
> - -
> rows: 0
DROP TABLE TEST;
> ok
CREATE TABLE TEST(A BIGINT, B INT) AS VALUES (1, 2);
> ok
SELECT * FROM TEST WHERE (A, B) IN ((1::BIGINT, 2), (3, 4));
> A B
> - -
> 1 2
> rows: 1
SELECT * FROM TEST WHERE (A, B) IN ((1000000000000, 2), (3, 4));
> A B
> - -
> rows: 0
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论