impossibl/pgjdbc-ng — pull request #101 by brettwooldridge (2014-10-23 08:30:02+00:00)
Title: Fix #95 handle various orderings of IN, OUT, and INOUT parameters

The existing code only works if IN or INOUT parameters occur before OUT parameters.

Given the (processed) SQL ``( SELECT * FROM test_somein_someout3 ($1,$2,$3))``, where ``$1`` and ``$2`` are OUT parameters and ``$3`` is an IN parameter, the former could would produce processed SQL like ``( SELECT * FROM test_somein_someout3 ($3))`` (IN and INOUT parameters must be removed). The problem with this is that PostgreSQL is expecting placeholders to start from ``$1``. As placeholders are processed the need to be "re-sequenced". If ``$2`` is removed, the remaining placeholders should be ``($1,$2)`` (with ``$3``→``$2``).

The existing regexes also had other issues. For example, if there were 10 or more parameters, ``SELECT ... ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)``, the regex for ``$1`` would also match the ``$1`` of ``$10`` and redact it, leaving ``$0``. While the new regex is quite a bit more complex, it covers every variation I would think of.

The existing regexes also had other issues, for example, when redacting ``$1``, ``$2`, and ``$3`` out of ``($1,$2,$3,$4)`` the result was ``(,,$1)`` (after the re-sequencing fix). The regexes were adjusted to remove multiple occurrences of sequential commas, so the result is a clean ``($1)``.

Additional test cases were added to cover various orderings of parameter types. Given the complexity of the regex changes, I'm not sure how easy it is for someone to review, but if you'd like to take a look...

I can expound more on what the regex is doing if requested.