Re: [RFC] PDO binary parameter support
| From: | Ilia | Date: | Sun, 01 Nov 2026 16:39:20 +0000 |
| Subject: | Re: [RFC] PDO binary parameter support | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-132985@lists.php.net to get a copy of this message | ||
Hi Calvin,
Here are a couple of follow-up notes.
On Fri, Oct 16, 2026 at 6:27 PM Calvin Buckley <calvin@cmpct.info> wrote:
> > 2. The fallback leaves each driver to choose STR or LOB, and STR
> corrupts data: pdo_pgsql reads text-format parameters as C strings
> (truncated at the first NUL), pdo_mysql loses the _binary introducer. A
> per-driver table (native bind, emulated quote, fetch) would pin this down..
>
> For drivers that use emulated prepares, perhaps we could check string
> contents instead and use binary quoting based on that, but that feels slow
> and what characters need binary quoting would differ per driver.
>
Content sniffing can't settle this. A bytea or varbinary value can be valid
text, and text can contain a NUL, so the driver has to be told. It also
doesn't help native prepares: pdo_pgsql sends text-format parameters as C
strings, so they truncate at the first NUL regardless of quoting. That's
the strongest argument for the RFC imho.
> > 3. Neither representation degrades safely. An unknown type 6 falls to
> text in the bundled drivers and pdo_oci, IM001 in pdo_ibm, and a fatal
> error in pdo_sqlsrv. A flag only survives where the type is masked with
> PDO_PARAM_TYPE(); the emulated-prepare parser, PDO::quote(), the pgsql
> quoter, fetch_value() and pdo_sqlsrv all compare the raw value. The flag
> works only if core masks it before quoting and fetch overrides; the RFC
> should require that, and define what PARAM_INT | PARAM_BINARY does
> (ValueError, I'd say).
>
> Marking this a breaking change for drivers seems reasonable then
>
The driver break decides between using a type versus a flag. A new type 6
is a fatal error in pdo_sqlsrv and IM001 in pdo_ibm until each driver ships
an update. A flag that core masks before quoting allows fetch to fall back
to STR/LOB in any driver that ignores it. I'd go with the flag, and
reject combinations
with INT/BOOL/NULL with a ValueError.
> > 5. Changing getColumnMeta()'s pdo_type breaks strict comparisons either
> way (6 or STR | BINARY). A separate key would avoid that.
>
> I suspect a BC break for things relying on getColumnMeta would happen
> regardless of strategy. We could try something like pdo_sqlite's blob key
> perhaps if we really want to avoid it.
pdo_sqlite already marks blobs in getColumnMeta()'s "flags" array, which is
a good precedent for leaving pdo_type alone.
--
Ilia Alshanetsky
Technologist, CTO, Entrepreneur
E: ilia@ilia.ws
T: @iliaa
B: http://ilia.ws