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.
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.
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(65535 AS BINARY);
CAST(CAST('FFFF' AS BINARY) AS INT);
CAST(TIMESTAMP '2010-01-01 10:40:00.123456' AS TIME(6))
"
"Functions (System)","COALESCE","
......
......@@ -21,8 +21,22 @@ Change Log
<h2>Next Version (unreleased)</h2>
<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>
<li>Issue #187: SHUTDOWN DEFRAG corrupts splitted file database
</li>
<li>PR #1571: Optimizing ConditionAndOr queries
</li>
<li>Issue #1565: SOME / ANY conflict
......
......@@ -25,7 +25,7 @@ public final class CurrentTimestamp {
* epoch and time zone offsets with seconds because such support is not
* 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;
return ValueTimestampTimeZone.fromDateValueAndNanos(
DateTimeUtils.dateValueFromAbsoluteDay(second / DateTimeUtils.SECONDS_PER_DAY),
......
......@@ -206,12 +206,6 @@ public class DbSettings extends SettingsBase {
*/
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 />
* Convert (C=? OR C=?) to (C IN(?, ?)).
......
......@@ -397,12 +397,8 @@ public class Comparison extends Condition {
if (l != null) {
switch (compareType) {
case IS_NULL:
if (session.getDatabase().getSettings().optimizeIsNull) {
filter.addIndexCondition(
IndexCondition.get(
Comparison.EQUAL_NULL_SAFE, l,
ValueExpression.getNull()));
}
filter.addIndexCondition(
IndexCondition.get(Comparison.EQUAL_NULL_SAFE, l, ValueExpression.getNull()));
}
}
return;
......
......@@ -33,7 +33,6 @@ import org.h2.value.ValueNull;
*/
public class IndexCursor implements Cursor {
private Session session;
private final TableFilter tableFilter;
private Index index;
private Table table;
......@@ -75,7 +74,6 @@ public class IndexCursor implements Cursor {
* @param indexConditions Index conditions.
*/
public void prepare(Session s, ArrayList<IndexCondition> indexConditions) {
this.session = s;
alwaysFalse = false;
start = end = null;
inList = null;
......@@ -142,14 +140,6 @@ public class IndexCursor implements Cursor {
inList = 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) {
......@@ -239,24 +229,16 @@ public class IndexCursor implements Cursor {
} else if (b == null) {
return a;
}
if (session.getDatabase().getSettings().optimizeIsNull) {
// IS NULL must be checked later
if (a == ValueNull.INSTANCE) {
return b;
} else if (b == ValueNull.INSTANCE) {
return a;
}
// IS NULL must be checked later
if (a == ValueNull.INSTANCE) {
return b;
} else if (b == ValueNull.INSTANCE) {
return a;
}
int comp = table.getDatabase().compare(a, b);
if (comp == 0) {
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;
}
......
......@@ -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;
if (tz == null) {
timeZone = tz = TimeZone.getDefault();
}
return tz;
return tz.getOffset(ms);
}
/**
......@@ -568,8 +569,9 @@ public class DateTimeUtils {
}
} else {
long millis = convertDateTimeValueToMillis(tz, dateValue, nanos / 1_000_000);
dateValue = dateValueFromDate(millis);
nanos = nanos % 1_000_000 + nanosFromDate(millis);
millis += getTimeZoneOffset(millis);
dateValue = dateValueFromLocalMillis(millis);
nanos = nanos % 1_000_000 + nanosFromLocalMillis(millis);
}
}
}
......@@ -1119,14 +1121,12 @@ public class DateTimeUtils {
}
/**
* Convert a UTC datetime in millis to an encoded date in the default
* timezone.
* Convert a local datetime in millis to an encoded date.
*
* @param ms the milliseconds
* @return the date value
*/
public static long dateValueFromDate(long ms) {
ms += getTimeZone().getOffset(ms);
public static long dateValueFromLocalMillis(long ms) {
long absoluteDay = ms / MILLIS_PER_DAY;
// Round toward negative infinity
if (ms < 0 && (absoluteDay * MILLIS_PER_DAY != ms)) {
......@@ -1152,14 +1152,12 @@ public class DateTimeUtils {
}
/**
* Convert a time in milliseconds in UTC to the nanoseconds since midnight
* (in the default timezone).
* Convert a time in milliseconds in local time to the nanoseconds since midnight.
*
* @param ms the milliseconds
* @return the nanoseconds
*/
public static long nanosFromDate(long ms) {
ms += getTimeZone().getOffset(ms);
public static long nanosFromLocalMillis(long ms) {
long absoluteDay = ms / MILLIS_PER_DAY;
// Round toward negative infinity
if (ms < 0 && (absoluteDay * MILLIS_PER_DAY != ms)) {
......@@ -1236,7 +1234,7 @@ public class DateTimeUtils {
* @return timestamp with time zone with specified value and current time zone
*/
public static ValueTimestampTimeZone timestampTimeZoneFromMillis(long ms) {
int offset = getTimeZone().getOffset(ms);
int offset = getTimeZoneOffset(ms);
ms += offset;
long absoluteDay = ms / MILLIS_PER_DAY;
// Round toward negative infinity
......
......@@ -242,8 +242,9 @@ public class StringUtils {
*/
public static String addAsterisk(String s, int index) {
if (s != null) {
index = Math.min(index, s.length());
s = s.substring(0, index) + "[*]" + s.substring(index);
int len = s.length();
index = Math.min(index, len);
s = new StringBuilder(len + 3).append(s, 0, index).append("[*]").append(s, index, len).toString();
}
return s;
}
......
......@@ -1043,7 +1043,9 @@ public abstract class Value {
ValueTimestampTimeZone ts = (ValueTimestampTimeZone) this;
long dateValue = ts.getDateValue(), timeNanos = ts.getTimeNanos();
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:
throw getDataConversionError(TIME);
......
......@@ -47,7 +47,8 @@ public class ValueDate extends Value {
* @return the value
*/
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 {
* @return the value
*/
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 {
* @return the value
*/
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 {
* @return the value
*/
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 {
public static ValueTimestamp get(Timestamp timestamp) {
long ms = timestamp.getTime();
long nanos = timestamp.getNanos() % 1_000_000;
long dateValue = DateTimeUtils.dateValueFromDate(ms);
nanos += DateTimeUtils.nanosFromDate(ms);
ms += DateTimeUtils.getTimeZoneOffset(ms);
long dateValue = DateTimeUtils.dateValueFromLocalMillis(ms);
nanos += DateTimeUtils.nanosFromLocalMillis(ms);
return fromDateValueAndNanos(dateValue, nanos);
}
......@@ -102,8 +103,9 @@ public class ValueTimestamp extends Value {
* @return the value
*/
public static ValueTimestamp fromMillisNanos(long ms, int nanos) {
long dateValue = DateTimeUtils.dateValueFromDate(ms);
long timeNanos = nanos + DateTimeUtils.nanosFromDate(ms);
ms += DateTimeUtils.getTimeZoneOffset(ms);
long dateValue = DateTimeUtils.dateValueFromLocalMillis(ms);
long timeNanos = nanos + DateTimeUtils.nanosFromLocalMillis(ms);
return fromDateValueAndNanos(dateValue, timeNanos);
}
......@@ -114,8 +116,9 @@ public class ValueTimestamp extends Value {
* @return the value
*/
public static ValueTimestamp fromMillis(long ms) {
long dateValue = DateTimeUtils.dateValueFromDate(ms);
long nanos = DateTimeUtils.nanosFromDate(ms);
ms += DateTimeUtils.getTimeZoneOffset(ms);
long dateValue = DateTimeUtils.dateValueFromLocalMillis(ms);
long nanos = DateTimeUtils.nanosFromLocalMillis(ms);
return fromDateValueAndNanos(dateValue, nanos);
}
......
......@@ -462,8 +462,10 @@ public class TestDate extends TestBase {
// test for bug on Java 1.8.0_60 in "Europe/Moscow" timezone.
// Doesn't affect most other timezones
long millis = 1407437460000L;
long result1 = DateTimeUtils.nanosFromDate(DateTimeUtils.getTimeUTCWithoutDst(millis));
long result2 = DateTimeUtils.nanosFromDate(DateTimeUtils.getTimeUTCWithoutDst(millis));
long ms = DateTimeUtils.getTimeUTCWithoutDst(millis);
ms += DateTimeUtils.getTimeZoneOffset(ms);
long result1 = DateTimeUtils.nanosFromLocalMillis(ms);
long result2 = DateTimeUtils.nanosFromLocalMillis(ms);
assertEquals(result1, result2);
}
......
......@@ -159,8 +159,9 @@ public class TestDateTimeUtils extends TestBase {
gc.set(year, month - 1, day, j / 2, (j & 1) * 30, 0);
long timeMillis = gc.getTimeInMillis();
ValueTimestamp ts = DateTimeUtils.convertTimestamp(new Timestamp(timeMillis), gc);
assertEquals(ts.getDateValue(), DateTimeUtils.dateValueFromDate(timeMillis));
assertEquals(ts.getTimeNanos(), DateTimeUtils.nanosFromDate(timeMillis));
timeMillis += DateTimeUtils.getTimeZoneOffset(timeMillis);
assertEquals(ts.getDateValue(), DateTimeUtils.dateValueFromLocalMillis(timeMillis));
assertEquals(ts.getTimeNanos(), DateTimeUtils.nanosFromLocalMillis(timeMillis));
}
}
}
......
......@@ -66,7 +66,7 @@ public class GenerateHelp {
"Multiple-Licensed under the MPL 2.0,\n" +
"# and the EPL 1.0 " +
"(http://h2database.com/html/license.html).\n" +
"# Initial Developer: H2 Group)\n");
"# Initial Developer: H2 Group\n");
csv = new Csv();
csv.setLineSeparator("\n");
csv.write(writer, rs2);
......
......@@ -804,3 +804,4 @@ qualification opportunity jumping exploited unacceptable vrs duplicated
queryparser tokenized freeze factorings recompilation unenclosed rfe dsync
econd irst bcef ordinality nord unnest
analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan
corrupts splitted disruption unintentional
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论