0001-apply-number-v1.patch
application/octet-stream
Filename: 0001-apply-number-v1.patch
Type: application/octet-stream
Part: 0
Message:
Fix number skipping in to_number
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v1-0001
| File | + | − |
|---|---|---|
| src/backend/utils/adt/formatting.c | 16 | 6 |
| src/test/regress/expected/numeric.out | 33 | 0 |
| src/test/regress/sql/numeric.sql | 10 | 0 |
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 46f45f6654..6ae02056d7 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -4655,6 +4655,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
FormatNode *n;
NUMProc _Np,
*Np = &_Np;
+ int separator_len;
+ bool noadd;
MemSet(Np, 0, sizeof(NUMProc));
@@ -4808,6 +4810,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
* Locale
*/
NUM_prepare_locale(Np);
+ separator_len = strlen(Np->L_thousands_sep);
/*
* Processor direct cycle
@@ -4819,6 +4822,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
for (n = node, Np->inout_p = Np->inout; n->type != NODE_TYPE_END; n++)
{
+ noadd = false;
if (!Np->is_to_char)
{
/*
@@ -4879,6 +4883,10 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
continue;
}
}
+ if(!strncmp(Np->inout_p, Np->L_thousands_sep, separator_len))
+ Np->inout_p += separator_len - 1;
+ else
+ noadd = true;
break;
case NUM_G:
@@ -4890,10 +4898,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
continue;
else
{
- int x = strlen(Np->L_thousands_sep);
-
- memset(Np->inout_p, ' ', x);
- Np->inout_p += x - 1;
+ memset(Np->inout_p, ' ', separator_len);
+ Np->inout_p += separator_len - 1;
}
}
else
@@ -4909,7 +4915,10 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
if (IS_FILLMODE(Np->Num))
continue;
}
- Np->inout_p += strlen(Np->L_thousands_sep) - 1;
+ if(!strncmp(Np->inout_p, Np->L_thousands_sep, separator_len))
+ Np->inout_p += separator_len - 1;
+ else
+ noadd = true;
}
break;
@@ -5030,7 +5039,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
if (Np->is_to_char)
*Np->inout_p = n->character;
}
- Np->inout_p++;
+ if (!noadd)
+ Np->inout_p++;
}
if (Np->is_to_char)
diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out
index ae0beb9b68..41b582de09 100644
--- a/src/test/regress/expected/numeric.out
+++ b/src/test/regress/expected/numeric.out
@@ -1925,3 +1925,36 @@ SELECT SUM((-9999)::numeric) FROM generate_series(1, 100000);
-999900000
(1 row)
+--
+-- Tests to regression test TODO item 'Fix to_number() handling for values not matching the format string'
+--
+select to_number('34,50','999,99');
+ to_number
+-----------
+ 3450
+(1 row)
+
+select to_number('34,50','999G99');
+ to_number
+-----------
+ 3450
+(1 row)
+
+select to_number('12,34','999G99');
+ to_number
+-----------
+ 1234
+(1 row)
+
+select to_number('123,000','999G');
+ to_number
+-----------
+ 123
+(1 row)
+
+select to_number('123456','999G999');
+ to_number
+-----------
+ 123456
+(1 row)
+
diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sql
index b51225c47f..e1dd3a405c 100644
--- a/src/test/regress/sql/numeric.sql
+++ b/src/test/regress/sql/numeric.sql
@@ -1005,3 +1005,13 @@ select scale(-13.000000000000000);
-- cases that need carry propagation
SELECT SUM(9999::numeric) FROM generate_series(1, 100000);
SELECT SUM((-9999)::numeric) FROM generate_series(1, 100000);
+
+--
+-- Tests to regression test TODO item 'Fix to_number() handling for values not matching the format string'
+--
+
+select to_number('34,50','999,99');
+select to_number('34,50','999G99');
+select to_number('12,34','999G99');
+select to_number('123,000','999G');
+select to_number('123456','999G999');