提交 616f7d0b authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add more EXTRACT fields from PostgreSQL

上级 e329948b
......@@ -1923,7 +1923,7 @@ yearField | monthField | dayOfMonthField
| hourField | minuteField | secondField
| millisecondField | microsecondField | nanosecondField
| timezoneHourField | timezoneMinuteField
| dayOfWeekField | isoDayOfWeekField
| dayOfWeekField | isoWeekYearField | isoDayOfWeekField
| weekOfYearField | isoWeekOfYearField
| quarterField | dayOfYearField | epochField
","
......@@ -2028,8 +2028,16 @@ Day of week (1-7). Sunday is 1.
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","
ISO_DAY_OF_WEEK
ISO_DAY_OF_WEEK | ISODOW
","
ISO day of week (1-7). Monday is 1.
","
......
......@@ -21,9 +21,19 @@ Change Log
<h2>Next Version (unreleased)</h2>
<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>
<li>PR #1717: Backward compatibility patch for #1592
<li>Issue #1592: Index out of bounds exception in Page.getKey()
</li>
<li>PR #1716: Improve documentation of some DML commands
</li>
......
......@@ -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>Datetime value functions return the same value within a transaction.
</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>
<h3>Ignite Compatibility Mode</h3>
......
......@@ -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_YEAR;
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.HOUR;
import static org.h2.expression.function.Function.ISO_DAY_OF_WEEK;
......@@ -43,6 +44,8 @@ import java.util.TimeZone;
import org.h2.api.ErrorCode;
import org.h2.api.IntervalQualifier;
import org.h2.engine.Mode;
import org.h2.engine.Mode.ModeEnum;
import org.h2.message.DbException;
import org.h2.util.DateTimeUtils;
import org.h2.util.IntervalUtils;
......@@ -73,6 +76,8 @@ public final class DateTimeFunctions {
DATE_PART.put("YEAR", YEAR);
DATE_PART.put("YYYY", 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("MONTH", MONTH);
DATE_PART.put("MM", MONTH);
......@@ -89,8 +94,9 @@ public final class DateTimeFunctions {
DATE_PART.put("SQL_TSI_DAY", DAY_OF_MONTH);
DATE_PART.put("DAY_OF_WEEK", 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("ISODOW", ISO_DAY_OF_WEEK);
DATE_PART.put("DAYOFYEAR", DAY_OF_YEAR);
DATE_PART.put("DAY_OF_YEAR", DAY_OF_YEAR);
DATE_PART.put("DY", DAY_OF_YEAR);
......@@ -170,6 +176,7 @@ public final class DateTimeFunctions {
count *= 7;
//$FALL-THROUGH$
case DAY_OF_WEEK:
case DOW:
case ISO_DAY_OF_WEEK:
case DAY_OF_MONTH:
case DAY_OF_YEAR:
......@@ -288,6 +295,7 @@ public final class DateTimeFunctions {
case DAY_OF_MONTH:
case DAY_OF_YEAR:
case DAY_OF_WEEK:
case DOW:
case ISO_DAY_OF_WEEK:
return absolute2 - absolute1;
case WEEK:
......@@ -335,13 +343,15 @@ public final class DateTimeFunctions {
* the date part
* @param value
* the date-time value
* @param mode
* the database mode
* @return extracted field
*/
public static Value extract(String part, Value value) {
public static Value extract(String part, Value value, Mode mode) {
Value result;
int field = getDatePart(part);
if (field != EPOCH) {
result = ValueInt.get(getIntDatePart(value, field));
result = ValueInt.get(getIntDatePart(value, field, mode));
} else {
// Case where we retrieve the EPOCH time.
if (value instanceof ValueInterval) {
......@@ -625,9 +635,11 @@ public final class DateTimeFunctions {
* the date value
* @param field
* the field type, see {@link Function} for constants
* @param mode
* the database mode
* @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) {
ValueInterval interval = (ValueInterval) date;
IntervalQualifier qualifier = interval.getQualifier();
......@@ -694,6 +706,13 @@ public final class DateTimeFunctions {
return DateTimeUtils.getDayOfYear(dateValue);
case DAY_OF_WEEK:
return DateTimeUtils.getSundayDayOfWeek(dateValue);
case DOW: {
int dow = DateTimeUtils.getSundayDayOfWeek(dateValue);
if (mode.getEnum() == ModeEnum.PostgreSQL) {
dow--;
}
return dow;
}
case WEEK:
GregorianCalendar gc = DateTimeUtils.getCalendar();
return DateTimeUtils.getWeekOfYear(dateValue, gc.getFirstDayOfWeek() - 1,
......
......@@ -120,7 +120,7 @@ public class Function extends Expression implements FunctionCall {
*/
public static final int MILLISECOND = 126, EPOCH = 127, MICROSECOND = 128, NANOSECOND = 129,
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,
IDENTITY = 153, SCOPE_IDENTITY = 154, AUTOCOMMIT = 155,
......@@ -849,7 +849,7 @@ public class Function extends Expression implements FunctionCall {
case SECOND:
case WEEK:
case YEAR:
result = ValueInt.get(DateTimeFunctions.getIntDatePart(v0, info.type));
result = ValueInt.get(DateTimeFunctions.getIntDatePart(v0, info.type, database.getMode()));
break;
case MONTH_NAME: {
int month = DateTimeUtils.monthFromDateValue(DateTimeUtils.dateAndTimeFromValue(v0)[0]);
......@@ -1462,7 +1462,7 @@ public class Function extends Expression implements FunctionCall {
result = DateTimeFunctions.truncateDate(v0.getString(), v1);
break;
case EXTRACT:
result = DateTimeFunctions.extract(v0.getString(), v1);
result = DateTimeFunctions.extract(v0.getString(), v1, database.getMode());
break;
case FORMATDATETIME: {
if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE) {
......
......@@ -178,3 +178,41 @@ SELECT EXTRACT(MICROSECOND FROM INTERVAL '11.123456789' SECOND);
SELECT EXTRACT(NANOSECOND FROM INTERVAL '11.123456789' SECOND);
>> 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
corrupts splitted disruption unintentional octets preconditions predicates subq objectweb insn opcodes
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
isodow isoyear
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论