mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge remote-tracking branch 'origin/bb-10.2-ext' into 10.3
This commit is contained in:
@@ -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;
|
||||||
|
@@ -11184,5 +11184,21 @@ SET NAMES utf8;
|
|||||||
CREATE TABLE t1 (a SET('a,bü'));
|
CREATE TABLE t1 (a SET('a,bü'));
|
||||||
ERROR 22007: Illegal set 'a,bü' value found during parsing
|
ERROR 22007: Illegal set 'a,bü' value found during parsing
|
||||||
#
|
#
|
||||||
|
# MDEV-12607 Hybrid functions create wrong VARBINARY length when mixing character and binary data
|
||||||
|
#
|
||||||
|
SET sql_mode='';
|
||||||
|
SET NAMES utf8;
|
||||||
|
CREATE OR REPLACE TABLE t1 AS SELECT COALESCE('ßa',_binary 'a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
COALESCE('ßa',_binary 'a')
|
||||||
|
ßa
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`COALESCE('ßa',_binary 'a')` varbinary(6) NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
#
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
|
@@ -3500,5 +3500,17 @@ t2 CREATE TABLE `t2` (
|
|||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-12601 Hybrid functions create a column of an impossible type DOUBLE(256,4)
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DOUBLE(255,4),b DOUBLE(255,3));
|
||||||
|
CREATE TABLE t2 AS SELECT COALESCE(a,b) FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`COALESCE(a,b)` double(255,4) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
|
@@ -4661,3 +4661,20 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.3 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-12592 Illegal mix of collations with the HEX function
|
||||||
|
#
|
||||||
|
SET NAMES utf8;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
|
||||||
|
INSERT INTO t1 VALUES (0x09),('a');
|
||||||
|
SELECT IF(a<' ',HEX(a),a) FROM t1 ORDER BY a;
|
||||||
|
IF(a<' ',HEX(a),a)
|
||||||
|
09
|
||||||
|
a
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of 10.3 tests
|
||||||
|
#
|
||||||
|
@@ -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);
|
||||||
|
@@ -381,11 +381,11 @@ POINT(0,0) MOD '0' LIMIT 0;
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`POINT(0,0)+'0'` longtext DEFAULT NULL,
|
`POINT(0,0)+'0'` tinytext DEFAULT NULL,
|
||||||
`POINT(0,0)-'0'` longtext DEFAULT NULL,
|
`POINT(0,0)-'0'` tinytext DEFAULT NULL,
|
||||||
`POINT(0,0)*'0'` longtext DEFAULT NULL,
|
`POINT(0,0)*'0'` tinytext DEFAULT NULL,
|
||||||
`POINT(0,0)/'0'` longtext DEFAULT NULL,
|
`POINT(0,0)/'0'` tinytext DEFAULT NULL,
|
||||||
`POINT(0,0) MOD '0'` longtext DEFAULT NULL
|
`POINT(0,0) MOD '0'` tinytext DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 AS SELECT
|
CREATE TABLE t1 AS SELECT
|
||||||
@@ -394,8 +394,8 @@ CREATE TABLE t1 AS SELECT
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`'0'+POINT(0,0)` longtext DEFAULT NULL,
|
`'0'+POINT(0,0)` tinytext DEFAULT NULL,
|
||||||
`'0'*POINT(0,0)` longtext DEFAULT NULL
|
`'0'*POINT(0,0)` tinytext DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 AS SELECT '0'-POINT(0,0) LIMIT 0;
|
CREATE TABLE t1 AS SELECT '0'-POINT(0,0) LIMIT 0;
|
||||||
|
@@ -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));
|
||||||
@@ -4030,65 +4030,65 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
CREATE TABLE t1 (a GEOMETRY);
|
CREATE TABLE t1 (a GEOMETRY);
|
||||||
SELECT POINT(1,1) + 1;
|
SELECT POINT(1,1) + 1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '+'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '+'
|
||||||
SELECT POINT(1,1) - 1;
|
SELECT POINT(1,1) - 1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '-'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '-'
|
||||||
SELECT POINT(1,1) * 1;
|
SELECT POINT(1,1) * 1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '*'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '*'
|
||||||
SELECT POINT(1,1) / 1;
|
SELECT POINT(1,1) / 1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '/'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '/'
|
||||||
SELECT POINT(1,1) MOD 1;
|
SELECT POINT(1,1) MOD 1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '%'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '%'
|
||||||
SELECT 1 + POINT(1,1);
|
SELECT 1 + POINT(1,1);
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '+'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '+'
|
||||||
SELECT 1 - POINT(1,1);
|
SELECT 1 - POINT(1,1);
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '-'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '-'
|
||||||
SELECT 1 * POINT(1,1);
|
SELECT 1 * POINT(1,1);
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '*'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '*'
|
||||||
SELECT 1 / POINT(1,1);
|
SELECT 1 / POINT(1,1);
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '/'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '/'
|
||||||
SELECT 1 MOD POINT(1,1);
|
SELECT 1 MOD POINT(1,1);
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '%'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '%'
|
||||||
SELECT a + 1 FROM t1;
|
SELECT a + 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '+'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '+'
|
||||||
SELECT a - 1 FROM t1;
|
SELECT a - 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '-'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '-'
|
||||||
SELECT a * 1 FROM t1;
|
SELECT a * 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '*'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '*'
|
||||||
SELECT a / 1 FROM t1;
|
SELECT a / 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '/'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '/'
|
||||||
SELECT a MOD 1 FROM t1;
|
SELECT a MOD 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '%'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '%'
|
||||||
SELECT 1 + a FROM t1;
|
SELECT 1 + a FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '+'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '+'
|
||||||
SELECT 1 - a FROM t1;
|
SELECT 1 - a FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '-'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '-'
|
||||||
SELECT 1 * a FROM t1;
|
SELECT 1 * a FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '*'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '*'
|
||||||
SELECT 1 / a FROM t1;
|
SELECT 1 / a FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '/'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '/'
|
||||||
SELECT 1 MOD a FROM t1;
|
SELECT 1 MOD a FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '%'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '%'
|
||||||
SELECT COALESCE(a) + 1 FROM t1;
|
SELECT COALESCE(a) + 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '+'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '+'
|
||||||
SELECT COALESCE(a) - 1 FROM t1;
|
SELECT COALESCE(a) - 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '-'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '-'
|
||||||
SELECT COALESCE(a) * 1 FROM t1;
|
SELECT COALESCE(a) * 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '*'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '*'
|
||||||
SELECT COALESCE(a) / 1 FROM t1;
|
SELECT COALESCE(a) / 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '/'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '/'
|
||||||
SELECT COALESCE(a) MOD 1 FROM t1;
|
SELECT COALESCE(a) MOD 1 FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '%'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '%'
|
||||||
SELECT 1 + COALESCE(a) FROM t1;
|
SELECT 1 + COALESCE(a) FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '+'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '+'
|
||||||
SELECT 1 - COALESCE(a) FROM t1;
|
SELECT 1 - COALESCE(a) FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '-'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '-'
|
||||||
SELECT 1 * COALESCE(a) FROM t1;
|
SELECT 1 * COALESCE(a) FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '*'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '*'
|
||||||
SELECT 1 / COALESCE(a) FROM t1;
|
SELECT 1 / COALESCE(a) FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '/'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '/'
|
||||||
SELECT 1 MOD COALESCE(a) FROM t1;
|
SELECT 1 MOD COALESCE(a) FROM t1;
|
||||||
ERROR HY000: Illegal parameter data types bigint and geometry for operation '%'
|
ERROR HY000: Illegal parameter data types int and geometry for operation '%'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# MDEV-12514 Split Item_temporal_func::fix_length_and_dec()
|
# MDEV-12514 Split Item_temporal_func::fix_length_and_dec()
|
||||||
|
@@ -76,12 +76,12 @@ def aaa @arg00 @arg00 8 20 1 Y 32768 0 63
|
|||||||
1
|
1
|
||||||
select 1 union select 1;
|
select 1 union select 1;
|
||||||
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 1 1 8 20 1 N 32769 0 63
|
def 1 1 3 11 1 N 32769 0 63
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
select * from (select 1 union select 1) aaa;
|
select * from (select 1 union select 1) aaa;
|
||||||
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 aaa 1 1 8 20 1 N 32769 0 63
|
def aaa 1 1 3 11 1 N 32769 0 63
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@@ -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
|
||||||
|
@@ -2052,8 +2052,8 @@ CALL p1();
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`var` varchar(255) DEFAULT NULL,
|
`var` tinytext DEFAULT NULL,
|
||||||
`rec.var` varchar(255) DEFAULT NULL
|
`rec.var` tinytext DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
@@ -2092,8 +2092,8 @@ CALL p1();
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`var` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
|
`var` text CHARACTER SET utf8 DEFAULT NULL,
|
||||||
`rec.var` varchar(255) CHARACTER SET utf8 DEFAULT NULL
|
`rec.var` text CHARACTER SET utf8 DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
|
@@ -1019,3 +1019,52 @@ cast('-0.0' as decimal(5,1)) < 0
|
|||||||
#
|
#
|
||||||
# End of 5.5 tests
|
# End of 5.5 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.3 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-9217 Split Item::tmp_table_field_from_field_type() into virtual methods in Type_handler
|
||||||
|
#
|
||||||
|
# This creates the old DECIMAL. Will be fixed in MDEV-12574.
|
||||||
|
CREATE TABLE t1 AS SELECT MAX(a) FROM t1dec102;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`MAX(a)` decimal(10,2)/*old*/ DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT COALESCE(a) FROM t1dec102;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`COALESCE(a)` decimal(10,2) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a BIGINT);
|
||||||
|
CREATE TABLE t2 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`a` decimal(21,2) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a MEDIUMINT);
|
||||||
|
CREATE TABLE t2 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`a` decimal(10,2) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a YEAR);
|
||||||
|
CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT a FROM t1dec102;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`a` decimal(10,2) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t1dec102;
|
||||||
|
@@ -1803,13 +1803,18 @@ id c1 + 0 c1
|
|||||||
3 2
|
3 2
|
||||||
4 0
|
4 0
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 4.1 tests
|
End of 4.1 tests
|
||||||
|
SET sql_mode='';
|
||||||
create table t1(f1 enum('a','b'), index(f1));
|
create table t1(f1 enum('a','b'), index(f1));
|
||||||
|
insert into t1 values(''),(''),('a'),('b');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'f1' at row 1
|
||||||
Warning 1265 Data truncated for column 'f1' at row 2
|
Warning 1265 Data truncated for column 'f1' at row 2
|
||||||
select * from t1 where f1='';
|
select * from t1 where f1='';
|
||||||
f1
|
f1
|
||||||
|
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
SET sql_mode=DEFAULT;
|
SET sql_mode=DEFAULT;
|
||||||
CREATE TABLE t1 (c1 ENUM('a', '', 'b'));
|
CREATE TABLE t1 (c1 ENUM('a', '', 'b'));
|
||||||
INSERT INTO t1 (c1) VALUES ('b');
|
INSERT INTO t1 (c1) VALUES ('b');
|
||||||
@@ -2219,3 +2224,90 @@ SELECT * FROM t1;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a
|
a
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Start of 10.3 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-12432 Range optimizer for ENUM and SET does not return "Impossible WHERE" in some case
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a ENUM('a','b','c','1'),KEY(a));
|
||||||
|
INSERT INTO t1 VALUES ('a'),('b'),('c'),('1');
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='xx';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='99999999';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1e0;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='100';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1x';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.0';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.1';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-12656 Crash in CREATE..SELECT..UNION with a ENUM column and NULL
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a ENUM('a'));
|
||||||
|
# non-UNION + table column
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT a FROM t1);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`(SELECT a FROM t1)` varchar(1) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t2;
|
||||||
|
# UNION + table column
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT a FROM t1 UNION SELECT NULL);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`(SELECT a FROM t1 UNION SELECT NULL)` varchar(1) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t2;
|
||||||
|
# UNION + SP variable
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE va ENUM('a');
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT va FROM t1 UNION SELECT NULL);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CALL p1();
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`(SELECT va FROM t1 UNION SELECT NULL)` varchar(1) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
# UNION + anchored SP variable
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE va TYPE OF t1.a;
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT va FROM t1 UNION SELECT NULL);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CALL p1();
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`(SELECT va FROM t1 UNION SELECT NULL)` varchar(1) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
@@ -316,3 +316,39 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.3 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-12432 Range optimizer for ENUM and SET does not return "Impossible WHERE" in some case
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a SET('a','b','c','1'),KEY(a));
|
||||||
|
INSERT INTO t1 VALUES ('a'),('b'),('c'),('1');
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='xx';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='99999999';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1e0;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='100';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1x';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.0';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.1';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -992,5 +992,25 @@ a b
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET @@timestamp=DEFAULT;
|
SET @@timestamp=DEFAULT;
|
||||||
#
|
#
|
||||||
|
# MDEV-12582 Wrong data type for CREATE..SELECT MAX(COALESCE(timestamp_column))
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP);
|
||||||
|
CREATE TABLE t2 AS SELECT
|
||||||
|
MAX(a),
|
||||||
|
COALESCE(a),
|
||||||
|
COALESCE(MAX(a)),
|
||||||
|
MAX(COALESCE(a))
|
||||||
|
FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`MAX(a)` timestamp NULL DEFAULT NULL,
|
||||||
|
`COALESCE(a)` timestamp NULL DEFAULT NULL,
|
||||||
|
`COALESCE(MAX(a))` timestamp NULL DEFAULT NULL,
|
||||||
|
`MAX(COALESCE(a))` timestamp NULL DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
|
@@ -852,7 +852,7 @@ select * from t1;
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`1` bigint(20) NOT NULL DEFAULT 0
|
`1` int(11) NOT NULL DEFAULT 0
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 select _latin1"test" union select _latin2"testt" ;
|
create table t1 select _latin1"test" union select _latin2"testt" ;
|
||||||
@@ -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
|
||||||
@@ -2156,3 +2178,33 @@ WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
|
|||||||
a b a b
|
a b a b
|
||||||
1 1 1 1
|
1 1 1 1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Start of 10.3 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-12619 UNION creates excessive integer column types for integer literals
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 AS SELECT 1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`1` int(1) NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE OR REPLACE TABLE t1 AS SELECT 1 UNION SELECT 1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`1` int(11) NOT NULL DEFAULT 0
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE OR REPLACE TABLE t1 AS SELECT * FROM (SELECT 1 UNION SELECT 1) AS t0;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`1` int(11) NOT NULL DEFAULT 0
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of 10.3 tests
|
||||||
|
#
|
||||||
|
@@ -2129,8 +2129,8 @@ CALL p1();
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE "t1" (
|
t1 CREATE TABLE "t1" (
|
||||||
"var" varchar(255) DEFAULT NULL,
|
"var" tinytext DEFAULT NULL,
|
||||||
"rec.var" varchar(255) DEFAULT NULL
|
"rec.var" tinytext DEFAULT NULL
|
||||||
)
|
)
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
@@ -2169,8 +2169,8 @@ CALL p1();
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE "t1" (
|
t1 CREATE TABLE "t1" (
|
||||||
"var" varchar(255) CHARACTER SET utf8 DEFAULT NULL,
|
"var" text CHARACTER SET utf8 DEFAULT NULL,
|
||||||
"rec.var" varchar(255) CHARACTER SET utf8 DEFAULT NULL
|
"rec.var" text CHARACTER SET utf8 DEFAULT NULL
|
||||||
)
|
)
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
|
@@ -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)));
|
||||||
|
@@ -1238,7 +1238,7 @@ Table Op Msg_type Msg_text
|
|||||||
test.tab check status OK
|
test.tab check status OK
|
||||||
DROP TABLE tab;
|
DROP TABLE tab;
|
||||||
CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(c1 > 0) ) ENGINE=InnoDB;
|
CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(c1 > 0) ) ENGINE=InnoDB;
|
||||||
ERROR HY000: Illegal parameter data types geometry and bigint for operation '>'
|
ERROR HY000: Illegal parameter data types geometry and int for operation '>'
|
||||||
CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(CAST(c1 AS BINARY) > 0) ) ENGINE=InnoDB;
|
CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(CAST(c1 AS BINARY) > 0) ) ENGINE=InnoDB;
|
||||||
CREATE SPATIAL INDEX idx1 ON tab(c1) ;
|
CREATE SPATIAL INDEX idx1 ON tab(c1) ;
|
||||||
SHOW CREATE TABLE tab;
|
SHOW CREATE TABLE tab;
|
||||||
|
@@ -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));
|
||||||
|
@@ -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;
|
||||||
|
@@ -2109,6 +2109,18 @@ SET NAMES utf8;
|
|||||||
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
--error ER_ILLEGAL_VALUE_FOR_TYPE
|
||||||
CREATE TABLE t1 (a SET('a,bü'));
|
CREATE TABLE t1 (a SET('a,bü'));
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12607 Hybrid functions create wrong VARBINARY length when mixing character and binary data
|
||||||
|
--echo #
|
||||||
|
SET sql_mode='';
|
||||||
|
SET NAMES utf8;
|
||||||
|
CREATE OR REPLACE TABLE t1 AS SELECT COALESCE('ßa',_binary 'a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@@ -500,6 +500,16 @@ SHOW CREATE TABLE t2;
|
|||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12601 Hybrid functions create a column of an impossible type DOUBLE(256,4)
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DOUBLE(255,4),b DOUBLE(255,3));
|
||||||
|
CREATE TABLE t2 AS SELECT COALESCE(a,b) FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
@@ -1806,3 +1806,23 @@ DROP TABLE t1;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12592 Illegal mix of collations with the HEX function
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET NAMES utf8;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
|
||||||
|
INSERT INTO t1 VALUES (0x09),('a');
|
||||||
|
SELECT IF(a<' ',HEX(a),a) FROM t1 ORDER BY a;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
@@ -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),
|
||||||
|
@@ -612,3 +612,46 @@ select cast('-0.0' as decimal(5,1)) < 0;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 5.5 tests
|
--echo # End of 5.5 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-9217 Split Item::tmp_table_field_from_field_type() into virtual methods in Type_handler
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||||
|
|
||||||
|
--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1dec102.frm
|
||||||
|
--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1dec102.MYD
|
||||||
|
--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1dec102.MYI
|
||||||
|
|
||||||
|
--echo # This creates the old DECIMAL. Will be fixed in MDEV-12574.
|
||||||
|
CREATE TABLE t1 AS SELECT MAX(a) FROM t1dec102;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 AS SELECT COALESCE(a) FROM t1dec102;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a BIGINT);
|
||||||
|
CREATE TABLE t2 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a MEDIUMINT);
|
||||||
|
CREATE TABLE t2 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a YEAR);
|
||||||
|
CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT a FROM t1dec102;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
DROP TABLE t1dec102;
|
||||||
|
@@ -179,10 +179,12 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Bug#28729: Field_enum wrongly reported an error while storing an empty string.
|
# Bug#28729: Field_enum wrongly reported an error while storing an empty string.
|
||||||
#
|
#
|
||||||
|
SET sql_mode='';
|
||||||
create table t1(f1 enum('a','b'), index(f1));
|
create table t1(f1 enum('a','b'), index(f1));
|
||||||
insert into t1 values(''),(''),('a'),('b');
|
insert into t1 values(''),(''),('a'),('b');
|
||||||
select * from t1 where f1='';
|
select * from t1 where f1='';
|
||||||
|
drop table t1;
|
||||||
SET sql_mode=DEFAULT;
|
SET sql_mode=DEFAULT;
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -454,3 +456,65 @@ SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
|
|||||||
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
|
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
|
||||||
ALTER TABLE t1 MODIFY a ENUM('2001','2002');
|
ALTER TABLE t1 MODIFY a ENUM('2001','2002');
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12432 Range optimizer for ENUM and SET does not return "Impossible WHERE" in some case
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a ENUM('a','b','c','1'),KEY(a));
|
||||||
|
INSERT INTO t1 VALUES ('a'),('b'),('c'),('1');
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='xx';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='99999999';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1e0;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='100';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1x';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.0';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.1';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12656 Crash in CREATE..SELECT..UNION with a ENUM column and NULL
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a ENUM('a'));
|
||||||
|
--echo # non-UNION + table column
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT a FROM t1);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
--echo # UNION + table column
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT a FROM t1 UNION SELECT NULL);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
--echo # UNION + SP variable
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE va ENUM('a');
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT va FROM t1 UNION SELECT NULL);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
CALL p1();
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
--echo # UNION + anchored SP variable
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE va TYPE OF t1.a;
|
||||||
|
CREATE TABLE t2 AS SELECT (SELECT va FROM t1 UNION SELECT NULL);
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
CALL p1();
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
@@ -218,3 +218,25 @@ DROP TABLE t1;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12432 Range optimizer for ENUM and SET does not return "Impossible WHERE" in some case
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a SET('a','b','c','1'),KEY(a));
|
||||||
|
INSERT INTO t1 VALUES ('a'),('b'),('c'),('1');
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='xx';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='99999999';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1e0;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=100.1;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='100';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1x';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.0';
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a='1.1';
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -587,6 +587,22 @@ SELECT * FROM t1 WHERE TIME'10:20:30' BETWEEN a and b;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET @@timestamp=DEFAULT;
|
SET @@timestamp=DEFAULT;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12582 Wrong data type for CREATE..SELECT MAX(COALESCE(timestamp_column))
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP);
|
||||||
|
CREATE TABLE t2 AS SELECT
|
||||||
|
MAX(a),
|
||||||
|
COALESCE(a),
|
||||||
|
COALESCE(MAX(a)),
|
||||||
|
MAX(COALESCE(a))
|
||||||
|
FROM t1;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@@ -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.
|
||||||
#
|
#
|
||||||
@@ -1507,3 +1523,27 @@ SELECT * FROM t1 t1_1 LEFT JOIN t1 t1_2 ON ( t1_2.b = t1_1.a )
|
|||||||
WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
|
WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12619 UNION creates excessive integer column types for integer literals
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 AS SELECT 1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE OR REPLACE TABLE t1 AS SELECT 1 UNION SELECT 1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE OR REPLACE TABLE t1 AS SELECT * FROM (SELECT 1 UNION SELECT 1) AS t0;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
121
sql/field.cc
121
sql/field.cc
@@ -125,7 +125,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
|
|||||||
//MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP
|
//MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP
|
||||||
MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR,
|
MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR,
|
||||||
//MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24
|
//MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24
|
||||||
MYSQL_TYPE_DECIMAL, MYSQL_TYPE_DECIMAL,
|
MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL,
|
||||||
//MYSQL_TYPE_DATE MYSQL_TYPE_TIME
|
//MYSQL_TYPE_DATE MYSQL_TYPE_TIME
|
||||||
MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR,
|
MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR,
|
||||||
//MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR
|
//MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR
|
||||||
@@ -520,7 +520,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
|
|||||||
/* MYSQL_TYPE_YEAR -> */
|
/* MYSQL_TYPE_YEAR -> */
|
||||||
{
|
{
|
||||||
//MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY
|
//MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY
|
||||||
MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
|
MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_TINY,
|
||||||
//MYSQL_TYPE_SHORT MYSQL_TYPE_LONG
|
//MYSQL_TYPE_SHORT MYSQL_TYPE_LONG
|
||||||
MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
|
MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
|
||||||
//MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE
|
//MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE
|
||||||
@@ -1256,14 +1256,14 @@ bool Field::can_optimize_group_min_max(const Item_bool_func *cond,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This covers all numeric types, ENUM, SET, BIT
|
This covers all numeric types, BIT
|
||||||
*/
|
*/
|
||||||
bool Field::can_optimize_range(const Item_bool_func *cond,
|
bool Field::can_optimize_range(const Item_bool_func *cond,
|
||||||
const Item *item,
|
const Item *item,
|
||||||
bool is_eq_func) const
|
bool is_eq_func) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(cmp_type() != TIME_RESULT); // Handled in Field_temporal
|
DBUG_ASSERT(cmp_type() != TIME_RESULT); // Handled in Field_temporal
|
||||||
DBUG_ASSERT(cmp_type() != STRING_RESULT); // Handled in Field_longstr
|
DBUG_ASSERT(cmp_type() != STRING_RESULT); // Handled in Field_str descendants
|
||||||
return item->cmp_type() != TIME_RESULT;
|
return item->cmp_type() != TIME_RESULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2003,15 +2003,15 @@ bool Field_num::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
|
|||||||
Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg, utype unireg_check_arg,
|
uchar null_bit_arg, utype unireg_check_arg,
|
||||||
const LEX_CSTRING *field_name_arg,
|
const LEX_CSTRING *field_name_arg,
|
||||||
CHARSET_INFO *charset_arg)
|
const DTCollation &collation)
|
||||||
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg)
|
unireg_check_arg, field_name_arg)
|
||||||
{
|
{
|
||||||
field_charset= charset_arg;
|
field_charset= collation.collation;
|
||||||
if (charset_arg->state & MY_CS_BINSORT)
|
if (collation.collation->state & MY_CS_BINSORT)
|
||||||
flags|=BINARY_FLAG;
|
flags|=BINARY_FLAG;
|
||||||
field_derivation= DERIVATION_IMPLICIT;
|
field_derivation= collation.derivation;
|
||||||
field_repertoire= my_charset_repertoire(charset_arg);
|
field_repertoire= collation.repertoire;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
@@ -7817,10 +7756,10 @@ Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
|||||||
enum utype unireg_check_arg,
|
enum utype unireg_check_arg,
|
||||||
const LEX_CSTRING *field_name_arg,
|
const LEX_CSTRING *field_name_arg,
|
||||||
TABLE_SHARE *share, uint blob_pack_length,
|
TABLE_SHARE *share, uint blob_pack_length,
|
||||||
CHARSET_INFO *cs)
|
const DTCollation &collation)
|
||||||
:Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
|
:Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
|
||||||
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
|
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
|
||||||
cs),
|
collation),
|
||||||
packlength(blob_pack_length)
|
packlength(blob_pack_length)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(blob_pack_length <= 4); // Only pack lengths 1-4 supported currently
|
DBUG_ASSERT(blob_pack_length <= 4); // Only pack lengths 1-4 supported currently
|
||||||
@@ -8237,6 +8176,22 @@ void Field_blob::sort_string(uchar *to,uint length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return the data type handler, according to packlength.
|
||||||
|
Implemented in field.cc rather than in field.h
|
||||||
|
to avoid exporting type_handler_xxx with MYSQL_PLUGIN_IMPORT.
|
||||||
|
*/
|
||||||
|
const Type_handler *Field_blob::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Field_blob::sql_type(String &res) const
|
void Field_blob::sql_type(String &res) const
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str;
|
||||||
@@ -8638,12 +8593,16 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
tmp=0;
|
tmp=0;
|
||||||
set_warning(WARN_DATA_TRUNCATED, 1);
|
set_warning(WARN_DATA_TRUNCATED, 1);
|
||||||
|
err= 1;
|
||||||
}
|
}
|
||||||
if (!get_thd()->count_cuted_fields)
|
if (!get_thd()->count_cuted_fields && !length)
|
||||||
err= 0;
|
err= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
set_warning(WARN_DATA_TRUNCATED, 1);
|
set_warning(WARN_DATA_TRUNCATED, 1);
|
||||||
|
err= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
store_type((ulonglong) tmp);
|
store_type((ulonglong) tmp);
|
||||||
return err;
|
return err;
|
||||||
@@ -8817,6 +8776,7 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
tmp=0;
|
tmp=0;
|
||||||
set_warning(WARN_DATA_TRUNCATED, 1);
|
set_warning(WARN_DATA_TRUNCATED, 1);
|
||||||
|
err= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (got_warning)
|
else if (got_warning)
|
||||||
@@ -9055,12 +9015,17 @@ uint Field_num::is_equal(Create_field *new_field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Field_enum::can_optimize_range(const Item_bool_func *cond,
|
||||||
|
const Item *item,
|
||||||
|
bool is_eq_func) const
|
||||||
|
{
|
||||||
|
return item->cmp_type() != TIME_RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Field_enum::can_optimize_keypart_ref(const Item_bool_func *cond,
|
bool Field_enum::can_optimize_keypart_ref(const Item_bool_func *cond,
|
||||||
const Item *item) const
|
const Item *item) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(cmp_type() == INT_RESULT);
|
|
||||||
DBUG_ASSERT(result_type() == STRING_RESULT);
|
|
||||||
|
|
||||||
switch (item->cmp_type())
|
switch (item->cmp_type())
|
||||||
{
|
{
|
||||||
case TIME_RESULT:
|
case TIME_RESULT:
|
||||||
@@ -10717,7 +10682,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 +10735,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;
|
||||||
|
227
sql/field.h
227
sql/field.h
@@ -525,27 +525,6 @@ inline bool is_temporal_type(enum_field_types type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tests if field type is temporal and has time part,
|
|
||||||
i.e. represents TIME, DATETIME or TIMESTAMP types in SQL.
|
|
||||||
|
|
||||||
@param type Field type, as returned by field->type().
|
|
||||||
@retval true If field type is temporal type with time part.
|
|
||||||
@retval false If field type is not temporal type with time part.
|
|
||||||
*/
|
|
||||||
inline bool is_temporal_type_with_time(enum_field_types type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case MYSQL_TYPE_TIME:
|
|
||||||
case MYSQL_TYPE_DATETIME:
|
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum enum_vcol_info_type
|
enum enum_vcol_info_type
|
||||||
{
|
{
|
||||||
VCOL_GENERATED_VIRTUAL, VCOL_GENERATED_STORED,
|
VCOL_GENERATED_VIRTUAL, VCOL_GENERATED_STORED,
|
||||||
@@ -872,11 +851,13 @@ public:
|
|||||||
to be quoted when used in constructing an SQL query.
|
to be quoted when used in constructing an SQL query.
|
||||||
*/
|
*/
|
||||||
virtual bool str_needs_quotes() { return FALSE; }
|
virtual bool str_needs_quotes() { return FALSE; }
|
||||||
virtual Item_result result_type () const=0;
|
Item_result result_type () const
|
||||||
virtual Item_result cmp_type () const { return result_type(); }
|
|
||||||
virtual const Type_handler *cast_to_int_type_handler() const
|
|
||||||
{
|
{
|
||||||
return Type_handler::get_handler_by_field_type(type());
|
return type_handler()->result_type();
|
||||||
|
}
|
||||||
|
Item_result cmp_type () const
|
||||||
|
{
|
||||||
|
return type_handler()->cmp_type();
|
||||||
}
|
}
|
||||||
static bool type_can_have_key_part(enum_field_types);
|
static bool type_can_have_key_part(enum_field_types);
|
||||||
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
|
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
|
||||||
@@ -992,8 +973,15 @@ 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 enum_field_types type() const =0;
|
virtual const Type_handler *type_handler() const= 0;
|
||||||
virtual enum_field_types real_type() const { return type(); }
|
virtual enum_field_types type() const
|
||||||
|
{
|
||||||
|
return type_handler()->field_type();
|
||||||
|
}
|
||||||
|
virtual enum_field_types real_type() const
|
||||||
|
{
|
||||||
|
return type_handler()->real_field_type();
|
||||||
|
}
|
||||||
virtual enum_field_types binlog_type() const
|
virtual enum_field_types binlog_type() const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -1318,9 +1306,6 @@ public:
|
|||||||
virtual enum Derivation derivation(void) const
|
virtual enum Derivation derivation(void) const
|
||||||
{ return DERIVATION_IMPLICIT; }
|
{ return DERIVATION_IMPLICIT; }
|
||||||
virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; }
|
virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; }
|
||||||
virtual void set_derivation(enum Derivation derivation_arg,
|
|
||||||
uint repertoire_arg)
|
|
||||||
{ }
|
|
||||||
virtual int set_time() { return 1; }
|
virtual int set_time() { return 1; }
|
||||||
bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
|
bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
|
||||||
int cuted_increment) const;
|
int cuted_increment) const;
|
||||||
@@ -1610,7 +1595,6 @@ public:
|
|||||||
uchar null_bit_arg, utype unireg_check_arg,
|
uchar null_bit_arg, 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);
|
||||||
enum Item_result result_type () const { return INT_RESULT; }
|
|
||||||
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
|
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
|
||||||
uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; }
|
uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; }
|
||||||
CHARSET_INFO *charset(void) const { return &my_charset_numeric; }
|
CHARSET_INFO *charset(void) const { return &my_charset_numeric; }
|
||||||
@@ -1672,8 +1656,8 @@ public:
|
|||||||
const Item_equal *item_equal);
|
const Item_equal *item_equal);
|
||||||
Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg, utype unireg_check_arg,
|
uchar null_bit_arg, utype unireg_check_arg,
|
||||||
const LEX_CSTRING *field_name_arg, CHARSET_INFO *charset);
|
const LEX_CSTRING *field_name_arg,
|
||||||
Item_result result_type () const { return STRING_RESULT; }
|
const DTCollation &collation);
|
||||||
uint decimals() const { return NOT_FIXED_DEC; }
|
uint decimals() const { return NOT_FIXED_DEC; }
|
||||||
int save_in_field(Field *to) { return save_in_field_str(to); }
|
int save_in_field(Field *to) { return save_in_field_str(to); }
|
||||||
bool memcpy_field_possible(const Field *from) const
|
bool memcpy_field_possible(const Field *from) const
|
||||||
@@ -1693,12 +1677,6 @@ public:
|
|||||||
uint repertoire(void) const { return field_repertoire; }
|
uint repertoire(void) const { return field_repertoire; }
|
||||||
CHARSET_INFO *charset(void) const { return field_charset; }
|
CHARSET_INFO *charset(void) const { return field_charset; }
|
||||||
enum Derivation derivation(void) const { return field_derivation; }
|
enum Derivation derivation(void) const { return field_derivation; }
|
||||||
void set_derivation(enum Derivation derivation_arg,
|
|
||||||
uint repertoire_arg)
|
|
||||||
{
|
|
||||||
field_derivation= derivation_arg;
|
|
||||||
field_repertoire= repertoire_arg;
|
|
||||||
}
|
|
||||||
bool binary() const { return field_charset == &my_charset_bin; }
|
bool binary() const { return field_charset == &my_charset_bin; }
|
||||||
uint32 max_display_length() { return field_length; }
|
uint32 max_display_length() { return field_length; }
|
||||||
friend class Create_field;
|
friend class Create_field;
|
||||||
@@ -1740,9 +1718,10 @@ protected:
|
|||||||
public:
|
public:
|
||||||
Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
|
Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg, utype unireg_check_arg,
|
uchar null_bit_arg, utype unireg_check_arg,
|
||||||
const LEX_CSTRING *field_name_arg, CHARSET_INFO *charset_arg)
|
const LEX_CSTRING *field_name_arg,
|
||||||
|
const DTCollation &collation)
|
||||||
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
||||||
field_name_arg, charset_arg)
|
field_name_arg, collation)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int store_decimal(const my_decimal *d);
|
int store_decimal(const my_decimal *d);
|
||||||
@@ -1781,7 +1760,6 @@ public:
|
|||||||
field_name_arg, dec_arg, zero_arg, unsigned_arg),
|
field_name_arg, dec_arg, zero_arg, unsigned_arg),
|
||||||
not_fixed(dec_arg >= FLOATING_POINT_DECIMALS)
|
not_fixed(dec_arg >= FLOATING_POINT_DECIMALS)
|
||||||
{}
|
{}
|
||||||
Item_result result_type () const { return REAL_RESULT; }
|
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
return do_field_real;
|
return do_field_real;
|
||||||
@@ -1818,7 +1796,7 @@ public:
|
|||||||
unireg_check_arg, field_name_arg,
|
unireg_check_arg, field_name_arg,
|
||||||
dec_arg, zero_arg, unsigned_arg)
|
dec_arg, zero_arg, unsigned_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_DECIMAL;}
|
const Type_handler *type_handler() const { return &type_handler_olddecimal; }
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
|
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
@@ -1863,12 +1841,8 @@ 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 Type_handler *type_handler() const { return &type_handler_newdecimal; }
|
||||||
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; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||||
Item_result result_type () const { return DECIMAL_RESULT; }
|
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
// if (from->real_type() == MYSQL_TYPE_BIT) // QQ: why?
|
// if (from->real_type() == MYSQL_TYPE_BIT) // QQ: why?
|
||||||
@@ -1918,7 +1892,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);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1933,7 +1906,7 @@ public:
|
|||||||
unireg_check_arg, field_name_arg,
|
unireg_check_arg, field_name_arg,
|
||||||
0, zero_arg,unsigned_arg)
|
0, zero_arg,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_TINY;}
|
const Type_handler *type_handler() const { return &type_handler_tiny; }
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; }
|
{ return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
@@ -1983,7 +1956,7 @@ public:
|
|||||||
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||||
NONE, field_name_arg, 0, 0, unsigned_arg)
|
NONE, field_name_arg, 0, 0, unsigned_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_SHORT;}
|
const Type_handler *type_handler() const { return &type_handler_short; }
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;}
|
{ return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;}
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
@@ -2018,7 +1991,7 @@ public:
|
|||||||
unireg_check_arg, field_name_arg,
|
unireg_check_arg, field_name_arg,
|
||||||
0, zero_arg,unsigned_arg)
|
0, zero_arg,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_INT24;}
|
const Type_handler *type_handler() const { return &type_handler_int24; }
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; }
|
{ return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
@@ -2058,7 +2031,7 @@ public:
|
|||||||
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||||
NONE, field_name_arg,0,0,unsigned_arg)
|
NONE, field_name_arg,0,0,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_LONG;}
|
const Type_handler *type_handler() const { return &type_handler_long; }
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; }
|
{ return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
@@ -2104,7 +2077,7 @@ public:
|
|||||||
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||||
NONE, field_name_arg,0,0,unsigned_arg)
|
NONE, field_name_arg,0,0,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_LONGLONG;}
|
const Type_handler *type_handler() const { return &type_handler_longlong; }
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; }
|
{ return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
@@ -2158,7 +2131,7 @@ public:
|
|||||||
if (dec_arg >= FLOATING_POINT_DECIMALS)
|
if (dec_arg >= FLOATING_POINT_DECIMALS)
|
||||||
dec_arg= NOT_FIXED_DEC;
|
dec_arg= NOT_FIXED_DEC;
|
||||||
}
|
}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_FLOAT;}
|
const Type_handler *type_handler() const { return &type_handler_float; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
int store(double nr);
|
int store(double nr);
|
||||||
@@ -2209,7 +2182,7 @@ public:
|
|||||||
if (dec_arg >= FLOATING_POINT_DECIMALS)
|
if (dec_arg >= FLOATING_POINT_DECIMALS)
|
||||||
dec_arg= NOT_FIXED_DEC;
|
dec_arg= NOT_FIXED_DEC;
|
||||||
}
|
}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_DOUBLE;}
|
const Type_handler *type_handler() const { return &type_handler_double; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
int store(double nr);
|
int store(double nr);
|
||||||
@@ -2242,11 +2215,11 @@ class Field_null :public Field_str {
|
|||||||
public:
|
public:
|
||||||
Field_null(uchar *ptr_arg, uint32 len_arg,
|
Field_null(uchar *ptr_arg, uint32 len_arg,
|
||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
||||||
CHARSET_INFO *cs)
|
const DTCollation &collation)
|
||||||
:Field_str(ptr_arg, len_arg, null, 1,
|
:Field_str(ptr_arg, len_arg, null, 1,
|
||||||
unireg_check_arg, field_name_arg, cs)
|
unireg_check_arg, field_name_arg, collation)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_NULL;}
|
const Type_handler *type_handler() const { return &type_handler_null; }
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
return do_field_string;
|
return do_field_string;
|
||||||
@@ -2296,7 +2269,6 @@ public:
|
|||||||
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
||||||
field_name_arg)
|
field_name_arg)
|
||||||
{ flags|= BINARY_FLAG; }
|
{ flags|= BINARY_FLAG; }
|
||||||
Item_result result_type () const { return STRING_RESULT; }
|
|
||||||
int store_hex_hybrid(const char *str, uint length)
|
int store_hex_hybrid(const char *str, uint length)
|
||||||
{
|
{
|
||||||
return store(str, length, &my_charset_bin);
|
return store(str, length, &my_charset_bin);
|
||||||
@@ -2317,7 +2289,6 @@ public:
|
|||||||
CHARSET_INFO *charset(void) const { return &my_charset_numeric; }
|
CHARSET_INFO *charset(void) const { return &my_charset_numeric; }
|
||||||
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
|
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
|
||||||
bool binary() const { return true; }
|
bool binary() const { return true; }
|
||||||
enum Item_result cmp_type () const { return TIME_RESULT; }
|
|
||||||
bool val_bool() { return val_real() != 0e0; }
|
bool val_bool() { return val_real() != 0e0; }
|
||||||
uint is_equal(Create_field *new_field);
|
uint is_equal(Create_field *new_field);
|
||||||
bool eq_def(const Field *field) const
|
bool eq_def(const Field *field) const
|
||||||
@@ -2394,7 +2365,7 @@ public:
|
|||||||
enum utype unireg_check_arg,
|
enum utype unireg_check_arg,
|
||||||
const LEX_CSTRING *field_name_arg,
|
const LEX_CSTRING *field_name_arg,
|
||||||
TABLE_SHARE *share);
|
TABLE_SHARE *share);
|
||||||
enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;}
|
const Type_handler *type_handler() const { return &type_handler_timestamp; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
int store(double nr);
|
int store(double nr);
|
||||||
@@ -2528,7 +2499,7 @@ public:
|
|||||||
Field_timestamp_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
|
Field_timestamp_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, share, dec_arg)
|
unireg_check_arg, field_name_arg, share, dec_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
const Type_handler *type_handler() const { return &type_handler_timestamp2; }
|
||||||
enum_field_types binlog_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
enum_field_types binlog_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
||||||
uint32 pack_length() const
|
uint32 pack_length() const
|
||||||
{
|
{
|
||||||
@@ -2559,14 +2530,19 @@ public:
|
|||||||
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, 1, 1)
|
unireg_check_arg, field_name_arg, 1, 1)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_YEAR;}
|
const Type_handler *type_handler() const { return &type_handler_year; }
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
if (eq_def(from))
|
if (eq_def(from))
|
||||||
return get_identical_copy_func();
|
return get_identical_copy_func();
|
||||||
switch (from->cmp_type()) {
|
switch (from->cmp_type()) {
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
|
{
|
||||||
|
const Type_handler *handler= from->type_handler();
|
||||||
|
if (handler == &type_handler_enum || handler == &type_handler_set)
|
||||||
|
return do_field_int;
|
||||||
return do_field_string;
|
return do_field_string;
|
||||||
|
}
|
||||||
case TIME_RESULT:
|
case TIME_RESULT:
|
||||||
return do_field_temporal;
|
return do_field_temporal;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
@@ -2604,7 +2580,7 @@ public:
|
|||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg)
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg)
|
||||||
:Field_temporal_with_date(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
|
:Field_temporal_with_date(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg) {}
|
unireg_check_arg, field_name_arg) {}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_DATE;}
|
const Type_handler *type_handler() const { return &type_handler_date; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
||||||
int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
|
int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
|
||||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||||
@@ -2640,8 +2616,7 @@ public:
|
|||||||
:Field_temporal_with_date(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
|
:Field_temporal_with_date(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg)
|
unireg_check_arg, field_name_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_DATE;}
|
const Type_handler *type_handler() const { return &type_handler_newdate; }
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; }
|
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
|
||||||
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
|
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
|
||||||
double val_real(void);
|
double val_real(void);
|
||||||
@@ -2679,7 +2654,7 @@ public:
|
|||||||
:Field_temporal(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
|
:Field_temporal(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg), curdays(0)
|
unireg_check_arg, field_name_arg), curdays(0)
|
||||||
{}
|
{}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_TIME;}
|
const Type_handler *type_handler() const { return &type_handler_time; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
@@ -2791,7 +2766,7 @@ public:
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
||||||
}
|
}
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_TIME2; }
|
const Type_handler *type_handler() const { return &type_handler_time2; }
|
||||||
enum_field_types binlog_type() const { return MYSQL_TYPE_TIME2; }
|
enum_field_types binlog_type() const { return MYSQL_TYPE_TIME2; }
|
||||||
uint32 pack_length() const
|
uint32 pack_length() const
|
||||||
{
|
{
|
||||||
@@ -2833,7 +2808,7 @@ public:
|
|||||||
unireg_check == TIMESTAMP_DNUN_FIELD)
|
unireg_check == TIMESTAMP_DNUN_FIELD)
|
||||||
flags|= ON_UPDATE_NOW_FLAG;
|
flags|= ON_UPDATE_NOW_FLAG;
|
||||||
}
|
}
|
||||||
enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
|
const Type_handler *type_handler() const { return &type_handler_datetime; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
|
||||||
double val_real(void);
|
double val_real(void);
|
||||||
longlong val_int(void);
|
longlong val_int(void);
|
||||||
@@ -2950,7 +2925,7 @@ public:
|
|||||||
:Field_datetime_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
|
:Field_datetime_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, dec_arg)
|
unireg_check_arg, field_name_arg, dec_arg)
|
||||||
{}
|
{}
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_DATETIME2; }
|
const Type_handler *type_handler() const { return &type_handler_datetime2; }
|
||||||
enum_field_types binlog_type() const { return MYSQL_TYPE_DATETIME2; }
|
enum_field_types binlog_type() const { return MYSQL_TYPE_DATETIME2; }
|
||||||
uint32 pack_length() const
|
uint32 pack_length() const
|
||||||
{
|
{
|
||||||
@@ -3028,29 +3003,35 @@ class Field_string :public Field_longstr {
|
|||||||
public:
|
public:
|
||||||
Warn_filter_string(const THD *thd, const Field_string *field);
|
Warn_filter_string(const THD *thd, const Field_string *field);
|
||||||
};
|
};
|
||||||
|
bool is_var_string() const
|
||||||
|
{
|
||||||
|
return can_alter_field_type &&
|
||||||
|
orig_table &&
|
||||||
|
(orig_table->s->db_create_options & HA_OPTION_PACK_RECORD) &&
|
||||||
|
field_length >= 4 &&
|
||||||
|
orig_table->s->frm_version < FRM_VER_TRUE_VARCHAR;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
bool can_alter_field_type;
|
bool can_alter_field_type;
|
||||||
Field_string(uchar *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
|
Field_string(uchar *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg,
|
uchar null_bit_arg,
|
||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
||||||
CHARSET_INFO *cs)
|
const DTCollation &collation)
|
||||||
:Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, cs),
|
unireg_check_arg, field_name_arg, collation),
|
||||||
can_alter_field_type(1) {};
|
can_alter_field_type(1) {};
|
||||||
Field_string(uint32 len_arg,bool maybe_null_arg,
|
Field_string(uint32 len_arg,bool maybe_null_arg,
|
||||||
const LEX_CSTRING *field_name_arg,
|
const LEX_CSTRING *field_name_arg,
|
||||||
CHARSET_INFO *cs)
|
const DTCollation &collation)
|
||||||
:Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
:Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
||||||
NONE, field_name_arg, cs),
|
NONE, field_name_arg, collation),
|
||||||
can_alter_field_type(1) {};
|
can_alter_field_type(1) {};
|
||||||
|
|
||||||
enum_field_types type() const
|
const Type_handler *type_handler() const
|
||||||
{
|
{
|
||||||
return ((can_alter_field_type && orig_table &&
|
if (is_var_string())
|
||||||
orig_table->s->db_create_options & HA_OPTION_PACK_RECORD &&
|
return &type_handler_var_string;
|
||||||
field_length >= 4) &&
|
return &type_handler_string;
|
||||||
orig_table->s->frm_version < FRM_VER_TRUE_VARCHAR ?
|
|
||||||
MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING);
|
|
||||||
}
|
}
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
|
{ return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
|
||||||
@@ -3092,7 +3073,6 @@ public:
|
|||||||
uint packed_col_length(const uchar *to, uint length);
|
uint packed_col_length(const uchar *to, uint length);
|
||||||
uint max_packed_col_length(uint max_length);
|
uint max_packed_col_length(uint max_length);
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_STRING; }
|
|
||||||
bool has_charset(void) const
|
bool has_charset(void) const
|
||||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||||
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
||||||
@@ -3123,24 +3103,24 @@ public:
|
|||||||
uint32 len_arg, uint length_bytes_arg,
|
uint32 len_arg, uint length_bytes_arg,
|
||||||
uchar *null_ptr_arg, uchar null_bit_arg,
|
uchar *null_ptr_arg, uchar null_bit_arg,
|
||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
||||||
TABLE_SHARE *share, CHARSET_INFO *cs)
|
TABLE_SHARE *share, const DTCollation &collation)
|
||||||
:Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, cs),
|
unireg_check_arg, field_name_arg, collation),
|
||||||
length_bytes(length_bytes_arg)
|
length_bytes(length_bytes_arg)
|
||||||
{
|
{
|
||||||
share->varchar_fields++;
|
share->varchar_fields++;
|
||||||
}
|
}
|
||||||
Field_varstring(uint32 len_arg,bool maybe_null_arg,
|
Field_varstring(uint32 len_arg,bool maybe_null_arg,
|
||||||
const LEX_CSTRING *field_name_arg,
|
const LEX_CSTRING *field_name_arg,
|
||||||
TABLE_SHARE *share, CHARSET_INFO *cs)
|
TABLE_SHARE *share, const DTCollation &collation)
|
||||||
:Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
:Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
||||||
NONE, field_name_arg, cs),
|
NONE, field_name_arg, collation),
|
||||||
length_bytes(len_arg < 256 ? 1 :2)
|
length_bytes(len_arg < 256 ? 1 :2)
|
||||||
{
|
{
|
||||||
share->varchar_fields++;
|
share->varchar_fields++;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
|
const Type_handler *type_handler() const { return &type_handler_varchar; }
|
||||||
enum ha_base_keytype key_type() const;
|
enum ha_base_keytype key_type() const;
|
||||||
uint row_pack_length() const { return field_length; }
|
uint row_pack_length() const { return field_length; }
|
||||||
bool zero_pack() const { return 0; }
|
bool zero_pack() const { return 0; }
|
||||||
@@ -3184,7 +3164,6 @@ public:
|
|||||||
uint max_packed_col_length(uint max_length);
|
uint max_packed_col_length(uint max_length);
|
||||||
uint32 data_length();
|
uint32 data_length();
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
|
|
||||||
bool has_charset(void) const
|
bool has_charset(void) const
|
||||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||||
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
||||||
@@ -3224,20 +3203,21 @@ protected:
|
|||||||
public:
|
public:
|
||||||
Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
||||||
TABLE_SHARE *share, uint blob_pack_length, CHARSET_INFO *cs);
|
TABLE_SHARE *share, uint blob_pack_length,
|
||||||
|
const DTCollation &collation);
|
||||||
Field_blob(uint32 len_arg,bool maybe_null_arg, const LEX_CSTRING *field_name_arg,
|
Field_blob(uint32 len_arg,bool maybe_null_arg, const LEX_CSTRING *field_name_arg,
|
||||||
CHARSET_INFO *cs)
|
const DTCollation &collation)
|
||||||
:Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
:Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
||||||
NONE, field_name_arg, cs),
|
NONE, field_name_arg, collation),
|
||||||
packlength(4)
|
packlength(4)
|
||||||
{
|
{
|
||||||
flags|= BLOB_FLAG;
|
flags|= BLOB_FLAG;
|
||||||
}
|
}
|
||||||
Field_blob(uint32 len_arg,bool maybe_null_arg,
|
Field_blob(uint32 len_arg,bool maybe_null_arg,
|
||||||
const LEX_CSTRING *field_name_arg,
|
const LEX_CSTRING *field_name_arg,
|
||||||
CHARSET_INFO *cs, bool set_packlength)
|
const DTCollation &collation, bool set_packlength)
|
||||||
:Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
:Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
|
||||||
NONE, field_name_arg, cs)
|
NONE, field_name_arg, collation)
|
||||||
{
|
{
|
||||||
flags|= BLOB_FLAG;
|
flags|= BLOB_FLAG;
|
||||||
packlength= 4;
|
packlength= 4;
|
||||||
@@ -3252,8 +3232,24 @@ 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;
|
||||||
/* 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
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We cannot return type_handler()->field_type() here.
|
||||||
|
Some pieces of the code (e.g. in engines) rely on the fact
|
||||||
|
that Field::type(), Field::real_type() and Item_field::field_type()
|
||||||
|
return MYSQL_TYPE_BLOB for all blob variants.
|
||||||
|
We should eventually fix all such code pieces to expect
|
||||||
|
all BLOB type codes.
|
||||||
|
*/
|
||||||
|
return MYSQL_TYPE_BLOB;
|
||||||
|
}
|
||||||
|
enum_field_types real_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TYPE_BLOB;
|
||||||
|
}
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
|
{ return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
@@ -3438,12 +3434,19 @@ 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; }
|
||||||
enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; }
|
const Type_handler *type_handler() const
|
||||||
|
{
|
||||||
|
return &type_handler_geometry;
|
||||||
|
}
|
||||||
|
enum_field_types type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TYPE_GEOMETRY;
|
||||||
|
}
|
||||||
|
enum_field_types real_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,
|
||||||
bool is_eq_func) const;
|
bool is_eq_func) const;
|
||||||
@@ -3492,20 +3495,15 @@ public:
|
|||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
||||||
uint packlength_arg,
|
uint packlength_arg,
|
||||||
TYPELIB *typelib_arg,
|
TYPELIB *typelib_arg,
|
||||||
CHARSET_INFO *charset_arg)
|
const DTCollation &collation)
|
||||||
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, charset_arg),
|
unireg_check_arg, field_name_arg, collation),
|
||||||
packlength(packlength_arg),typelib(typelib_arg)
|
packlength(packlength_arg),typelib(typelib_arg)
|
||||||
{
|
{
|
||||||
flags|=ENUM_FLAG;
|
flags|=ENUM_FLAG;
|
||||||
}
|
}
|
||||||
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
||||||
enum_field_types type() const { return MYSQL_TYPE_STRING; }
|
const Type_handler *type_handler() const { return &type_handler_enum; }
|
||||||
enum Item_result cmp_type () const { return INT_RESULT; }
|
|
||||||
const Type_handler *cast_to_int_type_handler() const
|
|
||||||
{
|
|
||||||
return &type_handler_longlong;
|
|
||||||
}
|
|
||||||
enum ha_base_keytype key_type() const;
|
enum ha_base_keytype key_type() const;
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
@@ -3546,7 +3544,6 @@ public:
|
|||||||
void store_type(ulonglong value);
|
void store_type(ulonglong value);
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_ENUM; }
|
|
||||||
uint pack_length_from_metadata(uint field_metadata)
|
uint pack_length_from_metadata(uint field_metadata)
|
||||||
{ return (field_metadata & 0x00ff); }
|
{ return (field_metadata & 0x00ff); }
|
||||||
uint row_pack_length() const { return pack_length(); }
|
uint row_pack_length() const { return pack_length(); }
|
||||||
@@ -3576,6 +3573,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool can_optimize_range(const Item_bool_func *cond,
|
||||||
|
const Item *item,
|
||||||
|
bool is_eq_func) const;
|
||||||
private:
|
private:
|
||||||
int do_save_field_metadata(uchar *first_byte);
|
int do_save_field_metadata(uchar *first_byte);
|
||||||
uint is_equal(Create_field *new_field);
|
uint is_equal(Create_field *new_field);
|
||||||
@@ -3588,12 +3588,12 @@ public:
|
|||||||
uchar null_bit_arg,
|
uchar null_bit_arg,
|
||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
|
||||||
uint32 packlength_arg,
|
uint32 packlength_arg,
|
||||||
TYPELIB *typelib_arg, CHARSET_INFO *charset_arg)
|
TYPELIB *typelib_arg, const DTCollation &collation)
|
||||||
:Field_enum(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field_enum(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg,
|
unireg_check_arg, field_name_arg,
|
||||||
packlength_arg,
|
packlength_arg,
|
||||||
typelib_arg,charset_arg),
|
typelib_arg, collation),
|
||||||
empty_set_string("", 0, charset_arg)
|
empty_set_string("", 0, collation.collation)
|
||||||
{
|
{
|
||||||
flags=(flags & ~ENUM_FLAG) | SET_FLAG;
|
flags=(flags & ~ENUM_FLAG) | SET_FLAG;
|
||||||
}
|
}
|
||||||
@@ -3606,7 +3606,7 @@ public:
|
|||||||
String *val_str(String*,String *);
|
String *val_str(String*,String *);
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
enum_field_types real_type() const { return MYSQL_TYPE_SET; }
|
const Type_handler *type_handler() const { return &type_handler_set; }
|
||||||
bool has_charset(void) const { return TRUE; }
|
bool has_charset(void) const { return TRUE; }
|
||||||
private:
|
private:
|
||||||
const String empty_set_string;
|
const String empty_set_string;
|
||||||
@@ -3636,13 +3636,12 @@ public:
|
|||||||
Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
|
Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
|
uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
|
||||||
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg);
|
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg);
|
||||||
enum_field_types type() const { return MYSQL_TYPE_BIT; }
|
const Type_handler *type_handler() const { return &type_handler_bit; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
|
||||||
uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
|
uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
|
||||||
uint32 max_data_length() const { return (field_length + 7) / 8; }
|
uint32 max_data_length() const { return (field_length + 7) / 8; }
|
||||||
uint32 max_display_length() { return field_length; }
|
uint32 max_display_length() { return field_length; }
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
Item_result result_type () const { return INT_RESULT; }
|
|
||||||
int reset(void) {
|
int reset(void) {
|
||||||
bzero(ptr, bytes_in_rec);
|
bzero(ptr, bytes_in_rec);
|
||||||
if (bit_ptr && (bit_len > 0)) // reset odd bits among null bits
|
if (bit_ptr && (bit_len > 0)) // reset odd bits among null bits
|
||||||
|
267
sql/item.cc
267
sql/item.cc
@@ -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),
|
||||||
@@ -2348,7 +2348,7 @@ void my_coll_agg_error(Item** args, uint count, const char *fname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_or_sum::agg_item_collations(DTCollation &c, const char *fname,
|
bool Type_std_attributes::agg_item_collations(DTCollation &c, const char *fname,
|
||||||
Item **av, uint count,
|
Item **av, uint count,
|
||||||
uint flags, int item_sep)
|
uint flags, int item_sep)
|
||||||
{
|
{
|
||||||
@@ -2395,7 +2395,7 @@ bool Item_func_or_sum::agg_item_collations(DTCollation &c, const char *fname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
|
bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
Item **args, uint nargs,
|
Item **args, uint nargs,
|
||||||
uint flags, int item_sep)
|
uint flags, int item_sep)
|
||||||
@@ -3780,7 +3780,7 @@ bool Item_param::set_from_item(THD *thd, Item *item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct st_value tmp;
|
struct st_value tmp;
|
||||||
if (!item->store(&tmp, 0))
|
if (!item->save_in_value(&tmp))
|
||||||
{
|
{
|
||||||
unsigned_flag= item->unsigned_flag;
|
unsigned_flag= item->unsigned_flag;
|
||||||
switch (item->cmp_type()) {
|
switch (item->cmp_type()) {
|
||||||
@@ -5834,24 +5834,6 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Type_handler *Item_field::real_type_handler() const
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Item_field::field_type ask Field_type() but sometimes field return
|
|
||||||
a different type, like for enum/set, so we need to ask real type.
|
|
||||||
*/
|
|
||||||
if (field->is_created_from_null_item)
|
|
||||||
return &type_handler_null;
|
|
||||||
/* work around about varchar type field detection */
|
|
||||||
enum_field_types type= field->real_type();
|
|
||||||
// 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;
|
|
||||||
return Type_handler::get_handler_by_real_type(type);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@brief
|
@brief
|
||||||
Mark virtual columns as used in a partitioning expression
|
Mark virtual columns as used in a partitioning expression
|
||||||
@@ -6216,178 +6198,6 @@ bool Item::eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a field to hold a string value from an item.
|
|
||||||
|
|
||||||
If too_big_for_varchar() create a blob @n
|
|
||||||
If max_length > 0 create a varchar @n
|
|
||||||
If max_length == 0 create a CHAR(0)
|
|
||||||
|
|
||||||
@param table Table for which the field is created
|
|
||||||
*/
|
|
||||||
|
|
||||||
Field *Item::make_string_field(TABLE *table)
|
|
||||||
{
|
|
||||||
Field *field;
|
|
||||||
MEM_ROOT *mem_root= table->in_use->mem_root;
|
|
||||||
DBUG_ASSERT(collation.collation);
|
|
||||||
/*
|
|
||||||
Note: the following check is repeated in
|
|
||||||
subquery_types_allow_materialization():
|
|
||||||
*/
|
|
||||||
if (too_big_for_varchar())
|
|
||||||
field= new (mem_root)
|
|
||||||
Field_blob(max_length, maybe_null, &name,
|
|
||||||
collation.collation, TRUE);
|
|
||||||
/* Item_type_holder holds the exact type, do not change it */
|
|
||||||
else if (max_length > 0 &&
|
|
||||||
(type() != Item::TYPE_HOLDER || field_type() != MYSQL_TYPE_STRING))
|
|
||||||
field= new (mem_root)
|
|
||||||
Field_varstring(max_length, maybe_null, &name, table->s,
|
|
||||||
collation.collation);
|
|
||||||
else
|
|
||||||
field= new (mem_root)
|
|
||||||
Field_string(max_length, maybe_null, &name, collation.collation);
|
|
||||||
if (field)
|
|
||||||
field->init(table);
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a field based on field_type of argument.
|
|
||||||
|
|
||||||
This is used to create a field for
|
|
||||||
- IFNULL(x,something)
|
|
||||||
- time functions
|
|
||||||
- prepared statement placeholders
|
|
||||||
- SP variables with data type references: DECLARE a t1.a%TYPE;
|
|
||||||
|
|
||||||
@retval
|
|
||||||
NULL error
|
|
||||||
@retval
|
|
||||||
\# Created field
|
|
||||||
*/
|
|
||||||
|
|
||||||
Field *Item::tmp_table_field_from_field_type(TABLE *table,
|
|
||||||
bool fixed_length,
|
|
||||||
bool set_blob_packlength)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
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;
|
|
||||||
|
|
||||||
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 */
|
|
||||||
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 */
|
|
||||||
}
|
|
||||||
if (field)
|
|
||||||
field->init(table);
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void Item_field::make_field(THD *thd, Send_field *tmp_field)
|
void Item_field::make_field(THD *thd, Send_field *tmp_field)
|
||||||
{
|
{
|
||||||
@@ -8945,7 +8755,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
|
|||||||
real_arg= arg->real_item();
|
real_arg= arg->real_item();
|
||||||
if (real_arg->type() != FIELD_ITEM)
|
if (real_arg->type() != FIELD_ITEM)
|
||||||
{
|
{
|
||||||
my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), arg->name);
|
my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), arg->name.str);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9715,9 +9525,8 @@ Item_cache_temporal::Item_cache_temporal(THD *thd,
|
|||||||
enum_field_types field_type_arg):
|
enum_field_types field_type_arg):
|
||||||
Item_cache_int(thd, field_type_arg)
|
Item_cache_int(thd, field_type_arg)
|
||||||
{
|
{
|
||||||
if (mysql_type_to_time_type(Item_cache_temporal::field_type()) ==
|
if (mysql_timestamp_type() == MYSQL_TIMESTAMP_ERROR)
|
||||||
MYSQL_TIMESTAMP_ERROR)
|
set_handler(&type_handler_datetime2);
|
||||||
set_handler_by_field_type(MYSQL_TYPE_DATETIME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -9825,7 +9634,7 @@ bool Item_cache_temporal::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unpack_time(value, ltime);
|
unpack_time(value, ltime);
|
||||||
ltime->time_type= mysql_type_to_time_type(field_type());
|
ltime->time_type= mysql_timestamp_type();
|
||||||
if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
|
if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
|
||||||
{
|
{
|
||||||
ltime->hour+= (ltime->month*32+ltime->day)*24;
|
ltime->hour+= (ltime->month*32+ltime->day)*24;
|
||||||
@@ -10267,7 +10076,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
|||||||
if (aggregate_for_result(item_type_handler))
|
if (aggregate_for_result(item_type_handler))
|
||||||
{
|
{
|
||||||
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
|
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
|
||||||
Item_type_holder::type_handler()->name().ptr(),
|
Item_type_holder::real_type_handler()->name().ptr(),
|
||||||
item_type_handler->name().ptr(),
|
item_type_handler->name().ptr(),
|
||||||
"UNION");
|
"UNION");
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
@@ -10375,6 +10184,14 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
|||||||
};
|
};
|
||||||
maybe_null|= item->maybe_null;
|
maybe_null|= item->maybe_null;
|
||||||
get_full_info(item);
|
get_full_info(item);
|
||||||
|
/*
|
||||||
|
Adjust data type for union, e.g.:
|
||||||
|
- convert type_handler_null to type_handler_string
|
||||||
|
- convert type_handler_olddecimal to type_handler_newdecimal
|
||||||
|
- adjust varchar/blob according to max_length
|
||||||
|
*/
|
||||||
|
set_handler(Item_type_holder::
|
||||||
|
real_type_handler()->type_handler_for_union(this));
|
||||||
|
|
||||||
/* Remember decimal integer part to be used in DECIMAL_RESULT handleng */
|
/* Remember decimal integer part to be used in DECIMAL_RESULT handleng */
|
||||||
prev_decimal_int_part= decimal_int_part();
|
prev_decimal_int_part= decimal_int_part();
|
||||||
@@ -10385,56 +10202,6 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Make temporary table field according collected information about type
|
|
||||||
of UNION result.
|
|
||||||
|
|
||||||
@param table temporary table for which we create fields
|
|
||||||
|
|
||||||
@return
|
|
||||||
created field
|
|
||||||
*/
|
|
||||||
|
|
||||||
Field *Item_type_holder::make_field_by_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;
|
|
||||||
|
|
||||||
switch (Item_type_holder::real_type_handler()->real_field_type()) {
|
|
||||||
case MYSQL_TYPE_ENUM:
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(enum_set_typelib);
|
|
||||||
field= new Field_enum((uchar *) 0, max_length, null_ptr, 0,
|
|
||||||
Field::NONE, &name,
|
|
||||||
get_enum_pack_length(enum_set_typelib->count),
|
|
||||||
enum_set_typelib, collation.collation);
|
|
||||||
if (field)
|
|
||||||
field->init(table);
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
case MYSQL_TYPE_SET:
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(enum_set_typelib);
|
|
||||||
field= new Field_set((uchar *) 0, max_length, null_ptr, 0,
|
|
||||||
Field::NONE, &name,
|
|
||||||
get_set_pack_length(enum_set_typelib->count),
|
|
||||||
enum_set_typelib, collation.collation);
|
|
||||||
if (field)
|
|
||||||
field->init(table);
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
case MYSQL_TYPE_NULL:
|
|
||||||
return make_string_field(table);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return tmp_table_field_from_field_type(table, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get full information from Item about enum/set fields to be able to create
|
Get full information from Item about enum/set fields to be able to create
|
||||||
them later.
|
them later.
|
||||||
|
216
sql/item.h
216
sql/item.h
@@ -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 &);
|
||||||
/**
|
/**
|
||||||
@@ -536,10 +536,22 @@ 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);
|
/**
|
||||||
Field *tmp_table_field_from_field_type(TABLE *table,
|
Create a field based on field_type of argument.
|
||||||
bool fixed_length,
|
This is used to create a field for
|
||||||
bool set_blob_packlength);
|
- IFNULL(x,something)
|
||||||
|
- time functions
|
||||||
|
- prepared statement placeholders
|
||||||
|
- SP variables with data type references: DECLARE a TYPE OF t1.a;
|
||||||
|
@retval NULL error
|
||||||
|
@retval !NULL on success
|
||||||
|
*/
|
||||||
|
Field *tmp_table_field_from_field_type(TABLE *table)
|
||||||
|
{
|
||||||
|
const Type_handler *h= type_handler()->type_handler_for_tmp_table(this);
|
||||||
|
return h->make_and_init_table_field(&name, Record_addr(maybe_null),
|
||||||
|
*this, table);
|
||||||
|
}
|
||||||
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);
|
||||||
@@ -664,54 +676,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual inline void quick_fix_field() { fixed= 1; }
|
virtual inline void quick_fix_field() { fixed= 1; }
|
||||||
|
|
||||||
bool store(struct st_value *value, ulonglong fuzzydate)
|
bool save_in_value(struct st_value *value)
|
||||||
{
|
{
|
||||||
switch (cmp_type()) {
|
return type_handler()->Item_save_in_value(this, value);
|
||||||
case INT_RESULT:
|
|
||||||
{
|
|
||||||
value->m_type= unsigned_flag ? DYN_COL_UINT : DYN_COL_INT;
|
|
||||||
value->value.m_longlong= val_int();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case REAL_RESULT:
|
|
||||||
{
|
|
||||||
value->m_type= DYN_COL_DOUBLE;
|
|
||||||
value->value.m_double= val_real();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DECIMAL_RESULT:
|
|
||||||
{
|
|
||||||
value->m_type= DYN_COL_DECIMAL;
|
|
||||||
my_decimal *dec= val_decimal(&value->m_decimal);
|
|
||||||
if (dec != &value->m_decimal && !null_value)
|
|
||||||
my_decimal2decimal(dec, &value->m_decimal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case STRING_RESULT:
|
|
||||||
{
|
|
||||||
value->m_type= DYN_COL_STRING;
|
|
||||||
String *str= val_str(&value->m_string);
|
|
||||||
if (str != &value->m_string && !null_value)
|
|
||||||
value->m_string.set(str->ptr(), str->length(), str->charset());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TIME_RESULT:
|
|
||||||
{
|
|
||||||
value->m_type= DYN_COL_DATETIME;
|
|
||||||
get_date(&value->value.m_time, fuzzydate);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ROW_RESULT:
|
|
||||||
DBUG_ASSERT(false);
|
|
||||||
null_value= true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (null_value)
|
|
||||||
{
|
|
||||||
value->m_type= DYN_COL_NULL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function returns 1 on overflow and -1 on fatal errors */
|
/* Function returns 1 on overflow and -1 on fatal errors */
|
||||||
@@ -1150,10 +1117,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint decimal_scale() const
|
uint decimal_scale() const
|
||||||
{
|
{
|
||||||
return decimals < NOT_FIXED_DEC ? decimals :
|
return type_handler()->Item_decimal_scale(this);
|
||||||
is_temporal_type_with_time(field_type()) ?
|
|
||||||
TIME_SECOND_PART_DIGITS :
|
|
||||||
MY_MIN(max_length, DECIMAL_MAX_SCALE);
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Returns how many digits a divisor adds into a division result.
|
Returns how many digits a divisor adds into a division result.
|
||||||
@@ -1174,10 +1138,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint divisor_precision_increment() const
|
uint divisor_precision_increment() const
|
||||||
{
|
{
|
||||||
return decimals < NOT_FIXED_DEC ? decimals :
|
return type_handler()->Item_divisor_precision_increment(this);
|
||||||
is_temporal_type_with_time(field_type()) ?
|
|
||||||
TIME_SECOND_PART_DIGITS :
|
|
||||||
decimals;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
TIME or DATETIME precision of the item: 0..6
|
TIME or DATETIME precision of the item: 0..6
|
||||||
@@ -1745,6 +1706,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
|
||||||
@@ -2263,7 +2226,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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -2639,19 +2602,29 @@ 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
|
||||||
|
{
|
||||||
|
const Type_handler *handler= field->type_handler();
|
||||||
|
return handler->type_handler_for_item_field();
|
||||||
|
}
|
||||||
enum Item_result result_type () const
|
enum Item_result result_type () const
|
||||||
{
|
{
|
||||||
return field->result_type();
|
return field->result_type();
|
||||||
}
|
}
|
||||||
const Type_handler *cast_to_int_type_handler() const
|
const Type_handler *cast_to_int_type_handler() const
|
||||||
{
|
{
|
||||||
return field->cast_to_int_type_handler();
|
return field->type_handler()->cast_to_int_type_handler();
|
||||||
}
|
}
|
||||||
enum_field_types field_type() const
|
enum_field_types field_type() const
|
||||||
{
|
{
|
||||||
return field->type();
|
return field->type();
|
||||||
}
|
}
|
||||||
const Type_handler *real_type_handler() const;
|
const Type_handler *real_type_handler() const
|
||||||
|
{
|
||||||
|
if (field->is_created_from_null_item)
|
||||||
|
return &type_handler_null;
|
||||||
|
return field->type_handler();
|
||||||
|
}
|
||||||
enum_monotonicity_info get_monotonicity_info() const
|
enum_monotonicity_info get_monotonicity_info() const
|
||||||
{
|
{
|
||||||
return MONOTONIC_STRICT_INCREASING;
|
return MONOTONIC_STRICT_INCREASING;
|
||||||
@@ -3187,6 +3160,17 @@ public:
|
|||||||
enum Type type() const { return INT_ITEM; }
|
enum Type type() const { return INT_ITEM; }
|
||||||
enum Item_result result_type () const { return INT_RESULT; }
|
enum Item_result result_type () const { return INT_RESULT; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
||||||
|
const Type_handler *type_handler() const
|
||||||
|
{
|
||||||
|
// The same condition is repeated in Item::create_tmp_field()
|
||||||
|
if (max_length > MY_INT32_NUM_DECIMAL_DIGITS - 2)
|
||||||
|
return &type_handler_longlong;
|
||||||
|
return &type_handler_long;
|
||||||
|
}
|
||||||
|
Field *create_tmp_field(bool group, TABLE *table)
|
||||||
|
{ return tmp_table_field_from_field_type(table); }
|
||||||
|
Field *create_field_for_create_select(TABLE *table)
|
||||||
|
{ return tmp_table_field_from_field_type(table); }
|
||||||
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
|
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
|
||||||
double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
|
double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
@@ -3645,7 +3629,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.
|
||||||
@@ -3653,7 +3644,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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -3690,6 +3681,10 @@ public:
|
|||||||
unsigned_flag=1;
|
unsigned_flag=1;
|
||||||
}
|
}
|
||||||
enum_field_types field_type() const { return int_field_type; }
|
enum_field_types field_type() const { return int_field_type; }
|
||||||
|
const Type_handler *type_handler() const
|
||||||
|
{
|
||||||
|
return Type_handler::get_handler_by_field_type(int_field_type);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -4068,80 +4063,31 @@ class Item_func_or_sum: public Item_result_field,
|
|||||||
public Item_args,
|
public Item_args,
|
||||||
public Used_tables_and_const_cache
|
public Used_tables_and_const_cache
|
||||||
{
|
{
|
||||||
bool agg_item_collations(DTCollation &c, const char *name,
|
|
||||||
Item **items, uint nitems,
|
|
||||||
uint flags, int item_sep);
|
|
||||||
bool agg_item_set_converter(const DTCollation &coll, const char *fname,
|
|
||||||
Item **args, uint nargs,
|
|
||||||
uint flags, int item_sep);
|
|
||||||
protected:
|
protected:
|
||||||
/*
|
|
||||||
Collect arguments' character sets together.
|
|
||||||
We allow to apply automatic character set conversion in some cases.
|
|
||||||
The conditions when conversion is possible are:
|
|
||||||
- arguments A and B have different charsets
|
|
||||||
- A wins according to coercibility rules
|
|
||||||
(i.e. a column is stronger than a string constant,
|
|
||||||
an explicit COLLATE clause is stronger than a column)
|
|
||||||
- character set of A is either superset for character set of B,
|
|
||||||
or B is a string constant which can be converted into the
|
|
||||||
character set of A without data loss.
|
|
||||||
|
|
||||||
If all of the above is true, then it's possible to convert
|
|
||||||
B into the character set of A, and then compare according
|
|
||||||
to the collation of A.
|
|
||||||
|
|
||||||
For functions with more than two arguments:
|
|
||||||
|
|
||||||
collect(A,B,C) ::= collect(collect(A,B),C)
|
|
||||||
|
|
||||||
Since this function calls THD::change_item_tree() on the passed Item **
|
|
||||||
pointers, it is necessary to pass the original Item **'s, not copies.
|
|
||||||
Otherwise their values will not be properly restored (see BUG#20769).
|
|
||||||
If the items are not consecutive (eg. args[2] and args[5]), use the
|
|
||||||
item_sep argument, ie.
|
|
||||||
|
|
||||||
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
|
|
||||||
*/
|
|
||||||
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
|
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
|
||||||
uint flags, int item_sep)
|
uint flags, int item_sep)
|
||||||
{
|
{
|
||||||
if (agg_item_collations(c, func_name(), items, nitems, flags, item_sep))
|
return Type_std_attributes::agg_arg_charsets(c, func_name(),
|
||||||
return true;
|
items, nitems,
|
||||||
|
|
||||||
return agg_item_set_converter(c, func_name(), items, nitems,
|
|
||||||
flags, item_sep);
|
flags, item_sep);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
Aggregate arguments for string result, e.g: CONCAT(a,b)
|
|
||||||
- convert to @@character_set_connection if all arguments are numbers
|
|
||||||
- allow DERIVATION_NONE
|
|
||||||
*/
|
|
||||||
bool agg_arg_charsets_for_string_result(DTCollation &c,
|
bool agg_arg_charsets_for_string_result(DTCollation &c,
|
||||||
Item **items, uint nitems,
|
Item **items, uint nitems,
|
||||||
int item_sep= 1)
|
int item_sep= 1)
|
||||||
{
|
{
|
||||||
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
return Type_std_attributes::
|
||||||
MY_COLL_ALLOW_COERCIBLE_CONV |
|
agg_arg_charsets_for_string_result(c, func_name(),
|
||||||
MY_COLL_ALLOW_NUMERIC_CONV;
|
items, nitems, item_sep);
|
||||||
return agg_arg_charsets(c, items, nitems, flags, item_sep);
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
Aggregate arguments for string result, when some comparison
|
|
||||||
is involved internally, e.g: REPLACE(a,b,c)
|
|
||||||
- convert to @@character_set_connection if all arguments are numbers
|
|
||||||
- disallow DERIVATION_NONE
|
|
||||||
*/
|
|
||||||
bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
|
bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
|
||||||
Item **items,
|
Item **items,
|
||||||
uint nitems,
|
uint nitems,
|
||||||
int item_sep= 1)
|
int item_sep= 1)
|
||||||
{
|
{
|
||||||
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
return Type_std_attributes::
|
||||||
MY_COLL_ALLOW_COERCIBLE_CONV |
|
agg_arg_charsets_for_string_result_with_comparison(c, func_name(),
|
||||||
MY_COLL_ALLOW_NUMERIC_CONV |
|
items, nitems,
|
||||||
MY_COLL_DISALLOW_NONE;
|
item_sep);
|
||||||
return agg_arg_charsets(c, items, nitems, flags, item_sep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4153,13 +4099,10 @@ protected:
|
|||||||
Item **items, uint nitems,
|
Item **items, uint nitems,
|
||||||
int item_sep= 1)
|
int item_sep= 1)
|
||||||
{
|
{
|
||||||
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
return Type_std_attributes::
|
||||||
MY_COLL_ALLOW_COERCIBLE_CONV |
|
agg_arg_charsets_for_comparison(c, func_name(), items, nitems, item_sep);
|
||||||
MY_COLL_DISALLOW_NONE;
|
|
||||||
return agg_arg_charsets(c, items, nitems, flags, item_sep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// This method is used by Arg_comparator
|
// This method is used by Arg_comparator
|
||||||
bool agg_arg_charsets_for_comparison(CHARSET_INFO **cs, Item **a, Item **b)
|
bool agg_arg_charsets_for_comparison(CHARSET_INFO **cs, Item **a, Item **b)
|
||||||
@@ -5879,11 +5822,12 @@ public:
|
|||||||
Item_type_holder(THD*, Item*);
|
Item_type_holder(THD*, Item*);
|
||||||
|
|
||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{ return Type_handler_hybrid_field_type::type_handler(); }
|
{
|
||||||
|
const Type_handler *handler= Type_handler_hybrid_field_type::type_handler();
|
||||||
|
return handler->type_handler_for_item_field();
|
||||||
|
}
|
||||||
enum_field_types field_type() const
|
enum_field_types field_type() const
|
||||||
{ return Type_handler_hybrid_field_type::field_type(); }
|
{ return Type_handler_hybrid_field_type::field_type(); }
|
||||||
enum_field_types real_field_type() const
|
|
||||||
{ return Type_handler_hybrid_field_type::real_field_type(); }
|
|
||||||
enum Item_result result_type () const
|
enum Item_result result_type () const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -5902,16 +5846,22 @@ public:
|
|||||||
}
|
}
|
||||||
const Type_handler *real_type_handler() const
|
const Type_handler *real_type_handler() const
|
||||||
{
|
{
|
||||||
return Item_type_holder::type_handler();
|
return Type_handler_hybrid_field_type::type_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Type type() const { return TYPE_HOLDER; }
|
enum Type type() const { return TYPE_HOLDER; }
|
||||||
|
TYPELIB *get_typelib() const { return enum_set_typelib; }
|
||||||
double val_real();
|
double val_real();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
String *val_str(String*);
|
String *val_str(String*);
|
||||||
bool join_types(THD *thd, Item *);
|
bool join_types(THD *thd, Item *);
|
||||||
Field *make_field_by_type(TABLE *table);
|
Field *create_tmp_field(bool group, TABLE *table)
|
||||||
|
{
|
||||||
|
return Item_type_holder::real_type_handler()->
|
||||||
|
make_and_init_table_field(&name, Record_addr(maybe_null),
|
||||||
|
*this, table);
|
||||||
|
}
|
||||||
Field::geometry_type get_geometry_type() const { return geometry_type; };
|
Field::geometry_type get_geometry_type() const { return geometry_type; };
|
||||||
Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||||
};
|
};
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
105
sql/item_func.cc
105
sql/item_func.cc
@@ -592,99 +592,6 @@ void Item_udf_func::fix_num_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set max_length/decimals of function if function is fixed point and
|
|
||||||
result length/precision depends on argument ones.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Item_func::count_decimal_length(Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
int max_int_part= 0;
|
|
||||||
decimals= 0;
|
|
||||||
unsigned_flag= 1;
|
|
||||||
for (uint i=0 ; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
set_if_bigger(decimals, item[i]->decimals);
|
|
||||||
set_if_bigger(max_int_part, item[i]->decimal_int_part());
|
|
||||||
set_if_smaller(unsigned_flag, item[i]->unsigned_flag);
|
|
||||||
}
|
|
||||||
int precision= MY_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
|
||||||
fix_char_length(my_decimal_precision_to_length_no_truncation(precision,
|
|
||||||
decimals,
|
|
||||||
unsigned_flag));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set max_length of if it is maximum length of its arguments.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Item_func::count_only_length(Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
uint32 char_length= 0;
|
|
||||||
unsigned_flag= 0;
|
|
||||||
for (uint i= 0; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
set_if_bigger(char_length, item[i]->max_char_length());
|
|
||||||
set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
|
|
||||||
}
|
|
||||||
fix_char_length(char_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set max_length/decimals of function if function is floating point and
|
|
||||||
result length/precision depends on argument ones.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Item_func::count_real_length(Item **items, uint nitems)
|
|
||||||
{
|
|
||||||
uint32 length= 0;
|
|
||||||
decimals= 0;
|
|
||||||
max_length= 0;
|
|
||||||
unsigned_flag= false;
|
|
||||||
for (uint i=0 ; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
if (decimals < FLOATING_POINT_DECIMALS)
|
|
||||||
{
|
|
||||||
set_if_bigger(decimals, items[i]->decimals);
|
|
||||||
/* Will be ignored if items[i]->decimals >= FLOATING_POINT_DECIMALS */
|
|
||||||
set_if_bigger(length, (items[i]->max_length - items[i]->decimals));
|
|
||||||
}
|
|
||||||
set_if_bigger(max_length, items[i]->max_length);
|
|
||||||
}
|
|
||||||
if (decimals < FLOATING_POINT_DECIMALS)
|
|
||||||
{
|
|
||||||
max_length= length;
|
|
||||||
length+= decimals;
|
|
||||||
if (length < max_length) // If previous operation gave overflow
|
|
||||||
max_length= UINT_MAX32;
|
|
||||||
else
|
|
||||||
max_length= length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Calculate max_length and decimals for string functions.
|
|
||||||
|
|
||||||
@param field_type Field type.
|
|
||||||
@param items Argument array.
|
|
||||||
@param nitems Number of arguments.
|
|
||||||
|
|
||||||
@retval False on success, true on error.
|
|
||||||
*/
|
|
||||||
bool Item_func::count_string_length(Item **items, uint nitems)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(!is_temporal_type(field_type()));
|
|
||||||
if (agg_arg_charsets_for_string_result(collation, items, nitems, 1))
|
|
||||||
return true;
|
|
||||||
count_only_length(items, nitems);
|
|
||||||
decimals= max_length ? NOT_FIXED_DEC : 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Item_func::signal_divide_by_null()
|
void Item_func::signal_divide_by_null()
|
||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
@@ -890,7 +797,7 @@ String *Item_func_hybrid_field_type::val_str_from_date_op(String *str)
|
|||||||
if (date_op_with_null_check(<ime) ||
|
if (date_op_with_null_check(<ime) ||
|
||||||
(null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
|
(null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
|
||||||
return (String *) 0;
|
return (String *) 0;
|
||||||
ltime.time_type= mysql_type_to_time_type(field_type());
|
ltime.time_type= mysql_timestamp_type();
|
||||||
str->length(my_TIME_to_str(<ime, const_cast<char*>(str->ptr()), decimals));
|
str->length(my_TIME_to_str(<ime, const_cast<char*>(str->ptr()), decimals));
|
||||||
str->set_charset(&my_charset_bin);
|
str->set_charset(&my_charset_bin);
|
||||||
DBUG_ASSERT(!null_value);
|
DBUG_ASSERT(!null_value);
|
||||||
@@ -902,7 +809,7 @@ double Item_func_hybrid_field_type::val_real_from_date_op()
|
|||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
if (date_op_with_null_check(<ime))
|
if (date_op_with_null_check(<ime))
|
||||||
return 0;
|
return 0;
|
||||||
ltime.time_type= mysql_type_to_time_type(field_type());
|
ltime.time_type= mysql_timestamp_type();
|
||||||
return TIME_to_double(<ime);
|
return TIME_to_double(<ime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -911,7 +818,7 @@ longlong Item_func_hybrid_field_type::val_int_from_date_op()
|
|||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
if (date_op_with_null_check(<ime))
|
if (date_op_with_null_check(<ime))
|
||||||
return 0;
|
return 0;
|
||||||
ltime.time_type= mysql_type_to_time_type(field_type());
|
ltime.time_type= mysql_timestamp_type();
|
||||||
return TIME_to_ulonglong(<ime);
|
return TIME_to_ulonglong(<ime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,7 +831,7 @@ Item_func_hybrid_field_type::val_decimal_from_date_op(my_decimal *dec)
|
|||||||
my_decimal_set_zero(dec);
|
my_decimal_set_zero(dec);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ltime.time_type= mysql_type_to_time_type(field_type());
|
ltime.time_type= mysql_timestamp_type();
|
||||||
return date2my_decimal(<ime, dec);
|
return date2my_decimal(<ime, dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2255,8 +2162,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;
|
||||||
|
@@ -42,44 +42,8 @@ protected:
|
|||||||
uint allowed_arg_cols;
|
uint allowed_arg_cols;
|
||||||
String *val_str_from_val_str_ascii(String *str, String *str2);
|
String *val_str_from_val_str_ascii(String *str, String *str2);
|
||||||
|
|
||||||
void count_only_length(Item **item, uint nitems);
|
|
||||||
void count_real_length(Item **item, uint nitems);
|
|
||||||
void count_decimal_length(Item **item, uint nitems);
|
|
||||||
bool count_string_length(Item **item, uint nitems);
|
|
||||||
uint count_max_decimals(Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
uint res= 0;
|
|
||||||
for (uint i= 0; i < nitems; i++)
|
|
||||||
set_if_bigger(res, item[i]->decimals);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
virtual bool check_allowed_arg_cols(uint argno);
|
virtual bool check_allowed_arg_cols(uint argno);
|
||||||
public:
|
public:
|
||||||
void aggregate_attributes_int(Item **items, uint nitems)
|
|
||||||
{
|
|
||||||
collation.set_numeric();
|
|
||||||
count_only_length(items, nitems);
|
|
||||||
decimals= 0;
|
|
||||||
}
|
|
||||||
void aggregate_attributes_real(Item **items, uint nitems)
|
|
||||||
{
|
|
||||||
collation.set_numeric();
|
|
||||||
count_real_length(items, nitems);
|
|
||||||
}
|
|
||||||
void aggregate_attributes_decimal(Item **items, uint nitems)
|
|
||||||
{
|
|
||||||
collation.set_numeric();
|
|
||||||
count_decimal_length(items, nitems);
|
|
||||||
}
|
|
||||||
bool aggregate_attributes_string(Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
return count_string_length(item, nitems);
|
|
||||||
}
|
|
||||||
void aggregate_attributes_temporal(uint int_part_length,
|
|
||||||
Item **item, uint nitems)
|
|
||||||
{
|
|
||||||
fix_attributes_temporal(int_part_length, count_max_decimals(item, nitems));
|
|
||||||
}
|
|
||||||
|
|
||||||
table_map not_null_tables_cache;
|
table_map not_null_tables_cache;
|
||||||
|
|
||||||
@@ -208,7 +172,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 +2219,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 +2260,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 +2621,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);
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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); }
|
||||||
};
|
};
|
||||||
|
@@ -1074,7 +1074,7 @@ public:
|
|||||||
}
|
}
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
{
|
{
|
||||||
collation.set(default_charset());
|
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
|
||||||
decimals=0;
|
decimals=0;
|
||||||
fix_char_length(args[0]->max_length * 2);
|
fix_char_length(args[0]->max_length * 2);
|
||||||
m_arg0_type_handler= args[0]->type_handler();
|
m_arg0_type_handler= args[0]->type_handler();
|
||||||
|
@@ -1202,51 +1202,15 @@ void Item_sum_hybrid::setup_hybrid(THD *thd, Item *item, Item *value_arg)
|
|||||||
|
|
||||||
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table)
|
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table)
|
||||||
{
|
{
|
||||||
Field *field;
|
|
||||||
MEM_ROOT *mem_root;
|
|
||||||
|
|
||||||
if (args[0]->type() == Item::FIELD_ITEM)
|
if (args[0]->type() == Item::FIELD_ITEM)
|
||||||
{
|
{
|
||||||
field= ((Item_field*) args[0])->field;
|
Field *field= ((Item_field*) args[0])->field;
|
||||||
if ((field= create_tmp_field_from_field(table->in_use, field, &name,
|
if ((field= create_tmp_field_from_field(table->in_use, field, &name,
|
||||||
table, NULL)))
|
table, NULL)))
|
||||||
field->flags&= ~NOT_NULL_FLAG;
|
field->flags&= ~NOT_NULL_FLAG;
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
DATE/TIME fields have STRING_RESULT result types.
|
|
||||||
In order to preserve field type, it's needed to handle DATE/TIME
|
|
||||||
fields creations separately.
|
|
||||||
*/
|
|
||||||
mem_root= table->in_use->mem_root;
|
|
||||||
switch (args[0]->field_type()) {
|
|
||||||
case MYSQL_TYPE_DATE:
|
|
||||||
{
|
|
||||||
field= new (mem_root)
|
|
||||||
Field_newdate(0, maybe_null ? (uchar*)"" : 0, 0, Field::NONE,
|
|
||||||
&name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MYSQL_TYPE_TIME:
|
|
||||||
{
|
|
||||||
field= new_Field_time(mem_root, 0, maybe_null ? (uchar*)"" : 0, 0,
|
|
||||||
Field::NONE, &name, decimals);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
|
||||||
case MYSQL_TYPE_DATETIME:
|
|
||||||
{
|
|
||||||
field= new_Field_datetime(mem_root, 0, maybe_null ? (uchar*)"" : 0, 0,
|
|
||||||
Field::NONE, &name, decimals);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return Item_sum::create_tmp_field(group, table);
|
return Item_sum::create_tmp_field(group, table);
|
||||||
}
|
|
||||||
if (field)
|
|
||||||
field->init(table);
|
|
||||||
return field;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1669,8 +1633,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 +1641,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3362,24 +3318,6 @@ void Item_func_group_concat::cleanup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Field *Item_func_group_concat::make_string_field(TABLE *table_arg)
|
|
||||||
{
|
|
||||||
Field *field;
|
|
||||||
DBUG_ASSERT(collation.collation);
|
|
||||||
|
|
||||||
if (too_big_for_varchar())
|
|
||||||
field= new Field_blob(max_length,
|
|
||||||
maybe_null, &name, collation.collation, TRUE);
|
|
||||||
else
|
|
||||||
field= new Field_varstring(max_length,
|
|
||||||
maybe_null, &name, table_arg->s, collation.collation);
|
|
||||||
|
|
||||||
if (field)
|
|
||||||
field->init(table_arg);
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Item *Item_func_group_concat::copy_or_same(THD* thd)
|
Item *Item_func_group_concat::copy_or_same(THD* thd)
|
||||||
{
|
{
|
||||||
return new (thd->mem_root) Item_func_group_concat(thd, this);
|
return new (thd->mem_root) Item_func_group_concat(thd, this);
|
||||||
|
@@ -1636,9 +1636,6 @@ class Item_func_group_concat : public Item_sum
|
|||||||
friend int dump_leaf_key(void* key_arg,
|
friend int dump_leaf_key(void* key_arg,
|
||||||
element_count count __attribute__((unused)),
|
element_count count __attribute__((unused)),
|
||||||
void* item_arg);
|
void* item_arg);
|
||||||
protected:
|
|
||||||
virtual Field *make_string_field(TABLE *table);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
||||||
bool is_distinct, List<Item> *is_select,
|
bool is_distinct, List<Item> *is_select,
|
||||||
|
@@ -1532,7 +1532,7 @@ String *Item_temporal_hybrid_func::val_str_ascii(String *str)
|
|||||||
/* Check that the returned timestamp type matches to the function type */
|
/* Check that the returned timestamp type matches to the function type */
|
||||||
DBUG_ASSERT(field_type() == MYSQL_TYPE_STRING ||
|
DBUG_ASSERT(field_type() == MYSQL_TYPE_STRING ||
|
||||||
ltime.time_type == MYSQL_TIMESTAMP_NONE ||
|
ltime.time_type == MYSQL_TIMESTAMP_NONE ||
|
||||||
mysql_type_to_time_type(field_type()) == ltime.time_type);
|
ltime.time_type == mysql_timestamp_type());
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3226,7 +3226,7 @@ void Item_func_str_to_date::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cached_timestamp_type= mysql_type_to_time_type(field_type());
|
cached_timestamp_type= mysql_timestamp_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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); }
|
||||||
|
@@ -7926,7 +7926,9 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param,
|
|||||||
if (!(res= value->val_str(&tmp)))
|
if (!(res= value->val_str(&tmp)))
|
||||||
DBUG_RETURN(&null_element);
|
DBUG_RETURN(&null_element);
|
||||||
|
|
||||||
if (field->cmp_type() != STRING_RESULT)
|
if (field->cmp_type() != STRING_RESULT ||
|
||||||
|
field->type_handler() == &type_handler_enum ||
|
||||||
|
field->type_handler() == &type_handler_set)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -8022,6 +8024,19 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
err= value->save_in_field_no_warnings(field, 1);
|
err= value->save_in_field_no_warnings(field, 1);
|
||||||
|
if (err > 0)
|
||||||
|
{
|
||||||
|
if (field->type_handler() == &type_handler_enum ||
|
||||||
|
field->type_handler() == &type_handler_set)
|
||||||
|
{
|
||||||
|
if (type == EQ_FUNC || type == EQUAL_FUNC)
|
||||||
|
{
|
||||||
|
tree= new (alloc) SEL_ARG(field, 0, 0);
|
||||||
|
tree->type= SEL_ARG::IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (err == 2 && field->cmp_type() == STRING_RESULT)
|
if (err == 2 && field->cmp_type() == STRING_RESULT)
|
||||||
{
|
{
|
||||||
if (type == EQ_FUNC || type == EQUAL_FUNC)
|
if (type == EQ_FUNC || type == EQUAL_FUNC)
|
||||||
@@ -8033,8 +8048,7 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
|
|||||||
tree= NULL; /* Cannot infer anything */
|
tree= NULL; /* Cannot infer anything */
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (err > 0)
|
|
||||||
{
|
|
||||||
if (field->cmp_type() != value->result_type())
|
if (field->cmp_type() != value->result_type())
|
||||||
{
|
{
|
||||||
if ((type == EQ_FUNC || type == EQUAL_FUNC) &&
|
if ((type == EQ_FUNC || type == EQUAL_FUNC) &&
|
||||||
|
@@ -843,34 +843,9 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
|
|||||||
all_are_fields &= (outer->real_item()->type() == Item::FIELD_ITEM &&
|
all_are_fields &= (outer->real_item()->type() == Item::FIELD_ITEM &&
|
||||||
inner->real_item()->type() == Item::FIELD_ITEM);
|
inner->real_item()->type() == Item::FIELD_ITEM);
|
||||||
total_key_length += inner->max_length;
|
total_key_length += inner->max_length;
|
||||||
if (outer->cmp_type() != inner->cmp_type())
|
if (!inner->type_handler()->subquery_type_allows_materialization(inner,
|
||||||
|
outer))
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
switch (outer->cmp_type()) {
|
|
||||||
case STRING_RESULT:
|
|
||||||
if (!(outer->collation.collation == inner->collation.collation))
|
|
||||||
DBUG_RETURN(FALSE);
|
|
||||||
// Materialization does not work with BLOB columns
|
|
||||||
if (inner->field_type() == MYSQL_TYPE_BLOB ||
|
|
||||||
inner->field_type() == MYSQL_TYPE_GEOMETRY)
|
|
||||||
DBUG_RETURN(FALSE);
|
|
||||||
/*
|
|
||||||
Materialization also is unable to work when create_tmp_table() will
|
|
||||||
create a blob column because item->max_length is too big.
|
|
||||||
The following check is copied from Item::make_string_field():
|
|
||||||
*/
|
|
||||||
if (inner->too_big_for_varchar())
|
|
||||||
{
|
|
||||||
DBUG_RETURN(FALSE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TIME_RESULT:
|
|
||||||
if (mysql_type_to_time_type(outer->field_type()) !=
|
|
||||||
mysql_type_to_time_type(inner->field_type()))
|
|
||||||
DBUG_RETURN(FALSE);
|
|
||||||
default:
|
|
||||||
/* suitable for materialization */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1922,7 +1922,7 @@ void partition_info::report_part_expr_error(bool use_subpart_expr)
|
|||||||
!(type == HASH_PARTITION && list_of_fields))
|
!(type == HASH_PARTITION && list_of_fields))
|
||||||
{
|
{
|
||||||
my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0),
|
my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0),
|
||||||
item_field->name);
|
item_field->name.str);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2352,6 +2352,26 @@ bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item_string *THD::make_string_literal(const char *str, size_t length,
|
||||||
|
uint repertoire)
|
||||||
|
{
|
||||||
|
if (!charset_is_collation_connection &&
|
||||||
|
(repertoire != MY_REPERTOIRE_ASCII ||
|
||||||
|
!my_charset_is_ascii_based(variables.collation_connection)))
|
||||||
|
{
|
||||||
|
LEX_STRING to;
|
||||||
|
if (convert_string(&to, variables.collation_connection,
|
||||||
|
str, length, variables.character_set_client))
|
||||||
|
return NULL;
|
||||||
|
str= to.str;
|
||||||
|
length= to.length;
|
||||||
|
}
|
||||||
|
return new (mem_root) Item_string(this, str, length,
|
||||||
|
variables.collation_connection,
|
||||||
|
DERIVATION_COERCIBLE, repertoire);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update some cache variables when character set changes
|
Update some cache variables when character set changes
|
||||||
*/
|
*/
|
||||||
@@ -3114,7 +3134,7 @@ int select_export::send_data(List<Item> &items)
|
|||||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||||
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||||
"string", printable_buff,
|
"string", printable_buff,
|
||||||
item->name, static_cast<long>(row_count));
|
item->name.str, static_cast<long>(row_count));
|
||||||
}
|
}
|
||||||
else if (copier.source_end_pos() < res->ptr() + res->length())
|
else if (copier.source_end_pos() < res->ptr() + res->length())
|
||||||
{
|
{
|
||||||
|
@@ -3427,6 +3427,20 @@ public:
|
|||||||
|
|
||||||
bool convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs);
|
bool convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a string literal with optional client->connection conversion.
|
||||||
|
@param str - the string in the client character set
|
||||||
|
@param length - length of the string
|
||||||
|
@param repertoire - the repertoire of the string
|
||||||
|
*/
|
||||||
|
Item_string *make_string_literal(const char *str, size_t length,
|
||||||
|
uint repertoire);
|
||||||
|
Item_string *make_string_literal(const Lex_string_with_metadata_st &str)
|
||||||
|
{
|
||||||
|
uint repertoire= str.repertoire(variables.character_set_client);
|
||||||
|
return make_string_literal(str.str, str.length, repertoire);
|
||||||
|
}
|
||||||
|
|
||||||
void add_changed_table(TABLE *table);
|
void add_changed_table(TABLE *table);
|
||||||
void add_changed_table(const char *key, long key_length);
|
void add_changed_table(const char *key, long key_length);
|
||||||
CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
|
CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
|
||||||
|
@@ -749,6 +749,9 @@ public:
|
|||||||
|
|
||||||
/* UNION methods */
|
/* UNION methods */
|
||||||
bool prepare(THD *thd, select_result *result, ulong additional_options);
|
bool prepare(THD *thd, select_result *result, ulong additional_options);
|
||||||
|
bool prepare_join(THD *thd, SELECT_LEX *sl, select_result *result,
|
||||||
|
ulong additional_options,
|
||||||
|
bool is_union_select);
|
||||||
bool optimize();
|
bool optimize();
|
||||||
bool exec();
|
bool exec();
|
||||||
bool exec_recursive();
|
bool exec_recursive();
|
||||||
|
@@ -15880,22 +15880,9 @@ 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);
|
|
||||||
break;
|
|
||||||
case STRING_RESULT:
|
|
||||||
DBUG_ASSERT(collation.collation);
|
|
||||||
/*
|
|
||||||
GEOMETRY fields have STRING_RESULT result type.
|
|
||||||
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);
|
|
||||||
else
|
|
||||||
new_field= make_string_field(table);
|
|
||||||
new_field->set_derivation(collation.derivation, collation.repertoire);
|
|
||||||
break;
|
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
new_field= Field_new_decimal::create_from_item(mem_root, this);
|
case STRING_RESULT:
|
||||||
|
new_field= tmp_table_field_from_field_type(table);
|
||||||
break;
|
break;
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
// This case should never be choosen
|
// This case should never be choosen
|
||||||
@@ -15981,7 +15968,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -16032,6 +16019,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case Item::TYPE_HOLDER:
|
||||||
case Item::SUM_FUNC_ITEM:
|
case Item::SUM_FUNC_ITEM:
|
||||||
{
|
{
|
||||||
result= item->create_tmp_field(group, table);
|
result= item->create_tmp_field(group, table);
|
||||||
@@ -16161,11 +16149,6 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
return create_tmp_field_from_item(thd, item, table,
|
return create_tmp_field_from_item(thd, item, table,
|
||||||
(make_copy_field ? 0 : copy_func),
|
(make_copy_field ? 0 : copy_func),
|
||||||
modify_item);
|
modify_item);
|
||||||
case Item::TYPE_HOLDER:
|
|
||||||
result= ((Item_type_holder *)item)->make_field_by_type(table);
|
|
||||||
result->set_derivation(item->collation.derivation,
|
|
||||||
item->collation.repertoire);
|
|
||||||
return result;
|
|
||||||
default: // Dosen't have to be stored
|
default: // Dosen't have to be stored
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -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 :
|
||||||
|
@@ -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) UINT_MAX32;
|
||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0); // we should never go here
|
DBUG_ASSERT(0); // we should never go here
|
||||||
return 0;
|
return 0;
|
||||||
|
887
sql/sql_type.cc
887
sql/sql_type.cc
@@ -21,39 +21,44 @@
|
|||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
static Type_handler_tiny type_handler_tiny;
|
Type_handler_row type_handler_row;
|
||||||
static Type_handler_short type_handler_short;
|
|
||||||
static Type_handler_long type_handler_long;
|
|
||||||
static Type_handler_int24 type_handler_int24;
|
|
||||||
static Type_handler_year type_handler_year;
|
|
||||||
static Type_handler_time type_handler_time;
|
|
||||||
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;
|
Type_handler_null type_handler_null;
|
||||||
Type_handler_row type_handler_row;
|
|
||||||
Type_handler_string type_handler_string;
|
Type_handler_tiny type_handler_tiny;
|
||||||
Type_handler_varchar type_handler_varchar;
|
Type_handler_short type_handler_short;
|
||||||
|
Type_handler_long type_handler_long;
|
||||||
|
Type_handler_int24 type_handler_int24;
|
||||||
Type_handler_longlong type_handler_longlong;
|
Type_handler_longlong type_handler_longlong;
|
||||||
Type_handler_float type_handler_float;
|
Type_handler_float type_handler_float;
|
||||||
Type_handler_double type_handler_double;
|
Type_handler_double type_handler_double;
|
||||||
Type_handler_newdecimal type_handler_newdecimal;
|
|
||||||
Type_handler_datetime type_handler_datetime;
|
|
||||||
Type_handler_bit type_handler_bit;
|
Type_handler_bit type_handler_bit;
|
||||||
Type_handler_enum type_handler_enum;
|
|
||||||
Type_handler_set type_handler_set;
|
|
||||||
|
|
||||||
|
Type_handler_olddecimal type_handler_olddecimal;
|
||||||
|
Type_handler_newdecimal type_handler_newdecimal;
|
||||||
|
|
||||||
|
Type_handler_year type_handler_year;
|
||||||
|
Type_handler_time type_handler_time;
|
||||||
|
Type_handler_date type_handler_date;
|
||||||
|
Type_handler_timestamp type_handler_timestamp;
|
||||||
|
Type_handler_timestamp2 type_handler_timestamp2;
|
||||||
|
Type_handler_datetime type_handler_datetime;
|
||||||
Type_handler_time2 type_handler_time2;
|
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_enum type_handler_enum;
|
||||||
|
Type_handler_set type_handler_set;
|
||||||
|
|
||||||
|
Type_handler_string type_handler_string;
|
||||||
|
Type_handler_var_string type_handler_var_string;
|
||||||
|
Type_handler_varchar type_handler_varchar;
|
||||||
|
|
||||||
|
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 +85,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) ||
|
||||||
@@ -115,6 +129,126 @@ void Type_std_attributes::set(const Field *field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint Type_std_attributes::count_max_decimals(Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
uint res= 0;
|
||||||
|
for (uint i= 0; i < nitems; i++)
|
||||||
|
set_if_bigger(res, item[i]->decimals);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set max_length/decimals of function if function is fixed point and
|
||||||
|
result length/precision depends on argument ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Type_std_attributes::count_decimal_length(Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
int max_int_part= 0;
|
||||||
|
decimals= 0;
|
||||||
|
unsigned_flag= 1;
|
||||||
|
for (uint i=0 ; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
set_if_bigger(decimals, item[i]->decimals);
|
||||||
|
set_if_bigger(max_int_part, item[i]->decimal_int_part());
|
||||||
|
set_if_smaller(unsigned_flag, item[i]->unsigned_flag);
|
||||||
|
}
|
||||||
|
int precision= MY_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
||||||
|
fix_char_length(my_decimal_precision_to_length_no_truncation(precision,
|
||||||
|
decimals,
|
||||||
|
unsigned_flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set max_length of if it is maximum length of its arguments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Type_std_attributes::count_only_length(Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
uint32 char_length= 0;
|
||||||
|
unsigned_flag= 0;
|
||||||
|
for (uint i= 0; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
set_if_bigger(char_length, item[i]->max_char_length());
|
||||||
|
set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
|
||||||
|
}
|
||||||
|
fix_char_length(char_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Type_std_attributes::count_octet_length(Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
max_length= 0;
|
||||||
|
unsigned_flag= 0;
|
||||||
|
for (uint i= 0; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
set_if_bigger(max_length, item[i]->max_length);
|
||||||
|
set_if_bigger(unsigned_flag, item[i]->unsigned_flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set max_length/decimals of function if function is floating point and
|
||||||
|
result length/precision depends on argument ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Type_std_attributes::count_real_length(Item **items, uint nitems)
|
||||||
|
{
|
||||||
|
uint32 length= 0;
|
||||||
|
decimals= 0;
|
||||||
|
max_length= 0;
|
||||||
|
unsigned_flag= false;
|
||||||
|
for (uint i=0 ; i < nitems ; i++)
|
||||||
|
{
|
||||||
|
if (decimals < FLOATING_POINT_DECIMALS)
|
||||||
|
{
|
||||||
|
set_if_bigger(decimals, items[i]->decimals);
|
||||||
|
/* Will be ignored if items[i]->decimals >= FLOATING_POINT_DECIMALS */
|
||||||
|
set_if_bigger(length, (items[i]->max_length - items[i]->decimals));
|
||||||
|
}
|
||||||
|
set_if_bigger(max_length, items[i]->max_length);
|
||||||
|
}
|
||||||
|
if (decimals < FLOATING_POINT_DECIMALS)
|
||||||
|
{
|
||||||
|
max_length= length;
|
||||||
|
length+= decimals;
|
||||||
|
if (length < max_length) // If previous operation gave overflow
|
||||||
|
max_length= UINT_MAX32;
|
||||||
|
else
|
||||||
|
max_length= length;
|
||||||
|
}
|
||||||
|
// Corner case: COALESCE(DOUBLE(255,4), DOUBLE(255,3)) -> FLOAT(255, 4)
|
||||||
|
set_if_smaller(max_length, MAX_FIELD_CHARLENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculate max_length and decimals for string functions.
|
||||||
|
|
||||||
|
@param field_type Field type.
|
||||||
|
@param items Argument array.
|
||||||
|
@param nitems Number of arguments.
|
||||||
|
|
||||||
|
@retval False on success, true on error.
|
||||||
|
*/
|
||||||
|
bool Type_std_attributes::count_string_length(const char *func_name,
|
||||||
|
Item **items, uint nitems)
|
||||||
|
{
|
||||||
|
if (agg_arg_charsets_for_string_result(collation, func_name,
|
||||||
|
items, nitems, 1))
|
||||||
|
return true;
|
||||||
|
if (collation.collation == &my_charset_bin)
|
||||||
|
count_octet_length(items, nitems);
|
||||||
|
else
|
||||||
|
count_only_length(items, nitems);
|
||||||
|
decimals= max_length ? NOT_FIXED_DEC : 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is used by:
|
This method is used by:
|
||||||
- Item_user_var_as_out_param::field_type()
|
- Item_user_var_as_out_param::field_type()
|
||||||
@@ -140,6 +274,36 @@ Type_handler::string_type_handler(uint max_octet_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *
|
||||||
|
Type_handler::varstring_type_handler(const Item *item)
|
||||||
|
{
|
||||||
|
if (!item->max_length)
|
||||||
|
return &type_handler_string;
|
||||||
|
if (item->too_big_for_varchar())
|
||||||
|
return blob_type_handler(item->max_length);
|
||||||
|
return &type_handler_varchar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *
|
||||||
|
Type_handler::blob_type_handler(const Item *item)
|
||||||
|
{
|
||||||
|
return blob_type_handler(item->max_length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
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).
|
||||||
@@ -222,6 +386,7 @@ const Name Type_handler_null::m_name_null(C_STRING_WITH_LEN("null"));
|
|||||||
|
|
||||||
const Name
|
const Name
|
||||||
Type_handler_string::m_name_char(C_STRING_WITH_LEN("char")),
|
Type_handler_string::m_name_char(C_STRING_WITH_LEN("char")),
|
||||||
|
Type_handler_var_string::m_name_var_string(C_STRING_WITH_LEN("varchar")),
|
||||||
Type_handler_varchar::m_name_varchar(C_STRING_WITH_LEN("varchar")),
|
Type_handler_varchar::m_name_varchar(C_STRING_WITH_LEN("varchar")),
|
||||||
Type_handler_tiny_blob::m_name_tinyblob(C_STRING_WITH_LEN("tinyblob")),
|
Type_handler_tiny_blob::m_name_tinyblob(C_STRING_WITH_LEN("tinyblob")),
|
||||||
Type_handler_medium_blob::m_name_mediumblob(C_STRING_WITH_LEN("mediumblob")),
|
Type_handler_medium_blob::m_name_mediumblob(C_STRING_WITH_LEN("mediumblob")),
|
||||||
@@ -303,6 +468,30 @@ const Type_handler *Type_handler_row::type_handler_for_comparison() const
|
|||||||
return &type_handler_row;
|
return &type_handler_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
const Type_handler *Type_handler_enum::type_handler_for_item_field() const
|
||||||
|
{
|
||||||
|
return &type_handler_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *Type_handler_enum::cast_to_int_type_handler() const
|
||||||
|
{
|
||||||
|
return &type_handler_longlong;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *Type_handler_set::type_handler_for_item_field() const
|
||||||
|
{
|
||||||
|
return &type_handler_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *Type_handler_set::cast_to_int_type_handler() const
|
||||||
|
{
|
||||||
|
return &type_handler_longlong;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
@@ -1152,6 +1341,446 @@ 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.
|
||||||
|
For now we have DBUG_ASSERT(0).
|
||||||
|
It will be removed 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 new (table->in_use->mem_root)
|
||||||
|
Field_decimal(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
|
||||||
|
Field::NONE, name, attr.decimals,
|
||||||
|
0/*zerofill*/,attr.unsigned_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Will be changed to "new Field_timestampf" when we reuse
|
||||||
|
make_table_field() for make_field() purposes in field.cc.
|
||||||
|
*/
|
||||||
|
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_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
|
||||||
|
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
DBUG_ASSERT will be removed when we reuse make_table_field()
|
||||||
|
for make_field() in field.cc
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Will be changed to "new Field_timef" when we reuse
|
||||||
|
make_table_field() for make_field() purposes in field.cc.
|
||||||
|
*/
|
||||||
|
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_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
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Will be changed to "new Field_datetimef" when we reuse
|
||||||
|
make_table_field() for make_field() purposes in field.cc.
|
||||||
|
*/
|
||||||
|
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_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
||||||
|
{
|
||||||
|
TYPELIB *typelib= attr.get_typelib();
|
||||||
|
DBUG_ASSERT(typelib);
|
||||||
|
return new (table->in_use->mem_root)
|
||||||
|
Field_enum(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
|
||||||
|
Field::NONE, name,
|
||||||
|
get_enum_pack_length(typelib->count), typelib,
|
||||||
|
attr.collation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Type_handler_set::make_table_field(const LEX_CSTRING *name,
|
||||||
|
const Record_addr &addr,
|
||||||
|
const Type_all_attributes &attr,
|
||||||
|
TABLE *table) const
|
||||||
|
|
||||||
|
{
|
||||||
|
TYPELIB *typelib= attr.get_typelib();
|
||||||
|
DBUG_ASSERT(typelib);
|
||||||
|
return new (table->in_use->mem_root)
|
||||||
|
Field_set(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit,
|
||||||
|
Field::NONE, name,
|
||||||
|
get_enum_pack_length(typelib->count), typelib,
|
||||||
|
attr.collation);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
uint32 Type_handler_decimal_result::max_display_length(const Item *item) const
|
uint32 Type_handler_decimal_result::max_display_length(const Item *item) const
|
||||||
@@ -1436,7 +2065,18 @@ bool Type_handler_string_result::
|
|||||||
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
|
||||||
{
|
{
|
||||||
return func->aggregate_attributes_string(items, nitems);
|
return func->aggregate_attributes_string(func->func_name(), items, nitems);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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(func->func_name(), items, nitems))
|
||||||
|
return true;
|
||||||
|
func->set_handler(blob_type_handler(func->max_length));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3187,3 +3827,204 @@ uint Type_handler_string_result::Item_temporal_precision(Item *item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
uint Type_handler::Item_decimal_scale(const Item *item) const
|
||||||
|
{
|
||||||
|
return item->decimals < NOT_FIXED_DEC ?
|
||||||
|
item->decimals :
|
||||||
|
MY_MIN(item->max_length, DECIMAL_MAX_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint Type_handler_temporal_result::
|
||||||
|
Item_decimal_scale_with_seconds(const Item *item) const
|
||||||
|
{
|
||||||
|
return item->decimals < NOT_FIXED_DEC ?
|
||||||
|
item->decimals :
|
||||||
|
TIME_SECOND_PART_DIGITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint Type_handler::Item_divisor_precision_increment(const Item *item) const
|
||||||
|
{
|
||||||
|
return item->decimals;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint Type_handler_temporal_result::
|
||||||
|
Item_divisor_precision_increment_with_seconds(const Item *item) const
|
||||||
|
{
|
||||||
|
return item->decimals < NOT_FIXED_DEC ?
|
||||||
|
item->decimals :
|
||||||
|
TIME_SECOND_PART_DIGITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
bool Type_handler_real_result::
|
||||||
|
subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(inner->cmp_type() == REAL_RESULT);
|
||||||
|
return outer->cmp_type() == REAL_RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_int_result::
|
||||||
|
subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(inner->cmp_type() == INT_RESULT);
|
||||||
|
return outer->cmp_type() == INT_RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_decimal_result::
|
||||||
|
subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(inner->cmp_type() == DECIMAL_RESULT);
|
||||||
|
return outer->cmp_type() == DECIMAL_RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_string_result::
|
||||||
|
subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(inner->cmp_type() == STRING_RESULT);
|
||||||
|
return outer->cmp_type() == STRING_RESULT &&
|
||||||
|
outer->collation.collation == inner->collation.collation &&
|
||||||
|
/*
|
||||||
|
Materialization also is unable to work when create_tmp_table() will
|
||||||
|
create a blob column because item->max_length is too big.
|
||||||
|
The following test is copied from varstring_type_handler().
|
||||||
|
*/
|
||||||
|
!inner->too_big_for_varchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_temporal_result::
|
||||||
|
subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(inner->cmp_type() == TIME_RESULT);
|
||||||
|
return mysql_timestamp_type() ==
|
||||||
|
outer->type_handler()->mysql_timestamp_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *
|
||||||
|
Type_handler_null::type_handler_for_tmp_table(const Item *item) const
|
||||||
|
{
|
||||||
|
return &type_handler_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *
|
||||||
|
Type_handler_null::type_handler_for_union(const Item *item) const
|
||||||
|
{
|
||||||
|
return &type_handler_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *
|
||||||
|
Type_handler_olddecimal::type_handler_for_tmp_table(const Item *item) const
|
||||||
|
{
|
||||||
|
return &type_handler_newdecimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type_handler *
|
||||||
|
Type_handler_olddecimal::type_handler_for_union(const Item *item) const
|
||||||
|
{
|
||||||
|
return &type_handler_newdecimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
bool Type_handler::check_null(const Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
if (item->null_value)
|
||||||
|
{
|
||||||
|
value->m_type= DYN_COL_NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_null::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
value->m_type= DYN_COL_NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_row::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
value->m_type= DYN_COL_NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_int_result::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
value->m_type= item->unsigned_flag ? DYN_COL_UINT : DYN_COL_INT;
|
||||||
|
value->value.m_longlong= item->val_int();
|
||||||
|
return check_null(item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_real_result::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
value->m_type= DYN_COL_DOUBLE;
|
||||||
|
value->value.m_double= item->val_real();
|
||||||
|
return check_null(item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_decimal_result::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
value->m_type= DYN_COL_DECIMAL;
|
||||||
|
my_decimal *dec= item->val_decimal(&value->m_decimal);
|
||||||
|
if (dec != &value->m_decimal && !item->null_value)
|
||||||
|
my_decimal2decimal(dec, &value->m_decimal);
|
||||||
|
return check_null(item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_string_result::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
value->m_type= DYN_COL_STRING;
|
||||||
|
String *str= item->val_str(&value->m_string);
|
||||||
|
if (str != &value->m_string && !item->null_value)
|
||||||
|
value->m_string.set(str->ptr(), str->length(), str->charset());
|
||||||
|
return check_null(item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_temporal_with_date::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
value->m_type= DYN_COL_DATETIME;
|
||||||
|
item->get_date(&value->value.m_time, sql_mode_for_dates(current_thd));
|
||||||
|
return check_null(item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_time_common::
|
||||||
|
Item_save_in_value(Item *item, st_value *value) const
|
||||||
|
{
|
||||||
|
value->m_type= DYN_COL_DATETIME;
|
||||||
|
item->get_time(&value->value.m_time);
|
||||||
|
return check_null(item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
544
sql/sql_type.h
544
sql/sql_type.h
@@ -60,9 +60,9 @@ class Item_func_div;
|
|||||||
class Item_func_mod;
|
class Item_func_mod;
|
||||||
class cmp_item;
|
class cmp_item;
|
||||||
class in_vector;
|
class in_vector;
|
||||||
class Type_std_attributes;
|
|
||||||
class Sort_param;
|
class Sort_param;
|
||||||
class Arg_comparator;
|
class Arg_comparator;
|
||||||
|
struct st_value;
|
||||||
struct TABLE;
|
struct TABLE;
|
||||||
struct SORT_FIELD_ATTR;
|
struct SORT_FIELD_ATTR;
|
||||||
|
|
||||||
@@ -130,6 +130,21 @@ public:
|
|||||||
derivation= DERIVATION_NONE;
|
derivation= DERIVATION_NONE;
|
||||||
repertoire= MY_REPERTOIRE_UNICODE30;
|
repertoire= MY_REPERTOIRE_UNICODE30;
|
||||||
}
|
}
|
||||||
|
DTCollation(CHARSET_INFO *collation_arg)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This constructor version is used in combination with Field constructors,
|
||||||
|
to pass "CHARSET_INFO" instead of the full DTCollation.
|
||||||
|
Therefore, derivation is set to DERIVATION_IMPLICIT, which is the
|
||||||
|
proper derivation for table fields.
|
||||||
|
We should eventually remove all code pieces that pass "CHARSET_INFO"
|
||||||
|
(e.g. in storage engine sources) and fix to pass the full DTCollation
|
||||||
|
instead. Then, this constructor can be removed.
|
||||||
|
*/
|
||||||
|
collation= collation_arg;
|
||||||
|
derivation= DERIVATION_IMPLICIT;
|
||||||
|
repertoire= my_charset_repertoire(collation_arg);
|
||||||
|
}
|
||||||
DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg)
|
DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg)
|
||||||
{
|
{
|
||||||
collation= collation_arg;
|
collation= collation_arg;
|
||||||
@@ -311,6 +326,155 @@ public:
|
|||||||
{
|
{
|
||||||
fix_attributes_temporal(MAX_DATETIME_WIDTH, dec);
|
fix_attributes_temporal(MAX_DATETIME_WIDTH, dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void count_only_length(Item **item, uint nitems);
|
||||||
|
void count_octet_length(Item **item, uint nitems);
|
||||||
|
void count_real_length(Item **item, uint nitems);
|
||||||
|
void count_decimal_length(Item **item, uint nitems);
|
||||||
|
bool count_string_length(const char *func_name, Item **item, uint nitems);
|
||||||
|
uint count_max_decimals(Item **item, uint nitems);
|
||||||
|
|
||||||
|
void aggregate_attributes_int(Item **items, uint nitems)
|
||||||
|
{
|
||||||
|
collation.set_numeric();
|
||||||
|
count_only_length(items, nitems);
|
||||||
|
decimals= 0;
|
||||||
|
}
|
||||||
|
void aggregate_attributes_real(Item **items, uint nitems)
|
||||||
|
{
|
||||||
|
collation.set_numeric();
|
||||||
|
count_real_length(items, nitems);
|
||||||
|
}
|
||||||
|
void aggregate_attributes_decimal(Item **items, uint nitems)
|
||||||
|
{
|
||||||
|
collation.set_numeric();
|
||||||
|
count_decimal_length(items, nitems);
|
||||||
|
}
|
||||||
|
bool aggregate_attributes_string(const char *func_name,
|
||||||
|
Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
return count_string_length(func_name, item, nitems);
|
||||||
|
}
|
||||||
|
void aggregate_attributes_temporal(uint int_part_length,
|
||||||
|
Item **item, uint nitems)
|
||||||
|
{
|
||||||
|
fix_attributes_temporal(int_part_length, count_max_decimals(item, nitems));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool agg_item_collations(DTCollation &c, const char *name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
uint flags, int item_sep);
|
||||||
|
bool agg_item_set_converter(const DTCollation &coll, const char *fname,
|
||||||
|
Item **args, uint nargs,
|
||||||
|
uint flags, int item_sep);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect arguments' character sets together.
|
||||||
|
We allow to apply automatic character set conversion in some cases.
|
||||||
|
The conditions when conversion is possible are:
|
||||||
|
- arguments A and B have different charsets
|
||||||
|
- A wins according to coercibility rules
|
||||||
|
(i.e. a column is stronger than a string constant,
|
||||||
|
an explicit COLLATE clause is stronger than a column)
|
||||||
|
- character set of A is either superset for character set of B,
|
||||||
|
or B is a string constant which can be converted into the
|
||||||
|
character set of A without data loss.
|
||||||
|
|
||||||
|
If all of the above is true, then it's possible to convert
|
||||||
|
B into the character set of A, and then compare according
|
||||||
|
to the collation of A.
|
||||||
|
|
||||||
|
For functions with more than two arguments:
|
||||||
|
|
||||||
|
collect(A,B,C) ::= collect(collect(A,B),C)
|
||||||
|
|
||||||
|
Since this function calls THD::change_item_tree() on the passed Item **
|
||||||
|
pointers, it is necessary to pass the original Item **'s, not copies.
|
||||||
|
Otherwise their values will not be properly restored (see BUG#20769).
|
||||||
|
If the items are not consecutive (eg. args[2] and args[5]), use the
|
||||||
|
item_sep argument, ie.
|
||||||
|
|
||||||
|
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets(DTCollation &c, const char *func_name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
uint flags, int item_sep)
|
||||||
|
{
|
||||||
|
if (agg_item_collations(c, func_name, items, nitems, flags, item_sep))
|
||||||
|
return true;
|
||||||
|
return agg_item_set_converter(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Aggregate arguments for string result, e.g: CONCAT(a,b)
|
||||||
|
- convert to @@character_set_connection if all arguments are numbers
|
||||||
|
- allow DERIVATION_NONE
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets_for_string_result(DTCollation &c, const char *func_name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
int item_sep)
|
||||||
|
{
|
||||||
|
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
||||||
|
MY_COLL_ALLOW_COERCIBLE_CONV |
|
||||||
|
MY_COLL_ALLOW_NUMERIC_CONV;
|
||||||
|
return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Aggregate arguments for string result, when some comparison
|
||||||
|
is involved internally, e.g: REPLACE(a,b,c)
|
||||||
|
- convert to @@character_set_connection if all arguments are numbers
|
||||||
|
- disallow DERIVATION_NONE
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
|
||||||
|
const char *func_name,
|
||||||
|
Item **items,
|
||||||
|
uint nitems,
|
||||||
|
int item_sep)
|
||||||
|
{
|
||||||
|
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
||||||
|
MY_COLL_ALLOW_COERCIBLE_CONV |
|
||||||
|
MY_COLL_ALLOW_NUMERIC_CONV |
|
||||||
|
MY_COLL_DISALLOW_NONE;
|
||||||
|
return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Aggregate arguments for comparison, e.g: a=b, a LIKE b, a RLIKE b
|
||||||
|
- don't convert to @@character_set_connection if all arguments are numbers
|
||||||
|
- don't allow DERIVATION_NONE
|
||||||
|
*/
|
||||||
|
bool agg_arg_charsets_for_comparison(DTCollation &c,
|
||||||
|
const char *func_name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
int item_sep)
|
||||||
|
{
|
||||||
|
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
|
||||||
|
MY_COLL_ALLOW_COERCIBLE_CONV |
|
||||||
|
MY_COLL_DISALLOW_NONE;
|
||||||
|
return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
virtual TYPELIB *get_typelib() const { return NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -327,6 +491,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:
|
||||||
@@ -341,8 +530,19 @@ protected:
|
|||||||
Item_func_or_sum_illegal_param(const char *name) const;
|
Item_func_or_sum_illegal_param(const char *name) const;
|
||||||
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;
|
||||||
|
bool check_null(const Item *item, st_value *value) 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);
|
||||||
|
/**
|
||||||
|
Return a string type handler for Item
|
||||||
|
If too_big_for_varchar() returns a BLOB variant, according to length.
|
||||||
|
If max_length > 0 create a VARCHAR(n)
|
||||||
|
If max_length == 0 create a CHAR(0)
|
||||||
|
@param item - the Item to get the handler to.
|
||||||
|
*/
|
||||||
|
static const Type_handler *varstring_type_handler(const Item *item);
|
||||||
|
static const Type_handler *blob_type_handler(const Item *item);
|
||||||
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);
|
||||||
static const Type_handler *get_handler_by_cmp_type(Item_result type);
|
static const Type_handler *get_handler_by_cmp_type(Item_result type);
|
||||||
@@ -367,6 +567,10 @@ public:
|
|||||||
virtual enum_field_types real_field_type() const { return field_type(); }
|
virtual enum_field_types real_field_type() const { return field_type(); }
|
||||||
virtual Item_result result_type() const= 0;
|
virtual Item_result result_type() const= 0;
|
||||||
virtual Item_result cmp_type() const= 0;
|
virtual Item_result cmp_type() const= 0;
|
||||||
|
virtual enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TIMESTAMP_ERROR;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
Prepared statement long data:
|
Prepared statement long data:
|
||||||
Check whether this parameter data type is compatible with long data.
|
Check whether this parameter data type is compatible with long data.
|
||||||
@@ -375,6 +579,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool is_param_long_data_type() const { return false; }
|
virtual bool is_param_long_data_type() const { return false; }
|
||||||
virtual const Type_handler *type_handler_for_comparison() const= 0;
|
virtual const Type_handler *type_handler_for_comparison() const= 0;
|
||||||
|
virtual const Type_handler *type_handler_for_item_field() const
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
virtual const Type_handler *type_handler_for_tmp_table(const Item *) const
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
virtual const Type_handler *type_handler_for_union(const Item *) const
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
virtual const Type_handler *cast_to_int_type_handler() const
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
virtual CHARSET_INFO *charset_for_protocol(const Item *item) const;
|
virtual CHARSET_INFO *charset_for_protocol(const Item *item) const;
|
||||||
virtual const Type_handler*
|
virtual const Type_handler*
|
||||||
type_handler_adjusted_to_max_octet_length(uint max_octet_length,
|
type_handler_adjusted_to_max_octet_length(uint max_octet_length,
|
||||||
@@ -391,6 +611,12 @@ public:
|
|||||||
}
|
}
|
||||||
virtual uint Item_time_precision(Item *item) const;
|
virtual uint Item_time_precision(Item *item) const;
|
||||||
virtual uint Item_datetime_precision(Item *item) const;
|
virtual uint Item_datetime_precision(Item *item) const;
|
||||||
|
virtual uint Item_decimal_scale(const Item *item) const;
|
||||||
|
/*
|
||||||
|
Returns how many digits a divisor adds into a division result.
|
||||||
|
See Item::divisor_precision_increment() in item.h for more comments.
|
||||||
|
*/
|
||||||
|
virtual uint Item_divisor_precision_increment(const Item *) const;
|
||||||
/**
|
/**
|
||||||
Makes a temporary table Field to handle numeric aggregate functions,
|
Makes a temporary table Field to handle numeric aggregate functions,
|
||||||
e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc.
|
e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc.
|
||||||
@@ -427,6 +653,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;
|
||||||
@@ -435,6 +669,7 @@ public:
|
|||||||
SORT_FIELD_ATTR *attr) const= 0;
|
SORT_FIELD_ATTR *attr) const= 0;
|
||||||
|
|
||||||
virtual uint32 max_display_length(const Item *item) const= 0;
|
virtual uint32 max_display_length(const Item *item) const= 0;
|
||||||
|
virtual bool Item_save_in_value(Item *item, st_value *value) const= 0;
|
||||||
virtual int Item_save_in_field(Item *item, Field *field,
|
virtual int Item_save_in_field(Item *item, Field *field,
|
||||||
bool no_conversions) const= 0;
|
bool no_conversions) const= 0;
|
||||||
|
|
||||||
@@ -480,6 +715,9 @@ public:
|
|||||||
Item *target_expr, Item *target_value,
|
Item *target_expr, Item *target_value,
|
||||||
Item_bool_func2 *source,
|
Item_bool_func2 *source,
|
||||||
Item *source_expr, Item *source_const) const= 0;
|
Item *source_expr, Item *source_const) const= 0;
|
||||||
|
virtual bool
|
||||||
|
subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const= 0;
|
||||||
virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0;
|
virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0;
|
||||||
virtual bool set_comparator_func(Arg_comparator *cmp) const= 0;
|
virtual bool set_comparator_func(Arg_comparator *cmp) const= 0;
|
||||||
virtual bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
virtual bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@@ -605,6 +843,12 @@ public:
|
|||||||
return ROW_RESULT;
|
return ROW_RESULT;
|
||||||
}
|
}
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const
|
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@@ -617,6 +861,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
|
||||||
@@ -633,6 +885,7 @@ public:
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@@ -834,11 +1087,14 @@ public:
|
|||||||
Item_result cmp_type() const { return REAL_RESULT; }
|
Item_result cmp_type() const { return REAL_RESULT; }
|
||||||
virtual ~Type_handler_real_result() {}
|
virtual ~Type_handler_real_result() {}
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const;
|
||||||
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
|
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
|
||||||
Sort_param *param) const;
|
Sort_param *param) const;
|
||||||
void sortlength(THD *thd,
|
void sortlength(THD *thd,
|
||||||
const Type_std_attributes *item,
|
const Type_std_attributes *item,
|
||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
@@ -889,6 +1145,8 @@ public:
|
|||||||
Item_result cmp_type() const { return DECIMAL_RESULT; }
|
Item_result cmp_type() const { return DECIMAL_RESULT; }
|
||||||
virtual ~Type_handler_decimal_result() {};
|
virtual ~Type_handler_decimal_result() {};
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const;
|
||||||
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
|
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
|
||||||
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
|
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
|
||||||
Sort_param *param) const;
|
Sort_param *param) const;
|
||||||
@@ -896,6 +1154,7 @@ public:
|
|||||||
const Type_std_attributes *item,
|
const Type_std_attributes *item,
|
||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
uint32 max_display_length(const Item *item) const;
|
uint32 max_display_length(const Item *item) const;
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
@@ -943,12 +1202,15 @@ public:
|
|||||||
Item_result cmp_type() const { return INT_RESULT; }
|
Item_result cmp_type() const { return INT_RESULT; }
|
||||||
virtual ~Type_handler_int_result() {}
|
virtual ~Type_handler_int_result() {}
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const;
|
||||||
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
|
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
|
||||||
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
|
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
|
||||||
Sort_param *param) const;
|
Sort_param *param) const;
|
||||||
void sortlength(THD *thd,
|
void sortlength(THD *thd,
|
||||||
const Type_std_attributes *item,
|
const Type_std_attributes *item,
|
||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
@@ -991,6 +1253,9 @@ public:
|
|||||||
|
|
||||||
class Type_handler_temporal_result: public Type_handler
|
class Type_handler_temporal_result: public Type_handler
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
uint Item_decimal_scale_with_seconds(const Item *item) const;
|
||||||
|
uint Item_divisor_precision_increment_with_seconds(const Item *) const;
|
||||||
public:
|
public:
|
||||||
Item_result result_type() const { return STRING_RESULT; }
|
Item_result result_type() const { return STRING_RESULT; }
|
||||||
Item_result cmp_type() const { return TIME_RESULT; }
|
Item_result cmp_type() const { return TIME_RESULT; }
|
||||||
@@ -1005,6 +1270,8 @@ public:
|
|||||||
Item *target_expr, Item *target_value,
|
Item *target_expr, Item *target_value,
|
||||||
Item_bool_func2 *source,
|
Item_bool_func2 *source,
|
||||||
Item *source_expr, Item *source_const) const;
|
Item *source_expr, Item *source_const) const;
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
||||||
@@ -1072,6 +1339,7 @@ public:
|
|||||||
{
|
{
|
||||||
return Item_temporal_precision(item, false);
|
return Item_temporal_precision(item, false);
|
||||||
}
|
}
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
String *print_item_value(THD *thd, Item *item, String *str) const
|
String *print_item_value(THD *thd, Item *item, String *str) const
|
||||||
{
|
{
|
||||||
@@ -1081,6 +1349,8 @@ public:
|
|||||||
Item *target_expr, Item *target_value,
|
Item *target_expr, Item *target_value,
|
||||||
Item_bool_func2 *source,
|
Item_bool_func2 *source,
|
||||||
Item *source_expr, Item *source_const) const;
|
Item *source_expr, Item *source_const) const;
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@@ -1156,6 +1426,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1169,6 +1443,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1185,6 +1463,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1198,6 +1480,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1211,6 +1497,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1224,6 +1514,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1241,6 +1535,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1255,6 +1553,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1268,6 +1570,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1278,7 +1584,20 @@ public:
|
|||||||
virtual ~Type_handler_time_common() { }
|
virtual ~Type_handler_time_common() { }
|
||||||
const Name name() const { return m_name_time; }
|
const Name name() const { return m_name_time; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||||
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TIMESTAMP_TIME;
|
||||||
|
}
|
||||||
|
uint Item_decimal_scale(const Item *item) const
|
||||||
|
{
|
||||||
|
return Item_decimal_scale_with_seconds(item);
|
||||||
|
}
|
||||||
|
uint Item_divisor_precision_increment(const Item *item) const
|
||||||
|
{
|
||||||
|
return Item_divisor_precision_increment_with_seconds(item);
|
||||||
|
}
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
String *print_item_value(THD *thd, Item *item, String *str) const;
|
String *print_item_value(THD *thd, Item *item, String *str) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@@ -1294,6 +1613,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1304,6 +1627,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1312,6 +1639,7 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result
|
|||||||
public:
|
public:
|
||||||
virtual ~Type_handler_temporal_with_date() {}
|
virtual ~Type_handler_temporal_with_date() {}
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
||||||
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
||||||
@@ -1325,6 +1653,10 @@ public:
|
|||||||
virtual ~Type_handler_date_common() {}
|
virtual ~Type_handler_date_common() {}
|
||||||
const Name name() const { return m_name_date; }
|
const Name name() const { return m_name_date; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||||
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TIMESTAMP_DATE;
|
||||||
|
}
|
||||||
String *print_item_value(THD *thd, Item *item, String *str) const;
|
String *print_item_value(THD *thd, Item *item, String *str) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
Item **items, uint nitems) const;
|
Item **items, uint nitems) const;
|
||||||
@@ -1336,6 +1668,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1343,8 +1679,13 @@ class Type_handler_newdate: public Type_handler_date_common
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Type_handler_newdate() {}
|
virtual ~Type_handler_newdate() {}
|
||||||
|
enum_field_types real_field_type() const { return MYSQL_TYPE_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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1355,6 +1696,18 @@ public:
|
|||||||
virtual ~Type_handler_datetime_common() {}
|
virtual ~Type_handler_datetime_common() {}
|
||||||
const Name name() const { return m_name_datetime; }
|
const Name name() const { return m_name_datetime; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||||
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TIMESTAMP_DATETIME;
|
||||||
|
}
|
||||||
|
uint Item_decimal_scale(const Item *item) const
|
||||||
|
{
|
||||||
|
return Item_decimal_scale_with_seconds(item);
|
||||||
|
}
|
||||||
|
uint Item_divisor_precision_increment(const Item *item) const
|
||||||
|
{
|
||||||
|
return Item_divisor_precision_increment_with_seconds(item);
|
||||||
|
}
|
||||||
String *print_item_value(THD *thd, Item *item, String *str) const;
|
String *print_item_value(THD *thd, Item *item, String *str) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
Item **items, uint nitems) const;
|
Item **items, uint nitems) const;
|
||||||
@@ -1367,6 +1720,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1377,6 +1734,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1387,6 +1748,18 @@ public:
|
|||||||
virtual ~Type_handler_timestamp_common() {}
|
virtual ~Type_handler_timestamp_common() {}
|
||||||
const Name name() const { return m_name_timestamp; }
|
const Name name() const { return m_name_timestamp; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
||||||
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TIMESTAMP_DATETIME;
|
||||||
|
}
|
||||||
|
uint Item_decimal_scale(const Item *item) const
|
||||||
|
{
|
||||||
|
return Item_decimal_scale_with_seconds(item);
|
||||||
|
}
|
||||||
|
uint Item_divisor_precision_increment(const Item *item) const
|
||||||
|
{
|
||||||
|
return Item_divisor_precision_increment_with_seconds(item);
|
||||||
|
}
|
||||||
String *print_item_value(THD *thd, Item *item, String *str) const;
|
String *print_item_value(THD *thd, Item *item, String *str) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
Item **items, uint nitems) const;
|
Item **items, uint nitems) const;
|
||||||
@@ -1399,6 +1772,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1409,6 +1786,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1419,8 +1800,14 @@ public:
|
|||||||
virtual ~Type_handler_olddecimal() {}
|
virtual ~Type_handler_olddecimal() {}
|
||||||
const Name name() const { return m_name_decimal; }
|
const Name name() const { return m_name_decimal; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; }
|
||||||
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
|
||||||
|
const Type_handler *type_handler_for_union(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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1433,6 +1820,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1444,9 +1835,16 @@ public:
|
|||||||
const Name name() const { return m_name_null; }
|
const Name name() const { return m_name_null; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
|
enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
|
||||||
|
const Type_handler *type_handler_for_union(const Item *) const;
|
||||||
uint32 max_display_length(const Item *item) const { return 0; }
|
uint32 max_display_length(const Item *item) const { return 0; }
|
||||||
|
bool Item_save_in_value(Item *item, st_value *value) 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1458,8 +1856,36 @@ public:
|
|||||||
const Name name() const { return m_name_char; }
|
const Name name() const { return m_name_char; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
||||||
bool is_param_long_data_type() const { return true; }
|
bool is_param_long_data_type() const { return true; }
|
||||||
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const
|
||||||
|
{
|
||||||
|
return varstring_type_handler(item);
|
||||||
|
}
|
||||||
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Old varchar */
|
||||||
|
class Type_handler_var_string: public Type_handler_string
|
||||||
|
{
|
||||||
|
static const Name m_name_var_string;
|
||||||
|
public:
|
||||||
|
virtual ~Type_handler_var_string() {}
|
||||||
|
const Name name() const { return m_name_var_string; }
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_VAR_STRING; }
|
||||||
|
enum_field_types real_field_type() const { return MYSQL_TYPE_STRING; }
|
||||||
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const
|
||||||
|
{
|
||||||
|
return varstring_type_handler(item);
|
||||||
|
}
|
||||||
|
const Type_handler *type_handler_for_union(const Item *item) const
|
||||||
|
{
|
||||||
|
return varstring_type_handler(item);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1470,9 +1896,21 @@ public:
|
|||||||
virtual ~Type_handler_varchar() {}
|
virtual ~Type_handler_varchar() {}
|
||||||
const Name name() const { return m_name_varchar; }
|
const Name name() const { return m_name_varchar; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
||||||
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const
|
||||||
|
{
|
||||||
|
return varstring_type_handler(item);
|
||||||
|
}
|
||||||
|
const Type_handler *type_handler_for_union(const Item *item) const
|
||||||
|
{
|
||||||
|
return varstring_type_handler(item);
|
||||||
|
}
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1480,7 +1918,22 @@ class Type_handler_blob_common: public Type_handler_string_result
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Type_handler_blob_common() { }
|
virtual ~Type_handler_blob_common() { }
|
||||||
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const
|
||||||
|
{
|
||||||
|
return blob_type_handler(item);
|
||||||
|
}
|
||||||
|
const Type_handler *type_handler_for_union(const Item *item) const
|
||||||
|
{
|
||||||
|
return blob_type_handler(item);
|
||||||
|
}
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1493,6 +1946,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1505,6 +1962,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1517,6 +1978,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1529,6 +1994,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1542,8 +2011,18 @@ public:
|
|||||||
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
|
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
|
||||||
bool is_param_long_data_type() const { return true; }
|
bool is_param_long_data_type() const { return true; }
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
|
const Item *outer) const
|
||||||
|
{
|
||||||
|
return false; // Materialization does not work with GEOMETRY columns
|
||||||
|
}
|
||||||
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;
|
||||||
@@ -1576,10 +2055,16 @@ class Type_handler_enum: public Type_handler_string_result
|
|||||||
public:
|
public:
|
||||||
virtual ~Type_handler_enum() {}
|
virtual ~Type_handler_enum() {}
|
||||||
const Name name() const { return m_name_enum; }
|
const Name name() const { return m_name_enum; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
||||||
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; }
|
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; }
|
||||||
|
const Type_handler *type_handler_for_item_field() const;
|
||||||
|
const Type_handler *cast_to_int_type_handler() 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1589,10 +2074,16 @@ class Type_handler_set: public Type_handler_string_result
|
|||||||
public:
|
public:
|
||||||
virtual ~Type_handler_set() {}
|
virtual ~Type_handler_set() {}
|
||||||
const Name name() const { return m_name_set; }
|
const Name name() const { return m_name_set; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
||||||
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_SET; }
|
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_SET; }
|
||||||
|
const Type_handler *type_handler_for_item_field() const;
|
||||||
|
const Type_handler *cast_to_int_type_handler() 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1628,6 +2119,10 @@ public:
|
|||||||
}
|
}
|
||||||
Item_result result_type() const { return m_type_handler->result_type(); }
|
Item_result result_type() const { return m_type_handler->result_type(); }
|
||||||
Item_result cmp_type() const { return m_type_handler->cmp_type(); }
|
Item_result cmp_type() const { return m_type_handler->cmp_type(); }
|
||||||
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
|
{
|
||||||
|
return m_type_handler->mysql_timestamp_type();
|
||||||
|
}
|
||||||
void set_handler(const Type_handler *other)
|
void set_handler(const Type_handler *other)
|
||||||
{
|
{
|
||||||
m_type_handler= other;
|
m_type_handler= other;
|
||||||
@@ -1673,22 +2168,47 @@ public:
|
|||||||
|
|
||||||
extern Type_handler_row type_handler_row;
|
extern Type_handler_row type_handler_row;
|
||||||
extern Type_handler_null type_handler_null;
|
extern Type_handler_null type_handler_null;
|
||||||
extern Type_handler_string type_handler_string;
|
|
||||||
extern Type_handler_varchar type_handler_varchar;
|
|
||||||
extern Type_handler_longlong type_handler_longlong;
|
|
||||||
extern Type_handler_float type_handler_float;
|
extern Type_handler_float type_handler_float;
|
||||||
extern Type_handler_double type_handler_double;
|
extern Type_handler_double type_handler_double;
|
||||||
extern Type_handler_newdecimal type_handler_newdecimal;
|
|
||||||
extern Type_handler_datetime type_handler_datetime;
|
|
||||||
extern Type_handler_longlong type_handler_longlong;
|
|
||||||
extern Type_handler_bit type_handler_bit;
|
extern Type_handler_bit type_handler_bit;
|
||||||
|
|
||||||
extern Type_handler_enum type_handler_enum;
|
extern Type_handler_enum type_handler_enum;
|
||||||
extern Type_handler_set type_handler_set;
|
extern Type_handler_set type_handler_set;
|
||||||
|
|
||||||
extern Type_handler_time2 type_handler_time2;
|
extern Type_handler_string type_handler_string;
|
||||||
extern Type_handler_newdate type_handler_newdate;
|
extern Type_handler_var_string type_handler_var_string;
|
||||||
extern Type_handler_datetime2 type_handler_datetime2;
|
extern Type_handler_varchar type_handler_varchar;
|
||||||
|
|
||||||
|
extern Type_handler_tiny_blob type_handler_tiny_blob;
|
||||||
|
extern Type_handler_medium_blob type_handler_medium_blob;
|
||||||
|
extern Type_handler_long_blob type_handler_long_blob;
|
||||||
|
extern Type_handler_blob type_handler_blob;
|
||||||
|
|
||||||
|
extern Type_handler_tiny type_handler_tiny;
|
||||||
|
extern Type_handler_short type_handler_short;
|
||||||
|
extern Type_handler_int24 type_handler_int24;
|
||||||
|
extern Type_handler_long type_handler_long;
|
||||||
|
extern Type_handler_longlong type_handler_longlong;
|
||||||
|
|
||||||
|
extern Type_handler_newdecimal type_handler_newdecimal;
|
||||||
|
extern Type_handler_olddecimal type_handler_olddecimal;
|
||||||
|
|
||||||
|
extern Type_handler_year type_handler_year;
|
||||||
|
extern Type_handler_newdate type_handler_newdate;
|
||||||
|
extern Type_handler_date type_handler_date;
|
||||||
|
extern Type_handler_time type_handler_time;
|
||||||
|
extern Type_handler_time2 type_handler_time2;
|
||||||
|
extern Type_handler_datetime type_handler_datetime;
|
||||||
|
extern Type_handler_datetime2 type_handler_datetime2;
|
||||||
|
extern Type_handler_timestamp type_handler_timestamp;
|
||||||
|
extern Type_handler_timestamp2 type_handler_timestamp2;
|
||||||
|
|
||||||
|
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
|
||||||
{
|
{
|
||||||
|
117
sql/sql_union.cc
117
sql/sql_union.cc
@@ -636,6 +636,59 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
|
||||||
|
select_result *tmp_result,
|
||||||
|
ulong additional_options,
|
||||||
|
bool is_union_select)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("st_select_lex_unit::prepare_join");
|
||||||
|
bool can_skip_order_by;
|
||||||
|
sl->options|= SELECT_NO_UNLOCK;
|
||||||
|
JOIN *join= new JOIN(thd_arg, sl->item_list,
|
||||||
|
(sl->options | thd_arg->variables.option_bits |
|
||||||
|
additional_options),
|
||||||
|
tmp_result);
|
||||||
|
if (!join)
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
|
thd_arg->lex->current_select= sl;
|
||||||
|
|
||||||
|
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
|
||||||
|
|
||||||
|
saved_error= join->prepare(sl->table_list.first,
|
||||||
|
sl->with_wild,
|
||||||
|
sl->where,
|
||||||
|
(can_skip_order_by ? 0 :
|
||||||
|
sl->order_list.elements) +
|
||||||
|
sl->group_list.elements,
|
||||||
|
can_skip_order_by ?
|
||||||
|
NULL : sl->order_list.first,
|
||||||
|
can_skip_order_by,
|
||||||
|
sl->group_list.first,
|
||||||
|
sl->having,
|
||||||
|
(is_union_select ? NULL :
|
||||||
|
thd_arg->lex->proc_list.first),
|
||||||
|
sl, this);
|
||||||
|
|
||||||
|
/* There are no * in the statement anymore (for PS) */
|
||||||
|
sl->with_wild= 0;
|
||||||
|
last_procedure= join->procedure;
|
||||||
|
|
||||||
|
if (saved_error || (saved_error= thd_arg->is_fatal_error))
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
/*
|
||||||
|
Remove all references from the select_lex_units to the subqueries that
|
||||||
|
are inside the ORDER BY clause.
|
||||||
|
*/
|
||||||
|
if (can_skip_order_by)
|
||||||
|
{
|
||||||
|
for (ORDER *ord= (ORDER *)sl->order_list.first; ord; ord= ord->next)
|
||||||
|
{
|
||||||
|
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_RETURN(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||||
@@ -748,14 +801,21 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
|
|
||||||
sl->context.resolve_in_select_list= TRUE;
|
sl->context.resolve_in_select_list= TRUE;
|
||||||
|
|
||||||
|
if (!is_union_select && !is_recursive)
|
||||||
|
{
|
||||||
|
if (prepare_join(thd_arg, first_sl, tmp_result, additional_options,
|
||||||
|
is_union_select))
|
||||||
|
goto err;
|
||||||
|
types= first_sl->item_list;
|
||||||
|
goto cont;
|
||||||
|
}
|
||||||
|
|
||||||
for (;sl; sl= sl->next_select())
|
for (;sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
bool can_skip_order_by;
|
if (prepare_join(thd_arg, sl, tmp_result, additional_options,
|
||||||
sl->options|= SELECT_NO_UNLOCK;
|
is_union_select))
|
||||||
JOIN *join= new JOIN(thd_arg, sl->item_list,
|
goto err;
|
||||||
(sl->options | thd_arg->variables.option_bits |
|
|
||||||
additional_options),
|
|
||||||
tmp_result);
|
|
||||||
/*
|
/*
|
||||||
setup_tables_done_option should be set only for very first SELECT,
|
setup_tables_done_option should be set only for very first SELECT,
|
||||||
because it protect from secont setup_tables call for select-like non
|
because it protect from secont setup_tables call for select-like non
|
||||||
@@ -763,53 +823,12 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
SELECT (for union it can be only INSERT ... SELECT).
|
SELECT (for union it can be only INSERT ... SELECT).
|
||||||
*/
|
*/
|
||||||
additional_options&= ~OPTION_SETUP_TABLES_DONE;
|
additional_options&= ~OPTION_SETUP_TABLES_DONE;
|
||||||
if (!join)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
thd_arg->lex->current_select= sl;
|
|
||||||
|
|
||||||
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
|
|
||||||
|
|
||||||
saved_error= join->prepare(sl->table_list.first,
|
|
||||||
sl->with_wild,
|
|
||||||
sl->where,
|
|
||||||
(can_skip_order_by ? 0 :
|
|
||||||
sl->order_list.elements) +
|
|
||||||
sl->group_list.elements,
|
|
||||||
can_skip_order_by ?
|
|
||||||
NULL : sl->order_list.first,
|
|
||||||
can_skip_order_by,
|
|
||||||
sl->group_list.first,
|
|
||||||
sl->having,
|
|
||||||
(is_union_select ? NULL :
|
|
||||||
thd_arg->lex->proc_list.first),
|
|
||||||
sl, this);
|
|
||||||
|
|
||||||
/* There are no * in the statement anymore (for PS) */
|
|
||||||
sl->with_wild= 0;
|
|
||||||
last_procedure= join->procedure;
|
|
||||||
|
|
||||||
if (saved_error || (saved_error= thd_arg->is_fatal_error))
|
|
||||||
goto err;
|
|
||||||
/*
|
|
||||||
Remove all references from the select_lex_units to the subqueries that
|
|
||||||
are inside the ORDER BY clause.
|
|
||||||
*/
|
|
||||||
if (can_skip_order_by)
|
|
||||||
{
|
|
||||||
for (ORDER *ord= (ORDER *)sl->order_list.first; ord; ord= ord->next)
|
|
||||||
{
|
|
||||||
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Use items list of underlaid select for derived tables to preserve
|
Use items list of underlaid select for derived tables to preserve
|
||||||
information about fields lengths and exact types
|
information about fields lengths and exact types
|
||||||
*/
|
*/
|
||||||
if (!is_union_select && !is_recursive)
|
if (sl == first_sl)
|
||||||
types= first_sl->item_list;
|
|
||||||
else if (sl == first_sl)
|
|
||||||
{
|
{
|
||||||
if (is_recursive)
|
if (is_recursive)
|
||||||
{
|
{
|
||||||
@@ -846,6 +865,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
Item *type, *item_tmp;
|
Item *type, *item_tmp;
|
||||||
while ((type= tp++, item_tmp= it++))
|
while ((type= tp++, item_tmp= it++))
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(item_tmp->fixed);
|
||||||
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
|
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
@@ -878,6 +898,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cont:
|
||||||
/*
|
/*
|
||||||
If the query is using select_union_direct, we have postponed
|
If the query is using select_union_direct, we have postponed
|
||||||
preparation of the underlying select_result until column types
|
preparation of the underlying select_result until column types
|
||||||
|
@@ -156,7 +156,7 @@ bool check_duplicate_names(THD *thd, List<Item> &item_list, bool gen_unique_view
|
|||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
|
my_error(ER_DUP_FIELDNAME, MYF(0), item->name.str);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13713,27 +13713,7 @@ load_data_set_elem:
|
|||||||
text_literal:
|
text_literal:
|
||||||
TEXT_STRING
|
TEXT_STRING
|
||||||
{
|
{
|
||||||
LEX_CSTRING tmp;
|
if (!($$= thd->make_string_literal($1)))
|
||||||
CHARSET_INFO *cs_con= thd->variables.collation_connection;
|
|
||||||
CHARSET_INFO *cs_cli= thd->variables.character_set_client;
|
|
||||||
uint repertoire= $1.repertoire(cs_cli);
|
|
||||||
if (thd->charset_is_collation_connection ||
|
|
||||||
(repertoire == MY_REPERTOIRE_ASCII &&
|
|
||||||
my_charset_is_ascii_based(cs_con)))
|
|
||||||
tmp= $1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LEX_STRING to;
|
|
||||||
if (thd->convert_string(&to, cs_con, $1.str, $1.length, cs_cli))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
tmp.str= to.str;
|
|
||||||
tmp.length= to.length;
|
|
||||||
}
|
|
||||||
$$= new (thd->mem_root) Item_string(thd, tmp.str, tmp.length,
|
|
||||||
cs_con,
|
|
||||||
DERIVATION_COERCIBLE,
|
|
||||||
repertoire);
|
|
||||||
if ($$ == NULL)
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| NCHAR_STRING
|
| NCHAR_STRING
|
||||||
|
@@ -13837,27 +13837,7 @@ load_data_set_elem:
|
|||||||
text_literal:
|
text_literal:
|
||||||
TEXT_STRING
|
TEXT_STRING
|
||||||
{
|
{
|
||||||
LEX_CSTRING tmp;
|
if (!($$= thd->make_string_literal($1)))
|
||||||
CHARSET_INFO *cs_con= thd->variables.collation_connection;
|
|
||||||
CHARSET_INFO *cs_cli= thd->variables.character_set_client;
|
|
||||||
uint repertoire= $1.repertoire(cs_cli);
|
|
||||||
if (thd->charset_is_collation_connection ||
|
|
||||||
(repertoire == MY_REPERTOIRE_ASCII &&
|
|
||||||
my_charset_is_ascii_based(cs_con)))
|
|
||||||
tmp= $1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LEX_STRING to;
|
|
||||||
if (thd->convert_string(&to, cs_con, $1.str, $1.length, cs_cli))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
tmp.str= to.str;
|
|
||||||
tmp.length= to.length;
|
|
||||||
}
|
|
||||||
$$= new (thd->mem_root) Item_string(thd, tmp.str, tmp.length,
|
|
||||||
cs_con,
|
|
||||||
DERIVATION_COERCIBLE,
|
|
||||||
repertoire);
|
|
||||||
if ($$ == NULL)
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| NCHAR_STRING
|
| NCHAR_STRING
|
||||||
|
Reference in New Issue
Block a user