提交 fc60923d authored 作者: Thomas Mueller's avatar Thomas Mueller

When doing an index lookup, decimal values 0.00 and 0.0 where not considered…

When doing an index lookup, decimal values 0.00 and 0.0 where not considered equal in version 1.2.128.
上级 d472d289
...@@ -286,7 +286,7 @@ public class ConstraintReferential extends Constraint { ...@@ -286,7 +286,7 @@ public class ConstraintReferential extends Constraint {
return; return;
} }
if (constraintColumnsEqual) { if (constraintColumnsEqual) {
if (!v.compareEqual(oldRow.getValue(idx))) { if (!database.areEqual(v, oldRow.getValue(idx))) {
constraintColumnsEqual = false; constraintColumnsEqual = false;
} }
} }
......
...@@ -253,14 +253,7 @@ public class Database implements DataHandler { ...@@ -253,14 +253,7 @@ public class Database implements DataHandler {
* @return true if both objects are equal * @return true if both objects are equal
*/ */
public boolean areEqual(Value a, Value b) throws SQLException { public boolean areEqual(Value a, Value b) throws SQLException {
// TODO optimization possible // can not use compareEqual because ValueDecimal 0.0 is not equal to 0.00.
// boolean is = a.compareEqual(b);
// boolean is2 = a.compareTo(b, compareMode) == 0;
// if(is != is2) {
// is = a.compareEqual(b);
// System.out.println("hey!");
// }
// return a.compareEqual(b);
return a.compareTo(b, compareMode) == 0; return a.compareTo(b, compareMode) == 0;
} }
...@@ -1171,6 +1164,11 @@ public class Database implements DataHandler { ...@@ -1171,6 +1164,11 @@ public class Database implements DataHandler {
} }
} }
/**
* Allocate a new object id.
*
* @return the id
*/
public synchronized int allocateObjectId() { public synchronized int allocateObjectId() {
int i = objectIds.nextClearBit(0); int i = objectIds.nextClearBit(0);
objectIds.set(i); objectIds.set(i);
...@@ -1375,6 +1373,11 @@ public class Database implements DataHandler { ...@@ -1375,6 +1373,11 @@ public class Database implements DataHandler {
updateWithChildren(session, obj); updateWithChildren(session, obj);
} }
/**
* Create a temporary file in the database folder.
*
* @return the file name
*/
public String createTempFile() throws SQLException { public String createTempFile() throws SQLException {
try { try {
boolean inTempDir = readOnly; boolean inTempDir = readOnly;
......
...@@ -163,7 +163,7 @@ public class Comparison extends Condition { ...@@ -163,7 +163,7 @@ public class Comparison extends Condition {
return ValueExpression.getNull(); return ValueExpression.getNull();
} }
Expression test = getCast(right, left.getType(), left.getPrecision(), left.getScale(), left.getDisplaySize(), session); Expression test = getCast(right, left.getType(), left.getPrecision(), left.getScale(), left.getDisplaySize(), session);
if (!r.compareEqual(test.getValue(session))) { if (!database.areEqual(r, test.getValue(session))) {
return ValueExpression.get(ValueBoolean.get(false)); return ValueExpression.get(ValueBoolean.get(false));
} }
right = test; right = test;
......
...@@ -748,7 +748,9 @@ public class FullText { ...@@ -748,7 +748,9 @@ public class FullText {
} }
/** /**
* Check if a the indexed columns of a row have changed. * Check if a the indexed columns of a row probably have changed. It may
* return true even if the change was minimal (for example from 0.0 to
* 0.00).
* *
* @param oldRow the old row * @param oldRow the old row
* @param newRow the new row * @param newRow the new row
......
...@@ -34,6 +34,7 @@ import org.h2.message.Trace; ...@@ -34,6 +34,7 @@ import org.h2.message.Trace;
import org.h2.message.TraceObject; import org.h2.message.TraceObject;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.value.CompareMode;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueLob; import org.h2.value.ValueLob;
...@@ -85,6 +86,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -85,6 +86,7 @@ public class JdbcConnection extends TraceObject implements Connection {
private boolean isInternal; private boolean isInternal;
private String catalog; private String catalog;
private Statement executingStatement; private Statement executingStatement;
private CompareMode compareMode = CompareMode.getInstance(null, 0);
/** /**
* INTERNAL * INTERNAL
...@@ -1479,7 +1481,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -1479,7 +1481,7 @@ public class JdbcConnection extends TraceObject implements Connection {
int id = getNextId(TraceObject.CLOB); int id = getNextId(TraceObject.CLOB);
debugCodeAssign("NClob", TraceObject.CLOB, id, "createNClob()"); debugCodeAssign("NClob", TraceObject.CLOB, id, "createNClob()");
checkClosedForWrite(); checkClosedForWrite();
ValueLob v = ValueLob.createSmallLob(Value.CLOB, MemoryUtils.EMPTY_BYTES); ValueLob v = ValueLob.createSmallLob(Value.CLOB, Utils.EMPTY_BYTES);
return new JdbcClob(this, v, id); return new JdbcClob(this, v, id);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
...@@ -1686,4 +1688,8 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -1686,4 +1688,8 @@ public class JdbcConnection extends TraceObject implements Connection {
return o; return o;
} }
CompareMode getCompareMode() {
return compareMode;
}
} }
...@@ -43,6 +43,7 @@ import org.h2.util.IOUtils; ...@@ -43,6 +43,7 @@ import org.h2.util.IOUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.CompareMode;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
...@@ -3524,8 +3525,9 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -3524,8 +3525,9 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
private void patchCurrentRow(Value[] row) throws SQLException { private void patchCurrentRow(Value[] row) throws SQLException {
boolean changed = false; boolean changed = false;
Value[] current = result.currentRow(); Value[] current = result.currentRow();
CompareMode mode = conn.getCompareMode();
for (int i = 0; i < row.length; i++) { for (int i = 0; i < row.length; i++) {
if (!row[i].compareEqual(current[i])) { if (row[i].compareTo(current[i], mode) != 0) {
changed = true; changed = true;
break; break;
} }
......
...@@ -151,10 +151,12 @@ public class ResultTempTable implements ResultExternal { ...@@ -151,10 +151,12 @@ public class ResultTempTable implements ResultExternal {
private Cursor find(Row row) throws SQLException { private Cursor find(Row row) throws SQLException {
Cursor cursor = index.find(session, row, row); Cursor cursor = index.find(session, row, row);
Value a = row.getValue(0);
while (cursor.next()) { while (cursor.next()) {
SearchRow found; SearchRow found;
found = cursor.getSearchRow(); found = cursor.getSearchRow();
if (found.getValue(0).equals(row.getValue(0))) { Value b = found.getValue(0);
if (session.getDatabase().areEqual(a, b)) {
return cursor; return cursor;
} }
} }
......
...@@ -227,9 +227,10 @@ public abstract class Value { ...@@ -227,9 +227,10 @@ public abstract class Value {
public abstract int hashCode(); public abstract int hashCode();
/** /**
* Check if the two values are equal. * Check if the two values have the same hash code. No data conversion is
* No data conversion is made; this method returns false * made; this method returns false if the other object is not of the same
* if the other object is not of the same class. * class. For some values, compareTo may return 0 even if equals return
* false. Example: ValueDecimal 0.0 and 0.00.
* *
* @param other the other value * @param other the other value
* @return true if they are equal * @return true if they are equal
...@@ -801,25 +802,6 @@ public abstract class Value { ...@@ -801,25 +802,6 @@ public abstract class Value {
return compareSecure(v, mode); return compareSecure(v, mode);
} }
/**
* Compare two values and return true if they contain the same data.
*
* @param v the value to compare against
* @return true if both values are the same * @throws SQLException
*/
public final boolean compareEqual(Value v) throws SQLException {
if (this == ValueNull.INSTANCE) {
return v == ValueNull.INSTANCE;
} else if (v == ValueNull.INSTANCE) {
return false;
}
if (getType() == v.getType()) {
return equals(v);
}
int t2 = Value.getHigherOrder(getType(), v.getType());
return convertTo(t2).equals(v.convertTo(t2));
}
/** /**
* Compare this value against another value using the specified compare * Compare this value against another value using the specified compare
* mode. * mode.
......
...@@ -204,6 +204,10 @@ public class ValueDecimal extends Value { ...@@ -204,6 +204,10 @@ public class ValueDecimal extends Value {
} }
public boolean equals(Object other) { public boolean equals(Object other) {
// Two BigDecimal objects are considered equal only if they are equal in
// value and scale (thus 2.0 is not equal to 2.00 when using equals;
// however -0.0 and 0.0 are). Can not use compareTo because 2.0 and 2.00
// have different hash codes
return other instanceof ValueDecimal && value.equals(((ValueDecimal) other).value); return other instanceof ValueDecimal && value.equals(((ValueDecimal) other).value);
} }
......
...@@ -129,6 +129,13 @@ public class ValueString extends Value { ...@@ -129,6 +129,13 @@ public class ValueString extends Value {
// return new ValueString(s.intern()); // return new ValueString(s.intern());
} }
/**
* Create a new String value of the current class.
* This method is meant to be overridden by subclasses.
*
* @param s the string
* @return the value
*/
protected Value getNew(String s) { protected Value getNew(String s) {
return ValueString.get(s); return ValueString.get(s);
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论