Details
-
Bug
-
Status: In Review (View Workflow)
-
Critical
-
Resolution: Unresolved
-
10.5, 10.6, 10.11, 11.4
-
Server 12.1 dev sprint
Description
The format description FM which toggles Fill Mode for TO_CHAR when used to dates is not recognized. For example:
SELECT CONCAT('/', TO_CHAR('2020-01-06 10:11:12', 'DAY'), '/'); |
Returns (note two spces at the end to fill up to the length of the longest day name (Wed):
/Monday /
|
The FM flag in Oracle negates this blank filling:
SELECT CONCAT('/', TO_CHAR('2020-01-06 10:11:12', 'FMDAY'), '/'); |
Returns:
/Monday/
|
In MariaDB the result of the latter is an error:
ERROR 3047 (HY000): Invalid argument error: date format not recognized at FMDAY in function to_char.
Implementation details
Let's extend TO_CHAR() to understand the "FM" key in the format string. "FM" should toggle padding of all components following it. TO_CHAR() starts with padding enabled. The first FM disables padding. The second FM enables padding, the third FM disables padding again, and so on.
- When FM is not specified (or is specified even number of times), all following it (until the next FM or until the end of the format) string format components DAY (weekday name) and MONTH (month name) are right-padded with spaces to the maximum possible DAY and MONTH name lengths respectively, according to the current locale in @@lc_time_names. So for example, with lc_time_names='en_US' all month names are right-padded with spaces up to 9 characters ('September' is the longest):
SET lc_time_names='en_US';
SELECT TO_CHAR('0001-02-03', 'MONTH'); -> 'February ' (padded to 9 chars)
When FM is typed odd number of times, DAY and MONTH names are not right-padded with trailing spaces:
SET lc_time_names='en_US';
SELECT TO_CHAR('0001-02-03', 'FMMONTH'); -> 'February' (not padded)
- When FM is not specified (or is specified even nubmer of times), all following it (until the next FM or until the end of the format) numeric components YYYY, YYY, YY, Y, DD, H12, H24, MI, SS are left-padded with leading digits '0' up to the maximum possible number of digits in the component (e.g. 4 for YYYY):
SELECT TO_CHAR('0001-02-03', 'YYYY'); -> '0001' (padded to 4 chars)
When FM is typed odd number of times, these numeric components are not left-padded with leading zeros:
SELECT TO_CHAR('0001-02-03', 'FMYYYY'); -> '1' (not padded)
Oracle documentation is incomplete and confusing
After reading the Oracle documentation about FM (see the Oracle docs: FM fill mode link below) one might get an impression that FM can only switch padding off and that there is no a way to "undo" the effect of FM to enable padding again further in the format string. This impression is incorrect. It looks like a bug in the documentation. In fact when FM is specified multiple times in the same format string, an odd FM disables padding, an even FM enables padding. In other words, every FM inverts the previous padding state.
So we'll implement FM in the way it actually works in Oracle, not in the way described in the documentation.
Attachments
Issue Links
- links to
ralf.gebhardt, this is a new feature.