[#7171] [#7446] Support parsing ISO_8601 interval literals

This commit is contained in:
lukaseder 2018-04-27 17:31:42 +02:00
parent ab370f918d
commit bfd146874f
4 changed files with 36 additions and 8 deletions

View File

@ -639,6 +639,7 @@ term =
| 'HOUR' '(' field ')'
| 'IFNULL' '(' field ',' field ')'
| 'INSTR' '(' field ',' field ')'
| intervalLiteral
| 'IIF' '(' condition ',' field ',' field ')'
| 'ISNULL' '(' field ',' field ')'
| ( 'LOWER' | 'LCASE' ) '(' field ')'
@ -897,6 +898,9 @@ timeLiteral = 'TIME' stringLiteral
timestampLiteral = 'TIMESTAMP' stringLiteral
;
intervalLiteral = 'INTERVAL' stringLiteral
;
signedInteger = todo
;

View File

@ -5089,15 +5089,16 @@ final class ParserImpl implements Parser {
private static final Interval parseIntervalLiteral(ParserContext ctx) {
String string = parseStringLiteral(ctx);
YearToMonth ym = YearToMonth.valueOf(string);
if (ym != null)
return ym;
DayToSecond ds = DayToSecond.valueOf(string);
if (ds != null)
return ds;
YearToMonth ym = YearToMonth.valueOf(string);
if (ym != null)
return ym;
throw ctx.exception("Illegal interval literal");
}

View File

@ -38,6 +38,7 @@
package org.jooq.types;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -85,7 +86,7 @@ public final class DayToSecond extends Number implements Interval, Comparable<Da
* Generated UID
*/
private static final long serialVersionUID = -3853596481984643811L;
private static final Pattern PATTERN = Pattern.compile("(\\+|-)?(?:(\\d+) )?(\\d+):(\\d+):(\\d+)(?:\\.(\\d+))?");
private static final Pattern PATTERN = Pattern.compile("([+-])?(?:(\\d+) )?(\\d+):(\\d+):(\\d+)(?:\\.(\\d+))?");
private final boolean negative;
private final int days;
@ -186,6 +187,15 @@ public final class DayToSecond extends Number implements Interval, Comparable<Da
return new DayToSecond(days, hours, minutes, seconds, nano, negative);
}
else {
try {
return DayToSecond.valueOf(Duration.parse(string));
}
catch (DateTimeParseException ignore) {}
}
}
}

View File

@ -79,7 +79,8 @@ public final class YearToMonth extends Number implements Interval, Comparable<Ye
* Generated UID
*/
private static final long serialVersionUID = 1308553645456594273L;
private static final Pattern PATTERN = Pattern.compile("(\\+|-)?(\\d+)-(\\d+)");
private static final Pattern PATTERN_SQL = Pattern.compile("([+-])?(\\d+)-(\\d+)");
private static final Pattern PATTERN_ISO = Pattern.compile("([+-])?P(?:([+-]?\\d+)Y)?(?:([+-]?\\d+)M)?", Pattern.CASE_INSENSITIVE);
private final boolean negative;
private final int years;
@ -123,15 +124,27 @@ public final class YearToMonth extends Number implements Interval, Comparable<Ye
*/
public static YearToMonth valueOf(String string) {
if (string != null) {
Matcher matcher = PATTERN.matcher(string);
Matcher matcher;
if (matcher.find()) {
if ((matcher = PATTERN_SQL.matcher(string)).find()) {
boolean negative = "-".equals(matcher.group(1));
int years = Integer.parseInt(matcher.group(2));
int months = Integer.parseInt(matcher.group(3));
return new YearToMonth(years, months, negative);
}
if ((matcher = PATTERN_ISO.matcher(string)).find()) {
boolean negative = "-".equals(matcher.group(1));
String group2 = matcher.group(2);
String group3 = matcher.group(3);
int years = group2 == null ? 0 : Integer.parseInt(group2);
int months = group3 == null ? 0 : Integer.parseInt(group3);
return new YearToMonth(years, months, negative);
}
}
return null;