Skip to content

Commit 09e99ce

Browse files
committed
Fix handling of format string text characters in to_timestamp()/to_date()
cf98467 introduced improvement of handling of spaces and separators in to_timestamp()/to_date() functions. In particular, now we're skipping spaces both before and after fields. That may cause format string text character to consume part of field in the situations, when it didn't happen before cf98467. This commit cause format string text character consume input string characters only when since previous field (or string beginning) number of skipped input string characters is not greater than number of corresponding format string characters (that is we didn't skip any extra characters in input string).
1 parent 38763d6 commit 09e99ce

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

src/backend/utils/adt/formatting.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3061,9 +3061,24 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
30613061
* Text character, so consume one character from input string.
30623062
* Notice we don't insist that the consumed character match the
30633063
* format's character.
3064-
* Text field ignores FX mode.
30653064
*/
3066-
s += pg_mblen(s);
3065+
if (!fx_mode)
3066+
{
3067+
/*
3068+
* In non FX mode we might have skipped some extra characters
3069+
* (more than specified in format string) before. In this
3070+
* case we don't skip input string character, because it might
3071+
* be part of field.
3072+
*/
3073+
if (extra_skip > 0)
3074+
extra_skip--;
3075+
else
3076+
s += pg_mblen(s);
3077+
}
3078+
else
3079+
{
3080+
s += pg_mblen(s);
3081+
}
30673082
continue;
30683083
}
30693084

src/test/regress/expected/horology.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3128,6 +3128,21 @@ SELECT to_date('2011 12 18', 'YYYY MM DD');
31283128
12-18-2011
31293129
(1 row)
31303130

3131+
SELECT to_date('2011 12 18', 'YYYYxMMxDD');
3132+
to_date
3133+
------------
3134+
12-18-2011
3135+
(1 row)
3136+
3137+
SELECT to_date('2011x 12x 18', 'YYYYxMMxDD');
3138+
to_date
3139+
------------
3140+
12-18-2011
3141+
(1 row)
3142+
3143+
SELECT to_date('2011 x12 x18', 'YYYYxMMxDD');
3144+
ERROR: invalid value "x1" for "MM"
3145+
DETAIL: Value must be an integer.
31313146
--
31323147
-- Check errors for some incorrect usages of to_timestamp() and to_date()
31333148
--

src/test/regress/sql/horology.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,10 @@ SELECT to_date('2011 12 18', 'YYYY MM DD');
495495
SELECT to_date('2011 12 18', 'YYYY MM DD');
496496
SELECT to_date('2011 12 18', 'YYYY MM DD');
497497

498+
SELECT to_date('2011 12 18', 'YYYYxMMxDD');
499+
SELECT to_date('2011x 12x 18', 'YYYYxMMxDD');
500+
SELECT to_date('2011 x12 x18', 'YYYYxMMxDD');
501+
498502
--
499503
-- Check errors for some incorrect usages of to_timestamp() and to_date()
500504
--

0 commit comments

Comments
 (0)