Skip to content
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

Bugfix for #62 #63

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

JoopClaireIT
Copy link

This fixes it for me locally. (First had the second part of the slice set to the size of the buffer, but of course that's completely senseless...)

Maybe check if this doesn't break anything.

This fixes it for me locally. (First had the second part of the slice set to the size of the buffer, but of course that's completely senseless...)
@alexbrainman
Copy link
Owner

I would like to understand what the problem is that we're fixing here. Lets decide that first at issue #62.

Alex

@haynesherway
Copy link

please merge this! I was about to submit the same thing

@haynesherway
Copy link

It has to do with how certain drivers report nulls. Sometimes they don't send back the SQL_NULL_DATA, I've noticed specifically with null dates. This adds an extra check to make sure we don't get the out of bounds error.

@alexbrainman
Copy link
Owner

This adds an extra check to make sure we don't get the out of bounds error.

c.Buffer size is passed to SQLBindCol, which returns c.Len. So unless SQLBindCol is broken, it cannot happen.

Another possibility is that the column type you use here cannot be used with SQLBindCol. Then the change in this PR is not going to fix your problem. NewColumn function decides whether to use SQLBindCol or not. Maybe you can adjust it to make this work for you.

Alternatively, if this PR works for you, you can always make this change in your own copy of this code, and keep it for yourself.

Alex

@haynesherway
Copy link

I did make the change in my own version, and have not had the problem since. It is a very specific issue, only with accessing a IBM iSeries DB2 from a 64-bit system. It seems the driver does not respond with a SQL_NULL_DATA in 64-bit, but rather in 32-bit, and therefore IsNull() is false, even though it should be true.

I have found a little bit of information on the subject:

I believe this returns a NULL and so when DBD::ODBC binds the column as an
SQL_C_LONG the driver sets the returned indicator to say SQL_NULL_DATA
which is -1. However, as your driver looks like it thinks SQLLEN/SQLULEN
are 4 byte quantities it writes 0xFFFFFFFF (-1 if a 4 byte integer) into a
8 byte quantity which now looks like 4294967295 and DBD::ODBC thinks the
column has been truncated.

It is also mentioned here: https://bugs.php.net/bug.php?id=54007

I am not sure if this corresponds to a known issue with the IBM driver, mentioned here https://docs.oracle.com/en/database/oracle/oracle-database/18/odbcr/odbc-driver-release-notes.pdf
"SQLBindParameter when used to bind a buffer as SQL_PARAM_INPUT_OUTPUT and having
a PL/SQL procedure with IN OUT parameter and if the parameter is not changed in
the procedure, then the driver will not return SQL_NULL_DATA in StrLen_or_IndPtr."

I know very little about the internals of the DB interactions, so I'm kind of digging at this blindly. Obviously, the correct solution would be for IBM to fix their driver, but since this has been brought up many times over the last few years and they have done nothing, and for me this is affecting production applications, at least this will be here for others looking for a solution in the future. If anyone else is experiencing the same issue, they can use the fork I created. I have also prefixed all the fields in my queries with COALESCE() to not allow for NULL values anywhere I can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants