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

Merge pull request #1181 from katzyn/current_timestamp

Improve CURRENT_TIMESTAMP and add LOCALTIME and LOCALTIMESTAMP
...@@ -3944,24 +3944,45 @@ CURRENT_DATE() ...@@ -3944,24 +3944,45 @@ CURRENT_DATE()
" "
"Functions (Time and Date)","CURRENT_TIME"," "Functions (Time and Date)","CURRENT_TIME","
{ CURRENT_TIME [ () ] | CURTIME() } { CURRENT_TIME [ ( [ int ] ) ] | LOCALTIME [ ( [ int ] ) ] | CURTIME() }
"," ","
Returns the current time. Returns the current time.
This method always returns the same value within a transaction. If fractional seconds precision is specified it should be from 0 to 9, 0 is default.
The specified value can be used only to limit precision of a result.
The actual maximum available precision depends on operating system and JVM and can be 3 (milliseconds) or higher.
Higher precision is not available before Java 9.
These methods always return the same value within a transaction.
"," ","
CURRENT_TIME() CURRENT_TIME()
" "
"Functions (Time and Date)","CURRENT_TIMESTAMP"," "Functions (Time and Date)","CURRENT_TIMESTAMP","
{ CURRENT_TIMESTAMP [ ( [ int ] ) ] | NOW( [ int ] ) } CURRENT_TIMESTAMP [ ( [ int ] ) ]
"," ","
Returns the current timestamp. Returns the current timestamp with time zone.
The precision parameter for nanoseconds precision is optional. Time zone offset is set to a current time zone offset
If fractional seconds precision is specified it should be from 0 to 9, 6 is default.
The specified value can be used only to limit precision of a result.
The actual maximum available precision depends on operating system and JVM and can be 3 (milliseconds) or higher.
Higher precision is not available before Java 9.
This method always returns the same value within a transaction. This method always returns the same value within a transaction.
"," ","
CURRENT_TIMESTAMP() CURRENT_TIMESTAMP()
" "
"Functions (Time and Date)","LOCALTIMESTAMP","
{ LOCALTIMESTAMP [ ( [ int ] ) ] | NOW( [ int ] ) }
","
Returns the current timestamp.
If fractional seconds precision is specified it should be from 0 to 9, 6 is default.
The specified value can be used only to limit precision of a result.
The actual maximum available precision depends on operating system and JVM and can be 3 (milliseconds) or higher.
Higher precision is not available before Java 9.
These methods always return the same value within a transaction.
","
LOCALTIMESTAMP()
"
"Functions (Time and Date)","DATEADD"," "Functions (Time and Date)","DATEADD","
{ DATEADD| TIMESTAMPADD } (datetimeField, addIntLong, dateAndTime) { DATEADD| TIMESTAMPADD } (datetimeField, addIntLong, dateAndTime)
"," ","
......
...@@ -504,8 +504,9 @@ unless they are quoted (surrounded with double quotes). The list is currently: ...@@ -504,8 +504,9 @@ unless they are quoted (surrounded with double quotes). The list is currently:
<code> <code>
ALL, CHECK, CONSTRAINT, CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT, EXCEPT, ALL, CHECK, CONSTRAINT, CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT, EXCEPT,
EXISTS, FALSE, FETCH, FOR, FOREIGN, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, INTERSECTS, EXISTS, FALSE, FETCH, FOR, FOREIGN, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, INTERSECTS,
IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL, OFFSET, ON, ORDER, PRIMARY, ROWNUM, SELECT, IS, JOIN, LIKE, LIMIT, LOCALTIME, LOCALTIMESTAMP, MINUS, NATURAL, NOT, NULL, OFFSET, ON, ORDER,
SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, WHERE, WITH PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, WHERE,
WITH
</code> </code>
</p><p> </p><p>
Certain words of this list are keywords because they are functions that can be used without '()' for compatibility, Certain words of this list are keywords because they are functions that can be used without '()' for compatibility,
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
import java.time.Instant;
import org.h2.value.ValueTimestampTimeZone;
public final class CurrentTimestamp {
/**
* Returns current timestamp.
*
* @return current timestamp
*/
public static ValueTimestampTimeZone get() {
Instant now = Instant.now();
long second = now.getEpochSecond();
int nano = now.getNano();
/*
* This code intentionally does not support properly dates before UNIX
* 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;
second += offsetSec;
return ValueTimestampTimeZone.fromDateValueAndNanos(
DateTimeUtils.dateValueFromAbsoluteDay(second / DateTimeUtils.SECONDS_PER_DAY),
second % DateTimeUtils.SECONDS_PER_DAY * 1_000_000_000 + nano, (short) (offsetSec / 60));
}
private CurrentTimestamp() {
}
}
...@@ -3148,6 +3148,8 @@ public class Parser { ...@@ -3148,6 +3148,8 @@ public class Parser {
r = readFunctionWithoutParameters("USER"); r = readFunctionWithoutParameters("USER");
} else if (equalsToken("CURRENT_TIMESTAMP", name)) { } else if (equalsToken("CURRENT_TIMESTAMP", name)) {
r = readFunctionWithoutParameters("CURRENT_TIMESTAMP"); r = readFunctionWithoutParameters("CURRENT_TIMESTAMP");
} else if (equalsToken("LOCALTIMESTAMP", name)) {
r = readFunctionWithoutParameters("LOCALTIMESTAMP");
} else if (equalsToken("SYSDATE", name)) { } else if (equalsToken("SYSDATE", name)) {
r = readFunctionWithoutParameters("CURRENT_TIMESTAMP"); r = readFunctionWithoutParameters("CURRENT_TIMESTAMP");
} else if (equalsToken("SYSTIMESTAMP", name)) { } else if (equalsToken("SYSTIMESTAMP", name)) {
...@@ -3158,6 +3160,8 @@ public class Parser { ...@@ -3158,6 +3160,8 @@ public class Parser {
r = readFunctionWithoutParameters("CURRENT_DATE"); r = readFunctionWithoutParameters("CURRENT_DATE");
} else if (equalsToken("CURRENT_TIME", name)) { } else if (equalsToken("CURRENT_TIME", name)) {
r = readFunctionWithoutParameters("CURRENT_TIME"); r = readFunctionWithoutParameters("CURRENT_TIME");
} else if (equalsToken("LOCALTIME", name)) {
r = readFunctionWithoutParameters("LOCALTIME");
} else if (equalsToken("SYSTIME", name)) { } else if (equalsToken("SYSTIME", name)) {
r = readFunctionWithoutParameters("CURRENT_TIME"); r = readFunctionWithoutParameters("CURRENT_TIME");
} else if (equalsToken("CURRENT", name)) { } else if (equalsToken("CURRENT", name)) {
......
...@@ -48,6 +48,7 @@ import org.h2.table.Table; ...@@ -48,6 +48,7 @@ import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.table.TableType; import org.h2.table.TableType;
import org.h2.util.ColumnNamerConfiguration; import org.h2.util.ColumnNamerConfiguration;
import org.h2.util.CurrentTimestamp;
import org.h2.util.SmallLRUCache; import org.h2.util.SmallLRUCache;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -55,6 +56,7 @@ import org.h2.value.ValueArray; ...@@ -55,6 +56,7 @@ import org.h2.value.ValueArray;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.h2.value.ValueString; import org.h2.value.ValueString;
import org.h2.value.ValueTimestampTimeZone;
/** /**
* A session represents an embedded database connection. When using the server * A session represents an embedded database connection. When using the server
...@@ -114,7 +116,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -114,7 +116,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
private volatile long cancelAtNs; private volatile long cancelAtNs;
private boolean closed; private boolean closed;
private final long sessionStart = System.currentTimeMillis(); private final long sessionStart = System.currentTimeMillis();
private long transactionStart; private ValueTimestampTimeZone transactionStart;
private long currentCommandStart; private long currentCommandStart;
private HashMap<String, Value> variables; private HashMap<String, Value> variables;
private HashSet<ResultInterface> temporaryResults; private HashSet<ResultInterface> temporaryResults;
...@@ -666,7 +668,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -666,7 +668,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
tablesToAnalyze = null; tablesToAnalyze = null;
currentTransactionName = null; currentTransactionName = null;
transactionStart = 0; transactionStart = null;
if (transaction != null) { if (transaction != null) {
try { try {
// increment the data mod count, so that other sessions // increment the data mod count, so that other sessions
...@@ -773,7 +775,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -773,7 +775,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
public void rollback() { public void rollback() {
checkCommitRollback(); checkCommitRollback();
currentTransactionName = null; currentTransactionName = null;
transactionStart = 0; transactionStart = null;
boolean needCommit = undoLog.size() > 0 || transaction != null; boolean needCommit = undoLog.size() > 0 || transaction != null;
if(needCommit) { if(needCommit) {
rollbackTo(null, false); rollbackTo(null, false);
...@@ -1128,7 +1130,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -1128,7 +1130,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
public void rollbackToSavepoint(String name) { public void rollbackToSavepoint(String name) {
checkCommitRollback(); checkCommitRollback();
currentTransactionName = null; currentTransactionName = null;
transactionStart = 0; transactionStart = null;
if (savepoints == null) { if (savepoints == null) {
throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name); throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name);
} }
...@@ -1453,9 +1455,9 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -1453,9 +1455,9 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
return sessionStart; return sessionStart;
} }
public long getTransactionStart() { public ValueTimestampTimeZone getTransactionStart() {
if (transactionStart == 0) { if (transactionStart == null) {
transactionStart = System.currentTimeMillis(); transactionStart = CurrentTimestamp.get();
} }
return transactionStart; return transactionStart;
} }
......
...@@ -98,7 +98,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -98,7 +98,7 @@ public class Function extends Expression implements FunctionCall {
public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102, public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102,
DATE_DIFF = 103, DAY_NAME = 104, DAY_OF_MONTH = 105, DATE_DIFF = 103, DAY_NAME = 104, DAY_OF_MONTH = 105,
DAY_OF_WEEK = 106, DAY_OF_YEAR = 107, HOUR = 108, MINUTE = 109, DAY_OF_WEEK = 106, DAY_OF_YEAR = 107, HOUR = 108, MINUTE = 109,
MONTH = 110, MONTH_NAME = 111, NOW = 112, QUARTER = 113, MONTH = 110, MONTH_NAME = 111, LOCALTIMESTAMP = 112, QUARTER = 113,
SECOND = 114, WEEK = 115, YEAR = 116, CURRENT_DATE = 117, SECOND = 114, WEEK = 115, YEAR = 116, CURRENT_DATE = 117,
CURRENT_TIME = 118, CURRENT_TIMESTAMP = 119, EXTRACT = 120, CURRENT_TIME = 118, CURRENT_TIMESTAMP = 119, EXTRACT = 120,
FORMATDATETIME = 121, PARSEDATETIME = 122, ISO_YEAR = 123, FORMATDATETIME = 121, PARSEDATETIME = 122, ISO_YEAR = 123,
...@@ -294,18 +294,22 @@ public class Function extends Expression implements FunctionCall { ...@@ -294,18 +294,22 @@ public class Function extends Expression implements FunctionCall {
addFunctionNotDeterministic("GETDATE", CURDATE, addFunctionNotDeterministic("GETDATE", CURDATE,
0, Value.DATE); 0, Value.DATE);
addFunctionNotDeterministic("CURRENT_TIME", CURRENT_TIME, addFunctionNotDeterministic("CURRENT_TIME", CURRENT_TIME,
0, Value.TIME); VAR_ARGS, Value.TIME);
addFunctionNotDeterministic("LOCALTIME", CURRENT_TIME,
VAR_ARGS, Value.TIME);
addFunctionNotDeterministic("SYSTIME", CURRENT_TIME, addFunctionNotDeterministic("SYSTIME", CURRENT_TIME,
0, Value.TIME); 0, Value.TIME);
addFunctionNotDeterministic("CURTIME", CURTIME, addFunctionNotDeterministic("CURTIME", CURTIME,
0, Value.TIME); 0, Value.TIME);
addFunctionNotDeterministic("CURRENT_TIMESTAMP", CURRENT_TIMESTAMP, addFunctionNotDeterministic("CURRENT_TIMESTAMP", CURRENT_TIMESTAMP,
VAR_ARGS, Value.TIMESTAMP); VAR_ARGS, Value.TIMESTAMP_TZ);
addFunctionNotDeterministic("SYSDATE", CURRENT_TIMESTAMP, addFunctionNotDeterministic("SYSDATE", CURRENT_TIMESTAMP,
VAR_ARGS, Value.TIMESTAMP); VAR_ARGS, Value.TIMESTAMP_TZ);
addFunctionNotDeterministic("SYSTIMESTAMP", CURRENT_TIMESTAMP, addFunctionNotDeterministic("SYSTIMESTAMP", CURRENT_TIMESTAMP,
VAR_ARGS, Value.TIMESTAMP_TZ);
addFunctionNotDeterministic("LOCALTIMESTAMP", LOCALTIMESTAMP,
VAR_ARGS, Value.TIMESTAMP); VAR_ARGS, Value.TIMESTAMP);
addFunctionNotDeterministic("NOW", NOW, addFunctionNotDeterministic("NOW", LOCALTIMESTAMP,
VAR_ARGS, Value.TIMESTAMP); VAR_ARGS, Value.TIMESTAMP);
addFunction("DATEADD", DATE_ADD, addFunction("DATEADD", DATE_ADD,
3, Value.TIMESTAMP); 3, Value.TIMESTAMP);
...@@ -823,28 +827,23 @@ public class Function extends Expression implements FunctionCall { ...@@ -823,28 +827,23 @@ public class Function extends Expression implements FunctionCall {
} }
case CURDATE: case CURDATE:
case CURRENT_DATE: { case CURRENT_DATE: {
long now = session.getTransactionStart(); result = session.getTransactionStart().convertTo(Value.DATE);
// need to normalize
result = ValueDate.fromMillis(now);
break; break;
} }
case CURTIME: case CURTIME:
case CURRENT_TIME: { case CURRENT_TIME: {
long now = session.getTransactionStart(); ValueTime vt = (ValueTime) session.getTransactionStart().convertTo(Value.TIME);
// need to normalize result = vt.convertScale(false, v0 == null ? 0 : v0.getInt());
result = ValueTime.fromMillis(now);
break; break;
} }
case NOW: case LOCALTIMESTAMP: {
case CURRENT_TIMESTAMP: { Value vt = session.getTransactionStart().convertTo(Value.TIMESTAMP);
long now = session.getTransactionStart(); result = vt.convertScale(false, v0 == null ? 6 : v0.getInt());
ValueTimestamp vt = ValueTimestamp.fromMillis(now); break;
if (v0 != null) {
Mode mode = database.getMode();
vt = (ValueTimestamp) vt.convertScale(
mode.convertOnlyToSmallerScale, v0.getInt());
} }
result = vt; case CURRENT_TIMESTAMP: {
ValueTimestampTimeZone vt = session.getTransactionStart();
result = vt.convertScale(false, v0 == null ? 6 : v0.getInt());
break; break;
} }
case DATABASE: case DATABASE:
...@@ -2067,7 +2066,8 @@ public class Function extends Expression implements FunctionCall { ...@@ -2067,7 +2066,8 @@ public class Function extends Expression implements FunctionCall {
case GREATEST: case GREATEST:
min = 1; min = 1;
break; break;
case NOW: case LOCALTIMESTAMP:
case CURRENT_TIME:
case CURRENT_TIMESTAMP: case CURRENT_TIMESTAMP:
case RAND: case RAND:
max = 1; max = 1;
......
...@@ -1545,9 +1545,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements ...@@ -1545,9 +1545,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements
* <pre> * <pre>
* ALL, CHECK, CONSTRAINT, CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, * ALL, CHECK, CONSTRAINT, CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP,
* DISTINCT, EXCEPT, EXISTS, FALSE, FETCH, FOR, FOREIGN, FROM, FULL, GROUP, * DISTINCT, EXCEPT, EXISTS, FALSE, FETCH, FOR, FOREIGN, FROM, FULL, GROUP,
* HAVING, INNER, INTERSECT, INTERSECTS, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, * HAVING, INNER, INTERSECT, INTERSECTS, IS, JOIN, LIKE, LIMIT, LOCALTIME,
* NOT, NULL, OFFSET, ON, ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, * LOCALTIMESTAMP, MINUS, NATURAL, NOT, NULL, OFFSET, ON, ORDER, PRIMARY, ROWNUM,
* SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, WHERE, WITH * SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, WHERE,
* WITH
* </pre> * </pre>
* *
* @return a list of additional the keywords * @return a list of additional the keywords
......
...@@ -21,20 +21,16 @@ import org.h2.message.DbException; ...@@ -21,20 +21,16 @@ import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueDate;
import org.h2.value.ValueEnum; import org.h2.value.ValueEnum;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.h2.value.ValueString; import org.h2.value.ValueString;
import org.h2.value.ValueTime; import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp;
import org.h2.value.ValueTimestampTimeZone;
import org.h2.value.ValueUuid; import org.h2.value.ValueUuid;
/** /**
...@@ -361,16 +357,13 @@ public class Column { ...@@ -361,16 +357,13 @@ public class Column {
if (dt.decimal) { if (dt.decimal) {
value = ValueInt.get(0).convertTo(type); value = ValueInt.get(0).convertTo(type);
} else if (dt.type == Value.TIMESTAMP) { } else if (dt.type == Value.TIMESTAMP) {
value = ValueTimestamp.fromMillis(session.getTransactionStart()); value = session.getTransactionStart().convertTo(Value.TIMESTAMP);
} else if (dt.type == Value.TIMESTAMP_TZ) { } else if (dt.type == Value.TIMESTAMP_TZ) {
long ms = session.getTransactionStart(); value = session.getTransactionStart();
value = ValueTimestampTimeZone.fromDateValueAndNanos(
DateTimeUtils.dateValueFromDate(ms),
DateTimeUtils.nanosFromDate(ms), (short) 0);
} else if (dt.type == Value.TIME) { } else if (dt.type == Value.TIME) {
value = ValueTime.fromNanos(0); value = ValueTime.fromNanos(0);
} else if (dt.type == Value.DATE) { } else if (dt.type == Value.DATE) {
value = ValueDate.fromMillis(session.getTransactionStart()); value = session.getTransactionStart().convertTo(Value.DATE);
} else { } else {
value = ValueString.get("").convertTo(type); value = ValueString.get("").convertTo(type);
} }
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
import org.h2.value.ValueTimestampTimeZone;
public final class CurrentTimestamp {
/*
* Signatures of methods should match with
* h2/src/java9/src/org/h2/util/CurrentTimestamp.java and precompiled
* h2/src/java9/precompiled/org/h2/util/CurrentTimestamp.class.
*/
/**
* Returns current timestamp.
*
* @return current timestamp
*/
public static ValueTimestampTimeZone get() {
long ms = System.currentTimeMillis();
/*
* This code intentionally does not support properly dates before UNIX
* epoch and time zone offsets with seconds because such support is not
* required for current dates.
*/
int offset = DateTimeUtils.getTimeZone().getOffset(ms);
ms += offset;
return ValueTimestampTimeZone.fromDateValueAndNanos(
DateTimeUtils.dateValueFromAbsoluteDay(ms / DateTimeUtils.MILLIS_PER_DAY),
ms % DateTimeUtils.MILLIS_PER_DAY * 1_000_000, (short) (offset / 60_000));
}
private CurrentTimestamp() {
}
}
...@@ -112,7 +112,7 @@ public class DateTimeUtils { ...@@ -112,7 +112,7 @@ public class DateTimeUtils {
* *
* @return local time zone * @return local time zone
*/ */
private static TimeZone getTimeZone() { static TimeZone getTimeZone() {
TimeZone tz = timeZone; TimeZone tz = timeZone;
if (tz == null) { if (tz == null) {
timeZone = tz = TimeZone.getDefault(); timeZone = tz = TimeZone.getDefault();
...@@ -506,7 +506,7 @@ public class DateTimeUtils { ...@@ -506,7 +506,7 @@ public class DateTimeUtils {
if (withTimeZone) { if (withTimeZone) {
if (tz != UTC) { if (tz != UTC) {
long millis = convertDateTimeValueToMillis(tz, dateValue, nanos / 1_000_000); long millis = convertDateTimeValueToMillis(tz, dateValue, nanos / 1_000_000);
tzMinutes = (short) (tz.getOffset(millis) / 1000 / 60); tzMinutes = (short) (tz.getOffset(millis) / 60_000);
} }
} else { } else {
long millis = convertDateTimeValueToMillis(tz, dateValue, nanos / 1_000_000); long millis = convertDateTimeValueToMillis(tz, dateValue, nanos / 1_000_000);
......
...@@ -147,10 +147,15 @@ public class ParserUtil { ...@@ -147,10 +147,15 @@ public class ParserUtil {
case 'J': case 'J':
return getKeywordOrIdentifier(s, "JOIN", KEYWORD); return getKeywordOrIdentifier(s, "JOIN", KEYWORD);
case 'L': case 'L':
if ("LIMIT".equals(s)) { if ("LIMIT".equals(s) || "LIKE".equals(s)) {
return KEYWORD; return KEYWORD;
} }
return getKeywordOrIdentifier(s, "LIKE", KEYWORD); if (additionalKeywords) {
if ("LOCALTIME".equals(s) || "LOCALTIMESTAMP".equals(s)) {
return KEYWORD;
}
}
return IDENTIFIER;
case 'M': case 'M':
return getKeywordOrIdentifier(s, "MINUS", KEYWORD); return getKeywordOrIdentifier(s, "MINUS", KEYWORD);
case 'N': case 'N':
......
...@@ -21,3 +21,12 @@ select length(now())>18 c1, length(current_timestamp())>18 c2, length(now(0))>18 ...@@ -21,3 +21,12 @@ select length(now())>18 c1, length(current_timestamp())>18 c2, length(now(0))>18
> ---- ---- ---- ---- > ---- ---- ---- ----
> TRUE TRUE TRUE TRUE > TRUE TRUE TRUE TRUE
> rows: 1 > rows: 1
SELECT CAST(CURRENT_TIME AS TIME(9)) = LOCALTIME;
>> TRUE
SELECT CAST(CURRENT_TIME(0) AS TIME(9)) = LOCALTIME(0);
>> TRUE
SELECT CAST(CURRENT_TIME(9) AS TIME(9)) = LOCALTIME(9);
>> TRUE
...@@ -2,3 +2,12 @@ ...@@ -2,3 +2,12 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
SELECT CAST(CURRENT_TIMESTAMP AS TIMESTAMP(9)) = LOCALTIMESTAMP;
>> TRUE
SELECT CAST(CURRENT_TIMESTAMP(0) AS TIMESTAMP(9)) = LOCALTIMESTAMP(0);
>> TRUE
SELECT CAST(CURRENT_TIMESTAMP(9) AS TIMESTAMP(9)) = LOCALTIMESTAMP(9);
>> TRUE
...@@ -501,9 +501,14 @@ public class Build extends BuildBase { ...@@ -501,9 +501,14 @@ public class Build extends BuildBase {
/** /**
* Add META-INF/versions for Java 9+. * Add META-INF/versions for Java 9+.
*
* @param includeCurrentTimestamp include CurrentTimestamp implementation
*/ */
private void addVersions() { private void addVersions(boolean includeCurrentTimestamp) {
copy("temp/META-INF/versions/9", files("src/java9/precompiled"), "src/java9/precompiled"); copy("temp/META-INF/versions/9", files("src/java9/precompiled"), "src/java9/precompiled");
if (!includeCurrentTimestamp) {
delete(files("temp/META-INF/versions/9/org/h2/util/CurrentTimestamp.class"));
}
} }
/** /**
...@@ -512,7 +517,7 @@ public class Build extends BuildBase { ...@@ -512,7 +517,7 @@ public class Build extends BuildBase {
@Description(summary = "Create the regular h2.jar file.") @Description(summary = "Create the regular h2.jar file.")
public void jar() { public void jar() {
compile(); compile();
addVersions(); addVersions(true);
manifest("H2 Database Engine", "org.h2.tools.Console"); manifest("H2 Database Engine", "org.h2.tools.Console");
FileList files = files("temp"). FileList files = files("temp").
exclude("temp/android/*"). exclude("temp/android/*").
...@@ -577,7 +582,7 @@ public class Build extends BuildBase { ...@@ -577,7 +582,7 @@ public class Build extends BuildBase {
@Description(summary = "Create h2client.jar with only the remote JDBC implementation.") @Description(summary = "Create h2client.jar with only the remote JDBC implementation.")
public void jarClient() { public void jarClient() {
compile(true, true, false); compile(true, true, false);
addVersions(); addVersions(false);
FileList files = files("temp"). FileList files = files("temp").
exclude("temp/org/h2/build/*"). exclude("temp/org/h2/build/*").
exclude("temp/org/h2/dev/*"). exclude("temp/org/h2/dev/*").
...@@ -604,7 +609,7 @@ public class Build extends BuildBase { ...@@ -604,7 +609,7 @@ public class Build extends BuildBase {
@Description(summary = "Create h2mvstore.jar containing only the MVStore.") @Description(summary = "Create h2mvstore.jar containing only the MVStore.")
public void jarMVStore() { public void jarMVStore() {
compileMVStore(true); compileMVStore(true);
addVersions(); addVersions(false);
manifestMVStore(); manifestMVStore();
FileList files = files("temp"); FileList files = files("temp");
files.exclude("*.DS_Store"); files.exclude("*.DS_Store");
...@@ -619,7 +624,7 @@ public class Build extends BuildBase { ...@@ -619,7 +624,7 @@ public class Build extends BuildBase {
@Description(summary = "Create h2small.jar containing only the embedded database.") @Description(summary = "Create h2small.jar containing only the embedded database.")
public void jarSmall() { public void jarSmall() {
compile(false, false, true); compile(false, false, true);
addVersions(); addVersions(true);
FileList files = files("temp"). FileList files = files("temp").
exclude("temp/android/*"). exclude("temp/android/*").
exclude("temp/org/h2/android/*"). exclude("temp/org/h2/android/*").
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论