-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix bug #80892 PDO::PARAM_INT on pdo_pgsql #6801
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
Conversation
Merged in 340a067 |
Hey all - we got a PR related to this change on Laravel: laravel/framework#37168 In summary, previously if you had a That's OK I guess, although fairly unexpected and large breaking change on a patch release? In addition, if we try to adjust Laravel to bind all booleans using But, it does put us in a pretty tough spot, since if we don't merge this PR change, people can no longer perform simple boolean queries in Laravel using PHP 8.0.5, while if we do merge it, we break all applications querying Ultimately, if this PR stands, we would just need to remove this convenience boolean to integer casting when working with Postgres and people could no longer pass booleans in our query builders when querying if a Any thoughts? /cc @driesvints |
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) { | ||
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT) { | ||
/* we need to check if the number requires bigints */ | ||
long long val = strtoll(Z_STRVAL_P(parameter), NULL, 10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without having looked into Taylor's issue yet, this code is clearly broken :( If the original value was null or bool, then it will stay as such, while this code assumes the value is always a string. Passing a null to a PARAM_INT binding causes a segfault now (bool doesn't for some reason).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed I thought I had better coverage :(
Thanks @taylorotwell - I will have a better look tomorrow. Also cc-ing @derickr @carusogabriel as RMs |
Was this PR merged without a review? |
@kamil-tekiela The bug report hit internals. The PR has been available for several days before I merged it in. In fact the strtoll usage itself had been reviewed and approved. In an ideal world everyone tests the RCs with their applications and this kind of BC breaks are intercepted. In an ideal world also I wouldn't have shuffled the code out of the previous else block above thining "yeah, it's ok, tests are green", but sadly that happened. That said, I'm currently working to fix the issue and making sure there are no regressions. |
mbeccati@ff69c9e is my tentative fix. It surely does fix the segmentation fault and leaves booleans out of the actual change. I don't know however if I've fully covered Laravel's test scenario. TBH I'm a bit on the fence on this one and I would also consider reverting the change. |
@mbeccati That patch looks reasonable as far as the segfault is concerned, but I don't think it would address Laravel's issue, which is the other way around: A boolean column addressed through PARAM_INT. |
Unfortunately the new test fails due to: The same test passes on 7.3. Segfault aside, fixing the the PARAM_INT bug brings a significant and unexpected behaviour change that doesn't belong to a minor release. If you agree, I will proceed with the revert. |
@mbeccati Yeah, I think we should revert this from the stable releases. That would still leave the question of whether this change should be made for PHP 8.1, or whether this should be left alone altogether. |
Reverted from 7.4 to master. I think the matter requires some more thoughts about pros and cons to apply a similar bug fix to 8.1+. Thanks again @taylorotwell for reporting. |
This PR has broken also atk4/dsql and atk4/data tests. I fixed it in atk4/dsql#299 . For some reasons, PARAM_INT (with this fix) can not be used with boolean columns, but PARAM_STR can. But this PR makes sense to me for PHP 8.1. FYI PARAM_BOOL in Oracle should on the other side map to PARAM_INT, as PARAM_BOOL does not work, see atk4/dsql#299 (comment) and based on https://stackoverflow.com/questions/3726758/is-there-any-boolean-type-in-oracle-databases it is not even supported by Oracle |
@mbeccati According to https://www.php.net/ChangeLog-7.php this ended up in the 7.4.18 release. Was that intentional? |
@hansgv Yes, it ended in 7.4.18 and 8.0.5... that's unfortunate. I wish more poeple would also test release candidates so that this kind of issues could be intercepted, reviewed and eventually rolled back before the final release. |
With that said, I think the actual bug is in the software trying to bind an integer for a boolean column and I hope we'll have a chance to fix binding in 8.1, even if that means people need to adjust their own code to avoid depending on PHP bugs. |
@mbeccati Will a new patch be released without this? If so, do you know when? Haven't found a way to downgrade to 7.4.16 on Ubuntu. |
@tbleckert The bug fix has been reverted on git and the revert will be in next point releases, that's all I know 🤷 |
@tbleckert Assuming you are using Ondrej's PPA, you might be able to request a backport of the revert at https://github.com/oerdnj/deb.sury.org. Not sure what their policy on this is. |
https://bugs.php.net/bug.php?id=80892#1620030664 indicates that this change probably isn't viable even for 8.1. The pgsql type system is too strict for this to work. |
@nikic Yes, it is possible that we can't fix the original issue without introducing other problems. That sucks, but I'm more and more inclined to drop all of this to avoid wasting time doing pointless research for 8.1. |
In atk4/dsql we run tests across all DB vendors and fix was needed, see https://github.com/atk4/dsql/pull/299/files#diff-cac2b61f4ef042b487661e448d66b69392b1de2f82c4a0e1de1a2fd1be614bffR532, however this change is welcomed from my side in PHP 8.1. I also find out that Oracle does not support boolean type at at, but php oci driver does not convert |
Looks like https://bugs.php.net/bug.php?id=81006 is people hitting the segfault part of this issue. |
It would appear Ondrej has released 7.4.18-2. Anyone know if this issue was fixed? |
@hansgv seems like 8.0.5-2 at least solved it: laravel/framework#37215 (comment) |
@hansgv Ondrej reverted the PR that was causing the pgsql package to break installations (eg. laravel). That works as far as I am concerned. The subject of this issue is another and does not seem to have a solution yet (and might not get one soon). |
for centos (remi repo): yum downgrade php-* --exclude=php-pecl-* |
I have had to set our docker image version |
For the record, PHP 7.4.19 / PHP 8.0.6 have been / will be released outside the usual schedule, with a fix for this regression only. |
Created PR for review - I will commit to the appropriate branches when ready.