1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

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.
This commit is contained in:
Alexander Barkov
2017-04-24 12:09:25 +04:00
parent 3cd7690a5e
commit 791374354c
27 changed files with 1213 additions and 277 deletions

View File

@@ -488,13 +488,35 @@ d date YES NULL
e varchar(1) YES NULL e varchar(1) YES NULL
f datetime YES NULL f datetime YES NULL
g time YES NULL g time YES NULL
h longblob YES NULL h blob YES NULL
dd time YES NULL dd time YES NULL
select * from t2; select * from t2;
a b c d e f g h dd a b c d e f g h dd
1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00 1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00
2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data 02:00:00 2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data 02:00:00
drop table t1, t2; drop table t1, t2;
CREATE TABLE t1 (
c_tinytext tinytext,
c_text text,
c_mediumtext mediumtext,
c_longtext longtext
);
CREATE TABLE t2 AS SELECT
ifnull(c_tinytext, CAST('yet another binary data' AS BINARY)),
ifnull(c_text, CAST('yet another binary data' AS BINARY)),
ifnull(c_mediumtext, CAST('yet another binary data' AS BINARY)),
ifnull(c_longtext, CAST('yet another binary data' AS BINARY))
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`ifnull(c_tinytext, CAST('yet another binary data' AS BINARY))` tinyblob DEFAULT NULL,
`ifnull(c_text, CAST('yet another binary data' AS BINARY))` blob DEFAULT NULL,
`ifnull(c_mediumtext, CAST('yet another binary data' AS BINARY))` mediumblob DEFAULT NULL,
`ifnull(c_longtext, CAST('yet another binary data' AS BINARY))` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, l datetime, m enum('a','b'), n set('a','b'), o char(10)); create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, l datetime, m enum('a','b'), n set('a','b'), o char(10));
create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1; create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1;
show create table t2; show create table t2;

View File

@@ -57,7 +57,7 @@ create table t1 select weight_string(repeat('t',66000)) as w;
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`w` longblob DEFAULT NULL `w` mediumblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
select weight_string(NULL); select weight_string(NULL);

View File

@@ -709,7 +709,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63
g g
select asbinary(g) from t1; select asbinary(g) from t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def asbinary(g) 252 4294967295 0 Y 128 0 63 def asbinary(g) 251 4294967295 0 Y 128 0 63
asbinary(g) asbinary(g)
drop table t1; drop table t1;
create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b));

View File

@@ -575,8 +575,14 @@ c_float FLOAT,
c_double DOUBLE, c_double DOUBLE,
c_decimal103 DECIMAL(10,3), c_decimal103 DECIMAL(10,3),
c_varchar10 VARCHAR(10), c_varchar10 VARCHAR(10),
c_tinytext TINYTEXT,
c_text TEXT, c_text TEXT,
c_mediumtext MEDIUMTEXT,
c_longtext LONGTEXT,
c_tinyblob TINYBLOB,
c_blob BLOB, c_blob BLOB,
c_mediumblob MEDIUMBLOB,
c_longblob LONGBLOB,
c_enum ENUM('one','two','tree'), c_enum ENUM('one','two','tree'),
c_datetime3 DATETIME(3), c_datetime3 DATETIME(3),
c_timestamp3 TIMESTAMP(3), c_timestamp3 TIMESTAMP(3),
@@ -899,6 +905,45 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
CREATE TABLE t2 AS SELECT CREATE TABLE t2 AS SELECT
NULLIF(c_tinytext, 1),
NULLIF(c_tinytext, c_smallint),
NULLIF(c_tinytext, c_tinyint),
NULLIF(c_tinytext, c_int),
NULLIF(c_tinytext, c_bigint),
NULLIF(c_tinytext, c_float),
NULLIF(c_tinytext, c_double),
NULLIF(c_tinytext, c_decimal103),
NULLIF(c_tinytext, c_varchar10),
NULLIF(c_tinytext, c_text),
NULLIF(c_tinytext, c_blob),
NULLIF(c_tinytext, c_enum),
NULLIF(c_tinytext, c_datetime3),
NULLIF(c_tinytext, c_timestamp3),
NULLIF(c_tinytext, c_date),
NULLIF(c_tinytext, c_time)
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`NULLIF(c_tinytext, 1)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_smallint)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_tinyint)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_int)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_bigint)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_float)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_double)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_decimal103)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_varchar10)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_text)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_blob)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_enum)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_datetime3)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_timestamp3)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_date)` tinytext DEFAULT NULL,
`NULLIF(c_tinytext, c_time)` tinytext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_text, 1), NULLIF(c_text, 1),
NULLIF(c_text, c_smallint), NULLIF(c_text, c_smallint),
NULLIF(c_text, c_tinyint), NULLIF(c_text, c_tinyint),
@@ -919,22 +964,139 @@ FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`NULLIF(c_text, 1)` longtext DEFAULT NULL, `NULLIF(c_text, 1)` text DEFAULT NULL,
`NULLIF(c_text, c_smallint)` longtext DEFAULT NULL, `NULLIF(c_text, c_smallint)` text DEFAULT NULL,
`NULLIF(c_text, c_tinyint)` longtext DEFAULT NULL, `NULLIF(c_text, c_tinyint)` text DEFAULT NULL,
`NULLIF(c_text, c_int)` longtext DEFAULT NULL, `NULLIF(c_text, c_int)` text DEFAULT NULL,
`NULLIF(c_text, c_bigint)` longtext DEFAULT NULL, `NULLIF(c_text, c_bigint)` text DEFAULT NULL,
`NULLIF(c_text, c_float)` longtext DEFAULT NULL, `NULLIF(c_text, c_float)` text DEFAULT NULL,
`NULLIF(c_text, c_double)` longtext DEFAULT NULL, `NULLIF(c_text, c_double)` text DEFAULT NULL,
`NULLIF(c_text, c_decimal103)` longtext DEFAULT NULL, `NULLIF(c_text, c_decimal103)` text DEFAULT NULL,
`NULLIF(c_text, c_varchar10)` longtext DEFAULT NULL, `NULLIF(c_text, c_varchar10)` text DEFAULT NULL,
`NULLIF(c_text, c_text)` longtext DEFAULT NULL, `NULLIF(c_text, c_text)` text DEFAULT NULL,
`NULLIF(c_text, c_blob)` longtext DEFAULT NULL, `NULLIF(c_text, c_blob)` text DEFAULT NULL,
`NULLIF(c_text, c_enum)` longtext DEFAULT NULL, `NULLIF(c_text, c_enum)` text DEFAULT NULL,
`NULLIF(c_text, c_datetime3)` longtext DEFAULT NULL, `NULLIF(c_text, c_datetime3)` text DEFAULT NULL,
`NULLIF(c_text, c_timestamp3)` longtext DEFAULT NULL, `NULLIF(c_text, c_timestamp3)` text DEFAULT NULL,
`NULLIF(c_text, c_date)` longtext DEFAULT NULL, `NULLIF(c_text, c_date)` text DEFAULT NULL,
`NULLIF(c_text, c_time)` longtext DEFAULT NULL `NULLIF(c_text, c_time)` text DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_mediumtext, 1),
NULLIF(c_mediumtext, c_smallint),
NULLIF(c_mediumtext, c_tinyint),
NULLIF(c_mediumtext, c_int),
NULLIF(c_mediumtext, c_bigint),
NULLIF(c_mediumtext, c_float),
NULLIF(c_mediumtext, c_double),
NULLIF(c_mediumtext, c_decimal103),
NULLIF(c_mediumtext, c_varchar10),
NULLIF(c_mediumtext, c_text),
NULLIF(c_mediumtext, c_blob),
NULLIF(c_mediumtext, c_enum),
NULLIF(c_mediumtext, c_datetime3),
NULLIF(c_mediumtext, c_timestamp3),
NULLIF(c_mediumtext, c_date),
NULLIF(c_mediumtext, c_time)
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`NULLIF(c_mediumtext, 1)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_smallint)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_tinyint)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_int)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_bigint)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_float)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_double)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_decimal103)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_varchar10)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_text)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_blob)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_enum)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_datetime3)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_timestamp3)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_date)` mediumtext DEFAULT NULL,
`NULLIF(c_mediumtext, c_time)` mediumtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_longtext, 1),
NULLIF(c_longtext, c_smallint),
NULLIF(c_longtext, c_tinyint),
NULLIF(c_longtext, c_int),
NULLIF(c_longtext, c_bigint),
NULLIF(c_longtext, c_float),
NULLIF(c_longtext, c_double),
NULLIF(c_longtext, c_decimal103),
NULLIF(c_longtext, c_varchar10),
NULLIF(c_longtext, c_text),
NULLIF(c_longtext, c_blob),
NULLIF(c_longtext, c_enum),
NULLIF(c_longtext, c_datetime3),
NULLIF(c_longtext, c_timestamp3),
NULLIF(c_longtext, c_date),
NULLIF(c_longtext, c_time)
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`NULLIF(c_longtext, 1)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_smallint)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_tinyint)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_int)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_bigint)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_float)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_double)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_decimal103)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_varchar10)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_text)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_blob)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_enum)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_datetime3)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_timestamp3)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_date)` longtext DEFAULT NULL,
`NULLIF(c_longtext, c_time)` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_tinyblob, 1),
NULLIF(c_tinyblob, c_smallint),
NULLIF(c_tinyblob, c_tinyint),
NULLIF(c_tinyblob, c_int),
NULLIF(c_tinyblob, c_bigint),
NULLIF(c_tinyblob, c_float),
NULLIF(c_tinyblob, c_double),
NULLIF(c_tinyblob, c_decimal103),
NULLIF(c_tinyblob, c_varchar10),
NULLIF(c_tinyblob, c_text),
NULLIF(c_tinyblob, c_blob),
NULLIF(c_tinyblob, c_enum),
NULLIF(c_tinyblob, c_datetime3),
NULLIF(c_tinyblob, c_timestamp3),
NULLIF(c_tinyblob, c_date),
NULLIF(c_tinyblob, c_time)
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`NULLIF(c_tinyblob, 1)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_smallint)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_tinyint)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_int)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_bigint)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_float)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_double)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_decimal103)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_varchar10)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_text)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_blob)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_enum)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_datetime3)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_timestamp3)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_date)` tinyblob DEFAULT NULL,
`NULLIF(c_tinyblob, c_time)` tinyblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
CREATE TABLE t2 AS SELECT CREATE TABLE t2 AS SELECT
@@ -958,22 +1120,100 @@ FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`NULLIF(c_blob, 1)` longblob DEFAULT NULL, `NULLIF(c_blob, 1)` blob DEFAULT NULL,
`NULLIF(c_blob, c_smallint)` longblob DEFAULT NULL, `NULLIF(c_blob, c_smallint)` blob DEFAULT NULL,
`NULLIF(c_blob, c_tinyint)` longblob DEFAULT NULL, `NULLIF(c_blob, c_tinyint)` blob DEFAULT NULL,
`NULLIF(c_blob, c_int)` longblob DEFAULT NULL, `NULLIF(c_blob, c_int)` blob DEFAULT NULL,
`NULLIF(c_blob, c_bigint)` longblob DEFAULT NULL, `NULLIF(c_blob, c_bigint)` blob DEFAULT NULL,
`NULLIF(c_blob, c_float)` longblob DEFAULT NULL, `NULLIF(c_blob, c_float)` blob DEFAULT NULL,
`NULLIF(c_blob, c_double)` longblob DEFAULT NULL, `NULLIF(c_blob, c_double)` blob DEFAULT NULL,
`NULLIF(c_blob, c_decimal103)` longblob DEFAULT NULL, `NULLIF(c_blob, c_decimal103)` blob DEFAULT NULL,
`NULLIF(c_blob, c_varchar10)` longblob DEFAULT NULL, `NULLIF(c_blob, c_varchar10)` blob DEFAULT NULL,
`NULLIF(c_blob, c_text)` longblob DEFAULT NULL, `NULLIF(c_blob, c_text)` blob DEFAULT NULL,
`NULLIF(c_blob, c_blob)` longblob DEFAULT NULL, `NULLIF(c_blob, c_blob)` blob DEFAULT NULL,
`NULLIF(c_blob, c_enum)` longblob DEFAULT NULL, `NULLIF(c_blob, c_enum)` blob DEFAULT NULL,
`NULLIF(c_blob, c_datetime3)` longblob DEFAULT NULL, `NULLIF(c_blob, c_datetime3)` blob DEFAULT NULL,
`NULLIF(c_blob, c_timestamp3)` longblob DEFAULT NULL, `NULLIF(c_blob, c_timestamp3)` blob DEFAULT NULL,
`NULLIF(c_blob, c_date)` longblob DEFAULT NULL, `NULLIF(c_blob, c_date)` blob DEFAULT NULL,
`NULLIF(c_blob, c_time)` longblob DEFAULT NULL `NULLIF(c_blob, c_time)` blob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_mediumblob, 1),
NULLIF(c_mediumblob, c_smallint),
NULLIF(c_mediumblob, c_tinyint),
NULLIF(c_mediumblob, c_int),
NULLIF(c_mediumblob, c_bigint),
NULLIF(c_mediumblob, c_float),
NULLIF(c_mediumblob, c_double),
NULLIF(c_mediumblob, c_decimal103),
NULLIF(c_mediumblob, c_varchar10),
NULLIF(c_mediumblob, c_text),
NULLIF(c_mediumblob, c_blob),
NULLIF(c_mediumblob, c_enum),
NULLIF(c_mediumblob, c_datetime3),
NULLIF(c_mediumblob, c_timestamp3),
NULLIF(c_mediumblob, c_date),
NULLIF(c_mediumblob, c_time)
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`NULLIF(c_mediumblob, 1)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_smallint)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_tinyint)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_int)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_bigint)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_float)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_double)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_decimal103)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_varchar10)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_text)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_blob)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_enum)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_datetime3)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_timestamp3)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_date)` mediumblob DEFAULT NULL,
`NULLIF(c_mediumblob, c_time)` mediumblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_longblob, 1),
NULLIF(c_longblob, c_smallint),
NULLIF(c_longblob, c_tinyint),
NULLIF(c_longblob, c_int),
NULLIF(c_longblob, c_bigint),
NULLIF(c_longblob, c_float),
NULLIF(c_longblob, c_double),
NULLIF(c_longblob, c_decimal103),
NULLIF(c_longblob, c_varchar10),
NULLIF(c_longblob, c_text),
NULLIF(c_longblob, c_blob),
NULLIF(c_longblob, c_enum),
NULLIF(c_longblob, c_datetime3),
NULLIF(c_longblob, c_timestamp3),
NULLIF(c_longblob, c_date),
NULLIF(c_longblob, c_time)
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`NULLIF(c_longblob, 1)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_smallint)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_tinyint)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_int)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_bigint)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_float)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_double)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_decimal103)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_varchar10)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_text)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_blob)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_enum)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_datetime3)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_timestamp3)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_date)` longblob DEFAULT NULL,
`NULLIF(c_longblob, c_time)` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
CREATE TABLE t2 AS SELECT CREATE TABLE t2 AS SELECT

View File

@@ -1449,6 +1449,28 @@ t2 CREATE TABLE `t2` (
`f8` mediumtext CHARACTER SET utf8 DEFAULT NULL `f8` mediumtext CHARACTER SET utf8 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2; drop table t1, t2;
CREATE TABLE t1
(
c_varchar varchar(1) character set utf8 collate utf8_general_ci,
c_tinytext tinytext,
c_text text,
c_mediumtext mediumtext,
c_longtext longtext
);
CREATE TABLE t2 AS
SELECT c_tinytext, c_text, c_mediumtext, c_longtext FROM t1
UNION
SELECT c_varchar, c_varchar, c_varchar, c_varchar FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`c_tinytext` text CHARACTER SET utf8 DEFAULT NULL,
`c_text` mediumtext CHARACTER SET utf8 DEFAULT NULL,
`c_mediumtext` longtext CHARACTER SET utf8 DEFAULT NULL,
`c_longtext` longtext CHARACTER SET utf8 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
(select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union
(select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union
(select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union

View File

@@ -681,7 +681,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63
g g
select ST_asbinary(g) from t1; select ST_asbinary(g) from t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def ST_asbinary(g) 252 4294967295 0 Y 128 0 63 def ST_asbinary(g) 251 4294967295 0 Y 128 0 63
ST_asbinary(g) ST_asbinary(g)
drop table t1; drop table t1;
create table t1 (a TEXT, b GEOMETRY NOT NULL, INDEX(b(5))); create table t1 (a TEXT, b GEOMETRY NOT NULL, INDEX(b(5)));

View File

@@ -681,7 +681,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63
g g
select ST_asbinary(g) from t1; select ST_asbinary(g) from t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def ST_asbinary(g) 252 4294967295 0 Y 128 0 63 def ST_asbinary(g) 251 4294967295 0 Y 128 0 63
ST_asbinary(g) ST_asbinary(g)
drop table t1; drop table t1;
create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b));

View File

@@ -402,6 +402,22 @@ explain t2;
select * from t2; select * from t2;
drop table t1, t2; drop table t1, t2;
CREATE TABLE t1 (
c_tinytext tinytext,
c_text text,
c_mediumtext mediumtext,
c_longtext longtext
);
CREATE TABLE t2 AS SELECT
ifnull(c_tinytext, CAST('yet another binary data' AS BINARY)),
ifnull(c_text, CAST('yet another binary data' AS BINARY)),
ifnull(c_mediumtext, CAST('yet another binary data' AS BINARY)),
ifnull(c_longtext, CAST('yet another binary data' AS BINARY))
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, l datetime, m enum('a','b'), n set('a','b'), o char(10)); create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, l datetime, m enum('a','b'), n set('a','b'), o char(10));
create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1; create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1;
show create table t2; show create table t2;

View File

@@ -414,8 +414,14 @@ CREATE TABLE t1
c_double DOUBLE, c_double DOUBLE,
c_decimal103 DECIMAL(10,3), c_decimal103 DECIMAL(10,3),
c_varchar10 VARCHAR(10), c_varchar10 VARCHAR(10),
c_tinytext TINYTEXT,
c_text TEXT, c_text TEXT,
c_mediumtext MEDIUMTEXT,
c_longtext LONGTEXT,
c_tinyblob TINYBLOB,
c_blob BLOB, c_blob BLOB,
c_mediumblob MEDIUMBLOB,
c_longblob LONGBLOB,
c_enum ENUM('one','two','tree'), c_enum ENUM('one','two','tree'),
c_datetime3 DATETIME(3), c_datetime3 DATETIME(3),
c_timestamp3 TIMESTAMP(3), c_timestamp3 TIMESTAMP(3),
@@ -596,6 +602,27 @@ FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
DROP TABLE t2; DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_tinytext, 1),
NULLIF(c_tinytext, c_smallint),
NULLIF(c_tinytext, c_tinyint),
NULLIF(c_tinytext, c_int),
NULLIF(c_tinytext, c_bigint),
NULLIF(c_tinytext, c_float),
NULLIF(c_tinytext, c_double),
NULLIF(c_tinytext, c_decimal103),
NULLIF(c_tinytext, c_varchar10),
NULLIF(c_tinytext, c_text),
NULLIF(c_tinytext, c_blob),
NULLIF(c_tinytext, c_enum),
NULLIF(c_tinytext, c_datetime3),
NULLIF(c_tinytext, c_timestamp3),
NULLIF(c_tinytext, c_date),
NULLIF(c_tinytext, c_time)
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT CREATE TABLE t2 AS SELECT
NULLIF(c_text, 1), NULLIF(c_text, 1),
NULLIF(c_text, c_smallint), NULLIF(c_text, c_smallint),
@@ -617,7 +644,70 @@ FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
DROP TABLE t2; DROP TABLE t2;
# QQ: this should probably create BLOB instead of LONGBLOB CREATE TABLE t2 AS SELECT
NULLIF(c_mediumtext, 1),
NULLIF(c_mediumtext, c_smallint),
NULLIF(c_mediumtext, c_tinyint),
NULLIF(c_mediumtext, c_int),
NULLIF(c_mediumtext, c_bigint),
NULLIF(c_mediumtext, c_float),
NULLIF(c_mediumtext, c_double),
NULLIF(c_mediumtext, c_decimal103),
NULLIF(c_mediumtext, c_varchar10),
NULLIF(c_mediumtext, c_text),
NULLIF(c_mediumtext, c_blob),
NULLIF(c_mediumtext, c_enum),
NULLIF(c_mediumtext, c_datetime3),
NULLIF(c_mediumtext, c_timestamp3),
NULLIF(c_mediumtext, c_date),
NULLIF(c_mediumtext, c_time)
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_longtext, 1),
NULLIF(c_longtext, c_smallint),
NULLIF(c_longtext, c_tinyint),
NULLIF(c_longtext, c_int),
NULLIF(c_longtext, c_bigint),
NULLIF(c_longtext, c_float),
NULLIF(c_longtext, c_double),
NULLIF(c_longtext, c_decimal103),
NULLIF(c_longtext, c_varchar10),
NULLIF(c_longtext, c_text),
NULLIF(c_longtext, c_blob),
NULLIF(c_longtext, c_enum),
NULLIF(c_longtext, c_datetime3),
NULLIF(c_longtext, c_timestamp3),
NULLIF(c_longtext, c_date),
NULLIF(c_longtext, c_time)
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_tinyblob, 1),
NULLIF(c_tinyblob, c_smallint),
NULLIF(c_tinyblob, c_tinyint),
NULLIF(c_tinyblob, c_int),
NULLIF(c_tinyblob, c_bigint),
NULLIF(c_tinyblob, c_float),
NULLIF(c_tinyblob, c_double),
NULLIF(c_tinyblob, c_decimal103),
NULLIF(c_tinyblob, c_varchar10),
NULLIF(c_tinyblob, c_text),
NULLIF(c_tinyblob, c_blob),
NULLIF(c_tinyblob, c_enum),
NULLIF(c_tinyblob, c_datetime3),
NULLIF(c_tinyblob, c_timestamp3),
NULLIF(c_tinyblob, c_date),
NULLIF(c_tinyblob, c_time)
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT CREATE TABLE t2 AS SELECT
NULLIF(c_blob, 1), NULLIF(c_blob, 1),
NULLIF(c_blob, c_smallint), NULLIF(c_blob, c_smallint),
@@ -639,6 +729,49 @@ FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
DROP TABLE t2; DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_mediumblob, 1),
NULLIF(c_mediumblob, c_smallint),
NULLIF(c_mediumblob, c_tinyint),
NULLIF(c_mediumblob, c_int),
NULLIF(c_mediumblob, c_bigint),
NULLIF(c_mediumblob, c_float),
NULLIF(c_mediumblob, c_double),
NULLIF(c_mediumblob, c_decimal103),
NULLIF(c_mediumblob, c_varchar10),
NULLIF(c_mediumblob, c_text),
NULLIF(c_mediumblob, c_blob),
NULLIF(c_mediumblob, c_enum),
NULLIF(c_mediumblob, c_datetime3),
NULLIF(c_mediumblob, c_timestamp3),
NULLIF(c_mediumblob, c_date),
NULLIF(c_mediumblob, c_time)
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
NULLIF(c_longblob, 1),
NULLIF(c_longblob, c_smallint),
NULLIF(c_longblob, c_tinyint),
NULLIF(c_longblob, c_int),
NULLIF(c_longblob, c_bigint),
NULLIF(c_longblob, c_float),
NULLIF(c_longblob, c_double),
NULLIF(c_longblob, c_decimal103),
NULLIF(c_longblob, c_varchar10),
NULLIF(c_longblob, c_text),
NULLIF(c_longblob, c_blob),
NULLIF(c_longblob, c_enum),
NULLIF(c_longblob, c_datetime3),
NULLIF(c_longblob, c_timestamp3),
NULLIF(c_longblob, c_date),
NULLIF(c_longblob, c_time)
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
# QQ: this should probably create a ENUM column instead of VARCHAR(4) # QQ: this should probably create a ENUM column instead of VARCHAR(4)
CREATE TABLE t2 AS SELECT CREATE TABLE t2 AS SELECT
NULLIF(c_enum, 1), NULLIF(c_enum, 1),

View File

@@ -889,6 +889,22 @@ create table t2 as select *, f6 as f8 from t1 union select *, f7 from t1;
show create table t2; show create table t2;
drop table t1, t2; drop table t1, t2;
CREATE TABLE t1
(
c_varchar varchar(1) character set utf8 collate utf8_general_ci,
c_tinytext tinytext,
c_text text,
c_mediumtext mediumtext,
c_longtext longtext
);
CREATE TABLE t2 AS
SELECT c_tinytext, c_text, c_mediumtext, c_longtext FROM t1
UNION
SELECT c_varchar, c_varchar, c_varchar, c_varchar FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
# #
# Bug#18175: Union select over 129 tables with a sum function fails. # Bug#18175: Union select over 129 tables with a sum function fails.
# #

View File

@@ -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) int Field_new_decimal::reset(void)
{ {
store_value(&decimal_zero); store_value(&decimal_zero);
@@ -10717,7 +10656,7 @@ uint32 Field_blob::char_length() const
case 3: case 3:
return 16777215; return 16777215;
case 4: case 4:
return (uint32) 4294967295U; return (uint32) UINT_MAX32;
default: default:
DBUG_ASSERT(0); // we should never go here DBUG_ASSERT(0); // we should never go here
return 0; return 0;
@@ -10770,7 +10709,7 @@ uint32 Field_blob::max_display_length()
case 3: case 3:
return 16777215 * field_charset->mbmaxlen; return 16777215 * field_charset->mbmaxlen;
case 4: case 4:
return (uint32) 4294967295U; return (uint32) UINT_MAX32;
default: default:
DBUG_ASSERT(0); // we should never go here DBUG_ASSERT(0); // we should never go here
return 0; return 0;

View File

@@ -971,6 +971,10 @@ public:
virtual bool zero_pack() const { return 1; } virtual bool zero_pack() const { return 1; }
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
virtual uint32 key_length() const { return pack_length(); } virtual uint32 key_length() const { return pack_length(); }
virtual const Type_handler *type_handler() const
{
return Type_handler::get_handler_by_field_type(type());
}
virtual enum_field_types type() const =0; virtual enum_field_types type() const =0;
virtual enum_field_types real_type() const { return type(); } virtual enum_field_types real_type() const { return type(); }
virtual enum_field_types binlog_type() const virtual enum_field_types binlog_type() const
@@ -1842,9 +1846,6 @@ public:
enum utype unireg_check_arg, enum utype unireg_check_arg,
const LEX_CSTRING *field_name_arg, const LEX_CSTRING *field_name_arg,
uint8 dec_arg, bool zero_arg, bool unsigned_arg); uint8 dec_arg, bool zero_arg, bool unsigned_arg);
Field_new_decimal(uint32 len_arg, bool maybe_null_arg,
const LEX_CSTRING *field_name_arg, uint8 dec_arg,
bool unsigned_arg);
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;} enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
Item_result result_type () const { return DECIMAL_RESULT; } Item_result result_type () const { return DECIMAL_RESULT; }
@@ -1897,7 +1898,6 @@ public:
uint16 mflags, int *order_var); uint16 mflags, int *order_var);
uint is_equal(Create_field *new_field); uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data); virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data);
static Field *create_from_item(MEM_ROOT *root, Item *);
Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item); Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item);
}; };
@@ -3231,6 +3231,15 @@ public:
:Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, &temp_lex_str, :Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, &temp_lex_str,
system_charset_info), system_charset_info),
packlength(packlength_arg) {} packlength(packlength_arg) {}
const Type_handler *type_handler() const
{
switch (packlength) {
case 1: return &type_handler_tiny_blob;
case 2: return &type_handler_blob;
case 3: return &type_handler_medium_blob;
}
return &type_handler_long_blob;
}
/* Note that the default copy constructor is used, in clone() */ /* Note that the default copy constructor is used, in clone() */
enum_field_types type() const { return MYSQL_TYPE_BLOB;} enum_field_types type() const { return MYSQL_TYPE_BLOB;}
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
@@ -3417,11 +3426,11 @@ public:
:Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg, share, blob_pack_length, &my_charset_bin) field_name_arg, share, blob_pack_length, &my_charset_bin)
{ geom_type= geom_type_arg; srid= field_srid; } { geom_type= geom_type_arg; srid= field_srid; }
Field_geom(uint32 len_arg,bool maybe_null_arg, const LEX_CSTRING *field_name_arg,
TABLE_SHARE *share, enum geometry_type geom_type_arg)
:Field_blob(len_arg, maybe_null_arg, field_name_arg, &my_charset_bin)
{ geom_type= geom_type_arg; srid= 0; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
const Type_handler *type_handler() const
{
return &type_handler_geometry;
}
enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; } enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; }
bool can_optimize_range(const Item_bool_func *cond, bool can_optimize_range(const Item_bool_func *cond,
const Item *item, const Item *item,

View File

@@ -518,7 +518,7 @@ Item::Item(THD *thd):
tables. tables.
*/ */
Item::Item(THD *thd, Item *item): Item::Item(THD *thd, Item *item):
Type_std_attributes(item), Type_all_attributes(item),
join_tab_idx(item->join_tab_idx), join_tab_idx(item->join_tab_idx),
is_expensive_cache(-1), is_expensive_cache(-1),
rsize(0), rsize(0),
@@ -5854,6 +5854,8 @@ const Type_handler *Item_field::real_type_handler() const
// TODO: We should add Field::real_type_handler() eventually // TODO: We should add Field::real_type_handler() eventually
if (type == MYSQL_TYPE_STRING && field->type() == MYSQL_TYPE_VAR_STRING) if (type == MYSQL_TYPE_STRING && field->type() == MYSQL_TYPE_VAR_STRING)
type= MYSQL_TYPE_VAR_STRING; type= MYSQL_TYPE_VAR_STRING;
else if (type == MYSQL_TYPE_BLOB)
return field->type_handler();
return Type_handler::get_handler_by_real_type(type); return Type_handler::get_handler_by_real_type(type);
} }
@@ -6276,122 +6278,23 @@ Field *Item::make_string_field(TABLE *table)
\# Created field \# Created field
*/ */
Field *Item::tmp_table_field_from_field_type(TABLE *table, Field *Item::tmp_table_field_from_field_type(TABLE *table)
bool fixed_length,
bool set_blob_packlength)
{ {
/* const Type_handler *handler= type_handler();
The field functions defines a field to be not null if null_ptr is not 0 Record_addr addr(maybe_null);
*/
uchar *null_ptr= maybe_null ? (uchar*) "" : 0;
Field *field;
MEM_ROOT *mem_root= table->in_use->mem_root;
switch (field_type()) { switch (handler->field_type()) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
field= Field_new_decimal::create_from_item(mem_root, this);
break;
case MYSQL_TYPE_TINY:
field= new (mem_root)
Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name, 0, unsigned_flag);
break;
case MYSQL_TYPE_SHORT:
field= new (mem_root)
Field_short((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name, 0, unsigned_flag);
break;
case MYSQL_TYPE_LONG:
field= new (mem_root)
Field_long((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name, 0, unsigned_flag);
break;
#ifdef HAVE_LONG_LONG
case MYSQL_TYPE_LONGLONG:
field= new (mem_root)
Field_longlong((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name, 0, unsigned_flag);
break;
#endif
case MYSQL_TYPE_FLOAT:
field= new (mem_root)
Field_float((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name, decimals, 0, unsigned_flag);
break;
case MYSQL_TYPE_DOUBLE:
field= new (mem_root)
Field_double((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name, decimals, 0, unsigned_flag);
break;
case MYSQL_TYPE_INT24:
field= new (mem_root)
Field_medium((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name, 0, unsigned_flag);
break;
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE:
field= new (mem_root)
Field_newdate(0, null_ptr, 0, Field::NONE, &name);
break;
case MYSQL_TYPE_TIME:
field= new_Field_time(mem_root, 0, null_ptr, 0, Field::NONE, &name,
decimals);
break;
case MYSQL_TYPE_TIMESTAMP:
field= new_Field_timestamp(mem_root, 0, null_ptr, 0,
Field::NONE, &name, 0, decimals);
break;
case MYSQL_TYPE_DATETIME:
field= new_Field_datetime(mem_root, 0, null_ptr, 0, Field::NONE,
&name, decimals);
break;
case MYSQL_TYPE_YEAR:
field= new (mem_root)
Field_year((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
&name);
break;
case MYSQL_TYPE_BIT:
field= new (mem_root)
Field_bit_as_char(NULL, max_length, null_ptr, 0, Field::NONE,
&name);
break;
default:
/* This case should never be chosen */
DBUG_ASSERT(0);
/* If something goes awfully wrong, it's better to get a string than die */
case MYSQL_TYPE_NULL: case MYSQL_TYPE_NULL:
case MYSQL_TYPE_STRING: case MYSQL_TYPE_STRING:
if (fixed_length && !too_big_for_varchar())
{
field= new (mem_root)
Field_string(max_length, maybe_null, &name, collation.collation);
break;
}
/* Fall through to make_string_field() */
case MYSQL_TYPE_ENUM: case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET: case MYSQL_TYPE_SET:
case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
return make_string_field(table); return make_string_field(table);
case MYSQL_TYPE_TINY_BLOB: default:
case MYSQL_TYPE_MEDIUM_BLOB: break;
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
field= new (mem_root)
Field_blob(max_length, maybe_null, &name,
collation.collation, set_blob_packlength);
break; // Blob handled outside of case
#ifdef HAVE_SPATIAL
case MYSQL_TYPE_GEOMETRY:
field= new (mem_root)
Field_geom(max_length, maybe_null, &name, table->s,
get_geometry_type());
#endif /* HAVE_SPATIAL */
} }
if (field) return handler->make_and_init_table_field(&name, addr, *this, table);
field->init(table);
return field;
} }
@@ -10423,10 +10326,16 @@ Field *Item_type_holder::make_field_by_type(TABLE *table)
} }
case MYSQL_TYPE_NULL: case MYSQL_TYPE_NULL:
return make_string_field(table); return make_string_field(table);
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
set_handler(Type_handler::blob_type_handler(max_length));
break;
default: default:
break; break;
} }
return tmp_table_field_from_field_type(table, false, true); return tmp_table_field_from_field_type(table);
} }

View File

@@ -483,7 +483,7 @@ public:
class Item: public Value_source, class Item: public Value_source,
public Type_std_attributes public Type_all_attributes
{ {
void operator=(Item &); void operator=(Item &);
/** /**
@@ -537,9 +537,7 @@ protected:
SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param); SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param);
virtual Field *make_string_field(TABLE *table); virtual Field *make_string_field(TABLE *table);
Field *tmp_table_field_from_field_type(TABLE *table, Field *tmp_table_field_from_field_type(TABLE *table);
bool fixed_length,
bool set_blob_packlength);
Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length); Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length);
void push_note_converted_to_negative_complement(THD *thd); void push_note_converted_to_negative_complement(THD *thd);
@@ -1744,6 +1742,8 @@ public:
} }
virtual Field::geometry_type get_geometry_type() const virtual Field::geometry_type get_geometry_type() const
{ return Field::GEOM_GEOMETRY; }; { return Field::GEOM_GEOMETRY; };
uint uint_geometry_type() const
{ return get_geometry_type(); }
String *check_well_formed_result(String *str, bool send_error= 0); String *check_well_formed_result(String *str, bool send_error= 0);
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs); bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
bool too_big_for_varchar() const bool too_big_for_varchar() const
@@ -2262,7 +2262,7 @@ public:
based on result_type(), which is less exact. based on result_type(), which is less exact.
*/ */
Field *create_field_for_create_select(TABLE *table) Field *create_field_for_create_select(TABLE *table)
{ return tmp_table_field_from_field_type(table, false, true); } { return tmp_table_field_from_field_type(table); }
}; };
@@ -2638,6 +2638,10 @@ public:
fast_field_copier setup_fast_field_copier(Field *field); fast_field_copier setup_fast_field_copier(Field *field);
table_map used_tables() const; table_map used_tables() const;
table_map all_used_tables() const; table_map all_used_tables() const;
const Type_handler *type_handler() const
{
return field->type_handler();
}
enum Item_result result_type () const enum Item_result result_type () const
{ {
return field->result_type(); return field->result_type();
@@ -3637,7 +3641,14 @@ public:
Item_partition_func_safe_string(thd, name_arg, safe_strlen(name_arg), &my_charset_bin) Item_partition_func_safe_string(thd, name_arg, safe_strlen(name_arg), &my_charset_bin)
{ max_length= length; } { max_length= length; }
enum Type type() const { return TYPE_HOLDER; } enum Type type() const { return TYPE_HOLDER; }
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; } enum_field_types field_type() const
{
return Item_blob::type_handler()->field_type();
}
const Type_handler *type_handler() const
{
return Type_handler::blob_type_handler(max_length);
}
const Type_handler *real_type_handler() const const Type_handler *real_type_handler() const
{ {
// Should not be called, Item_blob is used for SHOW purposes only. // Should not be called, Item_blob is used for SHOW purposes only.
@@ -3645,7 +3656,7 @@ public:
return &type_handler_varchar; return &type_handler_varchar;
} }
Field *create_field_for_schema(THD *thd, TABLE *table) Field *create_field_for_schema(THD *thd, TABLE *table)
{ return tmp_table_field_from_field_type(table, false, true); } { return tmp_table_field_from_field_type(table); }
}; };

View File

@@ -2577,7 +2577,7 @@ Item_func_nullif::fix_length_and_dec()
thd->change_item_tree(&args[0], m_cache); thd->change_item_tree(&args[0], m_cache);
thd->change_item_tree(&args[2], m_cache); thd->change_item_tree(&args[2], m_cache);
} }
set_handler_by_field_type(args[2]->field_type()); set_handler(args[2]->type_handler());
collation.set(args[2]->collation); collation.set(args[2]->collation);
decimals= args[2]->decimals; decimals= args[2]->decimals;
unsigned_flag= args[2]->unsigned_flag; unsigned_flag= args[2]->unsigned_flag;

View File

@@ -1057,7 +1057,7 @@ public:
} }
const char *func_name() const { return "ifnull"; } const char *func_name() const { return "ifnull"; }
Field *create_field_for_create_select(TABLE *table) Field *create_field_for_create_select(TABLE *table)
{ return tmp_table_field_from_field_type(table, false, false); } { return tmp_table_field_from_field_type(table); }
table_map not_null_tables() const { return 0; } table_map not_null_tables() const { return 0; }
uint decimal_precision() const uint decimal_precision() const

View File

@@ -2254,8 +2254,8 @@ void Item_func_int_val::fix_length_and_dec_int_or_decimal()
{ {
ulonglong tmp_max_length= (ulonglong ) args[0]->max_length - ulonglong tmp_max_length= (ulonglong ) args[0]->max_length -
(args[0]->decimals ? args[0]->decimals + 1 : 0) + 2; (args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
max_length= tmp_max_length > (ulonglong) 4294967295U ? max_length= tmp_max_length > (ulonglong) UINT_MAX32 ?
(uint32) 4294967295U : (uint32) tmp_max_length; (uint32) UINT_MAX32 : (uint32) tmp_max_length;
uint tmp= float_length(decimals); uint tmp= float_length(decimals);
set_if_smaller(max_length,tmp); set_if_smaller(max_length,tmp);
decimals= 0; decimals= 0;

View File

@@ -208,7 +208,7 @@ public:
{ {
return result_type() != STRING_RESULT ? return result_type() != STRING_RESULT ?
create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS) : create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS) :
tmp_table_field_from_field_type(table, false, false); tmp_table_field_from_field_type(table);
} }
Item *get_tmp_table_item(THD *thd); Item *get_tmp_table_item(THD *thd);
@@ -2255,12 +2255,6 @@ public:
bool update(); bool update();
bool fix_fields(THD *thd, Item **ref); bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec(); void fix_length_and_dec();
Field *create_field_for_create_select(TABLE *table)
{
return result_type() != STRING_RESULT ?
create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS) :
tmp_table_field_from_field_type(table, false, true);
}
table_map used_tables() const table_map used_tables() const
{ {
return used_tables_cache | RAND_TABLE_BIT; return used_tables_cache | RAND_TABLE_BIT;
@@ -2302,6 +2296,14 @@ public:
my_decimal *val_decimal(my_decimal*); my_decimal *val_decimal(my_decimal*);
String *val_str(String* str); String *val_str(String* str);
void fix_length_and_dec(); void fix_length_and_dec();
Field *create_field_for_create_select(TABLE *table)
{
return cmp_type() == STRING_RESULT ?
type_handler_long_blob.make_and_init_table_field(&(Item::name),
Record_addr(maybe_null),
*this, table) :
create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS);
}
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
/* /*
We must always return variables as strings to guard against selects of type We must always return variables as strings to guard against selects of type
@@ -2655,7 +2657,7 @@ public:
{ {
return result_type() != STRING_RESULT ? return result_type() != STRING_RESULT ?
sp_result_field : sp_result_field :
tmp_table_field_from_field_type(table, false, false); tmp_table_field_from_field_type(table);
} }
void make_field(THD *thd, Send_field *tmp_field); void make_field(THD *thd, Send_field *tmp_field);

View File

@@ -40,20 +40,11 @@
#include "opt_range.h" #include "opt_range.h"
Field *Item_geometry_func::create_field_for_create_select(TABLE *t_arg)
{
Field *result;
if ((result= new Field_geom(max_length, maybe_null, &name, t_arg->s,
get_geometry_type())))
result->init(t_arg);
return result;
}
void Item_geometry_func::fix_length_and_dec() void Item_geometry_func::fix_length_and_dec()
{ {
collation.set(&my_charset_bin); collation.set(&my_charset_bin);
decimals=0; decimals=0;
max_length= (uint32) 4294967295U; max_length= (uint32) UINT_MAX32;
maybe_null= 1; maybe_null= 1;
} }
@@ -206,7 +197,7 @@ String *Item_func_as_wkt::val_str_ascii(String *str)
void Item_func_as_wkt::fix_length_and_dec() void Item_func_as_wkt::fix_length_and_dec()
{ {
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length=MAX_BLOB_WIDTH; max_length= (uint32) UINT_MAX32;
maybe_null= 1; maybe_null= 1;
} }

View File

@@ -40,7 +40,6 @@ public:
Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {} Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
void fix_length_and_dec(); void fix_length_and_dec();
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; } enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
Field *create_field_for_create_select(TABLE *table);
}; };
class Item_func_geometry_from_text: public Item_geometry_func class Item_func_geometry_from_text: public Item_geometry_func
@@ -101,7 +100,7 @@ public:
Item_func_as_wkb(THD *thd, Item *a): Item_geometry_func(thd, a) {} Item_func_as_wkb(THD *thd, Item *a): Item_geometry_func(thd, a) {}
const char *func_name() const { return "st_aswkb"; } const char *func_name() const { return "st_aswkb"; }
String *val_str(String *); String *val_str(String *);
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; } enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_as_wkb>(thd, mem_root, this); } { return get_item_copy<Item_func_as_wkb>(thd, mem_root, this); }
}; };

View File

@@ -1669,8 +1669,6 @@ Item *Item_sum_avg::copy_or_same(THD* thd)
Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table) Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table)
{ {
Field *field;
MEM_ROOT *mem_root= table->in_use->mem_root;
if (group) if (group)
{ {
@@ -1679,21 +1677,15 @@ Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table)
The easiest way is to do this is to store both value in a string The easiest way is to do this is to store both value in a string
and unpack on access. and unpack on access.
*/ */
field= new (mem_root) Field *field= new (table->in_use->mem_root)
Field_string(((Item_sum_avg::result_type() == DECIMAL_RESULT) ? Field_string(((Item_sum_avg::result_type() == DECIMAL_RESULT) ?
dec_bin_size : sizeof(double)) + sizeof(longlong), dec_bin_size : sizeof(double)) + sizeof(longlong),
0, &name, &my_charset_bin); 0, &name, &my_charset_bin);
}
else if (Item_sum_avg::result_type() == DECIMAL_RESULT)
field= Field_new_decimal::create_from_item(mem_root, this);
else
{
field= new (mem_root) Field_double(max_length, maybe_null, &name,
decimals, TRUE);
}
if (field) if (field)
field->init(table); field->init(table);
return field; return field;
}
return tmp_table_field_from_field_type(table);
} }

View File

@@ -536,7 +536,7 @@ public:
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
{ return val_decimal_from_date(decimal_value); } { return val_decimal_from_date(decimal_value); }
Field *create_field_for_create_select(TABLE *table) Field *create_field_for_create_select(TABLE *table)
{ return tmp_table_field_from_field_type(table, false, false); } { return tmp_table_field_from_field_type(table); }
int save_in_field(Field *field, bool no_conversions) int save_in_field(Field *field, bool no_conversions)
{ return save_date_in_field(field, no_conversions); } { return save_date_in_field(field, no_conversions); }
}; };
@@ -1018,7 +1018,7 @@ class Item_extract :public Item_int_func
return true; return true;
} }
Field *create_field_for_create_select(TABLE *table) Field *create_field_for_create_select(TABLE *table)
{ return tmp_table_field_from_field_type(table, false, false); } { return tmp_table_field_from_field_type(table); }
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_extract>(thd, mem_root, this); } { return get_item_copy<Item_extract>(thd, mem_root, this); }

View File

@@ -15879,7 +15879,8 @@ Field *Item::create_tmp_field(bool group, TABLE *table, uint convert_int_length)
break; break;
} }
case TIME_RESULT: case TIME_RESULT:
new_field= tmp_table_field_from_field_type(table, true, false); case DECIMAL_RESULT:
new_field= tmp_table_field_from_field_type(table);
break; break;
case STRING_RESULT: case STRING_RESULT:
DBUG_ASSERT(collation.collation); DBUG_ASSERT(collation.collation);
@@ -15888,14 +15889,11 @@ Field *Item::create_tmp_field(bool group, TABLE *table, uint convert_int_length)
To preserve type they needed to be handled separately. To preserve type they needed to be handled separately.
*/ */
if (field_type() == MYSQL_TYPE_GEOMETRY) if (field_type() == MYSQL_TYPE_GEOMETRY)
new_field= tmp_table_field_from_field_type(table, true, false); new_field= tmp_table_field_from_field_type(table);
else else
new_field= make_string_field(table); new_field= make_string_field(table);
new_field->set_derivation(collation.derivation, collation.repertoire); new_field->set_derivation(collation.derivation, collation.repertoire);
break; break;
case DECIMAL_RESULT:
new_field= Field_new_decimal::create_from_item(mem_root, this);
break;
case ROW_RESULT: case ROW_RESULT:
// This case should never be choosen // This case should never be choosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
@@ -15980,7 +15978,7 @@ Field *Item::create_field_for_schema(THD *thd, TABLE *table)
field->init(table); field->init(table);
return field; return field;
} }
return tmp_table_field_from_field_type(table, false, false); return tmp_table_field_from_field_type(table);
} }

View File

@@ -5439,7 +5439,7 @@ static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs,
field->real_type() == MYSQL_TYPE_STRING) // For binary type field->real_type() == MYSQL_TYPE_STRING) // For binary type
{ {
uint32 octet_max_length= field->max_display_length(); uint32 octet_max_length= field->max_display_length();
if (is_blob && octet_max_length != (uint32) 4294967295U) if (is_blob && octet_max_length != (uint32) UINT_MAX32)
octet_max_length /= field->charset()->mbmaxlen; octet_max_length /= field->charset()->mbmaxlen;
longlong char_max_len= is_blob ? longlong char_max_len= is_blob ?
(longlong) octet_max_length / field->charset()->mbminlen : (longlong) octet_max_length / field->charset()->mbminlen :

View File

@@ -7368,7 +7368,7 @@ blob_length_by_type(enum_field_types type)
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
return 16777215; return 16777215;
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
return 4294967295U; return (uint) UINT32_MAX;
default: default:
DBUG_ASSERT(0); // we should never go here DBUG_ASSERT(0); // we should never go here
return 0; return 0;

View File

@@ -31,10 +31,6 @@ static Type_handler_date type_handler_date;
static Type_handler_timestamp type_handler_timestamp; static Type_handler_timestamp type_handler_timestamp;
static Type_handler_timestamp2 type_handler_timestamp2; static Type_handler_timestamp2 type_handler_timestamp2;
static Type_handler_olddecimal type_handler_olddecimal; static Type_handler_olddecimal type_handler_olddecimal;
static Type_handler_tiny_blob type_handler_tiny_blob;
static Type_handler_medium_blob type_handler_medium_blob;
static Type_handler_long_blob type_handler_long_blob;
static Type_handler_blob type_handler_blob;
Type_handler_null type_handler_null; Type_handler_null type_handler_null;
@@ -54,6 +50,11 @@ Type_handler_time2 type_handler_time2;
Type_handler_newdate type_handler_newdate; Type_handler_newdate type_handler_newdate;
Type_handler_datetime2 type_handler_datetime2; Type_handler_datetime2 type_handler_datetime2;
Type_handler_tiny_blob type_handler_tiny_blob;
Type_handler_medium_blob type_handler_medium_blob;
Type_handler_long_blob type_handler_long_blob;
Type_handler_blob type_handler_blob;
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
Type_handler_geometry type_handler_geometry; Type_handler_geometry type_handler_geometry;
#endif #endif
@@ -80,9 +81,18 @@ bool Type_handler_data::init()
m_type_aggregator_for_result.add(&type_handler_geometry, m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_geometry, &type_handler_geometry,
&type_handler_geometry) || &type_handler_geometry) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_tiny_blob,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry, m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_blob, &type_handler_blob,
&type_handler_long_blob) || &type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_medium_blob,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_long_blob,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry, m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_varchar, &type_handler_varchar,
&type_handler_long_blob) || &type_handler_long_blob) ||
@@ -140,6 +150,19 @@ Type_handler::string_type_handler(uint max_octet_length)
} }
const Type_handler *
Type_handler::blob_type_handler(uint max_octet_length)
{
if (max_octet_length <= 255)
return &type_handler_tiny_blob;
if (max_octet_length <= 65535)
return &type_handler_blob;
if (max_octet_length <= 16777215)
return &type_handler_medium_blob;
return &type_handler_long_blob;
}
/** /**
This method is used by: This method is used by:
- Item_sum_hybrid, e.g. MAX(item), MIN(item). - Item_sum_hybrid, e.g. MAX(item), MIN(item).
@@ -1152,6 +1175,423 @@ Field *Type_handler_set::make_conversion_table_field(TABLE *table,
((const Field_enum*) target)->typelib, target->charset()); ((const Field_enum*) target)->typelib, target->charset());
} }
/*************************************************************************/
Field *Type_handler::make_and_init_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
Field *field= make_table_field(name, addr, attr, table);
if (field)
field->init(table);
return field;
}
Field *Type_handler_tiny::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_tiny(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag);
}
Field *Type_handler_short::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_short(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag);
}
Field *Type_handler_int24::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_medium(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
Field::NONE, name,
0/*zerofill*/, attr.unsigned_flag);
}
Field *Type_handler_long::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_long(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag);
}
Field *Type_handler_longlong::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_longlong(addr.ptr, attr.max_length,
addr.null_ptr, addr.null_bit,
Field::NONE, name,
0/*zerofill*/, attr.unsigned_flag);
}
Field *Type_handler_float::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_float(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
Field::NONE, name,
attr.decimals, 0/*zerofill*/, attr.unsigned_flag);
}
Field *Type_handler_double::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_double(addr.ptr, attr.max_length,
addr.null_ptr, addr.null_bit,
Field::NONE, name,
attr.decimals, 0/*zerofill*/, attr.unsigned_flag);
}
Field *
Type_handler_olddecimal::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
/*
Currently make_table_field() is used for Item purpose only.
On Item level we have type_handler_newdecimal only.
Will be implemented when we reuse Type_handler::make_table_field()
in make_field() in field.cc, to open old tables with old decimal.
*/
DBUG_ASSERT(0);
return NULL;
}
Field *
Type_handler_newdecimal::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
uint8 dec= attr.decimals;
uint8 intg= attr.decimal_precision() - dec;
uint32 len= attr.max_char_length();
/*
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, attr.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 (table->in_use->mem_root)
Field_new_decimal(addr.ptr, len, addr.null_ptr, addr.null_bit,
Field::NONE, name,
dec, 0/*zerofill*/, attr.unsigned_flag);
}
Field *Type_handler_year::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_year(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
Field::NONE, name);
}
Field *Type_handler_null::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_null(addr.ptr, attr.max_length,
Field::NONE, name, attr.collation.collation);
}
Field *Type_handler_timestamp::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new_Field_timestamp(table->in_use->mem_root,
addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, table->s, attr.decimals);
}
Field *Type_handler_timestamp2::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_timestampf(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, table->s, attr.decimals);
}
Field *Type_handler_newdate::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_newdate(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name);
}
Field *Type_handler_date::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_date(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name);
}
Field *Type_handler_time::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new_Field_time(table->in_use->mem_root,
addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, attr.decimals);
}
Field *Type_handler_time2::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_timef(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, attr.decimals);
}
Field *Type_handler_datetime::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new_Field_datetime(table->in_use->mem_root,
addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, attr.decimals);
}
Field *Type_handler_datetime2::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_datetimef(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, attr.decimals);
}
Field *Type_handler_bit::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_bit_as_char(addr.ptr, attr.max_length,
addr.null_ptr, addr.null_bit,
Field::NONE, name);
}
Field *Type_handler_string::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_string(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
Field::NONE, name, attr.collation.collation);
}
Field *Type_handler_varchar::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_varstring(addr.ptr, attr.max_length,
HA_VARCHAR_PACKLENGTH(attr.max_length),
addr.null_ptr, addr.null_bit,
Field::NONE, name,
table->s, attr.collation.collation);
}
Field *Type_handler_tiny_blob::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_blob(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, table->s,
1, attr.collation.collation);
}
Field *Type_handler_blob::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_blob(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, table->s,
2, attr.collation.collation);
}
Field *
Type_handler_medium_blob::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_blob(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, table->s,
3, attr.collation.collation);
}
Field *Type_handler_long_blob::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_blob(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, table->s,
4, attr.collation.collation);
}
#ifdef HAVE_SPATIAL
Field *Type_handler_geometry::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
return new (table->in_use->mem_root)
Field_geom(addr.ptr, addr.null_ptr, addr.null_bit,
Field::NONE, name, table->s, 4,
(Field::geometry_type) attr.uint_geometry_type(),
0);
}
#endif
Field *Type_handler_enum::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
/*
Will be implemented when we split Item_type_holder::make_field_by_type()
and/or reuse Type_handler::make_table_field() in make_field() in field.cc
*/
DBUG_ASSERT(0);
return 0;
}
Field *Type_handler_set::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
/*
Will be implemented when we split Item_type_holder::make_field_by_type()
and/or reuse Type_handler::make_table_field() in make_field() in field.cc
*/
DBUG_ASSERT(0);
return 0;
}
/*************************************************************************/ /*************************************************************************/
uint32 Type_handler_decimal_result::max_display_length(const Item *item) const uint32 Type_handler_decimal_result::max_display_length(const Item *item) const
@@ -1440,6 +1880,17 @@ bool Type_handler_string_result::
} }
bool Type_handler_blob_common::
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
Item **items, uint nitems) const
{
if (func->aggregate_attributes_string(items, nitems))
return true;
func->set_handler(blob_type_handler(func->max_length));
return false;
}
bool Type_handler_date_common:: bool Type_handler_date_common::
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
Item **items, uint nitems) const Item **items, uint nitems) const

View File

@@ -314,6 +314,27 @@ public:
}; };
class Type_all_attributes: public Type_std_attributes
{
public:
Type_all_attributes()
:Type_std_attributes()
{ }
Type_all_attributes(const Type_all_attributes *other)
:Type_std_attributes(other)
{ }
// Returns total number of decimal digits
virtual uint decimal_precision() const= 0;
/*
Field::geometry_type is not visible here.
Let's use an "uint" wrapper for now. Later when we move Field_geom
into a plugin, this method will be replaced to some generic
datatype indepented method.
*/
virtual uint uint_geometry_type() const= 0;
};
class Name: private LEX_CSTRING class Name: private LEX_CSTRING
{ {
public: public:
@@ -327,6 +348,31 @@ public:
}; };
class Record_addr
{
public:
uchar *ptr; // Position to field in record
/**
Byte where the @c NULL bit is stored inside a record. If this Field is a
@c NOT @c NULL field, this member is @c NULL.
*/
uchar *null_ptr;
uchar null_bit; // Bit used to test null bit
Record_addr(uchar *ptr_arg,
uchar *null_ptr_arg,
uchar null_bit_arg)
:ptr(ptr_arg),
null_ptr(null_ptr_arg),
null_bit(null_bit_arg)
{ }
Record_addr(bool maybe_null)
:ptr(NULL),
null_ptr(maybe_null ? (uchar*) "" : 0),
null_bit(0)
{ }
};
class Type_handler class Type_handler
{ {
protected: protected:
@@ -342,6 +388,7 @@ protected:
bool bool
Item_func_or_sum_illegal_param(const Item_func_or_sum *) const; Item_func_or_sum_illegal_param(const Item_func_or_sum *) const;
public: public:
static const Type_handler *blob_type_handler(uint max_octet_length);
static const Type_handler *string_type_handler(uint max_octet_length); static const Type_handler *string_type_handler(uint max_octet_length);
static const Type_handler *get_handler_by_field_type(enum_field_types type); static const Type_handler *get_handler_by_field_type(enum_field_types type);
static const Type_handler *get_handler_by_real_type(enum_field_types type); static const Type_handler *get_handler_by_real_type(enum_field_types type);
@@ -431,6 +478,14 @@ public:
virtual Field *make_conversion_table_field(TABLE *TABLE, virtual Field *make_conversion_table_field(TABLE *TABLE,
uint metadata, uint metadata,
const Field *target) const= 0; const Field *target) const= 0;
virtual Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const= 0;
Field *make_and_init_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
virtual void make_sort_key(uchar *to, Item *item, virtual void make_sort_key(uchar *to, Item *item,
const SORT_FIELD_ATTR *sort_field, const SORT_FIELD_ATTR *sort_field,
Sort_param *param) const= 0; Sort_param *param) const= 0;
@@ -630,6 +685,14 @@ public:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return NULL; return NULL;
} }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const
{
DBUG_ASSERT(0);
return NULL;
}
void make_sort_key(uchar *to, Item *item, void make_sort_key(uchar *to, Item *item,
const SORT_FIELD_ATTR *sort_field, const SORT_FIELD_ATTR *sort_field,
Sort_param *param) const Sort_param *param) const
@@ -1179,6 +1242,10 @@ public:
uint32 max_display_length(const Item *item) const { return 4; } uint32 max_display_length(const Item *item) const { return 4; }
Field *make_conversion_table_field(TABLE *TABLE, uint metadata, Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1192,6 +1259,10 @@ public:
uint32 max_display_length(const Item *item) const { return 6; } uint32 max_display_length(const Item *item) const { return 6; }
Field *make_conversion_table_field(TABLE *TABLE, uint metadata, Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1208,6 +1279,10 @@ public:
} }
Field *make_conversion_table_field(TABLE *TABLE, uint metadata, Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1221,6 +1296,10 @@ public:
uint32 max_display_length(const Item *item) const { return 20; } uint32 max_display_length(const Item *item) const { return 20; }
Field *make_conversion_table_field(TABLE *TABLE, uint metadata, Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1234,6 +1313,10 @@ public:
uint32 max_display_length(const Item *item) const { return 8; } uint32 max_display_length(const Item *item) const { return 8; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1247,6 +1330,10 @@ public:
uint32 max_display_length(const Item *item) const; uint32 max_display_length(const Item *item) const;
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1264,6 +1351,10 @@ public:
} }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1278,6 +1369,10 @@ public:
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const; Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1291,6 +1386,10 @@ public:
uint32 max_display_length(const Item *item) const { return 53; } uint32 max_display_length(const Item *item) const { return 53; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1321,6 +1420,10 @@ public:
virtual ~Type_handler_time() {} virtual ~Type_handler_time() {}
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1331,6 +1434,10 @@ public:
enum_field_types real_field_type() const { return MYSQL_TYPE_TIME2; } enum_field_types real_field_type() const { return MYSQL_TYPE_TIME2; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1367,6 +1474,10 @@ public:
virtual ~Type_handler_date() {} virtual ~Type_handler_date() {}
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1376,6 +1487,10 @@ public:
virtual ~Type_handler_newdate() {} virtual ~Type_handler_newdate() {}
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1402,6 +1517,10 @@ public:
virtual ~Type_handler_datetime() {} virtual ~Type_handler_datetime() {}
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1412,6 +1531,10 @@ public:
enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; } enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1438,6 +1561,10 @@ public:
virtual ~Type_handler_timestamp() {} virtual ~Type_handler_timestamp() {}
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1448,6 +1575,10 @@ public:
enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; } enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1460,6 +1591,10 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; } enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1472,6 +1607,10 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1486,6 +1625,10 @@ public:
uint32 max_display_length(const Item *item) const { return 0; } uint32 max_display_length(const Item *item) const { return 0; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1499,6 +1642,10 @@ public:
bool is_param_long_data_type() const { return true; } bool is_param_long_data_type() const { return true; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1512,6 +1659,10 @@ public:
bool is_param_long_data_type() const { return true; } bool is_param_long_data_type() const { return true; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1525,6 +1676,8 @@ public:
return false; // Materialization does not work with BLOB columns return false; // Materialization does not work with BLOB columns
} }
bool is_param_long_data_type() const { return true; } bool is_param_long_data_type() const { return true; }
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
Item **items, uint nitems) const;
}; };
@@ -1537,6 +1690,10 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_TINY_BLOB; } enum_field_types field_type() const { return MYSQL_TYPE_TINY_BLOB; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1549,6 +1706,10 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_MEDIUM_BLOB; } enum_field_types field_type() const { return MYSQL_TYPE_MEDIUM_BLOB; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1561,6 +1722,10 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; } enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1573,6 +1738,10 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; } enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1593,6 +1762,11 @@ public:
} }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
bool is_traditional_type() const bool is_traditional_type() const
{ {
return false; return false;
@@ -1629,6 +1803,10 @@ public:
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; } virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1642,6 +1820,10 @@ public:
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_SET; } virtual enum_field_types real_field_type() const { return MYSQL_TYPE_SET; }
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
}; };
@@ -1742,6 +1924,10 @@ extern Type_handler_time2 type_handler_time2;
extern Type_handler_newdate type_handler_newdate; extern Type_handler_newdate type_handler_newdate;
extern Type_handler_datetime2 type_handler_datetime2; extern Type_handler_datetime2 type_handler_datetime2;
extern Type_handler_tiny_blob type_handler_tiny_blob;
extern Type_handler_blob type_handler_blob;
extern Type_handler_medium_blob type_handler_medium_blob;
extern Type_handler_long_blob type_handler_long_blob;
class Type_aggregator class Type_aggregator
{ {