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
DBAL FETCH silently returns truncated results when database emits an error after initial prefetch #4553
Comments
@amenning thank you for the report. Could you convert the code in the description to an integration test or at least a standalone script that reproduces the problem? This way, we could see what exactly is happening.
What is the return value in this case? According to the documentation,
So we normally don't promote warnings to an exception. IIRC there was a similar edge case where after having received |
I'm not entirely sure how to write an integration test for this since it requires an Oracle db to be present. I could mock out a db connection to cause the warning to be thrown, but that would lock in the current DB functionality now and not warn us for future changes/behavior with a db like Oracle. The warning that is issued is in the OCI8 result method when calling oci_fetch_array. It is an E_WARNING with message "oci_fetch_array(): ORA-04068: existing state of packages has been discarded ORA-04065: not executed, altered or dropped [] []". Do you have a preference on how the integration test should be developed? Should I attempt to mock out the db with today's behavior? |
We do have integration tests running on Oracle in GitHub actions. You can add a new integration test and submit a pull request. You can spin up a docker container locally and develop against it: $ docker run -p 1521:1521 wnameless/oracle-xe-11g-r2 Given that you have posted all the code snippets, I think I could put them together myself and reproduce the issue. It just may take extra time before I get to it. |
Nice, I didn't realize those types of tests were present in this repo already. I'll give that a go, thank you for that feedback. |
I have added a PR that adds a failing functional unit test - #4581 |
Thanks, @amenning! The test looks good. I'll try to debug it and see how the error handling could be improved. |
I've added a potential solution in that PR that passes all the tests. It throws a new truncated query result exception using an error handler surrounding the oci_fetch_array call that only screens E_WARNINGS for ORA type errors. |
[GH-4553] Simplify error handling in the OCI8 driver
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Bug Report
Summary
If one uses a FETCH to loop over a data set that is larger than the set prefetch size, it is possible that the result set will silently be truncated without an exception being thrown in PHP. DBAL should screen for DB errors for each fetch and emit a PHP exception.
This can become a problem when using distributed databases that are replicated from a central database source. Datasets could become invalidated when querying data on a replicated database that started before a DB refresh. The symptom of this issue will be that result sets can be truncated to any increment of the set prefetch size depending on when the results get invalidated on the DB. The rest of the PHP program could then be working with unexpected truncated result sets. Currently the only way to catch truncated result errors is to wrap the fetch method with a custom warning handler that screens for DB errors being emitted as PHP warnings (The PHP OCI8 driver only converts DB errors during a fetch to PHP warnings).
Current behavior
DBAL fetch will ignore db errors on subsequent fetches and can return truncated results without emitting a PHP exception.
How to reproduce
Example reproduction of issue with Oracle:
Expected behavior
DBAL should screen for DB errors on each fetch and emit a PHP exception instead of allowing truncated result sets.
The text was updated successfully, but these errors were encountered: