Skip to content

WIP: Implement PDO::PARAM_BINARY #11674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

NattyNarwhal
Copy link
Member

Adds a binary parameter type to PDO, making it semantically clear when you want a binary data string. This is particularly useful for ODBC (which will hex-encode binary data bound as SQL_C_CHAR) and DBLIB (which must escape binary data to avoid mangling the query over the wire).

When merged, this closes GH-11462.

My testing so far is on macOS 13 on ARM, with an SQL Server 2016 instance elsewhere on Windows.

Only DBLIB, SQLite, and ODBC have been modified for this. I haven't added support to OCI8, Firebird, MySQL, or Postgres; I'll likely do the latter two myself later if these make sense.

Notes:

  • It does seem PDO_SQLite reuses PARAM_LOB for binding binary non-LOB, non-stream strings. Maybe it'd be fine for other drivers to do this?
  • The PDO_ODBC one actually doesn't use the bound type specified by the bind type argument, but rather what's returned by the database. This adds support for binary data in a way that should be independent on PARAM_BINARY and be cherry-picked out.
    • Taking the user-provided type information into account would be a good idea, but require a bigger refactor
  • There are some test failures for PDO_ODBC, I'm not entire sure if related:
Bug #80783 (PDO ODBC truncates BLOB records at every 256th byte) [ext/pdo_odbc/tests/bug80783.phpt]
Bug #80783 (PDO ODBC truncates BLOB records at every 256th byte) [ext/pdo_odbc/tests/bug80783a.phpt]
via [ext/pdo_odbc/tests/common.phpt]
	ODBC PDO Common: Bug #36798 (Error parsing named parameters with queries containing high-ascii chars) [ext/pdo_odbc/tests/bug_36798.phpt]

Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick overview of this seems to make sense, but then I know nothing about databases.

Also CI is failing on some of the new tests

@NattyNarwhal
Copy link
Member Author

NattyNarwhal commented Jul 13, 2023

After looking at it, bug80783.phpt is affected by returning binary data instead of the hex-encoded thing; the ODBC change ignoring the PDO type to bind as would be breaking as a result. (Without a PDO_PARAM_BINARY or overriding the semantics of LOB, that might be trickier to backport w/o the new PDO type though.)

Oddly, the a variation of the test returns the raw UTF-16 because it's bound as binary for Unicode (as it was pre-PR) but not getting converted from 16-bit characters... which looks like it should always fail on not-Windows, because it does conversion with pdo_odbc_ucs22utf8, which is basically completely nopped out on not-Windows?

@NattyNarwhal
Copy link
Member Author

Turns out I've overthought this a bit and I think the PDO type override is probably adequate in get_col. I think bug80783a.phpt is busted on Unix though - it's not passing in normal master on macOS w/ the SQL Server driver.

Copy link
Member

@nielsdos nielsdos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two minor comments of 2 details I noticed that might help you out here.

Original text:
>If the user is specifying a PDO::PARAM_LOB, there's a good chance
>that it's a binary file (i.e. an image), that is too fragile to
>survive in a string, as escaping it is insufficient. Because
>PDO_DBLIB relies on PDO to fill in a parameterized query and
>submits the filled string to the server, it ends up mangling the
>query.
>
>This adds logic in the PDO_DBLIB quoter to handle binary parameters
>by using the SQL Server binary literal syntax (a hex string that
>begins with `0x`). This resolves the issue because PDO consults the
>quoter for filling in the query string.
...including a test.

I'm not sure if the semantics are right here though. This does binary
data if the DB returns it, instead of listening to the PDO param type.
This does mean that binary data works like expected, but the binary
bound to SQL_C_CHAR converting behaviour in some drivers[1] may be
desired and specified instead...

[1]: At least Db2i and SQL Server's drivers, when I tested them.
the PDO_DBLIB change predates the PDO_BINARY proposa, so...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Binary type for PDO
3 participants