diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-05-23 12:45:47 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-05-23 12:45:47 +0400 |
commit | d9304914bed2d6d45dbc9f43aa1e2f7ea3bbeb13 (patch) | |
tree | 75dd4ffb8bd8095ca7c2b666f2e0939e866ab623 /mysql-test/t/metadata.test | |
parent | 9b79888df82259743284501af5b156a18edc427f (diff) | |
download | mariadb-git-d9304914bed2d6d45dbc9f43aa1e2f7ea3bbeb13.tar.gz |
Fixing a few problems with data type and metadata for INT result functions (MDEV-12852, MDEV-12853, MDEV-12869)
This is a joint patch for:
MDEV-12852 Out-of-range errors when CAST(1-2 AS UNSIGNED
MDEV-12853 Out-of-range errors when CAST('-1' AS UNSIGNED
MDEV-12869 Wrong metadata for integer additive and multiplicative operators
1. Fixing all Item_func_numhybrid descendants to set the precise
data type handler (type_handler_long or type_handler_longlong)
at fix_fields() time. This fixes MDEV-12869.
2. Fixing Item_func_unsigned_typecast to set the precise data type handler
at fix_fields() time. This fixes MDEV-12852 and MDEV-12853.
This is done by:
- fixing Type_handler::Item_func_unsigned_fix_length_and_dec()
and Type_handler_string_result::Item_func_unsigned_fix_length_and_dec()
to properly detect situations when a negative epxression is converted
to UNSIGNED. In this case, length of the result is now always set to
MAX_BIGINT_WIDTH without trying to use args[0]->max_length, as very
short arguments can produce very long result in such conversion:
CAST(-1 AS UNSIGNED) -> 18446744073709551614
- adding a new virtual method "longlong Item::val_int_max() const",
to preserve the old behavior for expressions like this:
CAST(1 AS UNSIGNED)
to stay under the INT data type (instead of BIGINT) for small
positive integer literals. Using Item::unsigned_flag would not help,
because Item_int does not set unsigned_flag to "true" for positive
numbers.
3. Adding helper methods:
* Item::type_handler_long_or_longlong()
* Type_handler::type_handler_long_or_longlong()
and reusing them in a few places, to reduce code duplication.
4. Making reorganation in create_tmp_field() and
create_field_for_create_select() for Item_hybrid_func and descendants,
to reduce duplicate code. They all now have a similar behavior in
respect of creating fields. Only Item_func_user_var descendants have
a different behavior. So moving the default behvior to Item_hybrid_func,
and overriding behavior on Item_func_user_var level.
Diffstat (limited to 'mysql-test/t/metadata.test')
-rw-r--r-- | mysql-test/t/metadata.test | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/mysql-test/t/metadata.test b/mysql-test/t/metadata.test index 073f617dc16..d5d95cf7e8c 100644 --- a/mysql-test/t/metadata.test +++ b/mysql-test/t/metadata.test @@ -353,3 +353,115 @@ CREATE TABLE t1 AS SELECT @:=1e0; SELECT * FROM t1; DROP TABLE t1; --disable_metadata + +--echo # +--echo # MDEV-12869 Wrong metadata for integer additive and multiplicative operators +--echo # + +--enable_metadata +SELECT + 1+1, + 11+1, + 111+1, + 1111+1, + 11111+1, + 111111+1, + 1111111+1, + 11111111+1, + 111111111+1 LIMIT 0; + +SELECT + 1-1, + 11-1, + 111-1, + 1111-1, + 11111-1, + 111111-1, + 1111111-1, + 11111111-1, + 111111111-1 LIMIT 0; + +SELECT + 1*1, + 11*1, + 111*1, + 1111*1, + 11111*1, + 111111*1, + 1111111*1, + 11111111*1, + 111111111*1 LIMIT 0; + +SELECT + 1 MOD 1, + 11 MOD 1, + 111 MOD 1, + 1111 MOD 1, + 11111 MOD 1, + 111111 MOD 1, + 1111111 MOD 1, + 11111111 MOD 1, + 111111111 MOD 1, + 1111111111 MOD 1, + 11111111111 MOD 1 LIMIT 0; + +SELECT + -(1), + -(11), + -(111), + -(1111), + -(11111), + -(111111), + -(1111111), + -(11111111), + -(111111111) LIMIT 0; + +SELECT + ABS(1), + ABS(11), + ABS(111), + ABS(1111), + ABS(11111), + ABS(111111), + ABS(1111111), + ABS(11111111), + ABS(111111111), + ABS(1111111111) LIMIT 0; + +SELECT + CEILING(1), + CEILING(11), + CEILING(111), + CEILING(1111), + CEILING(11111), + CEILING(111111), + CEILING(1111111), + CEILING(11111111), + CEILING(111111111), + CEILING(1111111111) LIMIT 0; + +SELECT + FLOOR(1), + FLOOR(11), + FLOOR(111), + FLOOR(1111), + FLOOR(11111), + FLOOR(111111), + FLOOR(1111111), + FLOOR(11111111), + FLOOR(111111111), + FLOOR(1111111111) LIMIT 0; + +SELECT + ROUND(1), + ROUND(11), + ROUND(111), + ROUND(1111), + ROUND(11111), + ROUND(111111), + ROUND(1111111), + ROUND(11111111), + ROUND(111111111), + ROUND(1111111111) LIMIT 0; + +--disable_metadata |