fix_mixing_positinal_ordered_placeholders.patch
application/octet-stream
Filename: fix_mixing_positinal_ordered_placeholders.patch
Type: application/octet-stream
Part: 0
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: context
| File | + | − |
|---|---|---|
| doc/src/sgml/func.sgml | 2 | 1 |
| src/backend/utils/adt/varlena.c | 23 | 0 |
| src/test/regress/expected/text.out | 10 | 0 |
| src/test/regress/sql/text.sql | 2 | 0 |
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 1530,1536 ****
SQL literal; <literal>%%</literal> outputs a literal <literal>%</>.
A conversion can reference an explicit parameter position by preceding
the conversion specifier with <literal><replaceable>n</>$</>, where
! <replaceable>n</replaceable> is the argument position.
See also <xref linkend="plpgsql-quote-literal-example">.
</entry>
<entry><literal>format('Hello %s, %1$s', 'World')</literal></entry>
--- 1530,1537 ----
SQL literal; <literal>%%</literal> outputs a literal <literal>%</>.
A conversion can reference an explicit parameter position by preceding
the conversion specifier with <literal><replaceable>n</>$</>, where
! <replaceable>n</replaceable> is the argument position. A warnig is raised
! when positional and ordered placeholders are used together.
See also <xref linkend="plpgsql-quote-literal-example">.
</entry>
<entry><literal>format('Hello %s, %1$s', 'World')</literal></entry>
*** a/src/backend/utils/adt/varlena.c
--- b/src/backend/utils/adt/varlena.c
***************
*** 3958,3964 **** text_format(PG_FUNCTION_ARGS)
const char *start_ptr;
const char *end_ptr;
text *result;
! int arg = 0;
/* When format string is null, returns null */
if (PG_ARGISNULL(0))
--- 3958,3968 ----
const char *start_ptr;
const char *end_ptr;
text *result;
! int arg;
! int position = 0;
! bool positional = false;
! bool ordered = false;
! bool warning_emmited = false;
/* When format string is null, returns null */
if (PG_ARGISNULL(0))
***************
*** 4006,4013 **** text_format(PG_FUNCTION_ARGS)
*/
if (*cp < '0' || *cp > '9')
{
! ++arg;
! if (arg <= 0) /* overflow? */
{
/*
* Should not happen, as you can't pass billions of arguments
--- 4010,4025 ----
*/
if (*cp < '0' || *cp > '9')
{
! /* don't allow mix styles - reflects glibc behave */
! if (positional && !warning_emmited)
! {
! elog(WARNING, "ordered and positional placeholders are used together");
! warning_emmited = true;
! }
! ordered = true;
!
! ++position;
! if (position <= 0) /* overflow? */
{
/*
* Should not happen, as you can't pass billions of arguments
***************
*** 4017,4022 **** text_format(PG_FUNCTION_ARGS)
--- 4029,4035 ----
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("argument number is out of range")));
}
+ arg = position;
}
else
{
***************
*** 4054,4059 **** text_format(PG_FUNCTION_ARGS)
--- 4067,4079 ----
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unterminated conversion specifier")));
+ if (ordered && !warning_emmited)
+ {
+ elog(WARNING, "ordered and positional placeholders are used together");
+ warning_emmited = true;
+ }
+ positional = true;
+
/* There's no argument 0. */
if (arg == 0)
ereport(ERROR,
*** a/src/test/regress/expected/text.out
--- b/src/test/regress/expected/text.out
***************
*** 229,243 **** ERROR: unterminated conversion specifier
--- 229,253 ----
select format('%1$1', 1);
ERROR: unrecognized conversion specifier "1"
--checkk mix of positional and ordered placeholders
+ --should raise warnings
select format('Hello %s %1$s %s', 'World', 'Hello again');
+ WARNING: ordered and positional placeholders are used together
format
-------------------------------
Hello World World Hello again
(1 row)
select format('Hello %s %s, %2$s %2$s', 'World', 'Hello again');
+ WARNING: ordered and positional placeholders are used together
format
--------------------------------------------------
Hello World Hello again, Hello again Hello again
(1 row)
+ select format('Hello %s %2$s %s', 'World', 'Hello again');
+ WARNING: ordered and positional placeholders are used together
+ format
+ -------------------------------------
+ Hello World Hello again Hello again
+ (1 row)
+
*** a/src/test/regress/sql/text.sql
--- b/src/test/regress/sql/text.sql
***************
*** 74,78 **** select format('%1s', 1);
--- 74,80 ----
select format('%1$', 1);
select format('%1$1', 1);
--checkk mix of positional and ordered placeholders
+ --should raise warnings
select format('Hello %s %1$s %s', 'World', 'Hello again');
select format('Hello %s %s, %2$s %2$s', 'World', 'Hello again');
+ select format('Hello %s %2$s %s', 'World', 'Hello again');