This repository has been archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 186
DATE_FORMAT function #764
Merged
penghuo
merged 104 commits into
opendistro-for-elasticsearch:develop
from
lyndonbauto:lyndon/date-format-function
Oct 2, 2020
Merged
DATE_FORMAT function #764
Changes from all commits
Commits
Show all changes
104 commits
Select commit
Hold shift + click to select a range
fb2ed91
Bug fix, support long type for aggregation (#522)
penghuo 254f2e0
Opendistro Release 1.9.0 (#532)
joshuali925 33c6d3e
Rename release notes to use 4 digit versions (#547)
joshuali925 09132da
Revert changes ahead of develop branch in master (#551)
joshuali925 893cd18
Merge develop branch to master (#553)
joshuali925 923c96d
Merge all SQL repos and adjust workflows (#549) (#554)
joshuali925 4b33a2f
add date and time support (#560)
penghuo af74293
Revert "add date and time support (#560)" (#567)
penghuo baac103
resolve conflict
joshuali925 35e37a3
Merge develop to master for ODFE 1.9.0.1 release (#633)
joshuali925 0ed6594
Merge fixes for github release actions from develop to master (#638)
joshuali925 e4981e3
Fix odbc win32 release workflow for master (#642)
joshuali925 c11125d
add error details for all server communication errors (#645)
jordanw-bq 34b979e
Revert "add error details for all server communication errors (#645)"…
chloe-zh 5ab1bc8
Merge pull request #698 from opendistro-for-elasticsearch/develop
chloe-zh 8735723
Merge develop branch into master for od1.10 release (#701)
chloe-zh 332ee9c
Merge branch 'develop' of github.com:opendistro-for-elasticsearch/sql
chloe-zh 2939081
Merge workflow fix to master for od1.10 release (#704)
chloe-zh 9e82a91
Fix download link in package description (#729)
gaiksaya 89c6e05
Merge develop to master for ODFE 1.10.1.0 release (#733)
joshuali925 db82e29
add functions day, month, quarter, year
e46da70
fix build error
88a878b
fix doctest error
63ea788
fix doctest build error
7551dc8
fix doctest
a673fe2
add dayofmonth()
7c70c33
add dayofyear()
d87f8f4
add dayofweek()
242403c
fix dayofweek logic & add unit test
be7051d
fix doctest for dayofweek()
6834c10
add dayname
ee02527
add monthname
8ab2f63
fix checkstyle build error
458c34a
fix build error
e42aac1
fix doctest for monthname
960783b
add hour()
4d355b2
add minute()
0881f24
add second
d199d54
add microsecond
c88a6dd
fix datetime & timestamp issue for microsecond
4dd0db0
add time_to_sec
988d177
add subdate & date_sub
9c1d96b
Merge branch 'develop' of https://github.com/rupal-bq/sql into date-t…
693211a
fix doctest error
36449f7
fix build error
048d5d6
add KeywordsCanBeId for dayofweek
c0593d9
add to_days
7ee0dbc
add from_days()
7764a0d
arrange by alphabetical order
18a6a84
add manual IT
7054a4b
add string input for date functions
7e4c726
fix microsecond
f0a16ce
update doc
b757335
add date_add
a41aaad
add week
1a44c36
address PR comments
20acde3
update tests & doc
a51f2f7
Merge branch 'develop' of https://github.com/rupal-bq/sql into date-t…
42c7222
fix doc format
0f3894a
update tests for adddate
a73a8e9
move string conversion to ExprStringValue
ea9b190
add string type in doc
7f57158
Merge branch 'develop' of https://github.com/rupal-bq/sql into date-t…
498bdf0
edge case
61ac4e5
Merge branch 'develop' of https://github.com/rupal-bq/sql into date-t…
365b000
fix case 5 & 7
7840b12
Merge branch 'develop' of https://github.com/rupal-bq/sql into date-t…
0814004
add IT
8567662
update doc
9d51b9c
fix table
c869ff0
rename
6d19513
add string type
5ab8631
nit: add newline
ce4473b
fix type in comment
829fa06
Merge branch 'develop' of https://github.com/opendistro-for-elasticse…
lyndonbauto 6dc155c
nit
dc70cd6
add test cases for datetime function in ExpeStringValue
d93f02b
Merge branch 'develop' of https://github.com/rupal-bq/sql into date-t…
c001615
removing implicit def for keyword in parser
104e6b9
add dayofweek
0f8d8bc
Merge branch 'develop' of https://github.com/opendistro-for-elasticse…
lyndonbauto 6a8434f
Merge branch 'date-time-function-week' of https://github.com/rupal-bq…
lyndonbauto 84a111e
[1] Merged rupals week branch in
lyndonbauto 126890b
Merge branch 'develop' of https://github.com/rupal-bq/sql into date-t…
38e875d
Merge branch 'date-time-functions' of https://github.com/rupal-bq/sql…
lyndonbauto c73e430
add unit tests for null, missing values
4d3eff0
nit
e573d32
[1] Added integration tests.
lyndonbauto 9e68366
[1] Working on ppl integration tests.
lyndonbauto e6942e4
[1] Updated for integration tests
lyndonbauto a57014e
[1] Fixed schema verification
lyndonbauto 18820c6
[1] Adding documentation.
lyndonbauto e6bdab5
[1] Fixing documentation
lyndonbauto c72d100
Merge branch 'develop' of https://github.com/opendistro-for-elasticse…
lyndonbauto 568667f
[1] Simplified a bunch of logic
lyndonbauto cf69bbc
[1] Reducing changes that are from spacing
lyndonbauto 8d41f33
[1] Removed extra merge line
lyndonbauto 76cd45b
address PR comment
6267a24
[1] Updates
lyndonbauto e9793f3
no message
lyndonbauto c9b68db
[1] Pulling develop
lyndonbauto 8ee52f7
[1] Removed some unwanted changes.
lyndonbauto 1656d75
[1] Minor whitespace adjustements
lyndonbauto 21c5fc5
[1] Updating based on code review
lyndonbauto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
.../com/amazon/opendistroforelasticsearch/sql/expression/datetime/DateTimeFormatterUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package com.amazon.opendistroforelasticsearch.sql.expression.datetime; | ||
|
||
import com.amazon.opendistroforelasticsearch.sql.data.model.ExprStringValue; | ||
import com.amazon.opendistroforelasticsearch.sql.data.model.ExprValue; | ||
import com.google.common.collect.ImmutableMap; | ||
|
||
import java.time.LocalDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.Locale; | ||
import java.util.Map; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* This class converts a SQL style DATE_FORMAT format specifier and converts it to a | ||
* Java SimpleDateTime format. | ||
*/ | ||
class DateTimeFormatterUtil { | ||
private static final int SUFFIX_SPECIAL_START_TH = 11; | ||
private static final int SUFFIX_SPECIAL_END_TH = 13; | ||
private static final String SUFFIX_SPECIAL_TH = "th"; | ||
private static final Map<Integer, String> SUFFIX_CONVERTER = | ||
ImmutableMap.<Integer, String>builder() | ||
.put(1, "st").put(2, "nd").put(3, "rd").build(); | ||
|
||
// The following have special cases that need handling outside of the format options provided | ||
// by the DateTimeFormatter class. | ||
interface DateTimeFormatHandler { | ||
String getFormat(LocalDateTime date); | ||
} | ||
|
||
private static final Map<String, DateTimeFormatHandler> HANDLERS = | ||
ImmutableMap.<String, DateTimeFormatHandler>builder() | ||
.put("%a", (date) -> "EEE") // %a => EEE - Abbreviated weekday name (Sun..Sat) | ||
.put("%b", (date) -> "LLL") // %b => LLL - Abbreviated month name (Jan..Dec) | ||
.put("%c", (date) -> "MM") // %c => MM - Month, numeric (0..12) | ||
.put("%d", (date) -> "dd") // %d => dd - Day of the month, numeric (00..31) | ||
.put("%e", (date) -> "d") // %e => d - Day of the month, numeric (0..31) | ||
.put("%H", (date) -> "HH") // %H => HH - (00..23) | ||
.put("%h", (date) -> "hh") // %h => hh - (01..12) | ||
.put("%I", (date) -> "hh") // %I => hh - (01..12) | ||
.put("%i", (date) -> "mm") // %i => mm - Minutes, numeric (00..59) | ||
.put("%j", (date) -> "DDD") // %j => DDD - (001..366) | ||
.put("%k", (date) -> "H") // %k => H - (0..23) | ||
.put("%l", (date) -> "h") // %l => h - (1..12) | ||
.put("%p", (date) -> "a") // %p => a - AM or PM | ||
.put("%M", (date) -> "LLLL") // %M => LLLL - Month name (January..December) | ||
.put("%m", (date) -> "MM") // %m => MM - Month, numeric (00..12) | ||
.put("%r", (date) -> "hh:mm:ss a") // %r => hh:mm:ss a - hh:mm:ss followed by AM or PM | ||
.put("%S", (date) -> "ss") // %S => ss - Seconds (00..59) | ||
.put("%s", (date) -> "ss") // %s => ss - Seconds (00..59) | ||
.put("%T", (date) -> "HH:mm:ss") // %T => HH:mm:ss | ||
.put("%W", (date) -> "EEEE") // %W => EEEE - Weekday name (Sunday..Saturday) | ||
.put("%Y", (date) -> "yyyy") // %Y => yyyy - Year, numeric, 4 digits | ||
.put("%y", (date) -> "yy") // %y => yy - Year, numeric, 2 digits | ||
// The following are not directly supported by DateTimeFormatter. | ||
.put("%D", (date) -> // %w - Day of month with English suffix | ||
String.format("'%d%s'", date.getDayOfMonth(), getSuffix(date.getDayOfMonth()))) | ||
.put("%f", (date) -> // %f - Microseconds | ||
String.format("'%d'", (date.getNano() / 1000))) | ||
.put("%w", (date) -> // %w - Day of week (0 indexed) | ||
String.format("'%d'", date.getDayOfWeek().getValue())) | ||
.put("%U", (date) -> // %U Week where Sunday is the first day - WEEK() mode 0 | ||
String.format("'%d'", CalendarLookup.getWeekNumber(0, date.toLocalDate()))) | ||
.put("%u", (date) -> // %u Week where Monday is the first day - WEEK() mode 1 | ||
String.format("'%d'", CalendarLookup.getWeekNumber(1, date.toLocalDate()))) | ||
.put("%V", (date) -> // %V Week where Sunday is the first day - WEEK() mode 2 used with %X | ||
String.format("'%d'", CalendarLookup.getWeekNumber(2, date.toLocalDate()))) | ||
.put("%v", (date) -> // %v Week where Monday is the first day - WEEK() mode 3 used with %x | ||
String.format("'%d'", CalendarLookup.getWeekNumber(3, date.toLocalDate()))) | ||
.put("%X", (date) -> // %X Year for week where Sunday is the first day, 4 digits used with %V | ||
String.format("'%d'", CalendarLookup.getYearNumber(2, date.toLocalDate()))) | ||
.put("%x", (date) -> // %x Year for week where Monday is the first day, 4 digits used with %v | ||
String.format("'%d'", CalendarLookup.getYearNumber(3, date.toLocalDate()))) | ||
.build(); | ||
|
||
private static final Pattern pattern = Pattern.compile("%."); | ||
private static final String MOD_LITERAL = "%"; | ||
|
||
private DateTimeFormatterUtil() { | ||
} | ||
|
||
/** | ||
* Format the date using the date format String. | ||
* @param dateExpr the date ExprValue of Date/Datetime/Timestamp/String type. | ||
* @param formatExpr the format ExprValue of String type. | ||
* @return Date formatted using format and returned as a String. | ||
*/ | ||
static ExprValue getFormattedDate(ExprValue dateExpr, ExprValue formatExpr) { | ||
final LocalDateTime date = dateExpr.datetimeValue(); | ||
final Matcher matcher = pattern.matcher(formatExpr.stringValue()); | ||
final StringBuffer format = new StringBuffer(); | ||
while (matcher.find()) { | ||
matcher.appendReplacement(format, | ||
HANDLERS.getOrDefault(matcher.group(), (d) -> | ||
String.format("'%s'", matcher.group().replaceFirst(MOD_LITERAL, ""))) | ||
.getFormat(date)); | ||
} | ||
matcher.appendTail(format); | ||
|
||
// English Locale matches SQL requirements. | ||
// 'AM'/'PM' instead of 'a.m.'/'p.m.' | ||
// 'Sat' instead of 'Sat.' etc | ||
return new ExprStringValue(date.format( | ||
DateTimeFormatter.ofPattern(format.toString(), Locale.ENGLISH))); | ||
} | ||
|
||
/** | ||
* Returns English suffix of incoming value. | ||
* @param val Incoming value. | ||
* @return English suffix as String (st, nd, rd, th) | ||
*/ | ||
private static String getSuffix(int val) { | ||
// The numbers 11, 12, and 13 do not follow general suffix rules. | ||
if ((SUFFIX_SPECIAL_START_TH <= val) && (val <= SUFFIX_SPECIAL_END_TH)) { | ||
return SUFFIX_SPECIAL_TH; | ||
} | ||
return SUFFIX_CONVERTER.getOrDefault(val % 10, SUFFIX_SPECIAL_TH); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure the use case. Do you try to do something like this format.replace("%\W", () -> replace).
If so, i recommended to consider the https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#appendReplacement(java.lang.StringBuffer,%20java.lang.String)
which provide the more clean code structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realize I could do this, tahnks for the suggestion! I have updated with this change.