Skip to content

Commit

Permalink
[Fix](Planner)fix incorrect pattern when format pattern contains %x%v (
Browse files Browse the repository at this point in the history
  • Loading branch information
sohardforaname authored May 31, 2023
1 parent d93ff5d commit c39943f
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 103 deletions.
26 changes: 15 additions & 11 deletions fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import java.time.format.ResolverStyle;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAccessor;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -922,30 +923,33 @@ private static DateTimeFormatterBuilder formatBuilder(String pattern) throws Ana
case 'T': // %T Time, 24-hour (HH:mm:ss)
builder.appendPattern("HH:mm:ss");
break;
case 'v': // %v Week (01..53), where Monday is the first day of the week; used with %x
case 'V': // %V Week (01..53), where Sunday is the first day of the week; used with %X
builder.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2);
break;
case 'x':
case 'Y': // %Y Year, numeric, four digits
// %x Year for the week, where Monday is the first day of the week,
// numeric, four digits; used with %v
builder.appendValue(ChronoField.YEAR, 4);
case 'v': // %v Week (01..53), where Monday is the first day of the week; used with %x
builder.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2);
break;
case 'W': // %W Weekday name (Sunday..Saturday)
builder.appendText(ChronoField.DAY_OF_WEEK, TextStyle.FULL);
break;
case 'x': // %x Year for the week where Monday is the first day of the week,
builder.appendValue(IsoFields.WEEK_BASED_YEAR, 4);
break;
case 'X':
case 'Y': // %Y Year, numeric, four digits
// %X Year for the week, where Sunday is the first day of the week,
// numeric, four digits; used with %v
builder.appendValue(ChronoField.YEAR, 4);
break;
case 'y': // %y Year, numeric (two digits)
builder.appendValueReduced(ChronoField.YEAR, 2, 2, 1970);
break;
// TODO(Gabriel): support microseconds in date literal
case 'D': // %D Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
case 'f': // %f Microseconds (000000..999999)
case 'w': // %w Day of the week (0=Sunday..6=Saturday)
case 'U': // %U Week (00..53), where Sunday is the first day of the week
case 'u': // %u Week (00..53), where Monday is the first day of the week
case 'V': // %V Week (01..53), where Sunday is the first day of the week; used with %X
case 'X': // %X Year for the week where Sunday is the first day of the week,
// numeric, four digits; used with %V
case 'D': // %D Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
case 'w': // %w Day of the week (0=Sunday..6=Saturday)
throw new AnalysisException(String.format("%%%s not supported in date format string",
character));
case '%': // %% A literal "%" character
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAccessor;

/**
Expand Down Expand Up @@ -94,33 +95,36 @@ public static DateTimeFormatterBuilder formatBuilder(String pattern) throws Anal
case 's': // %s Seconds (00..59)
builder.appendValue(ChronoField.SECOND_OF_MINUTE, 2);
break;
case 'T': // %T Time, 24-hour (hh:mm:ss)
case 'T': // %T Time, 24-hour (HH:mm:ss)
builder.appendPattern("HH:mm:ss");
break;
case 'v': // %v Week (01..53), where Monday is the first day of the week; used with %x
case 'V': // %V Week (01..53), where Sunday is the first day of the week; used with %X
builder.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2);
break;
case 'x':
case 'Y': // %Y Year, numeric, four digits
// %x Year for the week, where Monday is the first day of the week,
// numeric, four digits; used with %v
builder.appendValue(ChronoField.YEAR, 4);
case 'v': // %v Week (01..53), where Monday is the first day of the week; used with %x
builder.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2);
break;
case 'W': // %W Weekday name (Sunday..Saturday)
builder.appendText(ChronoField.DAY_OF_WEEK, TextStyle.FULL);
break;
case 'x': // %x Year for the week where Monday is the first day of the week,
builder.appendValue(IsoFields.WEEK_BASED_YEAR, 4);
break;
case 'X':
case 'Y': // %Y Year, numeric, four digits
// %X Year for the week, where Sunday is the first day of the week,
// numeric, four digits; used with %v
builder.appendValue(ChronoField.YEAR, 4);
break;
case 'y': // %y Year, numeric (two digits)
builder.appendValueReduced(ChronoField.YEAR, 2, 2, 1970);
break;
// TODO(Gabriel): support microseconds in date literal
case 'D': // %D Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
case 'f': // %f Microseconds (000000..999999)
case 'w': // %w Day of the week (0=Sunday..6=Saturday)
case 'U': // %U Week (00..53), where Sunday is the first day of the week
case 'u': // %u Week (00..53), where Monday is the first day of the week
case 'V': // %V Week (01..53), where Sunday is the first day of the week; used with %X
case 'X': // %X Year for the week where Sunday is the first day of the week,
// numeric, four digits; used with %V
case 'D': // %D Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
case 'w': // %w Day of the week (0=Sunday..6=Saturday)
throw new AnalysisException(String.format("%%%s not supported in date format string",
character));
case '%': // %% A literal "%" character
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,13 @@ public void testDateTimeV2TypeDateTimeArithmeticFunctions() {
Assertions.assertEquals(DateTimeExtractAndTransform.toDays(dateLiteral).toSql(), answer[answerIdx++]);
Assertions.assertEquals(DateTimeExtractAndTransform.date(dateLiteral).toSql(), answer[answerIdx++]);
Assertions.assertEquals(DateTimeExtractAndTransform.dateV2(dateLiteral).toSql(), answer[answerIdx]);

Assertions.assertEquals("'2021 52 2022 01'", DateTimeExtractAndTransform.dateFormat(
new DateLiteral("2022-01-01 00:12:42"),
new VarcharLiteral("%x %v %X %V")).toSql());
Assertions.assertEquals("'2023 18 2023 19'", DateTimeExtractAndTransform.dateFormat(
new DateLiteral("2023-05-07 02:41:42"),
new VarcharLiteral("%x %v %X %V")).toSql());
}

@Test
Expand Down
Loading

0 comments on commit c39943f

Please sign in to comment.