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

Use TreeMap in LocalResultImpl

上级 21ffff1a
...@@ -26,14 +26,13 @@ import org.h2.value.ValueNull; ...@@ -26,14 +26,13 @@ import org.h2.value.ValueNull;
/** /**
* Used for optimised IN(...) queries where the contents of the IN list are all * Used for optimised IN(...) queries where the contents of the IN list are all
* constant and of the same type. * 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 { public class ConditionInConstantSet extends Condition {
private Expression left; private Expression left;
private final ArrayList<Expression> valueList; 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 final TreeSet<Value> valueSet;
private boolean hasNull; private boolean hasNull;
private final TypeInfo type; private final TypeInfo type;
......
...@@ -7,7 +7,7 @@ package org.h2.mvstore.db; ...@@ -7,7 +7,7 @@ package org.h2.mvstore.db;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.util.ArrayList; import java.util.Collection;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
...@@ -178,7 +178,7 @@ public abstract class MVTempResult implements ResultExternal { ...@@ -178,7 +178,7 @@ public abstract class MVTempResult implements ResultExternal {
} }
@Override @Override
public int addRows(ArrayList<Value[]> rows) { public int addRows(Collection<Value[]> rows) {
for (Value[] row : rows) { for (Value[] row : rows) {
addRow(row); addRow(row);
} }
......
...@@ -7,6 +7,7 @@ package org.h2.result; ...@@ -7,6 +7,7 @@ package org.h2.result;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.TreeMap;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.SessionInterface; import org.h2.engine.SessionInterface;
...@@ -14,7 +15,6 @@ import org.h2.expression.Expression; ...@@ -14,7 +15,6 @@ import org.h2.expression.Expression;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.db.MVTempResult; import org.h2.mvstore.db.MVTempResult;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.util.ValueHashMap;
import org.h2.value.TypeInfo; import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueRow; import org.h2.value.ValueRow;
...@@ -34,7 +34,9 @@ public class LocalResultImpl implements LocalResult { ...@@ -34,7 +34,9 @@ public class LocalResultImpl implements LocalResult {
private int rowId, rowCount; private int rowId, rowCount;
private ArrayList<Value[]> rows; private ArrayList<Value[]> rows;
private SortOrder sort; 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 Value[] currentRow;
private int offset; private int offset;
private int limit = -1; private int limit = -1;
...@@ -145,7 +147,7 @@ public class LocalResultImpl implements LocalResult { ...@@ -145,7 +147,7 @@ public class LocalResultImpl implements LocalResult {
public void setDistinct() { public void setDistinct() {
assert distinctIndexes == null; assert distinctIndexes == null;
distinct = true; distinct = true;
distinctRows = new ValueHashMap<>(); distinctRows = new TreeMap<>(session.getDatabase().getCompareMode());
} }
/** /**
...@@ -157,7 +159,7 @@ public class LocalResultImpl implements LocalResult { ...@@ -157,7 +159,7 @@ public class LocalResultImpl implements LocalResult {
public void setDistinct(int[] distinctIndexes) { public void setDistinct(int[] distinctIndexes) {
assert !distinct; assert !distinct;
this.distinctIndexes = distinctIndexes; this.distinctIndexes = distinctIndexes;
distinctRows = new ValueHashMap<>(); distinctRows = new TreeMap<>(session.getDatabase().getCompareMode());
} }
/** /**
...@@ -200,7 +202,7 @@ public class LocalResultImpl implements LocalResult { ...@@ -200,7 +202,7 @@ public class LocalResultImpl implements LocalResult {
return external.contains(values); return external.contains(values);
} }
if (distinctRows == null) { if (distinctRows == null) {
distinctRows = new ValueHashMap<>(); distinctRows = new TreeMap<>(session.getDatabase().getCompareMode());
for (Value[] row : rows) { for (Value[] row : rows) {
ValueRow array = getDistinctRow(row); ValueRow array = getDistinctRow(row);
distinctRows.put(array, array.getList()); distinctRows.put(array, array.getList());
...@@ -359,7 +361,7 @@ public class LocalResultImpl implements LocalResult { ...@@ -359,7 +361,7 @@ public class LocalResultImpl implements LocalResult {
addRowsToDisk(); addRowsToDisk();
} else { } else {
if (isAnyDistinct()) { if (isAnyDistinct()) {
rows = distinctRows.values(); rows = new ArrayList<>(distinctRows.values());
} }
if (sort != null && limit != 0 && !limitsWereApplied) { if (sort != null && limit != 0 && !limitsWereApplied) {
boolean withLimit = limit > 0 && withTiesSortOrder == null; boolean withLimit = limit > 0 && withTiesSortOrder == null;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
package org.h2.result; package org.h2.result;
import java.util.ArrayList; import java.util.Collection;
import org.h2.value.Value; import org.h2.value.Value;
/** /**
...@@ -40,7 +40,7 @@ public interface ResultExternal { ...@@ -40,7 +40,7 @@ public interface ResultExternal {
* @param rows the list of rows to add * @param rows the list of rows to add
* @return the new number of rows in this object * @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. * Close this object and delete the temporary file.
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
package org.h2.result; package org.h2.result;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.Collection;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.engine.Constants; import org.h2.engine.Constants;
...@@ -263,11 +263,7 @@ public class ResultTempTable implements ResultExternal { ...@@ -263,11 +263,7 @@ public class ResultTempTable implements ResultExternal {
} }
@Override @Override
public int addRows(ArrayList<Value[]> rows) { public int addRows(Collection<Value[]> rows) {
// speeds up inserting, but not really needed:
if (sort != null) {
sort.sort(rows);
}
for (Value[] values : rows) { for (Value[] values : rows) {
addRow(values); addRow(values);
} }
......
...@@ -8,3 +8,24 @@ CREATE TABLE TEST(I NUMERIC(-1)); ...@@ -8,3 +8,24 @@ CREATE TABLE TEST(I NUMERIC(-1));
CREATE TABLE TEST(I NUMERIC(-1, -1)); CREATE TABLE TEST(I NUMERIC(-1, -1));
> exception INVALID_VALUE_2 > 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; ...@@ -550,3 +550,62 @@ VALUES 1, 2;
> 1 > 1
> 2 > 2
> rows: 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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论