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

WIP - Issue #3631 - fix for Double data type when using MySQLi with languages that do not use '.' for the decimal point #3660

Closed
wants to merge 1 commit into from

Conversation

mmucklo
Copy link
Contributor

@mmucklo mmucklo commented Aug 18, 2019

Q A
Type bug
BC Break no
Fixed issues #3631

Summary

  • Add a special ParameterType for Double
  • Detect floats in MysqliStatement and pass the 'd' as the parameter type (see: mysqli_stmt::bind-param)
  • Create two tests cases, one for the standard '.' version, and one that extends the same test case, but switches the language to de_DE and tests the ',' case.

@mmucklo mmucklo force-pushed the issue/3631_part1 branch 3 times, most recently from 0208bae to dc71600 Compare August 18, 2019 08:21
@mmucklo mmucklo changed the title Issue #3631 - fix for Double data type when using MySQLi with languages that do not use '.' for the decimal point WIP - Issue #3631 - fix for Double data type when using MySQLi with languages that do not use '.' for the decimal point Aug 18, 2019
@mmucklo mmucklo force-pushed the issue/3631_part1 branch 6 times, most recently from becbb8a to 8ccef4d Compare August 19, 2019 07:00
tests/travis/install-language-de.sh Outdated Show resolved Hide resolved
$result2 = $this->select(2);
$result3 = $this->select(3);

if (is_string($result1)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is if needed here? Are there different results expected from the same SELECT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morozov

Not all SQL drivers operate the same as I discovered while testing this.

PDO in most if not all cases seems to return floats as strings, while mysqli appears to return them as actual floats.

I discovered this while testing.

As I wanted the test to work on all drivers, I need to convert the ones that are strings into floats so that my comparisons properly work.

This could probably be done differently, I'm open to suggestions.

foreach ($values as &$v) {
$params[] =& $v;
// fix for issue #3631 - detect parameter types as they have to be bound differently
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we want to autodetect the type of untyped parameters? They should be bound as strings by design.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morozov,

Removed this for now (was missing the case for double / d anyway, as I was still testing things out) - this is for a separate "part II" of the bug where another test fails when under de_DE when dealing with floats.

I may add it back later, or do a follow on PR once this is accepted.

@@ -29,4 +30,12 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $value === null ? null : (float) $value;
}

/**
* {@inheritdoc}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morozov

Just following convention set in IntegerType - do you want me to remove the inheritdoc?:

$diff2 = abs($result2 - $value2);
$diff3 = abs($result3 - $value3);

$this->assertLessThanOrEqual(0.0001, $diff1, sprintf('%f, %f, %f', $diff1, $result1, $value1));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does 0.001 come from?

$result2 = $this->selectDouble($value2);
$result3 = $this->selectDouble($value3);

$this->assertSame(is_int($result1) ? 1 : '1', $result1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There shouldn't be any conditionals in a test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morozov

Similar to my other comment, some drivers seem to return integers as strings in which case I have to either cast everything, or just detect.

I'm open to alternatives?

'SELECT val FROM double_table WHERE id = ?',
[$id],
0,
[ParameterType::INTEGER]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this relevant to the test? We're testing binding double values, not integers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morozov

As this is a test with Doubles, it's trying to test both insertion and result sets of the doubles to make sure what was inserted matches what's queried.

I can just test insertions / updates if you want things more concise. Although without querying the database, I may not know for sure if my insertion actually worked.

Please advise?

use const LC_ALL;
use function setlocale;

class LanguageDoubleTest extends DoubleTest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid extending tests if possible. Specifically in this case, if you want to test the same code paths using different locales, use a data provider.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morozov

Let me look into it.

{
protected function setUp() : void
{
setlocale(LC_ALL, 'de_DE.UTF-8', 'de_DE', 'de', 'ge');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if neither of the locales is available at the runtime? Should there be any teardown logic in the test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morozov

I can make a tear down.

For travis, every run has the de_DE language installed, but I suppose I could try to add detection logic here if it works.

… languages that do not use '.' for the decimal point
Base automatically changed from master to 4.0.x January 22, 2021 07:44
@morozov
Copy link
Member

morozov commented Jul 26, 2021

Closing as stale.

@morozov morozov closed this Jul 26, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants