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

expression: fix incorrect date arithmitical with negative interval #8523

Merged
merged 4 commits into from
Dec 4, 2018

Conversation

nanne007
Copy link
Contributor

@nanne007 nanne007 commented Nov 29, 2018

What problem does this PR solve?

#8497

What is changed and how it works?

Round the float interval, so that the date arithmetical can behave like mysql:

1.2  => 1
1.5  => 2
-1.2 => -1
-1.5 => -2

Check List

Tests

  • Unit test

Related changes

This bug affects almost all functions related to date arithmetical functions. May be it should

  • Need to cherry-pick to the release branch
  • Need to be included in the release note ?

This change is Reviewable

@sre-bot
Copy link
Contributor

sre-bot commented Nov 29, 2018

Hi contributor, thanks for your PR.

This patch needs to be approved by someone of admins. They should reply with "/ok-to-test" to accept this PR for running test automatically.

{date[0], fcSub, -0.5, date[1]},
{date[0], fcSub, -1.4, date[1]},
}
for _, test := range tests {
Copy link
Member

Choose a reason for hiding this comment

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

s/test/t/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using test is consistent with other usages in this file.

@eurekaka eurekaka added type/compatibility contribution This PR is from a community contributor. component/expression labels Nov 30, 2018
@@ -1527,7 +1527,7 @@ func extractSingleTimeValue(unit string, format string) (int64, int64, int64, fl
if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(format)
}
iv := int64(fv + 0.5)
iv := int64(math.Round(fv))
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we use floatStrToIntStr instead of Round? floatStrToIntStr does round operation also and it covers corner cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The float value is also needed.
iv is used in cases that float value should be rounded, like DAY, WEEK.

Copy link
Contributor

Choose a reason for hiding this comment

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

You mean inputs like 1.23a4 DAY ? 1.23a can pass strconv.ParseFloat @eurekaka
or something like 1e9223372036854775807 ?

I think the change here is ok, a sane person will not use those illegal input, so
strconv.ParseFloat + math.Round is suitable for most of the cases

Copy link
Member

Choose a reason for hiding this comment

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

MySQL(root@127.0.0.1:test) > select adddate("2018-12-09", interval "1e1" DAY);
+-------------------------------------------+
| adddate("2018-12-09", interval "1e1" DAY) |
+-------------------------------------------+
| 2018-12-10                                |
+-------------------------------------------+
1 row in set, 1 warning (0.00 sec)

MySQL(root@127.0.0.1:test) > select adddate("2018-12-09", interval "10" DAY);
+------------------------------------------+
| adddate("2018-12-09", interval "10" DAY) |
+------------------------------------------+
| 2018-12-19                               |
+------------------------------------------+
1 row in set (0.00 sec)

MySQL(root@127.0.0.1:test) > select adddate("2018-12-09", interval "9223372036854775807" DAY);
+-----------------------------------------------------------+
| adddate("2018-12-09", interval "9223372036854775807" DAY) |
+-----------------------------------------------------------+
| NULL                                                      |
+-----------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

MySQL(root@127.0.0.1:test) > show warnings;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1441 | Datetime function: datetime field overflow |
+---------+------+--------------------------------------------+
1 row in set (0.01 sec)

We should use strconv.ParseFloat() in this PR. floatStrToIntStr converts 1e1 to 10, which is not in MySQL. Another discovery is that TiDB does not properly handle the "Datetime function: datetime field overflow" warning:

TiDB(root@127.0.0.1:test) > select adddate("2018-12-09", interval "9223372036854775807" DAY);
+-----------------------------------------------------------+
| adddate("2018-12-09", interval "9223372036854775807" DAY) |
+-----------------------------------------------------------+
| 2018-12-09                                                |
+-----------------------------------------------------------+
1 row in set (0.00 sec)

Copy link
Member

Choose a reason for hiding this comment

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

You can do it in the next PR, this PR LGTM

@tiancaiamao
Copy link
Contributor

LGTM

@tiancaiamao tiancaiamao added the status/LGT1 Indicates that a PR has LGTM 1. label Nov 30, 2018
@nanne007
Copy link
Contributor Author

nanne007 commented Dec 3, 2018

Ping

@eurekaka
Copy link
Contributor

eurekaka commented Dec 3, 2018

@zz-jason PTAL

Copy link
Member

@zz-jason zz-jason left a comment

Choose a reason for hiding this comment

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

LGTM

@zz-jason
Copy link
Member

zz-jason commented Dec 3, 2018

/run-all-tests

@zz-jason zz-jason added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels Dec 3, 2018
@zz-jason zz-jason merged commit 6e27de2 into pingcap:master Dec 4, 2018
@zz-jason
Copy link
Member

zz-jason commented Dec 4, 2018

@lerencao Please cherry-pick this commit to release-2.1 and release-2.0 branch, thanks.

@nanne007
Copy link
Contributor Author

nanne007 commented Dec 4, 2018

@zz-jason

@zz-jason
Copy link
Member

zz-jason commented Dec 4, 2018

Got it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/expression contribution This PR is from a community contributor. status/LGT2 Indicates that a PR has LGTM 2. type/compatibility
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants