feat(query): support TH/th ordinal and V shift patterns in to_char#19830
feat(query): support TH/th ordinal and V shift patterns in to_char#19830kimjune01 wants to merge 6 commits into
Conversation
Implements the TH and th format patterns for the postgres-compatible number to_char function. TH appends uppercase ordinal suffixes (ST, ND, RD, TH) and th appends lowercase equivalents, following PostgreSQL semantics including teen-number rules (11th, 12th, 13th). Closes part of databendlabs#16524
Implements the V format pattern for the postgres-compatible number to_char function. V multiplies the input by 10^n where n is the count of digit positions after V, then formats as an integer. Works for both integer and float inputs. Closes part of databendlabs#16524
- Move TH/th suffix emission from post-processing to inline at token position, so trailing literals and signs appear after the suffix - Fix Tk0 not checking NumFlag::Multi in prepare(), which corrupted multi count for formats like "09V00" - Use round_ties_even() instead of round() for float V to match PostgreSQL's IEEE 754 tie-breaking semantics - Use checked arithmetic for integer V to prevent overflow/panic on large multi values Reviewed by codex (GPT-5.5) and Gemini 3.1 Pro.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 21fdfaa4cf
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // then rounds to the nearest integer. | ||
| // Total output width = pre + multi digits. | ||
| let multiplier = 10f64.powi(self.multi as i32); | ||
| let shifted = (value.abs() * multiplier).round_ties_even(); |
There was a problem hiding this comment.
Use away-from-zero rounding for
V shift ties
The V implementation for floating-point values currently uses round_ties_even(), but PostgreSQL rounds to_char(..., '...V...') half values away from zero (for example, to_char(12.45, '99V9') is documented as 125). With the current code, tie cases like 12.45 produce 124, so Databend will return PostgreSQL-incompatible results for common .5 boundaries.
Useful? React with 👍 / 👎.
| NumPoz::TkPR => (), | ||
| NumPoz::TkFM => (), | ||
| NumPoz::TkV => (), | ||
| NumPoz::TkTH | NumPoz::Tkth => { |
There was a problem hiding this comment.
Skip ordinal suffix conversion for negative
TH/th
The ordinal suffix branch always appends st/nd/rd/th, but PostgreSQL's numeric formatting rules state that TH/th does not convert values less than zero (and also not fractional inputs). As written, calls like to_char(-1, '9th') will emit an ordinal suffix, which breaks PostgreSQL compatibility for negative values.
Useful? React with 👍 / 👎.
|
I hereby agree to the terms of the CLA available at: https://docs.databend.com/dev/policies/cla/ |
|
Cannot validate on current setup, so drafting. Please close or take it over. |
I hereby agree to the terms of the CLA available at: https://docs.databend.com/dev/policies/cla/
Summary
TH/thordinal number suffix pattern for the postgres-compatibleto_charnumber formatting function. Appends ST, ND, RD, or TH (upper or lower) following PostgreSQL teen-number rules.Vshift-digits pattern that multiplies the input by 10^n where n is the count of digit positions after V.Tk0not checkingNumFlag::Multiinprepare(), which would corrupt the multiplier for formats like09V00.round_ties_even()for float V to match PostgreSQL's IEEE 754 tie-breaking.Closes part of #16524
Tests
Type of change
Test plan
99V999,9V9This change is