[MDEV-28221] User variables lose coercibility information, leading to unexpected collation errors Created: 2022-04-02 Updated: 2022-04-27 Resolved: 2022-04-26 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Variables |
| Fix Version/s: | N/A |
| Type: | Task | Priority: | Minor |
| Reporter: | Dean Trower | Assignee: | Sergei Golubchik |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | None | ||
| Description |
|
User variables seem to have a COERCIBILITY() of 2, the same as table columns, even when assigned values with higher COERCIBILITY. This can lead to unexpected errors:
Or perhaps more succinctly, the following look like they ought to be equivalent, but they aren't: 1. SELECT col='value' FROM table; I would like to suggest that they SHOULD BE... and that the way to make this work correctly would be for user variables to retain/remember the COERCIBILITY of whatever value they're assigned. SET @a := (SELECT column FROM table), @b := 'literal value'; Currently the returned coercibility values are (2,2)... but I am suggesting that they should be (2,4) instead, which are the coercibilities of the values that have been assigned to @a and @b respectively. |
| Comments |
| Comment by Sergei Golubchik [ 2022-04-07 ] | ||||||
|
I've moved it to a "Task", as the current behavior is clearly intentional (so, not a bug), user variables have "implicit" coercibility, like columns. | ||||||
| Comment by Dean Trower [ 2022-04-07 ] | ||||||
|
Thanks Sergei. I was looking for "Feature Request", but didn't see an option for it. | ||||||
| Comment by Alexander Barkov [ 2022-04-08 ] | ||||||
|
Hello Dean T, The current implementation is intentional.
Instead of fixing user variables to have a flexible collation derivation, I'd propose adding a new special syntax to set a collation derivation of ANY expression (including a user variable reference) to a given value. Something like this:
(the exact syntax is a subject for discussions) What do you think? Would this solution be useful for you? Thanks. | ||||||
| Comment by Dean Trower [ 2022-04-09 ] | ||||||
|
Hi Alexander. I suspect that most of the time
would not provide too much of an advantage over simply writing:
unless perhaps you're trying to output generic SQL where you don't know in advance the collation of v. So while it still may be helpful in some situations to have that syntax available (and I think anything that increases the programmer's fine-grained control is a good idea!), the real issue for me is that the in-equivalency between:
and
violates the "principle of least surprise", in that I'd look at them and expect them to work identically. While the above just generates an unexpected error, you can create (admittedly contrived) situations where there is no error, but the results of the statements might actually be different (which I think is very much worse, in being much harder to detect). e.g.
vs
Also, as far as I can see, stored routine variables suffer from exactly the same issues, so as far as your first two bullet points, it might be worth considering making those remember the coercibility of whatever's assigned to them as well: i.e. this feature request should apply to both session variables (@var) and stored procedure variables (DECLARE v varchar(20)) also. I guess the real question is then the weighing between "How useful a change is this in getting rid of unexpected collation bugs?" vs "How likely is this change to break existing code?" If you MySQL developers think that the latter would outweigh the former, then I'll happily defer to your greater wisdom and accept that my suggestion isn't workable. (In that case, maybe just update the docs to include an example of the problem, to make developers more aware of it? Perhaps on the "Comparison Operators" page?) | ||||||
| Comment by Sergei Golubchik [ 2022-04-26 ] | ||||||
|
Unfortunately, stored routine variables cannot remember the coercibility. Their behavior is specifically described by the SQL standard, and we have to follow the standard here. User variables are not part of the SQL standard, but, as bar wrote above, we tried to make them similar to stored routine variables. | ||||||
| Comment by Dean Trower [ 2022-04-27 ] | ||||||
|
Fair enough. |