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

ScalarColumnHydrator: prevent early-bail on falsy values #9663

Merged
merged 2 commits into from
Apr 19, 2022
Merged

ScalarColumnHydrator: prevent early-bail on falsy values #9663

merged 2 commits into from
Apr 19, 2022

Conversation

MrMitch
Copy link
Contributor

@MrMitch MrMitch commented Apr 15, 2022

Hi !

This is my first contribution to Doctrine, please let me know if there is anything I can do to facilitate the review process.

--

Fix #9230

Falsy values stop the hydration process in $query->getSingleColumnResult(). If the array of values fetched from the database contains a value that is "falsy", every value after that value and including that value is missing from the array that is returned.

This is because of the way the database values are retreived in ScalarColumnHydrator :

while ($row = $this->statement()->fetchOne()) {
$result[] = $row;
}

This PR fixes that by fetching all the values and returning them as is. As before, and to keep things consistent with the previous behavior of both ScalarHydrator and ScalarColumnHydrator, no type conversion is done between the database value and the PHP value. According to a comment in AbstractHydrator, this is the expected behavior for scalar hydrators that is a legacy behavior from 2.0 :

// WARNING: BC break! We know this is the desired behavior to type convert values, but this
// erroneous behavior exists since 2.0 and we're forced to keep compatibility.
if (! isset($cacheKeyInfo['isScalar'])) {
$type = $cacheKeyInfo['type'];
$value = $type ? $type->convertToPHPValue($value, $this->_platform) : $value;
$fieldName = $cacheKeyInfo['dqlAlias'] . '_' . $fieldName;
}

@derrabus
Copy link
Member

derrabus commented Apr 15, 2022

Your patch introduces some complexity to the codebase by duplicating logic from the DBAL. Naive question: Shouldn't your problem be fixed if you changed the loop this way?

-         while ($row = $this->statement()->fetchOne()) {
+         foreach ($this->statement()->iterateColumn() as $row) {

@MrMitch
Copy link
Contributor Author

MrMitch commented Apr 15, 2022

@derrabus Thank you for your quick reply. You're absolutely right, using a simple foreach loop produces the same result and reduces the complexity, I've amended the code accordingly.

We could even further reduce the length of the method by using return iterator_to_array($this->statement()->iterateColumn()), but I'm not sure that would add real value or maintainability.

@MrMitch
Copy link
Contributor Author

MrMitch commented Apr 18, 2022

@derrabus I've amended the code further to fix support for databases that have native support for boolean values (like PostgreSQL).

@derrabus derrabus added this to the 2.11.3 milestone Apr 19, 2022
@derrabus derrabus enabled auto-merge (squash) April 19, 2022 08:57
@derrabus
Copy link
Member

Thank you, @MrMitch!

@derrabus derrabus merged commit 4af1aa3 into doctrine:2.11.x Apr 19, 2022
@MrMitch MrMitch deleted the fix-falsy-values-cause-early-bail-in-scalar-column-hydrator-issue-9230 branch April 19, 2022 09:03
@MrMitch
Copy link
Contributor Author

MrMitch commented Apr 19, 2022

Happy to contribute, thank you for reviewing this with care.

derrabus added a commit that referenced this pull request Apr 19, 2022
* 2.11.x:
  ScalarColumnHydrator: prevent early-bail on falsy values (#9663)
derrabus added a commit that referenced this pull request Apr 19, 2022
* 2.12.x:
  Deprecate the doctrine binary (#9661)
  ScalarColumnHydrator: prevent early-bail on falsy values (#9663)
  Fix enum hydration when fetching partial results (#9657)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Single column hydration returns nothing if first item is false-like
2 participants