diff --git a/pkg/util/tochar/constants.go b/pkg/util/tochar/constants.go index ed40cdbc3f36..1d7641168b24 100644 --- a/pkg/util/tochar/constants.go +++ b/pkg/util/tochar/constants.go @@ -271,6 +271,14 @@ var dchKeywords = []keyWord{ //{"", 0, false, 0}, } +// Months in roman-numeral +// (Must be in reverse order for seq_search (in FROM_CHAR), because +// 'VIII' must have higher precedence than 'V') +var ( + ucMonthRomanNumerals = []string{"XII", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I"} + lcMonthRomanNumerals = []string{"xii", "xi", "x", "ix", "viii", "vii", "vi", "v", "iv", "iii", "ii", "i"} +) + // From https://github.com/postgres/postgres/blob/b0b72c64a0ce7bf5dd78a80b33d85c89c943ad0d/src/backend/utils/adt/formatting.c#L194-L198. type formatNodeType int diff --git a/pkg/util/tochar/testdata/ymd.ddt b/pkg/util/tochar/testdata/ymd.ddt index a677b331b431..8b404444444f 100644 --- a/pkg/util/tochar/testdata/ymd.ddt +++ b/pkg/util/tochar/testdata/ymd.ddt @@ -546,3 +546,38 @@ J 3 years 6 months 01:02:03 ---- 3 years 6 months 01:02:03: 1722306 + +# RM +timestamp +RM"x" +2020-02-01 BC 01:02:03 +2020-12-01 01:02:03 +2020-01-01 01:02:03 +---- +2020-02-01 BC 01:02:03: II x +2020-12-01 01:02:03: XII x +2020-01-01 01:02:03: I x + +timestamp +rm"< spaces here" +2020-02-01 BC 01:02:03 +2020-12-01 01:02:03 +2020-01-01 01:02:03 +---- +2020-02-01 BC 01:02:03: ii < spaces here +2020-12-01 01:02:03: xii < spaces here +2020-01-01 01:02:03: i < spaces here + +interval +FMRM" < no spaces here" +1 day +1 month 1 day +-1 month 1 day +-13 months +13 months +---- +1 day: < no spaces here +1 month 1 day: I < no spaces here +-1 month 1 day: XI < no spaces here +-13 months: XI < no spaces here +13 months: I < no spaces here diff --git a/pkg/util/tochar/tochar.go b/pkg/util/tochar/tochar.go index d2006f170bd4..993be69abce9 100644 --- a/pkg/util/tochar/tochar.go +++ b/pkg/util/tochar/tochar.go @@ -494,12 +494,30 @@ func timeToChar(t timeInterface, formatNodes []formatNode) (string, error) { sb.WriteString(fmt.Sprintf("%0*d", zeroPad, val)) sb.WriteString(fn.suffix.thVal(val)) case DCH_RM, DCH_rm: - // Roman numerals, not supporting this for now... - return "", pgerror.Newf( - pgcode.FeatureNotSupported, - "to_char format %s not supported", - fn.key.name, - ) + if t.Month() == 0 && t.Year() == 0 { + continue + } + // Roman numerals are in reverse order, which is why the indexes + // are reversed. + var idx int + if t.Month() == 0 { + if t.Year() >= 0 { + idx = 0 + } else { + idx = 11 + } + } else if t.Month() < 0 { + idx = -1 * int(t.Month()) + } else { + idx = 12 - int(t.Month()) + } + var str string + if fn.key.id == DCH_RM { + str = ucMonthRomanNumerals[idx] + } else { + str = lcMonthRomanNumerals[idx] + } + sb.WriteString(fmt.Sprintf("%*s", fn.suffix.zeroPad(-4), str)) case DCH_W: val := (t.Day()-1)/7 + 1 sb.WriteString(fmt.Sprintf("%d", val))