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: add implicit eval int and real for function dayname #21806

Merged
merged 4 commits into from Dec 17, 2020

Conversation

zanmato1984
Copy link
Contributor

@zanmato1984 zanmato1984 commented Dec 15, 2020

What problem does this PR solve?

Issue Number: close #19992

Problem Summary:

It's a bit long story.

MySQL has a weird behavior about function dayname() (IMO this apparently is a MySQL defect):

mysql> select dayname("1962-03-01")+1;
+-------------------------+
| dayname("1962-03-01")+1 |
+-------------------------+
|                       4 |
+-------------------------+

It evaluates as integer directly despite the function signature is actually string. Quoted of comments in MySQL source code:

TS-TODO: Item_func_dayname should be derived from Item_str_func.
In the current implementation funny things can happen:
select dayname(now())+1 -> 4

PR #9975 fixed this issue by removing the implicit cast from dayname() string to int/real, however introduced a more obvious bug:

mysql> select cast(dayname('2016-03-08') as double);                                                                                                                                                                                                                            
+---------------------------------------+                                                                                                                                                                                                                                       
| cast(dayname('2016-03-08') as double) |                           
+---------------------------------------+                                                                                               
| Tuesday                               |                           
+---------------------------------------+                                                                                                                                                                                                                                       

As shown above, unconditionally removing implicit cast gave the wrong result for non-arithmetic expressions involving function dayname().

What is changed and how it works?

What's Changed:

Don't use hasSpecialCasts anymore. Instead, mark dayname() as CanImplicitEvalInt/Real, and do "implicit" evalInt/Real in the actual cast functions.

Besides, since filter operator has its own path to evaluate expressions into boolean, modify it too to do "implicit" evalInt/Real.

How it Works:
Adding implicit evalInt/Real path makes cast functions directly evaluate dayname() as int/real, which further involve into whatever evaluation in the upper level of the expression tree.

Related changes

  • PR to update pingcap/docs/pingcap/docs-cn: none
  • Need to cherry-pick to the release branch: release-4.0

Check List

Tests

  • Unit test

Side effects

  • Performance regression
    • Consumes more CPU

Release note

  • Fix compatibility issue with MySQL for function dayname

Copy link
Member

@lzmhhh123 lzmhhh123 left a comment

Choose a reason for hiding this comment

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

LGTM

@ti-srebot ti-srebot added the status/LGT1 Indicates that a PR has LGTM 1. label Dec 15, 2020
@XuHuaiyu
Copy link
Contributor

/run-all-tests

@lzmhhh123
Copy link
Member

/run-all-tests

@zanmato1984
Copy link
Contributor Author

/run-all-tests

@XuHuaiyu XuHuaiyu requested review from ichn-hu and removed request for qw4990 and XuHuaiyu December 16, 2020 09:01
@ti-srebot ti-srebot removed the status/LGT1 Indicates that a PR has LGTM 1. label Dec 17, 2020
@ti-srebot ti-srebot added the status/LGT2 Indicates that a PR has LGTM 2. label Dec 17, 2020
@lzmhhh123
Copy link
Member

/merge

@ti-srebot ti-srebot added the status/can-merge Indicates a PR has been approved by a committer. label Dec 17, 2020
@ti-srebot
Copy link
Contributor

/run-all-tests

@ti-srebot
Copy link
Contributor

@zanmato1984 merge failed.

@zanmato1984
Copy link
Contributor Author

/run-all-tests

@lzmhhh123
Copy link
Member

/merge

@ti-srebot
Copy link
Contributor

/run-all-tests

@ti-srebot ti-srebot merged commit 556cccc into pingcap:master Dec 17, 2020
ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request Dec 17, 2020
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-4.0 in PR #21850

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/expression status/can-merge Indicates a PR has been approved by a committer. status/LGT2 Indicates that a PR has LGTM 2. type/bug-fix This PR fixes a bug.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DAYNAME() is not considered as TRUE when implicitly converted to Boolean
5 participants