1
0
mirror of https://github.com/MariaDB/server.git synced 2025-05-07 04:01:59 +03:00

68 Commits

Author SHA1 Message Date
Alexander Barkov
d9304914be 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.
2017-05-23 12:45:47 +04:00
Alexander Barkov
c84bbeda7f MDEV-12858 + MDEV+12859 + MDEV-12862 - a join patch fixing a few data type problems with CREATE..SELECT
MDEV-12858 Out-of-range error for CREATE..SELECT unsigned_int_column+1
MDEV-12859 Out-of-range error for CREATE..SELECT @a:=EXTRACT(MINUTE_MICROSECOND FROM..)
MDEV-12862 Data type of @a:=1e0 depends on the session character set

1. Moving a part of Item::create_tmp_field() into a new helper method
   Item::create_tmp_field_int() and reusing it in Item::create_tmp_field()
   and Item_func_signed::create_tmp_field().
   Fixing the code in Item::create_tmp_field_int() to call
   Type_handler::make_table_field() instead of doing "new Field_long[long]"
   directly. This change revealed a problem reported in MDEV-12862.

2. Changing the "long vs longlong" cut-off length for
     - Item_func::create_tmp_field()
     - Item_sum::create_tmp_field()
     - Item_func_get_user_var::create_tmp_field()
   from MY_INT32_NUM_DECIMAL_DIGITS to (MY_INT32_NUM_DECIMAL_DIGITS - 2).
   This fixes MDEV-12858.
   After this change, the "convert_int_length" parameter to
   Item::create_tmp_field() is not needed any more, because
   (MY_INT32_NUM_DECIMAL_DIGITS - 2) is always passed.
   So removing the "convert_int_length" parameter.

3. Fixing Item::create_tmp_field() to pass max_char_length() instead
   of max_length to the constructor of Field_double().
   This fixes MDEV-12862.

4. Additionally, fixing
   - Type_handler_{tiny|short|int24|long|longlong}::make_table_field()
   - Type_handler_{float|double}::make_table_field()
   to pass max_char_length() instead of max_length to Field contructors.
   This is needed by the change (1).

5. Adding new tests, and recording new correct results in the old tests in:
   - mysql-test/r/type_ranges.result
   - storage/tokudb/mysql-test/tokudb/r/type_ranges.result
2017-05-22 13:44:26 +04:00
Alexander Barkov
ac4ce47b09 MDEV-12849 Out-of-range errors when casting hex-hybrid to SIGNED and UNSIGNED 2017-05-19 18:45:01 +04:00
Alexander Barkov
5b034f1cf8 MDEV-12833 Split Column_definition::create_length_to_internal_length() to virtual methods in Type_handler 2017-05-17 18:07:20 +04:00
Alexander Barkov
278c3ea756 MDEV-12826 Add Type_handler::val_int_signed_typecast() and Type_handler::val_int_unsigned_typecast() 2017-05-17 14:02:25 +04:00
Alexander Barkov
fba7fbbc5c MDEV-9397 Split field.cc:calc_pack_length() into virtual methods in Type_handler
- Adding new virtual methods in Type_handler:
  * Column_definition_prepare_stage1()
  * Column_definition_prepare_stage2()
  * calc_pack_length()

- Using new methods to remove type specific code in:
  * Global function calc_pack_length()
  * Column_definition::prepare_create_field()
  * The loop body mysql_prepare_create_table()
  * Column_definition::sp_prepare_create_field()
2017-05-17 12:21:39 +04:00
Alexander Barkov
f1b729d352 MDEV-9188 Split Column_definition::check() into virtual methods in Type_handler 2017-05-16 14:29:51 +04:00
Alexander Barkov
705fc43eaa MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.

This fixes a number of bugs in UNION:

- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR

Details:

- sql_union.cc: Reusing attribute aggregation for UNION.
  Adding new methods:
  * st_select_lex_unit::join_union_type_handlers()
  * st_select_lex_unit::join_union_type_attributes()
  * st_select_lex_unit::join_union_item_types()
  Removing the old join_types()-based code.

- Changing Type_handler::Item_hybrid_func_fix_attributes()
  to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
  as three separate parameters instead of a single Item_hybrid_func parameter,
  to make it possible to pass both Item_hybrid_func and Type_holder.

- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
  from Item_type_holder::join_types() to
  * Type_handler_typelib::Item_hybrid_func_fix_attributes().
  * Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
  This makes GEOMETRY/ENUM/SET symmetric with all other data types
  (from the UNION point of view).
  Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().

- Adding new methods into Type_all_attributes:
  * Type_all_attributes::set_geometry_type() and
    Item_hybrid_func::set_geometry_type().
  * Adding Type_all_attributes::get_typelib().
  * Adding Type_all_attributes::set_typelib().

- Adding Type_handler_typelib as a common parent for
  Type_handler_enum and Type_handler_set, to avoid code duplication: they have
  already had two common methods, and we're adding one more shared method.

- Adding Type_all_attributes::set_maybe_null(), as some type handlers
  may want to set maybe_null (e.g. Type_handler_geometry) during data type
  attribute aggregation.

- Changing Type_geometry_attributes() to accept Type_handler
  and Type_all_attributes as two separate parameters, instead
  of a single Item parameter, to make it possible to pass Type_holder.

- Adding Item_args::add_argument().

- Moving Item_args::alloc_arguments() from "protected" to "public".

- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
  now it's very simple.
  Btw, this constructor should probably be eventually removed.
  It's now used only in sql_show.cc, which could be modified to use
  Item_return_decimal (for symmetry with Item_return_xxx created for all
  other data types). Or, another option: remove all Item_return_xxx and
  use Item_type_holder for all data types instead.

- storage/tokudb/mysql-test/tokudb/r/type_float.result
  Recording new results (MDEV-12594).

- mysql-test/r/cte_recursive.result
  Recording new results (MDEV-9497)

- mysql-test/r/subselect*.result
  Recording new results (MDEV-12595)

- mysql-test/r/metadata.result
  Recording new results (MDEV-9495)

- mysql-test/r/temp_table.result
  Recording new results (MDEV-12594)

- mysql-test/r/type_float.result
  Recording new results (MDEV-12594)
2017-05-15 23:45:31 +04:00
Alexander Barkov
7c44b8afb7 MDEV-12798 Item_param does not preserve exact field type in EXECUTE IMMEDIATE 'CREATE TABLE AS SELECT ?' USING POINT(1,1) 2017-05-15 14:58:05 +04:00
Alexander Barkov
cd32f84214 MDEV-12770 Add Type_handler::decimal_precision() + MDEV-12769
This patch for MDEV-12770 is also fixing:

MDEV-12769 Arithmetic operators with temporal types create excessive column types
2017-05-10 08:30:56 +04:00
Alexander Barkov
c898de84b7 MDEV-12714 Determine Item::field_type() from Item::type_handler() 2017-05-06 20:44:05 +04:00
Alexander Barkov
5a644e177f Adding "const" qualifier to Item::cols(), and to the "Item *cmp" parameter to Type_handler::make_const_item_for_comparison() 2017-05-06 15:05:59 +04:00
Alexander Barkov
9a360e97a2 Cleanup: changing set_handler_by_field_type(field_type()) to set_handler(type_handler()).
This gives better performance, as excludes handler-by-type lookup.
2017-05-06 14:52:18 +04:00
Alexander Barkov
380ec90905 MDEV-12710 Fix Item_cache constructors to accept Type_handler instead of enum_field_types 2017-05-06 13:34:16 +04:00
Alexander Barkov
26fa7232cf MDEV-12707 Split resolve_const_item() into virtual methods in Type_handler 2017-05-06 00:04:15 +04:00
Alexander Barkov
583b68e899 MDEV-12560, MDEV-12665 - geometry type not preserved in hybrid functions and UNION
This is a join patch fixing these two bugs:
MDEV-12560 Wrong data type for SELECT NULL UNION SELECT Point(1,1)
MDEV-12665 Hybrid functions do not preserve geometry type
2017-05-05 07:23:16 +04:00
Alexander Barkov
1ff79562b8 MDEV-12692 Split Item_func_between::fix_length_and_dec 2017-05-04 18:30:11 +04:00
Alexander Barkov
fe127562e2 MDEV-12687 Split Item::send() into virtual method in Type_handler 2017-05-04 16:05:21 +04:00
Alexander Barkov
01b308c39c MDEV-12617 CASE and CASE-alike hybrid functions do not preserve exact data types 2017-05-04 11:38:55 +04:00
Alexander Barkov
85b73e2254 MDEV-12656 Crash in CREATE..SELECT..UNION with a ENUM column and NULL 2017-05-02 11:39:20 +04:00
Alexander Barkov
50b70e765b MDEV-12655 Move Item_func::count_xxx_length() to Type_std_attributes 2017-05-02 07:49:06 +04:00
Alexander Barkov
c67971a8a3 MDEV-12649 Add Type_handler::Item_save_in_value 2017-04-30 22:50:37 +04:00
Alexander Barkov
7a19c59c00 MDEV-9395 Add Type_handler::Item_decimal_scale() and Item_divisor_precision_increment() 2017-04-29 21:34:57 +04:00
Alexander Barkov
441349aa06 MDEV-12588 Add Type_handler::type_handler_for_tmp_table() and Type_handler::type_handler_for_union()
1. Implementing the task according to the description:

a. Adding Type_handler::type_handler_for_tmp_table().
b. Adding Type_handler::type_handler_for_union_table.
c. Adding helper methods Type_handler::varstring_type_handler(const Item*),
   Type_handler::blob_type_handler(const Item*)
d. Removing Item::make_string_field() and
   Item_func_group_concat::make_string_field().
   They are not needed any more.
e. Simplifying Item::tmp_table_field_from_field_type() to just two lines.
f. Renaming Item_type_holder::make_field_by_type() and implementing
   virtual Item_type_holder::create_tmp_field() instead.
   The new implementation is also as simple as two lines.
g. Adding a new virtual method Type_all_attributes::get_typelib(),
   to access to TYPELIB definitions for ENUM and SET columns.
h. Simplifying the code branch for TIME_RESULT, DECIMAL_RESULT, STRING_RESULT
   in Item::create_tmp_field(). It's now just one line.
i. Implementing Type_handler_enum::make_table_field() and
   Type_handler_set::make_table_field().

2. Code simplification in Field_str constructor calls.

a. Changing the "CHARSET_INFO *cs" argument in constuctors for Field_str
   and its descendants to "const DTCollation &collation". This is to
   avoid two step initialization:
   - setting Field_str::derivation and Field_str::repertoire to the
     default values first
   - then resetting them using:
     set_derivation(item->derivation, item->repertoire).

b. Removing Field::set_derivation()

c. Adding a new constructor DTCollation(CHARSET_INFO *cs),
   for the old code compatibility.

3. Changes in test results

As a side effect some test results have changed, because
in the old version Item::make_string_field() converted
TINYBLOB to VARCHAR(255). Now TINYBLOB is preserved.

a. sp-row.result
   This query:
     CREATE TABLE t1 AS SELECT tinyblob_sp_variable;
   Now preserves TINYBLOB as the data type.
   Before the patch a VARCHAR(255) was created.

b. gis-debug.result
   This is a debug test, to make sure that + and - operators
   are commutative and non-commutative correspondingly.
   The exact data type is not really important.
   (But anyway, it now chooses a better data type that fits the result)
2017-04-27 14:37:27 +04:00
Alexander Barkov
2fd635409d MDEV-12426 Add Field::type_handler() + MDEV-12432
This is a joint patch for:

- MDEV-12426 Add Field::type_handler()
- MDEV-12432 Range optimizer for ENUM and SET does not return "Impossible WHERE" in some case

With the new type handler approach being added to Field, it was easier to fix
MDEV-12432 rather than to reproduce the old ENUM/SET behavior.

The patch does the following:

1. Adds Field::type_handler(), according to the task description.

2. Fixes the asymmetry between Fields and Items of ENUM and SET field types.
   Field_enum::cmp_type() returned INT_RESULT
   Item*::cmp_type() returned STRING_RESULT for ENUM and SET expressions

This asymmetry was originally done for easier coding in the optimizer sources.
However, in 10.1 we moved a lot of code to methods of the class Field:
- test_if_equality_guarantees_uniqueness()
- can_be_substituted_to_equal_item()
- get_equal_const_item()
- can_optimize_keypart_ref()
- can_optimize_hash_join()
- can_optimize_group_min_max()
- can_optimize_range()
- can_optimize_outer_join_table_elimination()

As of 10.2 only a few lines of the code in opt_range.cc, field.cc and field.h
still relayed on the fact that Field_enum::cmp_type() returns INT_RESULT:
- Some asserts in field.cc
- Field_year::get_copy_func()
- Item_func_like::get_mm_leaf()
- Item_bool_func::get_mm_leaf()
These lines have been fixed.

3. Item_bool_func::get_mm_leaf() did not work well for ENUM/SET,
see MDEV-12432. So the ENUM/SET code was rewritten, and the relevant
code in Field_enum::store() and Field_set::store() was fixed to
properly return errors to the caller.

4. The result of Field_decimal::result_type() was changed from REAL_RESULT
to DECIMAL_RESULT. Data type aggregation (e.g. in COALESCE()) is now more
precise for old DECIMAL, because Item::decimal_precision() now goes through
the DECIMAL_RESULT branch. Earlier it went through the REAL_RESULT branch.
2017-04-25 14:22:07 +04:00
Alexander Barkov
6cc40856ee A safety patch for MDEV-9217 Split Item::tmp_table_field_from_field_type() into virtual methods in Type_handler
During refactoring in Type_handler, it's safer to use new_Field_xxx
in Type_handler_xxx2::make_table_field(), to avoid creations of wrong
fields for fields of the TIME(0), DATETIME(0) and TIMESTAMP(0) types.
This will be changed back to "new" when we finish refactoring and
reuse Type_handler::make_table_field() in make_field() in field.cc.
2017-04-25 10:20:27 +04:00
Alexander Barkov
5f1544fef3 A cleanup for MDEV-9217 Split Item::tmp_table_field_from_field_type() into virtual methods in Type_handler
Fixing that the server tried to create the old decimal for:

  CREATE TABLE t2 AS SELECT old_decimal_field FROM t1
               UNION SELECT bigint_field FROM t1;

  CREATE TABLE t2 AS SELECT old_decimal_field FROM t1
               UNION SELECT mediumint_field FROM t1;

  CREATE TABLE t2 AS SELECT year FROM t1
               UNION SELECT old_decimal_field FROM t1;

  CREATE TABLE t2 AS SELCT COALESCE(old_decimal_field) FROM t1;

Solution:

1. field_types_merge_rules[][] had three MYSQL_TYPE_DECIMAL remainders.
   Fixing to MYSQL_TYPE_NEWDECIMAL, like it is done for all other type pairs.
   This fixes the above queries with UNION.

2. Convert MYSQL_TYPE_DECIMAL to MYSQL_TYPE_NEWDECIMAL in
   Item::tmp_table_field_from_field_type().
   This fixed the above query with COALESCE.

3. Adding "new Field_decimal" into Type_handler_olddecimal::make_table_field().
   In case if something goes wrong it will crash on assert only in debug builds,
   while create the old decimal in release.
   Note, this "new Field_decimal" will be needed later anyway,
   when we reuse Type_handler::make_table_field() in make_field() in field.cc.
2017-04-24 16:08:28 +04:00
Alexander Barkov
791374354c 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.
2017-04-24 12:09:25 +04:00
Alexander Barkov
3cd7690a5e MDEV-12568 Add Type_handler::subquery_type_allows_materialization() 2017-04-24 10:57:31 +04:00
Monty
5a759d31f7 Changing field::field_name and Item::name to LEX_CSTRING
Benefits of this patch:
- Removed a lot of calls to strlen(), especially for field_string
- Strings generated by parser are now const strings, less chance of
  accidently changing a string
- Removed a lot of calls with LEX_STRING as parameter (changed to pointer)
- More uniform code
- Item::name_length was not kept up to date. Now fixed
- Several bugs found and fixed (Access to null pointers,
  access of freed memory, wrong arguments to printf like functions)
- Removed a lot of casts from (const char*) to (char*)

Changes:
- This caused some ABI changes
  - lex_string_set now uses LEX_CSTRING
  - Some fucntions are now taking const char* instead of char*
- Create_field::change and after changed to LEX_CSTRING
- handler::connect_string, comment and engine_name() changed to LEX_CSTRING
- Checked printf() related calls to find bugs. Found and fixed several
  errors in old code.
- A lot of changes from LEX_STRING to LEX_CSTRING, especially related to
  parsing and events.
- Some changes from LEX_STRING and LEX_STRING & to LEX_CSTRING*
- Some changes for char* to const char*
- Added printf argument checking for my_snprintf()
- Introduced null_clex_str, star_clex_string, temp_lex_str to simplify
  code
- Added item_empty_name and item_used_name to be able to distingush between
  items that was given an empty name and items that was not given a name
  This is used in sql_yacc.yy to know when to give an item a name.
- select table_name."*' is not anymore same as table_name.*
- removed not used function Item::rename()
- Added comparision of item->name_length before some calls to
  my_strcasecmp() to speed up comparison
- Moved Item_sp_variable::make_field() from item.h to item.cc
- Some minimal code changes to avoid copying to const char *
- Fixed wrong error message in wsrep_mysql_parse()
- Fixed wrong code in find_field_in_natural_join() where real_item() was
  set when it shouldn't
- ER_ERROR_ON_RENAME was used with extra arguments.
- Removed some (wrong) ER_OUTOFMEMORY, as alloc_root will already
  give the error.

TODO:
- Check possible unsafe casts in plugin/auth_examples/qa_auth_interface.c
- Change code to not modify LEX_CSTRING for database name
  (as part of lower_case_table_names)
2017-04-23 22:35:46 +03:00
Alexander Barkov
658082551f MDEV-12506 Split Item_func_min_max::fix_length_and_dec() into methods in Type_handler + MDEV-12497 + MDEV-12504
This patch does the following:

1. Adds a new method Type_handler_hybrid_field_type::aggregate_for_min_max()

   - For non-traditional data types it uses
     type_handler_data->m_type_aggregator_for_result.find_handler()
     This allows pluggable data types to define in the future their
     own behavior of the result data type detection for LEAST/GREATEST.
     Also, this disallows expressions of the GEOMETRY data type
     (and its variants such as POINT) to be mixed in with
     numeric and temporal data types in LEAST/GREATEST.

   - For traditional data types it reproduces the old behavior of
     the result data type detection (but not attributes, see below).

2. Adds a new virtual method Type_handler::Item_func_min_max_fix_attributes()
   and reuses as much as possible the code that calculates data type attributes
   for CASE-alike functions (e.g. CASE..THEN, COALESCE, IF).

   As the old code responsible for attributes calculation in the old
   implementation of Item_func_min_max::fix_length_and_dec()
   was not fully correct, this automatically fixes the following bugs:

   - MDEV-12497 Wrong data type for LEAST(latin1_expr, utf8_expr)
     The old fix_length_and_dec() calculated max_length before
     character set aggregation. Now max_length is calculated after, in
     Item_func::count_string_length() called from
     Item_func::aggregate_attributes_string() called from
     Type_handler_string_result::Item_hybrid_func_fix_attributes() called from
     Type_handler::Item_func_min_max_fix_attributes() called from
     Item_func_min_max::fix_length_and_dec().

   - MDEV-12504 Wrong data type for LEAST(date_expr,time_expr)
     The old fix_length_and_dec() simply used the maximum of max_length
     among all arguments to set its own max_length and did not take
     into account that a mixture of DATE and TIME becomes DATETIME.
     Now this is correctly handled by:
     Type_handler_datetime_common::Item_hybrid_func_fix_attributes() called from
     Type_handler::Item_func_min_max_fix_attributes() called from
     Item_func_min_max::fix_length_and_dec().

3. Removes the old implementation of Item_func_min_max::fix_length_and_dec()
   and replaces it to calls of the new methods.

4. Cleanup: moves the code related to unsigned_flag processing
   from Type_handler_hybrid_field_type::aggregate_for_result()
   to   Type_handler_int_result::Item_hybrid_func_fix_attributes().
   This is done:
   - to avoid code duplication in
     Type_handler_hybrid_field_type::aggregate_for_min_max()
   - to get rid of one more call for field_type(), which is unfriendly
     to the conceipt of pluggable data types.
2017-04-22 23:47:27 +04:00
Alexander Barkov
ba670edfa3 MDEV-12559 Split Item::temporal_precision() into virtual methods in Type_handler
- Adding a new virtual method Type_handler::Item_time_precision()
- Adding a new virtual method Type_handler::Item_datetime_precision()
- Removing Item::temporal_precision() and adding Item::time_precision()
  and Item::datetime_precision() instead.
- Moving Item_func_convert_tz::fix_length_and_dec() from item_timefunc.cc
  to item_timefunc.h. It's only two lines, and we're changing it anyway.
- Removing Item_temporal_typecast::fix_length_and_dec_generic(),
  moving this code to
  Type_handler::Item_{date|time|datetime}_typecast_fix_length_and_dec().
  This allows to get rid of one more field_type() call.
  Also, in the old reduction, Item_date_typecast::fix_length_and_dec()
  unnecessarily called args[0]->temporal_precision(). The new reduction
  does not call args[0]->datetime_precision(), as DATE does not
  have fractional digits.
2017-04-22 21:59:00 +04:00
Alexander Barkov
e2b03cd3b5 MDEV-12514 Split Item_temporal_func::fix_length_and_dec() + MDEV-12515
This patch implements MDEV-12514 according to the task descriptions.
It automatically fixes:
MDEV-12515 Wrong value when storing DATE_ADD() and ADDTIME() to a numeric field

Additionally:

a. Moves Item_func::set_attributes_temporal() to
   Type_str_attributes::fix_attributes_temporal(),
  which is a more proper place and name for it.

b. Continues replacing calls for:
     set_handler_by_field_type(MYSQL_TYPE_XXX)
   to corresponding:
     set_handler(&type_handler_xxx)
   which is faster.
   Note, we should eventually get rid of almost all set_handler_by_field_type().

c. Makes type_handler_string, type_handler_time2, type_handler_newdate,
   type_handler_datetime2 public.
   (all built-in handlers will become public eventually)

d. Removing Item_temporal_func::sql_mode, as it was not used.
2017-04-19 05:20:19 +04:00
Alexander Barkov
45730fb11e MDEV-12238 Add Type_handler::Item_func_{plus|minus|mul|div|mod}_fix_length_and_dec() 2017-04-13 06:50:00 +04:00
Alexander Barkov
72f43df623 MDEV-10914 ROW data type for stored routine variables 2017-04-05 15:02:56 +04:00
Alexander Barkov
17309c4c12 MDEV-12303 Add Type_handler::Item_xxx_fix_length_and_dec() for CAST classes 2017-04-04 17:59:48 +04:00
Alexander Barkov
48c59f394b MDEV-12338 Split Item_type_holder::get_real_type() into virtual Item::real_type_handler() 2017-03-24 17:52:55 +04:00
Alexander Barkov
a1e5201488 MDEV-12357 Invalid read of size 8 in Type_aggregator::Type_aggregator() 2017-03-24 15:59:58 +04:00
Alexander Barkov
552072e4d1 MDEV-12239 Add Type_handler::Item_sum_{sum|avg|variance}_fix_length_and_dec() 2017-03-19 23:39:42 +04:00
Alexander Barkov
a4a48a37c4 MDEV-12199 Split Item_func_{abs|neg|int_val}::fix_length_and_dec() into methods in Type_handler 2017-03-10 16:12:58 +04:00
Alexander Barkov
3f83801d82 MDEV-12001 Split Item_func_round::fix_length_and_dec to virtual methods in Type_handler
This patch makes the following changes (according to the task description):
- Adds Type_handler::Item_func_round_fix_length_and_dec().
- Splits the code from Item_func_round::fix_length_and_dec() into new
  Item_func_round methods fix_arg_int(), fix_arg_decimal(), fix_arg_double().
- Calls the new Item_func_round methods from the relevant implementations of
  Type_handler_xxx::Item_func_round_fix_length_and_dec().
- Adds a new error message ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
- Makes ROUND() return the new error for GEOMETRY

Additionally:
- Inherits Item_func_round directly from Item_func_numhybrid as it
  uses nothing from Item_func_num1.
- Fixes "MDEV-12000 ROUND(expr,const_expr_returning_NULL) creates DOUBLE(0,0)".
  Now if args[1] returns NULL, the data type is set to DOUBLE with
  NOT_FIXED_DEC decimals instead of 0 decimals.
2017-02-07 21:07:28 +04:00
Alexander Barkov
02a4bbb412 MDEV-11913 Split sp_get_item_value() into methods in Type_handler
This patch also fixes:
 MDEV-11815 SP variables of temporal data types do not replicate correctly
Temporal values are now printed in temporal literal format, with the
SQL-standard data type prefix:
  TIME'10:20:30', DATE'2001-01-01', TIMESTAMP'2001-01-01 10:20:30'
Previously temporal values were printed using the text string notation, e.g.
 _latin1'10:20:30' COLLATE latin1_swedish_ci, hence the bug.
2017-02-01 15:36:22 +04:00
Alexander Barkov
68235f2c2b MDEV-11692 Comparison data type aggregation for pluggable data types 2017-02-01 08:00:50 +04:00
Alexander Barkov
59c58f6ec3 MDEV-9522 Split sql_select.cc:can_change_cond_ref_to_const into virtual methods in Type_handler 2017-01-13 17:25:16 +04:00
Alexander Barkov
060d4861b9 Fixing minor problems in the patch for MDEV-11478 (shortint vs smallint)
- Fixing Type_handler_short::name() to return "smallint" instead of "shortint".
- Fixing test markers "End of 10.2 tests" and "End of 10.3 test"
2016-12-30 21:13:34 +04:00
Alexander Barkov
9b2bcf19f4 MDEV-11528 Split Item_func_min_max::val_xxx() and Item_func_min_max::get_date() into methods in Type_handler 2016-12-30 15:39:33 +04:00
Alexander Barkov
8aa044e674 MDEV-11478 Result data type aggregation for pluggable data types 2016-12-29 11:53:14 +04:00
Alexander Barkov
f6138883b1 MDEV-11672 mysql_list_field() returns wrong default values for VIEW
The problem happened because Item_ident_for_show::field_type() always
returned MYSQL_TYPE_DOUBLE and ignored the actual data type of the
referenced Field. As a result, the execution always used
Item_ident_for_show::val_real() to send the default value of the field,
so most default values for non-numeric types were displayed as '0'.

This patch:
1. Cleanup:
   a. Removes Send_field::charsetnr, as it's been unused since
      introduction of Item::charset_for_protocol() in MySQL-5.5.
   b. Adds the "const" qualifier to Field::char_length().
      This is needed for (5.a), see below.

2. Introduces a new virtual method Type_handler::charset_for_protocol(),
   returning item->collation.collation for string data types, or
   &my_charset_bin for non-string data types.

3. Changes Item::charset_for_protocol() from virtual to non-virtual.
   It now calls type_handler()->charset_for_protocol().
   As a good side effect, duplicate code in Item::charset_for_protocol() and
   Item_temporal_hybrid_func::charset_for_protocol() is now gone.

4. Fixes Item_ident_for_show::field_type() to correctly return
   its data type according to the data type of the referenced field.
   This actually fixes the problem reported in MDEV-11672.
   Now the default value is sent using a correct method, e.g.
   val_str() for VARCHAR/TEXT, or val_int() for INT/BIGINT.
   This required additional changes:
   a. in DBUG_ASSERT in Protocol::store(const char *,size_t,CHARSET_INFO),
      This method is now used by mysqld_list_fields(), which
      (unlike normal SELECT queries) does not set
      field_types/field_pos/field_count.
   b. Item_ident_for_show::Item_ident_for_show() now set standard attributes
      (collation, decimals, max_length, unsigned_flag) according to the
      referenced field, to make charset_for_protocol() return the correct
      value and to make mysqld_list_fields() correctly send default
      values.

5. In order to share the code between Item_field::set_field() and
   Item_ident_for_show::Item_ident_for_show():
   a. Introduces a new method Type_std_attributes::set(const Field*)
   b. To make (a) possible, moves Item::fix_char_length() from Item
      to Type_std_attributes, also moves char_to_byte_length_safe()
      from item.h to sql_type.h
   c. Additionally, moves Item::fix_length_and_charset() and
      Item::max_char_length() from Item to Type_std_attributes.
      This is not directly needed for the fix and is done just for symmetry
      with fix_char_length(), as these three methods are directly related
      to each other.
2016-12-29 07:40:49 +04:00
Alexander Barkov
d8c695ead4 MDEV-11615 Split Item_hybrid_func::fix_attributes into virtual methods in Type_handler 2016-12-27 09:32:54 +04:00
Alexander Barkov
74891ed257 MDEV-11514, MDEV-11497, MDEV-11554, MDEV-11555 - IN and CASE type aggregation problems
This patch fixes a number of data type aggregation problems in IN and CASE:
- MDEV-11497 Wrong result for (int_expr IN (mixture of signed and unsigned expressions))
- MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result
- MDEV-11554 Wrong result for CASE on a mixture of signed and unsigned expressions
- MDEV-11555 CASE with a mixture of TIME and DATETIME returns a wrong result

1. The problem reported in MDEV-11514 and MDEV-11555 was in the wrong assumption
that items having the same cmp_type() can reuse the same cmp_item instance.
So Item_func_case and Item_func_in used a static array of cmp_item*,
one element per one XXX_RESULT.

TIME and DATETIME cannot reuse the same cmp_item, because arguments of
these types are compared very differently. TIME and DATETIME must have
different instances in the cmp_item array. Reusing the same cmp_item
for TIME and DATETIME leads to unexpected result and unexpected warnings.

Note, after adding more data types soon (e.g. INET6), the problem would
become more serious, as INET6 will most likely have STRING_RESULT, but
it won't be able to reuse the same cmp_item with VARCHAR/TEXT.

This patch introduces a new class Predicant_to_list_comparator,
which maintains an array of cmp_items, one element per distinct
Type_handler rather than one element per XXX_RESULT.

2. The problem reported in MDEV-11497 and MDEV-11554 happened because
Item_func_in and Item_func_case did not take into account the fact
that UNSIGNED and SIGNED values must be compared as DECIMAL rather than INT,
because they used item_cmp_type() to aggregate the arguments.
The relevant code now resides in Predicant_to_list_comparator::add_value()
and uses Type_handler_hybrid_field_type::aggregate_for_comparison(),
like Item_func_between does.
2016-12-17 23:35:12 +04:00