No rule in the scanner matches a NUL byte, so what re2c does with one
is undefined. Before 5ccc56b1e4 it happened to skip one character. Now
it returns a zero-length text token and pdo_parse_params() loops
forever, or reads an uninitialized YYMARKER if the NUL is the first
byte. Add a default rule so a NUL is skipped as one character of text
again.
Close GH-24496
The scanner that finds placeholders in queries excluded e/E from plain
text, because they can start an E'...' string. So every e/E in a query
(SELECT, WHERE, created_at, ...) ended a text token and became a
one-character token of its own. Allow e/E inside text as long as the
text doesn't end with one, so E'...' strings are still recognized.
Also let re2c generate bitmaps (-b) for the character classes instead
of a switch on every input character.
The scanner runs in PDO::prepare() and, with emulated prepares, again in
PDOStatement::execute(). Instructions for 200k calls of prepare():
emulated native
SELECT, 11 cols -24% -16%
INSERT, 8 params -15% -7%
For a whole emulated query (prepare, execute, fetch one row) against a
local server, PHP executes 7-9% fewer instructions.
Co-authored-by: Gina Peter Banyard <girgias@php.net>
Close GH-24353
This is, as the name and a comment in the header imply, an internal
header which is not supposed to be used by extensions other than PDO
(not even by drivers).
Since there is apparently no need to include this header in the parsers
of the drivers, we remove these includes, and no longer declare the
header to be installed. Given that the header is only exported for a
couple of weeks[1], this is not considered to be a BC break, because
it's unlikely that external drivers have already been adjusted to use
this header, and otherwise they can still be fixed; PHP 8.4 is still in
the pre-release stage.
[1] <https://github.com/php/php-src/pull/14797>
Closes GH-15688.