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

Merge pull request #1728 from katzyn/datetime

Add more EXTRACT fields from PostgreSQL
...@@ -1923,7 +1923,7 @@ yearField | monthField | dayOfMonthField ...@@ -1923,7 +1923,7 @@ yearField | monthField | dayOfMonthField
| hourField | minuteField | secondField | hourField | minuteField | secondField
| millisecondField | microsecondField | nanosecondField | millisecondField | microsecondField | nanosecondField
| timezoneHourField | timezoneMinuteField | timezoneHourField | timezoneMinuteField
| dayOfWeekField | isoDayOfWeekField | dayOfWeekField | isoWeekYearField | isoDayOfWeekField
| weekOfYearField | isoWeekOfYearField | weekOfYearField | isoWeekOfYearField
| quarterField | dayOfYearField | epochField | quarterField | dayOfYearField | epochField
"," ","
...@@ -2028,8 +2028,16 @@ Day of week (1-7). Sunday is 1. ...@@ -2028,8 +2028,16 @@ Day of week (1-7). Sunday is 1.
DAY_OF_WEEK DAY_OF_WEEK
" "
"Datetime fields","ISO week year field","
ISO_YEAR | ISOYEAR
","
Returns the ISO week year from a date/time value.
","
ISO_YEAR
"
"Datetime fields","ISO day of week field"," "Datetime fields","ISO day of week field","
ISO_DAY_OF_WEEK ISO_DAY_OF_WEEK | ISODOW
"," ","
ISO day of week (1-7). Monday is 1. ISO day of week (1-7). Monday is 1.
"," ","
......
...@@ -21,9 +21,19 @@ Change Log ...@@ -21,9 +21,19 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #1727: Support ISODOW as identifier for the extract function additional to ISO_DAY_OF_WEEK
</li>
<li>PR #1580, #1726: Disable remote database creation by default
</li>
<li>PR #1725: Add partial implementation of standard LISTAGG aggregate function
</li>
<li>PR #1722: Fix window definition lookup in some queries
</li>
<li>PR #1721: Fix derived column list in complex queries
</li>
<li>Issue #1718: Window function and values clause don't work well together <li>Issue #1718: Window function and values clause don't work well together
</li> </li>
<li>PR #1717: Backward compatibility patch for #1592 <li>Issue #1592: Index out of bounds exception in Page.getKey()
</li> </li>
<li>PR #1716: Improve documentation of some DML commands <li>PR #1716: Improve documentation of some DML commands
</li> </li>
......
...@@ -965,6 +965,7 @@ or the SQL statement <code>SET MODE PostgreSQL</code>. ...@@ -965,6 +965,7 @@ or the SQL statement <code>SET MODE PostgreSQL</code>.
</li><li>MONEY data type is treated like NUMERIC(19, 2) data type. </li><li>MONEY data type is treated like NUMERIC(19, 2) data type.
</li><li>Datetime value functions return the same value within a transaction. </li><li>Datetime value functions return the same value within a transaction.
</li><li>ARRAY_SLICE() out of bounds parameters are silently corrected. </li><li>ARRAY_SLICE() out of bounds parameters are silently corrected.
</li><li>EXTRACT function with DOW field returns (0-6), Sunday is 0.
</li></ul> </li></ul>
<h3>Ignite Compatibility Mode</h3> <h3>Ignite Compatibility Mode</h3>
......
...@@ -10,6 +10,7 @@ import static org.h2.expression.function.Function.DAY_OF_MONTH; ...@@ -10,6 +10,7 @@ import static org.h2.expression.function.Function.DAY_OF_MONTH;
import static org.h2.expression.function.Function.DAY_OF_WEEK; import static org.h2.expression.function.Function.DAY_OF_WEEK;
import static org.h2.expression.function.Function.DAY_OF_YEAR; import static org.h2.expression.function.Function.DAY_OF_YEAR;
import static org.h2.expression.function.Function.DECADE; import static org.h2.expression.function.Function.DECADE;
import static org.h2.expression.function.Function.DOW;
import static org.h2.expression.function.Function.EPOCH; import static org.h2.expression.function.Function.EPOCH;
import static org.h2.expression.function.Function.HOUR; import static org.h2.expression.function.Function.HOUR;
import static org.h2.expression.function.Function.ISO_DAY_OF_WEEK; import static org.h2.expression.function.Function.ISO_DAY_OF_WEEK;
...@@ -43,6 +44,8 @@ import java.util.TimeZone; ...@@ -43,6 +44,8 @@ import java.util.TimeZone;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.IntervalQualifier; import org.h2.api.IntervalQualifier;
import org.h2.engine.Mode;
import org.h2.engine.Mode.ModeEnum;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.DateTimeUtils; import org.h2.util.DateTimeUtils;
import org.h2.util.IntervalUtils; import org.h2.util.IntervalUtils;
...@@ -73,6 +76,8 @@ public final class DateTimeFunctions { ...@@ -73,6 +76,8 @@ public final class DateTimeFunctions {
DATE_PART.put("YEAR", YEAR); DATE_PART.put("YEAR", YEAR);
DATE_PART.put("YYYY", YEAR); DATE_PART.put("YYYY", YEAR);
DATE_PART.put("YY", YEAR); DATE_PART.put("YY", YEAR);
DATE_PART.put("ISO_YEAR", ISO_YEAR);
DATE_PART.put("ISOYEAR", ISO_YEAR);
DATE_PART.put("SQL_TSI_MONTH", MONTH); DATE_PART.put("SQL_TSI_MONTH", MONTH);
DATE_PART.put("MONTH", MONTH); DATE_PART.put("MONTH", MONTH);
DATE_PART.put("MM", MONTH); DATE_PART.put("MM", MONTH);
...@@ -89,8 +94,9 @@ public final class DateTimeFunctions { ...@@ -89,8 +94,9 @@ public final class DateTimeFunctions {
DATE_PART.put("SQL_TSI_DAY", DAY_OF_MONTH); DATE_PART.put("SQL_TSI_DAY", DAY_OF_MONTH);
DATE_PART.put("DAY_OF_WEEK", DAY_OF_WEEK); DATE_PART.put("DAY_OF_WEEK", DAY_OF_WEEK);
DATE_PART.put("DAYOFWEEK", DAY_OF_WEEK); DATE_PART.put("DAYOFWEEK", DAY_OF_WEEK);
DATE_PART.put("DOW", DAY_OF_WEEK); DATE_PART.put("DOW", DOW);
DATE_PART.put("ISO_DAY_OF_WEEK", ISO_DAY_OF_WEEK); DATE_PART.put("ISO_DAY_OF_WEEK", ISO_DAY_OF_WEEK);
DATE_PART.put("ISODOW", ISO_DAY_OF_WEEK);
DATE_PART.put("DAYOFYEAR", DAY_OF_YEAR); DATE_PART.put("DAYOFYEAR", DAY_OF_YEAR);
DATE_PART.put("DAY_OF_YEAR", DAY_OF_YEAR); DATE_PART.put("DAY_OF_YEAR", DAY_OF_YEAR);
DATE_PART.put("DY", DAY_OF_YEAR); DATE_PART.put("DY", DAY_OF_YEAR);
...@@ -170,6 +176,7 @@ public final class DateTimeFunctions { ...@@ -170,6 +176,7 @@ public final class DateTimeFunctions {
count *= 7; count *= 7;
//$FALL-THROUGH$ //$FALL-THROUGH$
case DAY_OF_WEEK: case DAY_OF_WEEK:
case DOW:
case ISO_DAY_OF_WEEK: case ISO_DAY_OF_WEEK:
case DAY_OF_MONTH: case DAY_OF_MONTH:
case DAY_OF_YEAR: case DAY_OF_YEAR:
...@@ -288,6 +295,7 @@ public final class DateTimeFunctions { ...@@ -288,6 +295,7 @@ public final class DateTimeFunctions {
case DAY_OF_MONTH: case DAY_OF_MONTH:
case DAY_OF_YEAR: case DAY_OF_YEAR:
case DAY_OF_WEEK: case DAY_OF_WEEK:
case DOW:
case ISO_DAY_OF_WEEK: case ISO_DAY_OF_WEEK:
return absolute2 - absolute1; return absolute2 - absolute1;
case WEEK: case WEEK:
...@@ -335,13 +343,15 @@ public final class DateTimeFunctions { ...@@ -335,13 +343,15 @@ public final class DateTimeFunctions {
* the date part * the date part
* @param value * @param value
* the date-time value * the date-time value
* @param mode
* the database mode
* @return extracted field * @return extracted field
*/ */
public static Value extract(String part, Value value) { public static Value extract(String part, Value value, Mode mode) {
Value result; Value result;
int field = getDatePart(part); int field = getDatePart(part);
if (field != EPOCH) { if (field != EPOCH) {
result = ValueInt.get(getIntDatePart(value, field)); result = ValueInt.get(getIntDatePart(value, field, mode));
} else { } else {
// Case where we retrieve the EPOCH time. // Case where we retrieve the EPOCH time.
if (value instanceof ValueInterval) { if (value instanceof ValueInterval) {
...@@ -625,9 +635,11 @@ public final class DateTimeFunctions { ...@@ -625,9 +635,11 @@ public final class DateTimeFunctions {
* the date value * the date value
* @param field * @param field
* the field type, see {@link Function} for constants * the field type, see {@link Function} for constants
* @param mode
* the database mode
* @return the value * @return the value
*/ */
public static int getIntDatePart(Value date, int field) { public static int getIntDatePart(Value date, int field, Mode mode) {
if (date instanceof ValueInterval) { if (date instanceof ValueInterval) {
ValueInterval interval = (ValueInterval) date; ValueInterval interval = (ValueInterval) date;
IntervalQualifier qualifier = interval.getQualifier(); IntervalQualifier qualifier = interval.getQualifier();
...@@ -694,6 +706,13 @@ public final class DateTimeFunctions { ...@@ -694,6 +706,13 @@ public final class DateTimeFunctions {
return DateTimeUtils.getDayOfYear(dateValue); return DateTimeUtils.getDayOfYear(dateValue);
case DAY_OF_WEEK: case DAY_OF_WEEK:
return DateTimeUtils.getSundayDayOfWeek(dateValue); return DateTimeUtils.getSundayDayOfWeek(dateValue);
case DOW: {
int dow = DateTimeUtils.getSundayDayOfWeek(dateValue);
if (mode.getEnum() == ModeEnum.PostgreSQL) {
dow--;
}
return dow;
}
case WEEK: case WEEK:
GregorianCalendar gc = DateTimeUtils.getCalendar(); GregorianCalendar gc = DateTimeUtils.getCalendar();
return DateTimeUtils.getWeekOfYear(dateValue, gc.getFirstDayOfWeek() - 1, return DateTimeUtils.getWeekOfYear(dateValue, gc.getFirstDayOfWeek() - 1,
......
...@@ -120,7 +120,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -120,7 +120,7 @@ public class Function extends Expression implements FunctionCall {
*/ */
public static final int MILLISECOND = 126, EPOCH = 127, MICROSECOND = 128, NANOSECOND = 129, public static final int MILLISECOND = 126, EPOCH = 127, MICROSECOND = 128, NANOSECOND = 129,
TIMEZONE_HOUR = 130, TIMEZONE_MINUTE = 131, DECADE = 132, CENTURY = 133, TIMEZONE_HOUR = 130, TIMEZONE_MINUTE = 131, DECADE = 132, CENTURY = 133,
MILLENNIUM = 134; MILLENNIUM = 134, DOW = 135;
public static final int DATABASE = 150, USER = 151, CURRENT_USER = 152, public static final int DATABASE = 150, USER = 151, CURRENT_USER = 152,
IDENTITY = 153, SCOPE_IDENTITY = 154, AUTOCOMMIT = 155, IDENTITY = 153, SCOPE_IDENTITY = 154, AUTOCOMMIT = 155,
...@@ -849,7 +849,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -849,7 +849,7 @@ public class Function extends Expression implements FunctionCall {
case SECOND: case SECOND:
case WEEK: case WEEK:
case YEAR: case YEAR:
result = ValueInt.get(DateTimeFunctions.getIntDatePart(v0, info.type)); result = ValueInt.get(DateTimeFunctions.getIntDatePart(v0, info.type, database.getMode()));
break; break;
case MONTH_NAME: { case MONTH_NAME: {
int month = DateTimeUtils.monthFromDateValue(DateTimeUtils.dateAndTimeFromValue(v0)[0]); int month = DateTimeUtils.monthFromDateValue(DateTimeUtils.dateAndTimeFromValue(v0)[0]);
...@@ -1462,7 +1462,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1462,7 +1462,7 @@ public class Function extends Expression implements FunctionCall {
result = DateTimeFunctions.truncateDate(v0.getString(), v1); result = DateTimeFunctions.truncateDate(v0.getString(), v1);
break; break;
case EXTRACT: case EXTRACT:
result = DateTimeFunctions.extract(v0.getString(), v1); result = DateTimeFunctions.extract(v0.getString(), v1, database.getMode());
break; break;
case FORMATDATETIME: { case FORMATDATETIME: {
if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE) { if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE) {
......
...@@ -178,3 +178,41 @@ SELECT EXTRACT(MICROSECOND FROM INTERVAL '11.123456789' SECOND); ...@@ -178,3 +178,41 @@ SELECT EXTRACT(MICROSECOND FROM INTERVAL '11.123456789' SECOND);
SELECT EXTRACT(NANOSECOND FROM INTERVAL '11.123456789' SECOND); SELECT EXTRACT(NANOSECOND FROM INTERVAL '11.123456789' SECOND);
>> 123456789 >> 123456789
SELECT D, ISO_YEAR(D) Y1, EXTRACT(ISO_YEAR FROM D) Y2, EXTRACT(ISOYEAR FROM D) Y3
FROM (VALUES DATE '2017-01-01', DATE '2017-01-02') V(D);
> D Y1 Y2 Y3
> ---------- ---- ---- ----
> 2017-01-01 2016 2016 2016
> 2017-01-02 2017 2017 2017
> rows: 2
SELECT D, EXTRACT(ISO_DAY_OF_WEEK FROM D) D1, EXTRACT(ISODOW FROM D) D2
FROM (VALUES DATE '2019-02-03', DATE '2019-02-04') V(D);
> D D1 D2
> ---------- -- --
> 2019-02-03 7 7
> 2019-02-04 1 1
> rows: 2
SELECT D, EXTRACT(DAY_OF_WEEK FROM D) D1, EXTRACT(DAY_OF_WEEK FROM D) D2, EXTRACT(DOW FROM D) D3
FROM (VALUES DATE '2019-02-02', DATE '2019-02-03') V(D);
> D D1 D2 D3
> ---------- -- -- --
> 2019-02-02 7 7 7
> 2019-02-03 1 1 1
> rows: 2
SET MODE PostgreSQL;
> ok
SELECT D, EXTRACT(DAY_OF_WEEK FROM D) D1, EXTRACT(DAY_OF_WEEK FROM D) D2, EXTRACT(DOW FROM D) D3
FROM (VALUES DATE '2019-02-02', DATE '2019-02-03') V(D);
> D D1 D2 D3
> ---------- -- -- --
> 2019-02-02 7 7 6
> 2019-02-03 1 1 0
> rows: 2
SET MODE Regular;
> ok
...@@ -807,3 +807,4 @@ analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin d ...@@ -807,3 +807,4 @@ analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin d
corrupts splitted disruption unintentional octets preconditions predicates subq objectweb insn opcodes corrupts splitted disruption unintentional octets preconditions predicates subq objectweb insn opcodes
preserves masking holder unboxing avert iae transformed subtle reevaluate exclusions subclause ftbl rgr preserves masking holder unboxing avert iae transformed subtle reevaluate exclusions subclause ftbl rgr
presorted inclusion contexts aax mwd percentile cont interpolate mwa hypothetical regproc childed listagg foreground presorted inclusion contexts aax mwd percentile cont interpolate mwa hypothetical regproc childed listagg foreground
isodow isoyear
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论