Unverified 提交 d6cebc3f authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1595 from katzyn/misc

DBSettings.optimizeIsNull removal and other minor changes
...@@ -4816,10 +4816,12 @@ When converting a number to binary, the number of bytes matches the precision. ...@@ -4816,10 +4816,12 @@ When converting a number to binary, the number of bytes matches the precision.
When converting a string to binary, it is hex encoded (every byte two characters); When converting a string to binary, it is hex encoded (every byte two characters);
a hex string can be converted to a number by first converting it to binary. a hex string can be converted to a number by first converting it to binary.
If a direct conversion is not possible, the value is first converted to a string. If a direct conversion is not possible, the value is first converted to a string.
Note that some data types may need explicitly specified precision to avoid overflow or rounding.
"," ","
CAST(NAME AS INT); CAST(NAME AS INT);
CAST(65535 AS BINARY); CAST(65535 AS BINARY);
CAST(CAST('FFFF' AS BINARY) AS INT); CAST(CAST('FFFF' AS BINARY) AS INT);
CAST(TIMESTAMP '2010-01-01 10:40:00.123456' AS TIME(6))
" "
"Functions (System)","COALESCE"," "Functions (System)","COALESCE","
......
...@@ -21,8 +21,22 @@ Change Log ...@@ -21,8 +21,22 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #1594: DBSettings.optimizeIsNull and dead code in IndexCursor.getMax()
</li>
<li>PR #1591: Use multi-catch java 7 language construction to simplify code
</li>
<li>Issue #1582: h2 not using best index for &gt;=
</li>
<li>PR #1588: Add support for java.time.Period
</li>
<li>Issue #446: FILE_READ from classpath not working because of 0 byte file length
</li>
<li>PR #1579: fix unintentional append mode disruption
</li>
<li>Issue #1573: DELETE FROM w/ ROWNUM and subquery <li>Issue #1573: DELETE FROM w/ ROWNUM and subquery
</li> </li>
<li>Issue #187: SHUTDOWN DEFRAG corrupts splitted file database
</li>
<li>PR #1571: Optimizing ConditionAndOr queries <li>PR #1571: Optimizing ConditionAndOr queries
</li> </li>
<li>Issue #1565: SOME / ANY conflict <li>Issue #1565: SOME / ANY conflict
......
...@@ -25,7 +25,7 @@ public final class CurrentTimestamp { ...@@ -25,7 +25,7 @@ public final class CurrentTimestamp {
* epoch and time zone offsets with seconds because such support is not * epoch and time zone offsets with seconds because such support is not
* required for current dates. * required for current dates.
*/ */
int offsetSec = DateTimeUtils.getTimeZone().getOffset(second * 1_000 + nano / 1_000_000) / 1000; int offsetSec = DateTimeUtils.getTimeZoneOffset(second * 1_000 + nano / 1_000_000) / 1000;
second += offsetSec; second += offsetSec;
return ValueTimestampTimeZone.fromDateValueAndNanos( return ValueTimestampTimeZone.fromDateValueAndNanos(
DateTimeUtils.dateValueFromAbsoluteDay(second / DateTimeUtils.SECONDS_PER_DAY), DateTimeUtils.dateValueFromAbsoluteDay(second / DateTimeUtils.SECONDS_PER_DAY),
......
...@@ -206,12 +206,6 @@ public class DbSettings extends SettingsBase { ...@@ -206,12 +206,6 @@ public class DbSettings extends SettingsBase {
*/ */
public final boolean optimizeInSelect = get("OPTIMIZE_IN_SELECT", true); public final boolean optimizeInSelect = get("OPTIMIZE_IN_SELECT", true);
/**
* Database setting <code>OPTIMIZE_IS_NULL</code> (default: false).<br />
* Use an index for condition of the form columnName IS NULL.
*/
public final boolean optimizeIsNull = get("OPTIMIZE_IS_NULL", true);
/** /**
* Database setting <code>OPTIMIZE_OR</code> (default: true).<br /> * Database setting <code>OPTIMIZE_OR</code> (default: true).<br />
* Convert (C=? OR C=?) to (C IN(?, ?)). * Convert (C=? OR C=?) to (C IN(?, ?)).
......
...@@ -397,12 +397,8 @@ public class Comparison extends Condition { ...@@ -397,12 +397,8 @@ public class Comparison extends Condition {
if (l != null) { if (l != null) {
switch (compareType) { switch (compareType) {
case IS_NULL: case IS_NULL:
if (session.getDatabase().getSettings().optimizeIsNull) { filter.addIndexCondition(
filter.addIndexCondition( IndexCondition.get(Comparison.EQUAL_NULL_SAFE, l, ValueExpression.getNull()));
IndexCondition.get(
Comparison.EQUAL_NULL_SAFE, l,
ValueExpression.getNull()));
}
} }
} }
return; return;
......
...@@ -33,7 +33,6 @@ import org.h2.value.ValueNull; ...@@ -33,7 +33,6 @@ import org.h2.value.ValueNull;
*/ */
public class IndexCursor implements Cursor { public class IndexCursor implements Cursor {
private Session session;
private final TableFilter tableFilter; private final TableFilter tableFilter;
private Index index; private Index index;
private Table table; private Table table;
...@@ -75,7 +74,6 @@ public class IndexCursor implements Cursor { ...@@ -75,7 +74,6 @@ public class IndexCursor implements Cursor {
* @param indexConditions Index conditions. * @param indexConditions Index conditions.
*/ */
public void prepare(Session s, ArrayList<IndexCondition> indexConditions) { public void prepare(Session s, ArrayList<IndexCondition> indexConditions) {
this.session = s;
alwaysFalse = false; alwaysFalse = false;
start = end = null; start = end = null;
inList = null; inList = null;
...@@ -142,14 +140,6 @@ public class IndexCursor implements Cursor { ...@@ -142,14 +140,6 @@ public class IndexCursor implements Cursor {
inList = null; inList = null;
inResult = null; inResult = null;
} }
if (!session.getDatabase().getSettings().optimizeIsNull) {
if (isStart && isEnd) {
if (v == ValueNull.INSTANCE) {
// join on a column=NULL is always false
alwaysFalse = true;
}
}
}
} }
} }
if (inColumn != null) { if (inColumn != null) {
...@@ -239,24 +229,16 @@ public class IndexCursor implements Cursor { ...@@ -239,24 +229,16 @@ public class IndexCursor implements Cursor {
} else if (b == null) { } else if (b == null) {
return a; return a;
} }
if (session.getDatabase().getSettings().optimizeIsNull) { // IS NULL must be checked later
// IS NULL must be checked later if (a == ValueNull.INSTANCE) {
if (a == ValueNull.INSTANCE) { return b;
return b; } else if (b == ValueNull.INSTANCE) {
} else if (b == ValueNull.INSTANCE) { return a;
return a;
}
} }
int comp = table.getDatabase().compare(a, b); int comp = table.getDatabase().compare(a, b);
if (comp == 0) { if (comp == 0) {
return a; return a;
} }
if (a == ValueNull.INSTANCE || b == ValueNull.INSTANCE) {
if (session.getDatabase().getSettings().optimizeIsNull) {
// column IS NULL AND column <op> <not null> is always false
return null;
}
}
return (comp > 0) == bigger ? a : b; return (comp > 0) == bigger ? a : b;
} }
......
...@@ -122,16 +122,17 @@ public class DateTimeUtils { ...@@ -122,16 +122,17 @@ public class DateTimeUtils {
} }
/** /**
* Returns local time zone. * Returns local time zone offset for a specified timestamp.
* *
* @return local time zone * @param ms milliseconds since Epoch in UTC
* @return local time zone offset
*/ */
static TimeZone getTimeZone() { public static int getTimeZoneOffset(long ms) {
TimeZone tz = timeZone; TimeZone tz = timeZone;
if (tz == null) { if (tz == null) {
timeZone = tz = TimeZone.getDefault(); timeZone = tz = TimeZone.getDefault();
} }
return tz; return tz.getOffset(ms);
} }
/** /**
...@@ -568,8 +569,9 @@ public class DateTimeUtils { ...@@ -568,8 +569,9 @@ public class DateTimeUtils {
} }
} else { } else {
long millis = convertDateTimeValueToMillis(tz, dateValue, nanos / 1_000_000); long millis = convertDateTimeValueToMillis(tz, dateValue, nanos / 1_000_000);
dateValue = dateValueFromDate(millis); millis += getTimeZoneOffset(millis);
nanos = nanos % 1_000_000 + nanosFromDate(millis); dateValue = dateValueFromLocalMillis(millis);
nanos = nanos % 1_000_000 + nanosFromLocalMillis(millis);
} }
} }
} }
...@@ -1119,14 +1121,12 @@ public class DateTimeUtils { ...@@ -1119,14 +1121,12 @@ public class DateTimeUtils {
} }
/** /**
* Convert a UTC datetime in millis to an encoded date in the default * Convert a local datetime in millis to an encoded date.
* timezone.
* *
* @param ms the milliseconds * @param ms the milliseconds
* @return the date value * @return the date value
*/ */
public static long dateValueFromDate(long ms) { public static long dateValueFromLocalMillis(long ms) {
ms += getTimeZone().getOffset(ms);
long absoluteDay = ms / MILLIS_PER_DAY; long absoluteDay = ms / MILLIS_PER_DAY;
// Round toward negative infinity // Round toward negative infinity
if (ms < 0 && (absoluteDay * MILLIS_PER_DAY != ms)) { if (ms < 0 && (absoluteDay * MILLIS_PER_DAY != ms)) {
...@@ -1152,14 +1152,12 @@ public class DateTimeUtils { ...@@ -1152,14 +1152,12 @@ public class DateTimeUtils {
} }
/** /**
* Convert a time in milliseconds in UTC to the nanoseconds since midnight * Convert a time in milliseconds in local time to the nanoseconds since midnight.
* (in the default timezone).
* *
* @param ms the milliseconds * @param ms the milliseconds
* @return the nanoseconds * @return the nanoseconds
*/ */
public static long nanosFromDate(long ms) { public static long nanosFromLocalMillis(long ms) {
ms += getTimeZone().getOffset(ms);
long absoluteDay = ms / MILLIS_PER_DAY; long absoluteDay = ms / MILLIS_PER_DAY;
// Round toward negative infinity // Round toward negative infinity
if (ms < 0 && (absoluteDay * MILLIS_PER_DAY != ms)) { if (ms < 0 && (absoluteDay * MILLIS_PER_DAY != ms)) {
...@@ -1236,7 +1234,7 @@ public class DateTimeUtils { ...@@ -1236,7 +1234,7 @@ public class DateTimeUtils {
* @return timestamp with time zone with specified value and current time zone * @return timestamp with time zone with specified value and current time zone
*/ */
public static ValueTimestampTimeZone timestampTimeZoneFromMillis(long ms) { public static ValueTimestampTimeZone timestampTimeZoneFromMillis(long ms) {
int offset = getTimeZone().getOffset(ms); int offset = getTimeZoneOffset(ms);
ms += offset; ms += offset;
long absoluteDay = ms / MILLIS_PER_DAY; long absoluteDay = ms / MILLIS_PER_DAY;
// Round toward negative infinity // Round toward negative infinity
......
...@@ -242,8 +242,9 @@ public class StringUtils { ...@@ -242,8 +242,9 @@ public class StringUtils {
*/ */
public static String addAsterisk(String s, int index) { public static String addAsterisk(String s, int index) {
if (s != null) { if (s != null) {
index = Math.min(index, s.length()); int len = s.length();
s = s.substring(0, index) + "[*]" + s.substring(index); index = Math.min(index, len);
s = new StringBuilder(len + 3).append(s, 0, index).append("[*]").append(s, index, len).toString();
} }
return s; return s;
} }
......
...@@ -1043,7 +1043,9 @@ public abstract class Value { ...@@ -1043,7 +1043,9 @@ public abstract class Value {
ValueTimestampTimeZone ts = (ValueTimestampTimeZone) this; ValueTimestampTimeZone ts = (ValueTimestampTimeZone) this;
long dateValue = ts.getDateValue(), timeNanos = ts.getTimeNanos(); long dateValue = ts.getDateValue(), timeNanos = ts.getTimeNanos();
long millis = DateTimeUtils.getMillis(dateValue, timeNanos, ts.getTimeZoneOffsetMins()); long millis = DateTimeUtils.getMillis(dateValue, timeNanos, ts.getTimeZoneOffsetMins());
return ValueTime.fromNanos(DateTimeUtils.nanosFromDate(millis) + timeNanos % 1_000_000); return ValueTime.fromNanos(
DateTimeUtils.nanosFromLocalMillis(millis + DateTimeUtils.getTimeZoneOffset(millis))
+ timeNanos % 1_000_000);
} }
case ENUM: case ENUM:
throw getDataConversionError(TIME); throw getDataConversionError(TIME);
......
...@@ -47,7 +47,8 @@ public class ValueDate extends Value { ...@@ -47,7 +47,8 @@ public class ValueDate extends Value {
* @return the value * @return the value
*/ */
public static ValueDate get(Date date) { public static ValueDate get(Date date) {
return fromDateValue(DateTimeUtils.dateValueFromDate(date.getTime())); long ms = date.getTime();
return fromDateValue(DateTimeUtils.dateValueFromLocalMillis(ms + DateTimeUtils.getTimeZoneOffset(ms)));
} }
/** /**
...@@ -58,7 +59,7 @@ public class ValueDate extends Value { ...@@ -58,7 +59,7 @@ public class ValueDate extends Value {
* @return the value * @return the value
*/ */
public static ValueDate fromMillis(long ms) { public static ValueDate fromMillis(long ms) {
return fromDateValue(DateTimeUtils.dateValueFromDate(ms)); return fromDateValue(DateTimeUtils.dateValueFromLocalMillis(ms + DateTimeUtils.getTimeZoneOffset(ms)));
} }
/** /**
......
...@@ -84,7 +84,8 @@ public class ValueTime extends Value { ...@@ -84,7 +84,8 @@ public class ValueTime extends Value {
* @return the value * @return the value
*/ */
public static ValueTime get(Time time) { public static ValueTime get(Time time) {
return fromNanos(DateTimeUtils.nanosFromDate(time.getTime())); long ms = time.getTime();
return fromNanos(DateTimeUtils.nanosFromLocalMillis(ms + DateTimeUtils.getTimeZoneOffset(ms)));
} }
/** /**
...@@ -95,7 +96,7 @@ public class ValueTime extends Value { ...@@ -95,7 +96,7 @@ public class ValueTime extends Value {
* @return the value * @return the value
*/ */
public static ValueTime fromMillis(long ms) { public static ValueTime fromMillis(long ms) {
return fromNanos(DateTimeUtils.nanosFromDate(ms)); return fromNanos(DateTimeUtils.nanosFromLocalMillis(ms + DateTimeUtils.getTimeZoneOffset(ms)));
} }
/** /**
......
...@@ -89,8 +89,9 @@ public class ValueTimestamp extends Value { ...@@ -89,8 +89,9 @@ public class ValueTimestamp extends Value {
public static ValueTimestamp get(Timestamp timestamp) { public static ValueTimestamp get(Timestamp timestamp) {
long ms = timestamp.getTime(); long ms = timestamp.getTime();
long nanos = timestamp.getNanos() % 1_000_000; long nanos = timestamp.getNanos() % 1_000_000;
long dateValue = DateTimeUtils.dateValueFromDate(ms); ms += DateTimeUtils.getTimeZoneOffset(ms);
nanos += DateTimeUtils.nanosFromDate(ms); long dateValue = DateTimeUtils.dateValueFromLocalMillis(ms);
nanos += DateTimeUtils.nanosFromLocalMillis(ms);
return fromDateValueAndNanos(dateValue, nanos); return fromDateValueAndNanos(dateValue, nanos);
} }
...@@ -102,8 +103,9 @@ public class ValueTimestamp extends Value { ...@@ -102,8 +103,9 @@ public class ValueTimestamp extends Value {
* @return the value * @return the value
*/ */
public static ValueTimestamp fromMillisNanos(long ms, int nanos) { public static ValueTimestamp fromMillisNanos(long ms, int nanos) {
long dateValue = DateTimeUtils.dateValueFromDate(ms); ms += DateTimeUtils.getTimeZoneOffset(ms);
long timeNanos = nanos + DateTimeUtils.nanosFromDate(ms); long dateValue = DateTimeUtils.dateValueFromLocalMillis(ms);
long timeNanos = nanos + DateTimeUtils.nanosFromLocalMillis(ms);
return fromDateValueAndNanos(dateValue, timeNanos); return fromDateValueAndNanos(dateValue, timeNanos);
} }
...@@ -114,8 +116,9 @@ public class ValueTimestamp extends Value { ...@@ -114,8 +116,9 @@ public class ValueTimestamp extends Value {
* @return the value * @return the value
*/ */
public static ValueTimestamp fromMillis(long ms) { public static ValueTimestamp fromMillis(long ms) {
long dateValue = DateTimeUtils.dateValueFromDate(ms); ms += DateTimeUtils.getTimeZoneOffset(ms);
long nanos = DateTimeUtils.nanosFromDate(ms); long dateValue = DateTimeUtils.dateValueFromLocalMillis(ms);
long nanos = DateTimeUtils.nanosFromLocalMillis(ms);
return fromDateValueAndNanos(dateValue, nanos); return fromDateValueAndNanos(dateValue, nanos);
} }
......
...@@ -462,8 +462,10 @@ public class TestDate extends TestBase { ...@@ -462,8 +462,10 @@ public class TestDate extends TestBase {
// test for bug on Java 1.8.0_60 in "Europe/Moscow" timezone. // test for bug on Java 1.8.0_60 in "Europe/Moscow" timezone.
// Doesn't affect most other timezones // Doesn't affect most other timezones
long millis = 1407437460000L; long millis = 1407437460000L;
long result1 = DateTimeUtils.nanosFromDate(DateTimeUtils.getTimeUTCWithoutDst(millis)); long ms = DateTimeUtils.getTimeUTCWithoutDst(millis);
long result2 = DateTimeUtils.nanosFromDate(DateTimeUtils.getTimeUTCWithoutDst(millis)); ms += DateTimeUtils.getTimeZoneOffset(ms);
long result1 = DateTimeUtils.nanosFromLocalMillis(ms);
long result2 = DateTimeUtils.nanosFromLocalMillis(ms);
assertEquals(result1, result2); assertEquals(result1, result2);
} }
......
...@@ -159,8 +159,9 @@ public class TestDateTimeUtils extends TestBase { ...@@ -159,8 +159,9 @@ public class TestDateTimeUtils extends TestBase {
gc.set(year, month - 1, day, j / 2, (j & 1) * 30, 0); gc.set(year, month - 1, day, j / 2, (j & 1) * 30, 0);
long timeMillis = gc.getTimeInMillis(); long timeMillis = gc.getTimeInMillis();
ValueTimestamp ts = DateTimeUtils.convertTimestamp(new Timestamp(timeMillis), gc); ValueTimestamp ts = DateTimeUtils.convertTimestamp(new Timestamp(timeMillis), gc);
assertEquals(ts.getDateValue(), DateTimeUtils.dateValueFromDate(timeMillis)); timeMillis += DateTimeUtils.getTimeZoneOffset(timeMillis);
assertEquals(ts.getTimeNanos(), DateTimeUtils.nanosFromDate(timeMillis)); assertEquals(ts.getDateValue(), DateTimeUtils.dateValueFromLocalMillis(timeMillis));
assertEquals(ts.getTimeNanos(), DateTimeUtils.nanosFromLocalMillis(timeMillis));
} }
} }
} }
......
...@@ -66,7 +66,7 @@ public class GenerateHelp { ...@@ -66,7 +66,7 @@ public class GenerateHelp {
"Multiple-Licensed under the MPL 2.0,\n" + "Multiple-Licensed under the MPL 2.0,\n" +
"# and the EPL 1.0 " + "# and the EPL 1.0 " +
"(http://h2database.com/html/license.html).\n" + "(http://h2database.com/html/license.html).\n" +
"# Initial Developer: H2 Group)\n"); "# Initial Developer: H2 Group\n");
csv = new Csv(); csv = new Csv();
csv.setLineSeparator("\n"); csv.setLineSeparator("\n");
csv.write(writer, rs2); csv.write(writer, rs2);
......
...@@ -804,3 +804,4 @@ qualification opportunity jumping exploited unacceptable vrs duplicated ...@@ -804,3 +804,4 @@ qualification opportunity jumping exploited unacceptable vrs duplicated
queryparser tokenized freeze factorings recompilation unenclosed rfe dsync queryparser tokenized freeze factorings recompilation unenclosed rfe dsync
econd irst bcef ordinality nord unnest econd irst bcef ordinality nord unnest
analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan
corrupts splitted disruption unintentional
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论