提交 318ebff0 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Move ENUM-specific tricks to Value.compareTo()

上级 ec9efaa4
......@@ -352,7 +352,7 @@ public class ConstraintReferential extends Constraint {
int idx = cols[i].getColumnId();
Value c = check.getValue(idx);
Value f = found.getValue(idx);
if (searchTable.compareTypeSafe(c, f) != 0) {
if (searchTable.compareValues(c, f) != 0) {
allEqual = false;
break;
}
......
......@@ -394,7 +394,7 @@ public class Database implements DataHandler {
*/
public boolean areEqual(Value a, Value b) {
// can not use equals because ValueDecimal 0.0 is not equal to 0.00.
return a.compareTo(b, compareMode) == 0;
return a.compareTo(b, mode, compareMode) == 0;
}
/**
......@@ -407,7 +407,7 @@ public class Database implements DataHandler {
* 1 otherwise
*/
public int compare(Value a, Value b) {
return a.compareTo(b, compareMode);
return a.compareTo(b, mode, compareMode);
}
/**
......
......@@ -10,6 +10,7 @@ import java.util.Comparator;
import java.util.Map;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.util.ValueHashMap;
import org.h2.value.CompareMode;
import org.h2.value.Value;
......@@ -53,13 +54,14 @@ class AggregateDataHistogram extends AggregateData {
values[i] = ValueArray.get(new Value[] { entry.getKey(), ValueLong.get(d.count) });
i++;
}
final Mode mode = database.getMode();
final CompareMode compareMode = database.getCompareMode();
Arrays.sort(values, new Comparator<ValueArray>() {
@Override
public int compare(ValueArray v1, ValueArray v2) {
Value a1 = v1.getList()[0];
Value a2 = v2.getList()[0];
return a1.compareTo(a2, compareMode);
return a1.compareTo(a2, mode, compareMode);
}
});
Value v = ValueArray.get(values);
......
......@@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.engine.SysProperties;
import org.h2.index.Cursor;
......@@ -160,7 +161,8 @@ class AggregateDataMedian extends AggregateDataCollecting {
if (v2 == ValueNull.INSTANCE) {
return v;
}
return getMedian(v, v2, dataType, session.getDatabase().getCompareMode());
Database database = session.getDatabase();
return getMedian(v, v2, dataType, database.getMode(), database.getCompareMode());
}
return v;
}
......@@ -171,19 +173,19 @@ class AggregateDataMedian extends AggregateDataCollecting {
if (a == null) {
return ValueNull.INSTANCE;
}
final CompareMode mode = database.getCompareMode();
Arrays.sort(a, mode);
final CompareMode compareMode = database.getCompareMode();
Arrays.sort(a, compareMode);
int len = a.length;
int idx = len / 2;
Value v1 = a[idx];
if ((len & 1) == 1) {
return v1.convertTo(dataType);
}
return getMedian(a[idx - 1], v1, dataType, mode);
return getMedian(a[idx - 1], v1, dataType, database.getMode(), compareMode);
}
private static Value getMedian(Value v0, Value v1, int dataType, CompareMode mode) {
if (v0.compareTo(v1, mode) == 0) {
private static Value getMedian(Value v0, Value v1, int dataType, Mode databaseMode, CompareMode compareMode) {
if (v0.compareTo(v1, databaseMode, compareMode) == 0) {
return v0.convertTo(dataType);
}
switch (dataType) {
......
......@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.h2.api.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.engine.SysProperties;
import org.h2.index.IndexCondition;
......@@ -20,7 +19,6 @@ import org.h2.table.TableFilter;
import org.h2.util.MathUtils;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueEnum;
import org.h2.value.ValueGeometry;
import org.h2.value.ValueNull;
......@@ -271,22 +269,7 @@ public class Comparison extends Condition {
return ValueNull.INSTANCE;
}
}
int leftType = left.getType();
int rightType = right.getType();
if (leftType != rightType || leftType == Value.ENUM) {
int dataType = Value.getHigherOrder(leftType, rightType);
if (dataType == Value.ENUM) {
String[] enumerators = ValueEnum.getEnumeratorsForBinaryOperation(l, r);
l = l.convertToEnum(enumerators);
r = r.convertToEnum(enumerators);
} else {
Mode mode = database.getMode();
l = l.convertTo(dataType, -1, mode);
r = r.convertTo(dataType, -1, mode);
}
}
boolean result = compareNotNull(database, l, r, compareType);
return ValueBoolean.get(result);
return ValueBoolean.get(compareNotNull(database, l, r, compareType));
}
/**
......
......@@ -53,7 +53,6 @@ public class ConditionIn extends Condition {
if (r == ValueNull.INSTANCE) {
hasNull = true;
} else {
r = r.convertTo(l.getType(), -1, database.getMode());
result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL);
if (result) {
break;
......
......@@ -89,7 +89,6 @@ public class ConditionInParameter extends Condition {
if (r == ValueNull.INSTANCE) {
hasNull = true;
} else {
r = r.convertTo(l.getType(), -1, database.getMode());
result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL);
if (result) {
break;
......@@ -100,7 +99,6 @@ public class ConditionInParameter extends Condition {
if (value == ValueNull.INSTANCE) {
hasNull = true;
} else {
value = value.convertTo(l.getType(), -1, database.getMode());
result = Comparison.compareNotNull(database, l, value, Comparison.EQUAL);
}
}
......
......@@ -363,7 +363,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
if (aNull || bNull) {
return SortOrder.compareNull(aNull, sortType);
}
int comp = table.compareTypeSafe(a, b);
int comp = table.compareValues(a, b);
if ((sortType & SortOrder.DESCENDING) != 0) {
comp = -comp;
}
......
......@@ -7,6 +7,7 @@ package org.h2.index;
import java.util.ArrayList;
import java.util.HashSet;
import org.h2.engine.Session;
import org.h2.expression.Comparison;
import org.h2.message.DbException;
......@@ -246,7 +247,7 @@ public class IndexCursor implements Cursor {
return a;
}
}
int comp = a.compareTo(b, table.getDatabase().getCompareMode());
int comp = table.getDatabase().compare(a, b);
if (comp == 0) {
return a;
}
......
......@@ -32,6 +32,7 @@ import java.util.UUID;
import org.h2.api.ErrorCode;
import org.h2.api.TimestampWithTimeZone;
import org.h2.command.CommandInterface;
import org.h2.engine.Mode;
import org.h2.engine.SysProperties;
import org.h2.message.DbException;
import org.h2.message.TraceObject;
......@@ -3954,12 +3955,13 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
return getTraceObjectName() + ": " + result;
}
private void patchCurrentRow(Value[] row) {
private void patchCurrentRow(Value[] row) throws SQLException {
boolean changed = false;
Value[] current = result.currentRow();
CompareMode mode = conn.getCompareMode();
Mode databaseMode = conn.getMode();
CompareMode compareMode = conn.getCompareMode();
for (int i = 0; i < row.length; i++) {
if (row[i].compareTo(current[i], mode) != 0) {
if (row[i].compareTo(current[i], databaseMode, compareMode) != 0) {
changed = true;
break;
}
......
......@@ -13,6 +13,7 @@ import java.util.Queue;
import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.index.BaseIndex;
import org.h2.index.Cursor;
......@@ -106,15 +107,17 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
}
public static final class Comparator implements java.util.Comparator<Source> {
private final Mode databaseMode;
private final CompareMode compareMode;
public Comparator(CompareMode compareMode) {
public Comparator(Mode databaseMode, CompareMode compareMode) {
this.databaseMode = databaseMode;
this.compareMode = compareMode;
}
@Override
public int compare(Source one, Source two) {
return one.currentRowData.compareTo(two.currentRowData, compareMode);
return one.currentRowData.compareTo(two.currentRowData, databaseMode, compareMode);
}
}
}
......@@ -123,7 +126,8 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
public void addBufferedRows(List<String> bufferNames) {
CompareMode compareMode = database.getCompareMode();
int buffersCount = bufferNames.size();
Queue<Source> queue = new PriorityQueue<>(buffersCount, new Source.Comparator(compareMode));
Queue<Source> queue = new PriorityQueue<>(buffersCount,
new Source.Comparator(database.getMode(), compareMode));
for (String bufferName : bufferNames) {
Iterator<ValueArray> iter = openMap(bufferName).keyIterator(null);
if (iter.hasNext()) {
......
......@@ -12,7 +12,6 @@ import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Objects;
import org.h2.api.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Mode;
......@@ -36,7 +35,6 @@ import org.h2.value.ValueBytes;
import org.h2.value.ValueDate;
import org.h2.value.ValueDecimal;
import org.h2.value.ValueDouble;
import org.h2.value.ValueEnum;
import org.h2.value.ValueFloat;
import org.h2.value.ValueGeometry;
import org.h2.value.ValueInt;
......@@ -82,7 +80,7 @@ public class ValueDataType implements DataType {
SpatialDataType spatialType;
public ValueDataType() {
this(CompareMode.getInstance(null, 0), Mode.getRegular(), null, null);
this(CompareMode.getInstance(null, 0), null, null, null);
}
public ValueDataType(Database database, int[] sortTypes) {
......@@ -147,20 +145,7 @@ public class ValueDataType implements DataType {
return SortOrder.compareNull(aNull, sortType);
}
int aType = a.getType();
int bType = b.getType();
if (aType != bType || aType == Value.ENUM) {
int t2 = Value.getHigherOrder(aType, bType);
if (t2 == Value.ENUM) {
String[] enumerators = ValueEnum.getEnumeratorsForBinaryOperation(a, b);
a = a.convertToEnum(enumerators);
b = b.convertToEnum(enumerators);
} else {
a = a.convertTo(t2, -1, mode);
b = b.convertTo(t2, -1, mode);
}
}
int comp = a.compareTypeSafe(b, compareMode);
int comp = a.compareTo(b, mode, compareMode);
if ((sortType & SortOrder.DESCENDING) != 0) {
comp = -comp;
......
......@@ -18,7 +18,6 @@ import org.h2.command.dml.AllColumnsForPlan;
import org.h2.constraint.Constraint;
import org.h2.engine.Constants;
import org.h2.engine.DbObject;
import org.h2.engine.Mode;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.engine.UndoLogRecord;
......@@ -41,7 +40,6 @@ import org.h2.schema.TriggerObject;
import org.h2.util.Utils;
import org.h2.value.CompareMode;
import org.h2.value.Value;
import org.h2.value.ValueEnum;
import org.h2.value.ValueNull;
/**
......@@ -1209,25 +1207,8 @@ public abstract class Table extends SchemaObjectBase {
* @return 0 if both values are equal, -1 if the first value is smaller, and
* 1 otherwise
*/
public int compareTypeSafe(Value a, Value b) {
if (a == b) {
return 0;
}
int aType = a.getType();
int bType = b.getType();
if (aType != bType || aType == Value.ENUM) {
int dataType = Value.getHigherOrder(aType, bType);
if (dataType == Value.ENUM) {
String[] enumerators = ValueEnum.getEnumeratorsForBinaryOperation(a, b);
a = a.convertToEnum(enumerators);
b = b.convertToEnum(enumerators);
} else {
Mode mode = database.getMode();
a = a.convertTo(dataType, -1, mode);
b = b.convertTo(dataType, -1, mode);
}
}
return a.compareTypeSafe(b, compareMode);
public int compareValues(Value a, Value b) {
return a.compareTo(b, database.getMode(), compareMode);
}
public CompareMode getCompareMode() {
......
......@@ -289,7 +289,7 @@ public class CompareMode implements Comparator<Value> {
@Override
public int compare(Value o1, Value o2) {
return o1.compareTo(o2, this);
return o1.compareTo(o2, null, this);
}
}
......@@ -1169,11 +1169,12 @@ public abstract class Value {
* mode.
*
* @param v the other value
* @param mode the compare mode
* @param databaseMode the database mode
* @param compareMode the compare mode
* @return 0 if both values are equal, -1 if the other value is smaller, and
* 1 otherwise
*/
public final int compareTo(Value v, CompareMode mode) {
public final int compareTo(Value v, Mode databaseMode, CompareMode compareMode) {
if (this == v) {
return 0;
}
......@@ -1182,11 +1183,21 @@ public abstract class Value {
} else if (v == ValueNull.INSTANCE) {
return 1;
}
if (getType() == v.getType()) {
return compareSecure(v, mode);
Value l = this;
int leftType = l.getType();
int rightType = v.getType();
if (leftType != rightType || leftType == Value.ENUM) {
int dataType = Value.getHigherOrder(leftType, rightType);
if (dataType == Value.ENUM) {
String[] enumerators = ValueEnum.getEnumeratorsForBinaryOperation(l, v);
l = l.convertToEnum(enumerators);
v = v.convertToEnum(enumerators);
} else {
l = l.convertTo(dataType, -1, databaseMode);
v = v.convertTo(dataType, -1, databaseMode);
}
}
int t2 = Value.getHigherOrder(getType(), v.getType());
return convertTo(t2).compareSecure(v.convertTo(t2), mode);
return l.compareSecure(v, compareMode);
}
public int getScale() {
......
......@@ -11,6 +11,7 @@ import java.sql.SQLException;
import java.util.Arrays;
import org.h2.engine.Constants;
import org.h2.engine.Mode;
import org.h2.engine.SysProperties;
import org.h2.util.MathUtils;
import org.h2.util.StatementBuilder;
......@@ -109,7 +110,7 @@ public class ValueArray extends Value {
for (int i = 0; i < len; i++) {
Value v1 = values[i];
Value v2 = v.values[i];
int comp = v1.compareTo(v2, mode);
int comp = v1.compareTo(v2, /* TODO */ null, mode);
if (comp != 0) {
return comp;
}
......
......@@ -226,7 +226,7 @@ public class TestDataPage extends TestBase implements DataHandler {
data.reset();
Value v2 = data.readValue();
assertEquals(v.getType(), v2.getType());
assertEquals(0, v.compareTo(v2, compareMode));
assertEquals(0, v.compareTo(v2, null, compareMode));
assertEquals(123, data.readInt());
}
......
......@@ -87,13 +87,13 @@ public class TestDate extends TestBase {
assertTrue(d1.equals(d1));
assertTrue(d1.equals(d1b));
assertTrue(d1b.equals(d1));
assertEquals(0, d1.compareTo(d1b, null));
assertEquals(0, d1b.compareTo(d1, null));
assertEquals(0, d1.compareTo(d1b, null, null));
assertEquals(0, d1b.compareTo(d1, null, null));
ValueDate d2 = ValueDate.parse("2002-02-02");
assertFalse(d1.equals(d2));
assertFalse(d2.equals(d1));
assertEquals(-1, d1.compareTo(d2, null));
assertEquals(1, d2.compareTo(d1, null));
assertEquals(-1, d1.compareTo(d2, null, null));
assertEquals(1, d2.compareTo(d1, null, null));
// can't convert using java.util.Date
assertEquals(
......@@ -175,13 +175,13 @@ public class TestDate extends TestBase {
assertTrue(t1.equals(t1));
assertTrue(t1.equals(t1b));
assertTrue(t1b.equals(t1));
assertEquals(0, t1.compareTo(t1b, null));
assertEquals(0, t1b.compareTo(t1, null));
assertEquals(0, t1.compareTo(t1b, null, null));
assertEquals(0, t1b.compareTo(t1, null, null));
ValueTime t2 = ValueTime.parse("22:22:22");
assertFalse(t1.equals(t2));
assertFalse(t2.equals(t1));
assertEquals(-1, t1.compareTo(t2, null));
assertEquals(1, t2.compareTo(t1, null));
assertEquals(-1, t1.compareTo(t2, null, null));
assertEquals(1, t2.compareTo(t1, null, null));
if (SysProperties.UNLIMITED_TIME_RANGE) {
assertEquals(-1, t1.negate().getSignum());
......@@ -271,13 +271,13 @@ public class TestDate extends TestBase {
assertTrue(t1.equals(t1));
assertTrue(t1.equals(t1b));
assertTrue(t1b.equals(t1));
assertEquals(0, t1.compareTo(t1b, null));
assertEquals(0, t1b.compareTo(t1, null));
assertEquals(0, t1.compareTo(t1b, null, null));
assertEquals(0, t1b.compareTo(t1, null, null));
ValueTimestamp t2 = ValueTimestamp.parse("2002-02-02 02:02:02.222");
assertFalse(t1.equals(t2));
assertFalse(t2.equals(t1));
assertEquals(-1, t1.compareTo(t2, null));
assertEquals(1, t2.compareTo(t1, null));
assertEquals(-1, t1.compareTo(t2, null, null));
assertEquals(1, t2.compareTo(t1, null, null));
t1 = ValueTimestamp.parse("2001-01-01 01:01:01.123456789");
assertEquals("2001-01-01 01:01:01.123456789",
t1.getString());
......
......@@ -138,27 +138,27 @@ public class TestTimeStampWithTimeZone extends TestDb {
private void test2() {
ValueTimestampTimeZone a = ValueTimestampTimeZone.parse("1970-01-01 12:00:00.00+00:15");
ValueTimestampTimeZone b = ValueTimestampTimeZone.parse("1970-01-01 12:00:01.00+01:15");
int c = a.compareTo(b, null);
int c = a.compareTo(b, null, null);
assertEquals(1, c);
c = b.compareTo(a, null);
c = b.compareTo(a, null, null);
assertEquals(-1, c);
}
private void test3() {
ValueTimestampTimeZone a = ValueTimestampTimeZone.parse("1970-01-02 00:00:02.00+01:15");
ValueTimestampTimeZone b = ValueTimestampTimeZone.parse("1970-01-01 23:00:01.00+00:15");
int c = a.compareTo(b, null);
int c = a.compareTo(b, null, null);
assertEquals(1, c);
c = b.compareTo(a, null);
c = b.compareTo(a, null, null);
assertEquals(-1, c);
}
private void test4() {
ValueTimestampTimeZone a = ValueTimestampTimeZone.parse("1970-01-02 00:00:01.00+01:15");
ValueTimestampTimeZone b = ValueTimestampTimeZone.parse("1970-01-01 23:00:01.00+00:15");
int c = a.compareTo(b, null);
int c = a.compareTo(b, null, null);
assertEquals(0, c);
c = b.compareTo(a, null);
c = b.compareTo(a, null, null);
assertEquals(0, c);
}
......@@ -209,7 +209,7 @@ public class TestTimeStampWithTimeZone extends TestDb {
assertEquals(t, tstz.convertTo(Value.TIME));
assertEquals(ts.getTimestamp(), tstz.getTimestamp());
if (testReverse) {
assertEquals(0, tstz.compareTo(ts.convertTo(Value.TIMESTAMP_TZ), null));
assertEquals(0, tstz.compareTo(ts.convertTo(Value.TIMESTAMP_TZ), null, null));
assertEquals(d.convertTo(Value.TIMESTAMP).convertTo(Value.TIMESTAMP_TZ),
d.convertTo(Value.TIMESTAMP_TZ));
assertEquals(t.convertTo(Value.TIMESTAMP).convertTo(Value.TIMESTAMP_TZ),
......
......@@ -63,7 +63,7 @@ public class TestValueHashMap extends TestBase implements DataHandler {
Comparator<Value> vc = new Comparator<Value>() {
@Override
public int compare(Value v1, Value v2) {
return v1.compareTo(v2, compareMode);
return v1.compareTo(v2, null, compareMode);
}
};
for (int i = 0; i < 10000; i++) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论