diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-04-24 12:09:25 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-04-24 12:09:25 +0400 |
commit | 791374354c9f11fde2325777276522cdd71679c2 (patch) | |
tree | 75624141dd614bc28600d9837ccabab1be245d19 /sql/field.cc | |
parent | 3cd7690a5e79d73ccb3f8e1e071c523e7c6ef9b1 (diff) | |
download | mariadb-git-791374354c9f11fde2325777276522cdd71679c2.tar.gz |
MDEV-9217 Split Item::tmp_table_field_from_field_type() into virtual methods in Type_handler
- Adding Type_handler::make_table_field() and moving pieces of the code
from Item::tmp_table_field_from_field_type() to virtual implementations
for various type handlers.
- Adding a new Type_all_attributes, to access to Item's extended
attributes, such as decimal_precision() and geometry_type().
- Adding a new class Record_addr, to pass record related information
to Type_handler methods (ptr, null_ptr and null_bit) as a single structure.
Note, later it will possibly be extended for BIT-alike field purposes,
by adding new members (bit_ptr_arg, bit_ofs_arg).
- Moving the code from Field_new_decimal::create_from_item()
to Type_handler_newdecimal::make_table_field().
- Removing Field_new_decimal() and Field_geom() helper constructor
variants that were used for temporary field creation.
- Adding Item_field::type_handler(), Field::type_handler() and
Field_blob::type_handler() to return correct type handlers for
blob variants, according to Field_blob::packlength.
- Adding Type_handler_blob_common, as a common parent for
Type_handler_tiny_blob, Type_handler_blob, Type_handler_medium_blob
and Type_handler_long_blob.
- Implementing Type_handler_blob_common::Item_hybrid_func_fix_attributes().
It's needed for cases when TEXT variants of different character sets are mixed
in LEAST, GREATEST, CASE and its abreviations (IF, IFNULL, COALESCE), e.g.:
CREATE TABLE t1 (
a TINYTEXT CHARACTER SET latin1,
b TINYTEXT CHARACTER SET utf8
);
CREATE TABLE t2 AS SELECT COALESCE(a,b) FROM t1;
Type handler aggregation returns TINYTEXT as a common data type
for the two columns. But as conversion from latin1 to utf8
happens for "a", the maximum possible length of "a" grows from 255 to 255*3.
Type_handler_blob_common::Item_hybrid_func_fix_attributes() makes sure
to update the blob type handler according to max_length.
- Adding Type_handler::blob_type_handler(uint max_octet_length).
- Adding a few m_type_aggregator_for_result.add() pairs, because
now Item_xxx::type_handler() can return pointers to type_handler_tiny_blob,
type_handler_blob, type_handler_medium_blob, type_handler_long_blob.
Before the patch only type_handler_blob was possible result of type_handler().
- Making type_handler_tiny_blob, type_handler_blob, type_handler_medium_blob,
type_handler_long_blob public.
- Removing the condition in Item_sum_avg::create_tmp_field()
checking Item_sum_avg::result_type() against DECIMAL_RESULT.
Now both REAL_RESULT and DECIMAL_RESULT are symmetrically handled
by tmp_table_field_from_field_type().
- Removing Item_geometry_func::create_field_for_create_select(),
as the inherited version perfectly works.
- Fixing Item_func_as_wkb::field_type() to return MYSQL_TYPE_LONG_BLOB
rather than MYSQL_TYPE_BLOB. It's needed to make sure that
tmp_table_field_from_field_type() creates a LONGBLOB field for AsWKB().
- Fixing Item_func_as_wkt::fix_length_and_dec() to set max_length to
UINT32_MAX rather than MAX_BLOB_WIDTH, to make sure that
tmp_table_field_from_field_type() creates a LONGTEXT field for AsWKT().
- Removing Item_func_set_user_var::create_field_for_create_select(),
as the inherited version works fine.
- Adding Item_func_get_user_var::create_field_for_create_select() to
make sure that "CREATE TABLE t1 AS SELECT @string_user variable"
always creates a field of LONGTEXT/LONGBLOB type.
- Item_func_ifnull::create_field_for_create_select()
behavior has changed. Before the patch it passed set_blob_packflag=false,
which meant to create LONGBLOB for all blob variants.
Now it takes into account max_length, which gives better column
data types for:
CREATE TABLE t2 AS SELECT IFNULL(blob_column1, blob_column2) FROM t1;
- Fixing Item_func_nullif::fix_length_and_dec() to use
set_handler(args[2]->type_handler()) instead of
set_handler_by_field_type(args[2]->field_type()).
This is needed to distinguish between BLOB variants.
- Implementing Item_blob::type_handler(), to make sure to create
proper BLOB field variant, according to max_length, for queries like:
CREATE TABLE t1 AS
SELECT some_blob_field FROM INFORMATION_SCHEMA.SOME_TABLE;
- Fixing Item_field::real_type_handler() to make sure that
the code aggregating fields for UNION gets a proper BLOB
variant type handler from fields.
- Adding a special code into Item_type_holder::make_field_by_type(),
to make sure that after aggregating field types it also properly
takes into account max_length when mixing TEXT variants of different
character sets and chooses a proper TEXT variant:
CREATE TABLE t1 (
a TINYTEXT CHARACTER SET latin1,
b TINYTEXT CHARACTER SET utf8
);
CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT b FROM t1;
- Adding tests, for better coverage of IFNULL, NULLIF, UNION.
- The fact that tmp_table_field_from_field_type() now takes
into account BLOB variants (instead of always creating LONGBLOB),
tests results for WEIGHT_STRING() and NULLIF() and UNION
have become more precise.
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 65 |
1 files changed, 2 insertions, 63 deletions
diff --git a/sql/field.cc b/sql/field.cc index 9215a6b8e60..91efcd52b0f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2912,67 +2912,6 @@ Field_new_decimal::Field_new_decimal(uchar *ptr_arg, } -Field_new_decimal::Field_new_decimal(uint32 len_arg, - bool maybe_null_arg, - const LEX_CSTRING *name, - uint8 dec_arg, - bool unsigned_arg) - :Field_num((uchar*) 0, len_arg, - maybe_null_arg ? (uchar*) "": 0, 0, - NONE, name, dec_arg, 0, unsigned_arg) -{ - precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg); - set_if_smaller(precision, DECIMAL_MAX_PRECISION); - DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && - (dec <= DECIMAL_MAX_SCALE)); - bin_size= my_decimal_get_binary_size(precision, dec); -} - - -Field *Field_new_decimal::create_from_item(MEM_ROOT *mem_root, Item *item) -{ - uint8 dec= item->decimals; - uint8 intg= item->decimal_precision() - dec; - uint32 len= item->max_char_length(); - DBUG_ASSERT (item->result_type() == DECIMAL_RESULT); - - /* - Trying to put too many digits overall in a DECIMAL(prec,dec) - will always throw a warning. We must limit dec to - DECIMAL_MAX_SCALE however to prevent an assert() later. - */ - - if (dec > 0) - { - signed int overflow; - - dec= MY_MIN(dec, DECIMAL_MAX_SCALE); - - /* - If the value still overflows the field with the corrected dec, - we'll throw out decimals rather than integers. This is still - bad and of course throws a truncation warning. - +1: for decimal point - */ - - const int required_length= - my_decimal_precision_to_length(intg + dec, dec, - item->unsigned_flag); - - overflow= required_length - len; - - if (overflow > 0) - dec= MY_MAX(0, dec - overflow); // too long, discard fract - else - /* Corrected value fits. */ - len= required_length; - } - return new (mem_root) - Field_new_decimal(len, item->maybe_null, &item->name, - dec, item->unsigned_flag); -} - - int Field_new_decimal::reset(void) { store_value(&decimal_zero); @@ -10717,7 +10656,7 @@ uint32 Field_blob::char_length() const case 3: return 16777215; case 4: - return (uint32) 4294967295U; + return (uint32) UINT_MAX32; default: DBUG_ASSERT(0); // we should never go here return 0; @@ -10770,7 +10709,7 @@ uint32 Field_blob::max_display_length() case 3: return 16777215 * field_charset->mbmaxlen; case 4: - return (uint32) 4294967295U; + return (uint32) UINT_MAX32; default: DBUG_ASSERT(0); // we should never go here return 0; |