提交 52b412bd authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Fix HASH indexes for data types without total ordering

上级 da92e62b
......@@ -5,6 +5,9 @@
*/
package org.h2.index;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session;
import org.h2.message.DbException;
......@@ -15,7 +18,7 @@ import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.RegularTable;
import org.h2.table.TableFilter;
import org.h2.util.ValueHashMap;
import org.h2.value.DataType;
import org.h2.value.Value;
/**
......@@ -27,20 +30,21 @@ public class HashIndex extends BaseIndex {
* The index of the indexed column.
*/
private final int indexColumn;
private final boolean totalOrdering;
private final RegularTable tableData;
private ValueHashMap<Long> rows;
private Map<Value, Long> rows;
public HashIndex(RegularTable table, int id, String indexName,
IndexColumn[] columns, IndexType indexType) {
public HashIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, IndexType indexType) {
super(table, id, indexName, columns, indexType);
this.indexColumn = columns[0].column.getColumnId();
Column column = columns[0].column;
indexColumn = column.getColumnId();
totalOrdering = DataType.hasTotalOrdering(column.getType().getValueType());
this.tableData = table;
reset();
}
private void reset() {
rows = new ValueHashMap<>();
rows = totalOrdering ? new HashMap<Value, Long>() : new TreeMap<Value, Long>(database.getCompareMode());
}
@Override
......
......@@ -6,6 +6,9 @@
package org.h2.index;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session;
......@@ -18,7 +21,7 @@ import org.h2.table.IndexColumn;
import org.h2.table.RegularTable;
import org.h2.table.TableFilter;
import org.h2.util.Utils;
import org.h2.util.ValueHashMap;
import org.h2.value.DataType;
import org.h2.value.Value;
/**
......@@ -32,20 +35,24 @@ public class NonUniqueHashIndex extends BaseIndex {
* The index of the indexed column.
*/
private final int indexColumn;
private ValueHashMap<ArrayList<Long>> rows;
private final boolean totalOrdering;
private Map<Value, ArrayList<Long>> rows;
private final RegularTable tableData;
private long rowCount;
public NonUniqueHashIndex(RegularTable table, int id, String indexName,
IndexColumn[] columns, IndexType indexType) {
super(table, id, indexName, columns, indexType);
this.indexColumn = columns[0].column.getColumnId();
this.tableData = table;
Column column = columns[0].column;
indexColumn = column.getColumnId();
totalOrdering = DataType.hasTotalOrdering(column.getType().getValueType());
tableData = table;
reset();
}
private void reset() {
rows = new ValueHashMap<>();
rows = totalOrdering ? new HashMap<Value, ArrayList<Long>>()
: new TreeMap<Value, ArrayList<Long>>(database.getCompareMode());
rowCount = 0;
}
......
......@@ -1454,6 +1454,51 @@ public class DataType {
return type == Value.GEOMETRY || type == Value.ENUM;
}
/**
* Check if the given type has total ordering.
*
* @param type the value type
* @return true if the value type has total ordering
*/
public static boolean hasTotalOrdering(int type) {
switch (type) {
case Value.BOOLEAN:
case Value.BYTE:
case Value.SHORT:
case Value.INT:
case Value.LONG:
// Negative zeroes and NaNs are normalized
case Value.DOUBLE:
case Value.FLOAT:
case Value.TIME:
case Value.DATE:
case Value.TIMESTAMP:
case Value.BYTES:
// Serialized data is compared
case Value.JAVA_OBJECT:
case Value.UUID:
// EWKB is used
case Value.GEOMETRY:
case Value.ENUM:
case Value.INTERVAL_YEAR:
case Value.INTERVAL_MONTH:
case Value.INTERVAL_DAY:
case Value.INTERVAL_HOUR:
case Value.INTERVAL_MINUTE:
case Value.INTERVAL_SECOND:
case Value.INTERVAL_YEAR_TO_MONTH:
case Value.INTERVAL_DAY_TO_HOUR:
case Value.INTERVAL_DAY_TO_MINUTE:
case Value.INTERVAL_DAY_TO_SECOND:
case Value.INTERVAL_HOUR_TO_MINUTE:
case Value.INTERVAL_HOUR_TO_SECOND:
case Value.INTERVAL_MINUTE_TO_SECOND:
return true;
default:
return false;
}
}
/**
* Check if the given value type supports the add operation.
*
......
......@@ -58,3 +58,34 @@ CREATE UNIQUE INDEX TEST_IDX ON TEST(N);
DROP TABLE TEST;
> ok
CREATE MEMORY TABLE TEST(N NUMERIC) AS VALUES (0), (0.0), (2), (NULL);
> ok
CREATE HASH INDEX TEST_IDX ON TEST(N);
> ok
SELECT N FROM TEST WHERE N = 0;
> N
> ---
> 0
> 0.0
> rows: 2
DROP INDEX TEST_IDX;
> ok
CREATE UNIQUE HASH INDEX TEST_IDX ON TEST(N);
> exception DUPLICATE_KEY_1
DELETE FROM TEST WHERE N = 0 LIMIT 1;
> update count: 1
CREATE UNIQUE HASH INDEX TEST_IDX ON TEST(N);
> ok
SELECT 1 FROM TEST WHERE N = 0;
>> 1
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论