• Alexander Barkov's avatar
    MDEV-9217 Split Item::tmp_table_field_from_field_type() into virtual methods in Type_handler · 79137435
    Alexander Barkov authored
    - 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.
    79137435
1.result 59.8 KB