Fix MCOL 4632 and 4648 and further issues when casting to [U]BIGINT. #2874
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes MCOL-4632 and MCOL-4648 and some other casting issues that I found while investigating both issues.
Why?
We use
uintX_t
constants to mark NULL values in result rows. E.g. instorage/columnstore/columnstore/utils/funcexp/funcexp.cpp
l.394:If
isNull
gets set bygetUintVal()
we writeUBIGINTNULL
into the result row. If howeverval
equalsUBIGINTNULL
(or 2^64 - 2) the output row also gets written withUBIGINTNULL
and later on wrongly displayed asNULL
and not with the expected numeric value of 2^64 - 2.At the core of the issue is that we cannot store the whole range of
[U]BIGINT
s, because we have blocked some values by constant markers. It is not possible to insert values which are assigned constant markers into aBIGINT
column (this is covered by aOut of range value for column
error), but it is possible thatCAST
operation results take on the blocked values and are then wrongly/unexpectedly displayed as NULL.Besides the issues from casting DECIMAL->BIGINT and DECIMAL->UBIGINT, I've also been able to find the same issue for - - UBIGINT->BIGINT
(All cases are documented in the
mcol_4632
andmcol_4648
files inmysql-test/columnstore/bugfixes
.)How?
Main changes are in
func_cast.cpp
where forFunc_cast_signed::getIntVal()
andFunc_cast_unsigned::getUintVal()
I checked and updated every switch case to include a check for unallowed return values which are now encoded asjoblist::MIN_MCS_BIGINT
andjoblist::MAX_MCS_UBIGINT
.Update: The previously described approach would have been the preferred way to ensure consistency. (Float values were already handled that way, meaning that one in the current version cannot cast to neither
[U]BIGINTEMPTYROW
nor[U]BIGINTNULL
. However, as theEMPTYROW
constant gets displayed as the correct INT value, there are some regression tests expecting to be able to cast to theEMPTYROW
constant. (And some tests actually expecting a cast to NULL, but we are going to fix these at least.)Therefore the new approach will be to allow casting to
EMPTYROW
constants from all datatypes (including floats) and disallow casting toNULL
constants. All of this again handled inFunc_cast_signed::getIntVal()
andFunc_cast_unsigned::getUintVal()
and the respective casting methods per type.Testing?
All cases are tested with regression tests in
mcol_4632
andmcol_4648
files inmysql-test/columnstore/bugfixes
.