Closed morozov closed 3 years ago
I talked to @tessus and @kadler and we're not sure this might not be the correct fix. When I looked at the original report, I noticed the type you had was CHAR FOR BIT DATA
. Our suspicion is SQL/CLI treats this as a string (which is null terminated, AFAIK, so truncating with strlen is appropriate), and not a binary (which absolutely can have nulls).
At least on IBM i (I can't say for LUW, tessus would be better at that), FOR BIT DATA
implies CCSID 65535 (raw). Thus, kadler implemented a workaround for FOR BIT DATA
to mark them as SQL_BINARY
instead of SQL_CHAR
in the Python driver. I think backporting this to the PHP driver might be the better good alternative, assuming it works for LUW too.
assuming it works for LUW too
It should. FOR BIT DATA
should be bound to BINARY by default anyway. My current dev box is shot, but I wanted to setup a new VM at one point. I hope I'll get to it soon, althought I can't promise anything.
The test code uses the query SELECT X'410042' V FROM sysibm.sysdummy1
, which would not be considered a CHAR() FOR BIT DATA
, but a regular VARCHAR
in JOB CCSID. So the code I wrote wouldn't apply.
AFAIK, there is no way easy way to deal with this when using IBM i CLI, since it erroneously returns SQL_NTS
when null-terminated string support is enabled (IBM i CLI has a tenuous grasp of the standard AFAICT). Thus, the caller has no clue how much data was actually returned. I think the only way to handle this would be to memset the data to a non-null value and then search from the end for the null byte added by CLI.
@kadler it shouldn't be a problem. I implemented the test using SELECT X'410042' V FROM sysibm.sysdummy1
for the sake of simplicity. The actual problem is about fetching stored data. So if you can fix it the right way based on the underlying data type, the test can be reworked too (in a way that the issue is originally documented).
Ahh, I didn't see the original report. SELECT CAST(X'410042' as VARCHAR(10) FOR BIT DATA) V FROM sysibm.sysdummy1
should do it, or just VALUES(CAST(X'410042' as VARCHAR(10) FOR BIT DATA))
. (Substitute whatever length desired in the cast.)
Is SQL_DESC_COLUMN_CCSID
used to determine the CCSID
of the column available in the LUW client library? I don't see it defined in the include/sqlcli.h
shipped as part the LUW driver, and the library for python uses it with only with IBM i (as mentioned above).
I believe it's an IBM i-only thing. I'm not sure if there's an equivalent way to do it using LUW libraries.
I believe it's an IBM i-only thing. I'm not sure if there's an equivalent way to do it using LUW libraries.
In this case, how do we proceed here? I believe this suggestion is no longer valid:
I think backporting this to the PHP driver might be the better good alternative, assuming it works for LUW too.
Tested locally with ibmcom/db2:11.5.6.0: