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:
@@ -488,13 +488,35 @@ d date YES NULL
|
||||
e varchar(1) YES NULL
|
||||
f datetime YES NULL
|
||||
g time YES NULL
|
||||
h longblob YES NULL
|
||||
h blob YES NULL
|
||||
dd time YES NULL
|
||||
select * from t2;
|
||||
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
|
||||
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;
|
||||
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 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;
|
||||
|
@@ -57,7 +57,7 @@ create table t1 select weight_string(repeat('t',66000)) as w;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`w` longblob DEFAULT NULL
|
||||
`w` mediumblob DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
select weight_string(NULL);
|
||||
|
@@ -709,7 +709,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63
|
||||
g
|
||||
select asbinary(g) from t1;
|
||||
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)
|
||||
drop table t1;
|
||||
create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b));
|
||||
|
@@ -575,8 +575,14 @@ c_float FLOAT,
|
||||
c_double DOUBLE,
|
||||
c_decimal103 DECIMAL(10,3),
|
||||
c_varchar10 VARCHAR(10),
|
||||
c_tinytext TINYTEXT,
|
||||
c_text TEXT,
|
||||
c_mediumtext MEDIUMTEXT,
|
||||
c_longtext LONGTEXT,
|
||||
c_tinyblob TINYBLOB,
|
||||
c_blob BLOB,
|
||||
c_mediumblob MEDIUMBLOB,
|
||||
c_longblob LONGBLOB,
|
||||
c_enum ENUM('one','two','tree'),
|
||||
c_datetime3 DATETIME(3),
|
||||
c_timestamp3 TIMESTAMP(3),
|
||||
@@ -899,6 +905,45 @@ t2 CREATE TABLE `t2` (
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
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;
|
||||
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, c_smallint),
|
||||
NULLIF(c_text, c_tinyint),
|
||||
@@ -919,22 +964,139 @@ FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`NULLIF(c_text, 1)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_smallint)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_tinyint)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_int)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_bigint)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_float)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_double)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_decimal103)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_varchar10)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_text)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_blob)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_enum)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_datetime3)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_timestamp3)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_date)` longtext DEFAULT NULL,
|
||||
`NULLIF(c_text, c_time)` longtext DEFAULT NULL
|
||||
`NULLIF(c_text, 1)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_smallint)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_tinyint)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_int)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_bigint)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_float)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_double)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_decimal103)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_varchar10)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_text)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_blob)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_enum)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_datetime3)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_timestamp3)` text DEFAULT NULL,
|
||||
`NULLIF(c_text, c_date)` text 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
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2 AS SELECT
|
||||
@@ -958,22 +1120,100 @@ FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`NULLIF(c_blob, 1)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_smallint)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_tinyint)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_int)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_bigint)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_float)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_double)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_decimal103)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_varchar10)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_text)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_blob)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_enum)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_datetime3)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_timestamp3)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_date)` longblob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_time)` longblob DEFAULT NULL
|
||||
`NULLIF(c_blob, 1)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_smallint)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_tinyint)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_int)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_bigint)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_float)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_double)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_decimal103)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_varchar10)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_text)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_blob)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_enum)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_datetime3)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_timestamp3)` blob DEFAULT NULL,
|
||||
`NULLIF(c_blob, c_date)` blob 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
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2 AS SELECT
|
||||
|
@@ -1449,6 +1449,28 @@ t2 CREATE TABLE `t2` (
|
||||
`f8` mediumtext CHARACTER SET utf8 DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
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
|
||||
|
@@ -681,7 +681,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63
|
||||
g
|
||||
select ST_asbinary(g) from t1;
|
||||
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)
|
||||
drop table t1;
|
||||
create table t1 (a TEXT, b GEOMETRY NOT NULL, INDEX(b(5)));
|
||||
|
@@ -681,7 +681,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63
|
||||
g
|
||||
select ST_asbinary(g) from t1;
|
||||
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)
|
||||
drop table t1;
|
||||
create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b));
|
||||
|
@@ -402,6 +402,22 @@ explain t2;
|
||||
select * from 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 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;
|
||||
|
@@ -414,8 +414,14 @@ CREATE TABLE t1
|
||||
c_double DOUBLE,
|
||||
c_decimal103 DECIMAL(10,3),
|
||||
c_varchar10 VARCHAR(10),
|
||||
c_tinytext TINYTEXT,
|
||||
c_text TEXT,
|
||||
c_mediumtext MEDIUMTEXT,
|
||||
c_longtext LONGTEXT,
|
||||
c_tinyblob TINYBLOB,
|
||||
c_blob BLOB,
|
||||
c_mediumblob MEDIUMBLOB,
|
||||
c_longblob LONGBLOB,
|
||||
c_enum ENUM('one','two','tree'),
|
||||
c_datetime3 DATETIME(3),
|
||||
c_timestamp3 TIMESTAMP(3),
|
||||
@@ -596,6 +602,27 @@ FROM t1;
|
||||
SHOW CREATE 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
|
||||
NULLIF(c_text, 1),
|
||||
NULLIF(c_text, c_smallint),
|
||||
@@ -617,7 +644,70 @@ FROM t1;
|
||||
SHOW CREATE 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
|
||||
NULLIF(c_blob, 1),
|
||||
NULLIF(c_blob, c_smallint),
|
||||
@@ -639,6 +729,49 @@ FROM t1;
|
||||
SHOW CREATE 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)
|
||||
CREATE TABLE t2 AS SELECT
|
||||
NULLIF(c_enum, 1),
|
||||
|
@@ -889,6 +889,22 @@ create table t2 as select *, f6 as f8 from t1 union select *, f7 from t1;
|
||||
show create table 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.
|
||||
#
|
||||
|
65
sql/field.cc
65
sql/field.cc
@@ -2912,67 +2912,6 @@ Field_new_decimal::Field_new_decimal(uchar *ptr_arg,
|
||||
}
|
||||
|
||||
|
||||
Field_new_decimal::Field_new_decimal(uint32 len_arg,
|
||||
bool maybe_null_arg,
|
||||
const LEX_CSTRING *name,
|
||||
uint8 dec_arg,
|
||||
bool unsigned_arg)
|
||||
:Field_num((uchar*) 0, len_arg,
|
||||
maybe_null_arg ? (uchar*) "": 0, 0,
|
||||
NONE, name, dec_arg, 0, unsigned_arg)
|
||||
{
|
||||
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
||||
(dec <= DECIMAL_MAX_SCALE));
|
||||
bin_size= my_decimal_get_binary_size(precision, dec);
|
||||
}
|
||||
|
||||
|
||||
Field *Field_new_decimal::create_from_item(MEM_ROOT *mem_root, Item *item)
|
||||
{
|
||||
uint8 dec= item->decimals;
|
||||
uint8 intg= item->decimal_precision() - dec;
|
||||
uint32 len= item->max_char_length();
|
||||
DBUG_ASSERT (item->result_type() == DECIMAL_RESULT);
|
||||
|
||||
/*
|
||||
Trying to put too many digits overall in a DECIMAL(prec,dec)
|
||||
will always throw a warning. We must limit dec to
|
||||
DECIMAL_MAX_SCALE however to prevent an assert() later.
|
||||
*/
|
||||
|
||||
if (dec > 0)
|
||||
{
|
||||
signed int overflow;
|
||||
|
||||
dec= MY_MIN(dec, DECIMAL_MAX_SCALE);
|
||||
|
||||
/*
|
||||
If the value still overflows the field with the corrected dec,
|
||||
we'll throw out decimals rather than integers. This is still
|
||||
bad and of course throws a truncation warning.
|
||||
+1: for decimal point
|
||||
*/
|
||||
|
||||
const int required_length=
|
||||
my_decimal_precision_to_length(intg + dec, dec,
|
||||
item->unsigned_flag);
|
||||
|
||||
overflow= required_length - len;
|
||||
|
||||
if (overflow > 0)
|
||||
dec= MY_MAX(0, dec - overflow); // too long, discard fract
|
||||
else
|
||||
/* Corrected value fits. */
|
||||
len= required_length;
|
||||
}
|
||||
return new (mem_root)
|
||||
Field_new_decimal(len, item->maybe_null, &item->name,
|
||||
dec, item->unsigned_flag);
|
||||
}
|
||||
|
||||
|
||||
int Field_new_decimal::reset(void)
|
||||
{
|
||||
store_value(&decimal_zero);
|
||||
@@ -10717,7 +10656,7 @@ uint32 Field_blob::char_length() const
|
||||
case 3:
|
||||
return 16777215;
|
||||
case 4:
|
||||
return (uint32) 4294967295U;
|
||||
return (uint32) UINT_MAX32;
|
||||
default:
|
||||
DBUG_ASSERT(0); // we should never go here
|
||||
return 0;
|
||||
@@ -10770,7 +10709,7 @@ uint32 Field_blob::max_display_length()
|
||||
case 3:
|
||||
return 16777215 * field_charset->mbmaxlen;
|
||||
case 4:
|
||||
return (uint32) 4294967295U;
|
||||
return (uint32) UINT_MAX32;
|
||||
default:
|
||||
DBUG_ASSERT(0); // we should never go here
|
||||
return 0;
|
||||
|
25
sql/field.h
25
sql/field.h
@@ -971,6 +971,10 @@ public:
|
||||
virtual bool zero_pack() const { return 1; }
|
||||
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||
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 real_type() const { return type(); }
|
||||
virtual enum_field_types binlog_type() const
|
||||
@@ -1842,9 +1846,6 @@ public:
|
||||
enum utype unireg_check_arg,
|
||||
const LEX_CSTRING *field_name_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 ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||
Item_result result_type () const { return DECIMAL_RESULT; }
|
||||
@@ -1897,7 +1898,6 @@ public:
|
||||
uint16 mflags, int *order_var);
|
||||
uint is_equal(Create_field *new_field);
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -3231,6 +3231,15 @@ public:
|
||||
:Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, &temp_lex_str,
|
||||
system_charset_info),
|
||||
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() */
|
||||
enum_field_types type() const { return MYSQL_TYPE_BLOB;}
|
||||
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_name_arg, share, blob_pack_length, &my_charset_bin)
|
||||
{ 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; }
|
||||
const Type_handler *type_handler() const
|
||||
{
|
||||
return &type_handler_geometry;
|
||||
}
|
||||
enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; }
|
||||
bool can_optimize_range(const Item_bool_func *cond,
|
||||
const Item *item,
|
||||
|
125
sql/item.cc
125
sql/item.cc
@@ -518,7 +518,7 @@ Item::Item(THD *thd):
|
||||
tables.
|
||||
*/
|
||||
Item::Item(THD *thd, Item *item):
|
||||
Type_std_attributes(item),
|
||||
Type_all_attributes(item),
|
||||
join_tab_idx(item->join_tab_idx),
|
||||
is_expensive_cache(-1),
|
||||
rsize(0),
|
||||
@@ -5854,6 +5854,8 @@ const Type_handler *Item_field::real_type_handler() const
|
||||
// TODO: We should add Field::real_type_handler() eventually
|
||||
if (type == MYSQL_TYPE_STRING && field->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);
|
||||
|
||||
}
|
||||
@@ -6276,122 +6278,23 @@ Field *Item::make_string_field(TABLE *table)
|
||||
\# Created field
|
||||
*/
|
||||
|
||||
Field *Item::tmp_table_field_from_field_type(TABLE *table,
|
||||
bool fixed_length,
|
||||
bool set_blob_packlength)
|
||||
Field *Item::tmp_table_field_from_field_type(TABLE *table)
|
||||
{
|
||||
/*
|
||||
The field functions defines a field to be not null if null_ptr is not 0
|
||||
*/
|
||||
uchar *null_ptr= maybe_null ? (uchar*) "" : 0;
|
||||
Field *field;
|
||||
MEM_ROOT *mem_root= table->in_use->mem_root;
|
||||
const Type_handler *handler= type_handler();
|
||||
Record_addr addr(maybe_null);
|
||||
|
||||
switch (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 */
|
||||
switch (handler->field_type()) {
|
||||
case MYSQL_TYPE_NULL:
|
||||
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_SET:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
return make_string_field(table);
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
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 */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (field)
|
||||
field->init(table);
|
||||
return field;
|
||||
return handler->make_and_init_table_field(&name, addr, *this, table);
|
||||
}
|
||||
|
||||
|
||||
@@ -10423,10 +10326,16 @@ Field *Item_type_holder::make_field_by_type(TABLE *table)
|
||||
}
|
||||
case MYSQL_TYPE_NULL:
|
||||
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:
|
||||
break;
|
||||
}
|
||||
return tmp_table_field_from_field_type(table, false, true);
|
||||
return tmp_table_field_from_field_type(table);
|
||||
}
|
||||
|
||||
|
||||
|
25
sql/item.h
25
sql/item.h
@@ -483,7 +483,7 @@ public:
|
||||
|
||||
|
||||
class Item: public Value_source,
|
||||
public Type_std_attributes
|
||||
public Type_all_attributes
|
||||
{
|
||||
void operator=(Item &);
|
||||
/**
|
||||
@@ -537,9 +537,7 @@ protected:
|
||||
SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param);
|
||||
|
||||
virtual Field *make_string_field(TABLE *table);
|
||||
Field *tmp_table_field_from_field_type(TABLE *table,
|
||||
bool fixed_length,
|
||||
bool set_blob_packlength);
|
||||
Field *tmp_table_field_from_field_type(TABLE *table);
|
||||
Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length);
|
||||
|
||||
void push_note_converted_to_negative_complement(THD *thd);
|
||||
@@ -1744,6 +1742,8 @@ public:
|
||||
}
|
||||
virtual Field::geometry_type get_geometry_type() const
|
||||
{ return Field::GEOM_GEOMETRY; };
|
||||
uint uint_geometry_type() const
|
||||
{ return get_geometry_type(); }
|
||||
String *check_well_formed_result(String *str, bool send_error= 0);
|
||||
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
|
||||
bool too_big_for_varchar() const
|
||||
@@ -2262,7 +2262,7 @@ public:
|
||||
based on result_type(), which is less exact.
|
||||
*/
|
||||
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);
|
||||
table_map 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
|
||||
{
|
||||
return field->result_type();
|
||||
@@ -3637,7 +3641,14 @@ public:
|
||||
Item_partition_func_safe_string(thd, name_arg, safe_strlen(name_arg), &my_charset_bin)
|
||||
{ max_length= length; }
|
||||
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
|
||||
{
|
||||
// Should not be called, Item_blob is used for SHOW purposes only.
|
||||
@@ -3645,7 +3656,7 @@ public:
|
||||
return &type_handler_varchar;
|
||||
}
|
||||
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); }
|
||||
};
|
||||
|
||||
|
||||
|
@@ -2577,7 +2577,7 @@ Item_func_nullif::fix_length_and_dec()
|
||||
thd->change_item_tree(&args[0], 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);
|
||||
decimals= args[2]->decimals;
|
||||
unsigned_flag= args[2]->unsigned_flag;
|
||||
|
@@ -1057,7 +1057,7 @@ public:
|
||||
}
|
||||
const char *func_name() const { return "ifnull"; }
|
||||
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; }
|
||||
uint decimal_precision() const
|
||||
|
@@ -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 -
|
||||
(args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
|
||||
max_length= tmp_max_length > (ulonglong) 4294967295U ?
|
||||
(uint32) 4294967295U : (uint32) tmp_max_length;
|
||||
max_length= tmp_max_length > (ulonglong) UINT_MAX32 ?
|
||||
(uint32) UINT_MAX32 : (uint32) tmp_max_length;
|
||||
uint tmp= float_length(decimals);
|
||||
set_if_smaller(max_length,tmp);
|
||||
decimals= 0;
|
||||
|
@@ -208,7 +208,7 @@ public:
|
||||
{
|
||||
return result_type() != STRING_RESULT ?
|
||||
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);
|
||||
|
||||
@@ -2255,12 +2255,6 @@ public:
|
||||
bool update();
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
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
|
||||
{
|
||||
return used_tables_cache | RAND_TABLE_BIT;
|
||||
@@ -2302,6 +2296,14 @@ public:
|
||||
my_decimal *val_decimal(my_decimal*);
|
||||
String *val_str(String* str);
|
||||
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);
|
||||
/*
|
||||
We must always return variables as strings to guard against selects of type
|
||||
@@ -2655,7 +2657,7 @@ public:
|
||||
{
|
||||
return result_type() != STRING_RESULT ?
|
||||
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);
|
||||
|
||||
|
@@ -40,20 +40,11 @@
|
||||
#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()
|
||||
{
|
||||
collation.set(&my_charset_bin);
|
||||
decimals=0;
|
||||
max_length= (uint32) 4294967295U;
|
||||
max_length= (uint32) UINT_MAX32;
|
||||
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()
|
||||
{
|
||||
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
|
||||
max_length=MAX_BLOB_WIDTH;
|
||||
max_length= (uint32) UINT_MAX32;
|
||||
maybe_null= 1;
|
||||
}
|
||||
|
||||
|
@@ -40,7 +40,6 @@ public:
|
||||
Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
|
||||
void fix_length_and_dec();
|
||||
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
|
||||
@@ -101,7 +100,7 @@ public:
|
||||
Item_func_as_wkb(THD *thd, Item *a): Item_geometry_func(thd, a) {}
|
||||
const char *func_name() const { return "st_aswkb"; }
|
||||
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)
|
||||
{ return get_item_copy<Item_func_as_wkb>(thd, mem_root, this); }
|
||||
};
|
||||
|
@@ -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 *field;
|
||||
MEM_ROOT *mem_root= table->in_use->mem_root;
|
||||
|
||||
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
|
||||
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) ?
|
||||
dec_bin_size : sizeof(double)) + sizeof(longlong),
|
||||
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)
|
||||
field->init(table);
|
||||
return field;
|
||||
}
|
||||
return tmp_table_field_from_field_type(table);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -536,7 +536,7 @@ public:
|
||||
my_decimal *val_decimal(my_decimal *decimal_value)
|
||||
{ return val_decimal_from_date(decimal_value); }
|
||||
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)
|
||||
{ return save_date_in_field(field, no_conversions); }
|
||||
};
|
||||
@@ -1018,7 +1018,7 @@ class Item_extract :public Item_int_func
|
||||
return true;
|
||||
}
|
||||
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)
|
||||
{ return get_item_copy<Item_extract>(thd, mem_root, this); }
|
||||
|
@@ -15879,7 +15879,8 @@ Field *Item::create_tmp_field(bool group, TABLE *table, uint convert_int_length)
|
||||
break;
|
||||
}
|
||||
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;
|
||||
case STRING_RESULT:
|
||||
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.
|
||||
*/
|
||||
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
|
||||
new_field= make_string_field(table);
|
||||
new_field->set_derivation(collation.derivation, collation.repertoire);
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
new_field= Field_new_decimal::create_from_item(mem_root, this);
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
// This case should never be choosen
|
||||
DBUG_ASSERT(0);
|
||||
@@ -15980,7 +15978,7 @@ Field *Item::create_field_for_schema(THD *thd, TABLE *table)
|
||||
field->init(table);
|
||||
return field;
|
||||
}
|
||||
return tmp_table_field_from_field_type(table, false, false);
|
||||
return tmp_table_field_from_field_type(table);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
{
|
||||
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;
|
||||
longlong char_max_len= is_blob ?
|
||||
(longlong) octet_max_length / field->charset()->mbminlen :
|
||||
|
@@ -7368,7 +7368,7 @@ blob_length_by_type(enum_field_types type)
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
return 16777215;
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
return 4294967295U;
|
||||
return (uint) UINT32_MAX;
|
||||
default:
|
||||
DBUG_ASSERT(0); // we should never go here
|
||||
return 0;
|
||||
|
459
sql/sql_type.cc
459
sql/sql_type.cc
@@ -31,10 +31,6 @@ static Type_handler_date type_handler_date;
|
||||
static Type_handler_timestamp type_handler_timestamp;
|
||||
static Type_handler_timestamp2 type_handler_timestamp2;
|
||||
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;
|
||||
@@ -54,6 +50,11 @@ Type_handler_time2 type_handler_time2;
|
||||
Type_handler_newdate type_handler_newdate;
|
||||
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
|
||||
Type_handler_geometry type_handler_geometry;
|
||||
#endif
|
||||
@@ -80,9 +81,18 @@ bool Type_handler_data::init()
|
||||
m_type_aggregator_for_result.add(&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,
|
||||
&type_handler_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,
|
||||
&type_handler_varchar,
|
||||
&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:
|
||||
- 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());
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
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
|
||||
@@ -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::
|
||||
Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||
Item **items, uint nitems) const
|
||||
|
186
sql/sql_type.h
186
sql/sql_type.h
@@ -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
|
||||
{
|
||||
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
|
||||
{
|
||||
protected:
|
||||
@@ -342,6 +388,7 @@ protected:
|
||||
bool
|
||||
Item_func_or_sum_illegal_param(const Item_func_or_sum *) const;
|
||||
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 *get_handler_by_field_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,
|
||||
uint metadata,
|
||||
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,
|
||||
const SORT_FIELD_ATTR *sort_field,
|
||||
Sort_param *param) const= 0;
|
||||
@@ -630,6 +685,14 @@ public:
|
||||
DBUG_ASSERT(0);
|
||||
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,
|
||||
const SORT_FIELD_ATTR *sort_field,
|
||||
Sort_param *param) const
|
||||
@@ -1179,6 +1242,10 @@ public:
|
||||
uint32 max_display_length(const Item *item) const { return 4; }
|
||||
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
|
||||
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,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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;
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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,
|
||||
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_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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() {}
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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() {}
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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() {}
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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() {}
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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() {}
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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
|
||||
}
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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,
|
||||
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
|
||||
{
|
||||
return false;
|
||||
@@ -1629,6 +1803,10 @@ public:
|
||||
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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; }
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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_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
|
||||
{
|
||||
|
Reference in New Issue
Block a user