Skip to content

Commit

Permalink
Add support for standard interval literals with precision
Browse files Browse the repository at this point in the history
  • Loading branch information
katzyn committed Apr 9, 2022
1 parent 5657be7 commit a71a66e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 84 deletions.
78 changes: 7 additions & 71 deletions h2/src/main/org/h2/command/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -5491,78 +5491,14 @@ private Expression readInterval() {
}
String s = token.value(session).getString();
read();
IntervalQualifier qualifier;
switch (currentTokenType) {
case YEAR:
read();
if (readIf(TO)) {
read(MONTH);
qualifier = IntervalQualifier.YEAR_TO_MONTH;
} else {
qualifier = IntervalQualifier.YEAR;
}
break;
case MONTH:
read();
qualifier = IntervalQualifier.MONTH;
break;
case DAY:
read();
if (readIf(TO)) {
switch (currentTokenType) {
case HOUR:
qualifier = IntervalQualifier.DAY_TO_HOUR;
break;
case MINUTE:
qualifier = IntervalQualifier.DAY_TO_MINUTE;
break;
case SECOND:
qualifier = IntervalQualifier.DAY_TO_SECOND;
break;
default:
throw intervalDayError();
}
read();
} else {
qualifier = IntervalQualifier.DAY;
}
break;
case HOUR:
read();
if (readIf(TO)) {
switch (currentTokenType) {
case MINUTE:
qualifier = IntervalQualifier.HOUR_TO_MINUTE;
break;
case SECOND:
qualifier = IntervalQualifier.HOUR_TO_SECOND;
break;
default:
throw intervalHourError();
}
read();
} else {
qualifier = IntervalQualifier.HOUR;
}
break;
case MINUTE:
read();
if (readIf(TO)) {
read(SECOND);
qualifier = IntervalQualifier.MINUTE_TO_SECOND;
} else {
qualifier = IntervalQualifier.MINUTE;
}
break;
case SECOND:
read();
qualifier = IntervalQualifier.SECOND;
break;
default:
throw intervalQualifierError();
}
TypeInfo typeInfo = readIntervalQualifier();
try {
return ValueExpression.get(IntervalUtils.parseInterval(qualifier, negative, s));
ValueInterval interval = IntervalUtils.parseInterval(
IntervalQualifier.valueOf(typeInfo.getValueType() - Value.INTERVAL_YEAR), negative, s);
if (typeInfo.getDeclaredPrecision() != -1L || typeInfo.getDeclaredScale() != -1) {
return TypedValueExpression.get(interval.castTo(typeInfo, session), typeInfo);
}
return ValueExpression.get(interval);
} catch (Exception e) {
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2, e, "INTERVAL", s);
}
Expand Down
47 changes: 34 additions & 13 deletions h2/src/main/org/h2/res/help.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2400,105 +2400,126 @@ INTERVAL '1-2' YEAR TO MONTH
"

"Literals","INTERVAL YEAR","
INTERVAL [-|+] '[-|+]yearInt' YEAR
INTERVAL [-|+] '[-|+]yearInt' YEAR [ ( precisionInt ) ]
","
An INTERVAL YEAR literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' YEAR
"

"Literals","INTERVAL MONTH","
INTERVAL [-|+] '[-|+]monthInt' MONTH
INTERVAL [-|+] '[-|+]monthInt' MONTH [ ( precisionInt ) ]
","
An INTERVAL MONTH literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' MONTH
"

"Literals","INTERVAL DAY","
INTERVAL [-|+] '[-|+]dayInt' DAY
INTERVAL [-|+] '[-|+]dayInt' DAY [ ( precisionInt ) ]
","
An INTERVAL DAY literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' DAY
"

"Literals","INTERVAL HOUR","
INTERVAL [-|+] '[-|+]hourInt' HOUR
INTERVAL [-|+] '[-|+]hourInt' HOUR [ ( precisionInt ) ]
","
An INTERVAL HOUR literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' HOUR
"

"Literals","INTERVAL MINUTE","
INTERVAL [-|+] '[-|+]minuteInt' MINUTE
INTERVAL [-|+] '[-|+]minuteInt' MINUTE [ ( precisionInt ) ]
","
An INTERVAL MINUTE literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' MINUTE
"

"Literals","INTERVAL SECOND","
INTERVAL [-|+] '[-|+]secondInt[.nnnnnnnnn]' SECOND
INTERVAL [-|+] '[-|+]secondInt[.nnnnnnnnn]'
SECOND [ ( precisionInt [, fractionalPrecisionInt ] ) ]
","
An INTERVAL SECOND literal.
If precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '10.123' SECOND
"

"Literals","INTERVAL YEAR TO MONTH","
INTERVAL [-|+] '[-|+]yearInt-monthInt' YEAR TO MONTH
INTERVAL [-|+] '[-|+]yearInt-monthInt' YEAR [ ( precisionInt ) ] TO MONTH
","
An INTERVAL YEAR TO MONTH literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '1-6' YEAR TO MONTH
"

"Literals","INTERVAL DAY TO HOUR","
INTERVAL [-|+] '[-|+]dayInt hoursInt' DAY TO HOUR
INTERVAL [-|+] '[-|+]dayInt hoursInt' DAY [ ( precisionInt ) ] TO HOUR
","
An INTERVAL DAY TO HOUR literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '10 11' DAY TO HOUR
"

"Literals","INTERVAL DAY TO MINUTE","
INTERVAL [-|+] '[-|+]dayInt hh:mm' DAY TO MINUTE
INTERVAL [-|+] '[-|+]dayInt hh:mm' DAY [ ( precisionInt ) ] TO MINUTE
","
An INTERVAL DAY TO MINUTE literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '10 11:12' DAY TO MINUTE
"

"Literals","INTERVAL DAY TO SECOND","
INTERVAL [-|+] '[-|+]dayInt hh:mm:ss[.nnnnnnnnn]' DAY TO SECOND
INTERVAL [-|+] '[-|+]dayInt hh:mm:ss[.nnnnnnnnn]' DAY [ ( precisionInt ) ]
TO SECOND [ ( fractionalPrecisionInt ) ]
","
An INTERVAL DAY TO SECOND literal.
If leading field precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '10 11:12:13.123' DAY TO SECOND
"

"Literals","INTERVAL HOUR TO MINUTE","
INTERVAL [-|+] '[-|+]hh:mm' HOUR TO MINUTE
INTERVAL [-|+] '[-|+]hh:mm' HOUR [ ( precisionInt ) ] TO MINUTE
","
An INTERVAL HOUR TO MINUTE literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '10:11' HOUR TO MINUTE
"

"Literals","INTERVAL HOUR TO SECOND","
INTERVAL [-|+] '[-|+]hh:mm:ss[.nnnnnnnnn]' HOUR TO SECOND
INTERVAL [-|+] '[-|+]hh:mm:ss[.nnnnnnnnn]' HOUR [ ( precisionInt ) ]
TO SECOND [ ( fractionalPrecisionInt ) ]
","
An INTERVAL HOUR TO SECOND literal.
If leading field precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '10:11:12.123' HOUR TO SECOND
"

"Literals","INTERVAL MINUTE TO SECOND","
INTERVAL [-|+] '[-|+]mm:ss[.nnnnnnnnn]' MINUTE TO SECOND
INTERVAL [-|+] '[-|+]mm:ss[.nnnnnnnnn]' MINUTE [ ( precisionInt ) ]
TO SECOND [ ( fractionalPrecisionInt ) ]
","
An INTERVAL MINUTE TO SECOND literal.
If leading field precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '11:12.123' MINUTE TO SECOND
"
Expand Down
3 changes: 3 additions & 0 deletions h2/src/test/org/h2/test/scripts/datatypes/interval.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1100,3 +1100,6 @@ SELECT T1, T2, (T1 - T2) YEAR TO MONTH, (T2 - T1) YEAR TO MONTH FROM (VALUES

SELECT (DATE '2010-01-02' - DATE '2000-01-01') YEAR;
>> INTERVAL '10' YEAR

VALUES INTERVAL '100' YEAR(2);
> exception INVALID_DATETIME_CONSTANT_2

0 comments on commit a71a66e

Please sign in to comment.