fix_mixing_positinal_ordered_placeholders_warnings_20130126.patch
application/octet-stream
Filename: fix_mixing_positinal_ordered_placeholders_warnings_20130126.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 | 22 | 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
***************
*** 1532,1538 ****
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>
--- 1532,1539 ----
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
***************
*** 4003,4008 **** text_format(PG_FUNCTION_ARGS)
--- 4003,4012 ----
Oid element_type = InvalidOid;
Oid prev_type = InvalidOid;
FmgrInfo typoutputfinfo;
+ int position = 0;
+ bool positional = false;
+ bool ordered = false;
+ bool warning_emmited = false;
/* When format string is null, returns null */
if (PG_ARGISNULL(0))
***************
*** 4092,4099 **** 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
--- 4096,4111 ----
*/
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
***************
*** 4103,4108 **** text_format(PG_FUNCTION_ARGS)
--- 4115,4121 ----
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("argument number is out of range")));
}
+ arg = position;
}
else
{
***************
*** 4140,4145 **** text_format(PG_FUNCTION_ARGS)
--- 4153,4165 ----
(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
***************
*** 265,282 **** ERROR: unterminated conversion specifier
--- 265,292 ----
select format('%1$1', 1);
ERROR: unrecognized conversion specifier "1"
-- check mix of positional and ordered placeholders
+ -- should raise warning
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)
+
-- check variadic labeled arguments
select format('%s, %s', variadic array['Hello','World']);
format
*** a/src/test/regress/sql/text.sql
--- b/src/test/regress/sql/text.sql
***************
*** 82,89 **** select format('%1s', 1);
--- 82,91 ----
select format('%1$', 1);
select format('%1$1', 1);
-- check mix of positional and ordered placeholders
+ -- should raise warning
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');
-- check variadic labeled arguments
select format('%s, %s', variadic array['Hello','World']);
select format('%s, %s', variadic array[1, 2]);