Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into magare.gmz:/home/kgeorge/mysql/autopush/B28366-5.0-opt-win
This commit is contained in:
commit
865f294fcf
@ -39,10 +39,10 @@ t2 CREATE TABLE `t2` (
|
||||
`Field_name` varbinary(255) NOT NULL default '',
|
||||
`Min_value` varbinary(255) default NULL,
|
||||
`Max_value` varbinary(255) default NULL,
|
||||
`Min_length` int(11) NOT NULL default '0',
|
||||
`Max_length` int(11) NOT NULL default '0',
|
||||
`Empties_or_zeros` int(11) NOT NULL default '0',
|
||||
`Nulls` int(11) NOT NULL default '0',
|
||||
`Min_length` bigint(11) NOT NULL default '0',
|
||||
`Max_length` bigint(11) NOT NULL default '0',
|
||||
`Empties_or_zeros` bigint(11) NOT NULL default '0',
|
||||
`Nulls` bigint(11) NOT NULL default '0',
|
||||
`Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
|
||||
`Std` varbinary(255) default NULL,
|
||||
`Optimal_fieldtype` varbinary(64) NOT NULL default ''
|
||||
@ -58,10 +58,10 @@ t2 CREATE TABLE `t2` (
|
||||
`Field_name` varbinary(255) NOT NULL default '',
|
||||
`Min_value` varbinary(255) default NULL,
|
||||
`Max_value` varbinary(255) default NULL,
|
||||
`Min_length` int(11) NOT NULL default '0',
|
||||
`Max_length` int(11) NOT NULL default '0',
|
||||
`Empties_or_zeros` int(11) NOT NULL default '0',
|
||||
`Nulls` int(11) NOT NULL default '0',
|
||||
`Min_length` bigint(11) NOT NULL default '0',
|
||||
`Max_length` bigint(11) NOT NULL default '0',
|
||||
`Empties_or_zeros` bigint(11) NOT NULL default '0',
|
||||
`Nulls` bigint(11) NOT NULL default '0',
|
||||
`Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
|
||||
`Std` varbinary(255) default NULL,
|
||||
`Optimal_fieldtype` varbinary(64) NOT NULL default ''
|
||||
@ -81,10 +81,10 @@ t2 CREATE TABLE `t2` (
|
||||
`Field_name` varbinary(255) NOT NULL default '',
|
||||
`Min_value` varbinary(255) default NULL,
|
||||
`Max_value` varbinary(255) default NULL,
|
||||
`Min_length` int(11) NOT NULL default '0',
|
||||
`Max_length` int(11) NOT NULL default '0',
|
||||
`Empties_or_zeros` int(11) NOT NULL default '0',
|
||||
`Nulls` int(11) NOT NULL default '0',
|
||||
`Min_length` bigint(11) NOT NULL default '0',
|
||||
`Max_length` bigint(11) NOT NULL default '0',
|
||||
`Empties_or_zeros` bigint(11) NOT NULL default '0',
|
||||
`Nulls` bigint(11) NOT NULL default '0',
|
||||
`Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
|
||||
`Std` varbinary(255) default NULL,
|
||||
`Optimal_fieldtype` varbinary(64) NOT NULL default ''
|
||||
|
@ -232,7 +232,7 @@ a b
|
||||
delete from t1 where a=0;
|
||||
update t1 set a=NULL where b=6;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 4
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
update t1 set a=300 where b=7;
|
||||
SET SQL_MODE='';
|
||||
insert into t1(a,b)values(NULL,8);
|
||||
@ -274,7 +274,7 @@ a b
|
||||
delete from t1 where a=0;
|
||||
update t1 set a=NULL where b=13;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 9
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
update t1 set a=500 where b=14;
|
||||
select * from t1 order by b;
|
||||
a b
|
||||
|
@ -13,7 +13,7 @@ Warnings:
|
||||
Note 1050 Table 't1' already exists
|
||||
insert into t1 values (""),(null);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 2
|
||||
Warning 1048 Column 'b' cannot be null
|
||||
select * from t1;
|
||||
b
|
||||
|
||||
|
@ -84,4 +84,15 @@ CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR
|
||||
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
|
||||
CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK
|
||||
2006-10-03
|
||||
create table t1 (a int, b varchar(10));
|
||||
insert into t1 values (1, '2001-01-01'),(2, '2002-02-02');
|
||||
select '2007-01-01' + interval a day from t1;
|
||||
'2007-01-01' + interval a day
|
||||
2007-01-02
|
||||
2007-01-03
|
||||
select b + interval a day from t1;
|
||||
b + interval a day
|
||||
2001-01-02
|
||||
2002-02-04
|
||||
drop table t1;
|
||||
End of 5.0 tests
|
||||
|
@ -63,7 +63,7 @@ insert into t1 values(NULL);
|
||||
ERROR 23000: Column 'id' cannot be null
|
||||
insert into t1 values (1), (NULL), (2);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'id' at row 2
|
||||
Warning 1048 Column 'id' cannot be null
|
||||
select * from t1;
|
||||
id
|
||||
1
|
||||
|
@ -606,8 +606,8 @@ NULL 2 100
|
||||
create table t2(No int not null, Field int not null, Count int not null);
|
||||
insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'No' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'No' at row 2
|
||||
Warning 1048 Column 'No' cannot be null
|
||||
Warning 1048 Column 'No' cannot be null
|
||||
select * from t2;
|
||||
No Field Count
|
||||
0 1 100
|
||||
|
@ -378,7 +378,7 @@ id c1 cnt
|
||||
INSERT IGNORE INTO t1 (id,c1) SELECT 1,NULL
|
||||
ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c1' at row 1
|
||||
Warning 1048 Column 'c1' cannot be null
|
||||
Error 1048 Column 'c1' cannot be null
|
||||
SELECT * FROM t1;
|
||||
id c1 cnt
|
||||
@ -386,7 +386,7 @@ id c1 cnt
|
||||
INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2
|
||||
ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c1' at row 1
|
||||
Warning 1048 Column 'c1' cannot be null
|
||||
Error 1048 Column 'c1' cannot be null
|
||||
SELECT * FROM t1;
|
||||
id c1 cnt
|
||||
|
@ -159,8 +159,8 @@ CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
|
||||
UNIQUE (c,i));
|
||||
INSERT INTO t1 (c) VALUES (NULL),(NULL);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 2
|
||||
Warning 1048 Column 'c' cannot be null
|
||||
Warning 1048 Column 'c' cannot be null
|
||||
SELECT * FROM t1;
|
||||
c i
|
||||
1
|
||||
|
@ -123,3 +123,5 @@ release_lock("lock27563")
|
||||
drop table t1, t2;
|
||||
drop function bug27563;
|
||||
drop procedure proc27563;
|
||||
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 ';
|
||||
EXECUTE stmt;
|
||||
|
@ -130,3 +130,14 @@ def v3 renamed 8 12 0 Y 32896 0 63
|
||||
renamed
|
||||
drop table t1;
|
||||
drop view v1,v2,v3;
|
||||
select a.* from (select 2147483648 as v_large) a;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def a v_large v_large 8 10 10 N 32769 0 63
|
||||
v_large
|
||||
2147483648
|
||||
select a.* from (select 214748364 as v_small) a;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def a v_small v_small 3 9 9 N 32769 0 63
|
||||
v_small
|
||||
214748364
|
||||
End of 5.0 tests
|
||||
|
@ -97,39 +97,39 @@ Warnings:
|
||||
Warning 1265 Data truncated for column 'd' at row 1
|
||||
UPDATE t1 SET d=NULL;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 1
|
||||
Warning 1048 Column 'd' cannot be null
|
||||
INSERT INTO t1 (a) values (null);
|
||||
ERROR 23000: Column 'a' cannot be null
|
||||
INSERT INTO t1 (a) values (1/null);
|
||||
ERROR 23000: Column 'a' cannot be null
|
||||
INSERT INTO t1 (a) values (null),(null);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
INSERT INTO t1 (b) values (null);
|
||||
ERROR 23000: Column 'b' cannot be null
|
||||
INSERT INTO t1 (b) values (1/null);
|
||||
ERROR 23000: Column 'b' cannot be null
|
||||
INSERT INTO t1 (b) values (null),(null);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 2
|
||||
Warning 1048 Column 'b' cannot be null
|
||||
Warning 1048 Column 'b' cannot be null
|
||||
INSERT INTO t1 (c) values (null);
|
||||
ERROR 23000: Column 'c' cannot be null
|
||||
INSERT INTO t1 (c) values (1/null);
|
||||
ERROR 23000: Column 'c' cannot be null
|
||||
INSERT INTO t1 (c) values (null),(null);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 2
|
||||
Warning 1048 Column 'c' cannot be null
|
||||
Warning 1048 Column 'c' cannot be null
|
||||
INSERT INTO t1 (d) values (null);
|
||||
ERROR 23000: Column 'd' cannot be null
|
||||
INSERT INTO t1 (d) values (1/null);
|
||||
ERROR 23000: Column 'd' cannot be null
|
||||
INSERT INTO t1 (d) values (null),(null);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 2
|
||||
Warning 1048 Column 'd' cannot be null
|
||||
Warning 1048 Column 'd' cannot be null
|
||||
select * from t1;
|
||||
a b c d
|
||||
0 0000-00-00 00:00:00 0
|
||||
|
@ -342,7 +342,7 @@ index (id2)
|
||||
);
|
||||
insert into t1 values(null,null),(1,1);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'id2' at row 1
|
||||
Warning 1048 Column 'id2' cannot be null
|
||||
select * from t1;
|
||||
id id2
|
||||
NULL 0
|
||||
|
@ -696,8 +696,8 @@ CREATE VIEW v1 AS
|
||||
SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
|
||||
DESC v1;
|
||||
Field Type Null Key Default Extra
|
||||
a int(11) YES 0
|
||||
LENGTH(a) int(10) YES NULL
|
||||
a bigint(11) YES NULL
|
||||
LENGTH(a) bigint(10) YES NULL
|
||||
COUNT(*) bigint(21) NO 0
|
||||
SELECT * FROM v1;
|
||||
a LENGTH(a) COUNT(*)
|
||||
|
@ -1304,7 +1304,7 @@ set @arg00=NULL;
|
||||
set @arg01=2;
|
||||
execute stmt1 using @arg00, @arg01;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
select a,b from t1 order by a;
|
||||
a b
|
||||
0 two
|
||||
|
@ -1287,7 +1287,7 @@ set @arg00=NULL;
|
||||
set @arg01=2;
|
||||
execute stmt1 using @arg00, @arg01;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
select a,b from t1 order by a;
|
||||
a b
|
||||
0 two
|
||||
|
@ -1288,7 +1288,7 @@ set @arg00=NULL;
|
||||
set @arg01=2;
|
||||
execute stmt1 using @arg00, @arg01;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
select a,b from t1 order by a;
|
||||
a b
|
||||
0 two
|
||||
|
@ -1330,7 +1330,7 @@ set @arg00=NULL;
|
||||
set @arg01=2;
|
||||
execute stmt1 using @arg00, @arg01;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
select a,b from t1 order by a;
|
||||
a b
|
||||
0 two
|
||||
@ -4351,7 +4351,7 @@ set @arg00=NULL;
|
||||
set @arg01=2;
|
||||
execute stmt1 using @arg00, @arg01;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
select a,b from t1 order by a;
|
||||
a b
|
||||
0 two
|
||||
|
@ -1287,7 +1287,7 @@ set @arg00=NULL;
|
||||
set @arg01=2;
|
||||
execute stmt1 using @arg00, @arg01;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
select a,b from t1 order by a;
|
||||
a b
|
||||
0 two
|
||||
|
@ -1287,7 +1287,7 @@ set @arg00=NULL;
|
||||
set @arg01=2;
|
||||
execute stmt1 using @arg00, @arg01;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
select a,b from t1 order by a;
|
||||
a b
|
||||
0 two
|
||||
|
@ -106,4 +106,10 @@ a b
|
||||
1 6
|
||||
drop table t1;
|
||||
drop view v1;
|
||||
CREATE TABLE t1(a INT);
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
ERROR 42S01: Table 'v1' already exists
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
|
@ -4909,7 +4909,7 @@ create table t3 as select * from v1|
|
||||
show create table t3|
|
||||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`j` int(11) default NULL
|
||||
`j` bigint(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t3|
|
||||
j
|
||||
@ -6152,3 +6152,14 @@ count(*)
|
||||
3
|
||||
drop table t1,t2;
|
||||
drop function bug27354;
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE FUNCTION metered(a INT) RETURNS INT RETURN 12;
|
||||
CREATE VIEW v1 AS SELECT test.metered(a) as metered FROM t1;
|
||||
SHOW CREATE VIEW v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`metered`(`t1`.`a`) AS `metered` from `t1`
|
||||
DROP VIEW v1;
|
||||
DROP FUNCTION metered;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
|
@ -993,16 +993,16 @@ ERROR 23000: Column 'col2' cannot be null
|
||||
INSERT INTO t1 VALUES (103,'',NULL);
|
||||
ERROR 23000: Column 'col3' cannot be null
|
||||
UPDATE t1 SET col1=NULL WHERE col1 =100;
|
||||
ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1
|
||||
ERROR 23000: Column 'col1' cannot be null
|
||||
UPDATE t1 SET col2 =NULL WHERE col2 ='hello';
|
||||
ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
|
||||
ERROR 23000: Column 'col2' cannot be null
|
||||
UPDATE t1 SET col2 =NULL where col3 IS NOT NULL;
|
||||
ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
|
||||
ERROR 23000: Column 'col2' cannot be null
|
||||
INSERT IGNORE INTO t1 values (NULL,NULL,NULL);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col3' at row 1
|
||||
Warning 1048 Column 'col1' cannot be null
|
||||
Warning 1048 Column 'col2' cannot be null
|
||||
Warning 1048 Column 'col3' cannot be null
|
||||
SELECT * FROM t1;
|
||||
col1 col2 col3
|
||||
100 hello 2004-08-20
|
||||
@ -1027,11 +1027,11 @@ ERROR HY000: Field 'col2' doesn't have a default value
|
||||
INSERT INTO t1 (col1) SELECT 1;
|
||||
ERROR HY000: Field 'col2' doesn't have a default value
|
||||
INSERT INTO t1 SELECT 1,NULL;
|
||||
ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
|
||||
ERROR 23000: Column 'col2' cannot be null
|
||||
INSERT IGNORE INTO t1 values (NULL,NULL);
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
|
||||
Warning 1048 Column 'col1' cannot be null
|
||||
Warning 1048 Column 'col2' cannot be null
|
||||
INSERT IGNORE INTO t1 (col1) values (3);
|
||||
Warnings:
|
||||
Warning 1364 Field 'col2' doesn't have a default value
|
||||
|
@ -1779,3 +1779,10 @@ create table t1(exhausting_charset enum('ABCDEFGHIJKLMNOPQRSTUVWXYZ','
|
||||
!"','#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~','xx\','yy\€','zz亗儎厗噲墛媽崕彁憭摂晼棙櫄洔潪煚、¥ウЖ┆<D096><E29486><EFBFBD>辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬<E8B28A><E9BCAC><EFBFBD><EFBFBD>'));
|
||||
ERROR 42000: Field separator argument is not what is expected; check the manual
|
||||
End of 4.1 tests
|
||||
create table t1(f1 set('a','b'), index(f1));
|
||||
insert into t1 values(''),(''),('a'),('b');
|
||||
select * from t1 where f1='';
|
||||
f1
|
||||
|
||||
|
||||
drop table t1;
|
||||
|
@ -317,3 +317,10 @@ SHOW COUNT(*) WARNINGS;
|
||||
SHOW COUNT(*) ERRORS;
|
||||
@@session.error_count
|
||||
1
|
||||
create table t1(f1 int);
|
||||
insert into t1 values(1),(1),(2);
|
||||
select @a:=f1, count(f1) from t1 group by 1;
|
||||
@a:=f1 count(f1)
|
||||
1 2
|
||||
2 1
|
||||
drop table t1;
|
||||
|
@ -1497,7 +1497,7 @@ insert into v3(b) values (10);
|
||||
insert into v3(a) select a from t2;
|
||||
insert into v3(b) select b from t2;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
insert into v3(a) values (1) on duplicate key update a=a+10000+VALUES(a);
|
||||
select * from t1;
|
||||
a b
|
||||
@ -2779,7 +2779,7 @@ CREATE TABLE t1 (i int, j int);
|
||||
CREATE VIEW v1 AS SELECT COALESCE(i,j) FROM t1;
|
||||
DESCRIBE v1;
|
||||
Field Type Null Key Default Extra
|
||||
COALESCE(i,j) int(11) YES NULL
|
||||
COALESCE(i,j) bigint(11) YES NULL
|
||||
CREATE TABLE t2 SELECT COALESCE(i,j) FROM t1;
|
||||
DESCRIBE t2;
|
||||
Field Type Null Key Default Extra
|
||||
@ -3367,6 +3367,23 @@ SHOW CREATE VIEW v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(1.23456789 as decimal(8,0)) AS `col`
|
||||
DROP VIEW v1;
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE TABLE t2 (b INT, c INT DEFAULT 0);
|
||||
INSERT INTO t1 (a) VALUES (1), (2);
|
||||
INSERT INTO t2 (b) VALUES (1), (2);
|
||||
CREATE VIEW v1 AS SELECT t2.b,t2.c FROM t1, t2
|
||||
WHERE t1.a=t2.b AND t2.b < 3 WITH CHECK OPTION;
|
||||
SELECT * FROM v1;
|
||||
b c
|
||||
1 0
|
||||
2 0
|
||||
UPDATE v1 SET c=1 WHERE b=1;
|
||||
SELECT * FROM v1;
|
||||
b c
|
||||
1 1
|
||||
2 0
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (id int);
|
||||
CREATE TABLE t2 (id int, c int DEFAULT 0);
|
||||
INSERT INTO t1 (id) VALUES (1);
|
||||
@ -3377,4 +3394,65 @@ WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
||||
UPDATE v1 SET c=1;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (a1 INT, c INT DEFAULT 0);
|
||||
CREATE TABLE t2 (a2 INT);
|
||||
CREATE TABLE t3 (a3 INT);
|
||||
CREATE TABLE t4 (a4 INT);
|
||||
INSERT INTO t1 (a1) VALUES (1),(2);
|
||||
INSERT INTO t2 (a2) VALUES (1),(2);
|
||||
INSERT INTO t3 (a3) VALUES (1),(2);
|
||||
INSERT INTO t4 (a4) VALUES (1),(2);
|
||||
CREATE VIEW v1 AS
|
||||
SELECT t1.a1, t1.c FROM t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3
|
||||
WITH CHECK OPTION;
|
||||
SELECT * FROM v1;
|
||||
a1 c
|
||||
1 0
|
||||
2 0
|
||||
UPDATE v1 SET c=3;
|
||||
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||
PREPARE t FROM 'UPDATE v1 SET c=3';
|
||||
EXECUTE t;
|
||||
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||
EXECUTE t;
|
||||
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||
INSERT INTO v1(a1, c) VALUES (3, 3);
|
||||
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||
UPDATE v1 SET c=1 WHERE a1=1;
|
||||
SELECT * FROM v1;
|
||||
a1 c
|
||||
1 1
|
||||
2 0
|
||||
SELECT * FROM t1;
|
||||
a1 c
|
||||
1 1
|
||||
2 0
|
||||
CREATE VIEW v2 AS SELECT t1.a1, t1.c
|
||||
FROM (t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3)
|
||||
JOIN (t3 JOIN t4 ON t3.a3=t4.a4)
|
||||
ON t2.a2=t3.a3 WITH CHECK OPTION;
|
||||
SELECT * FROM v2;
|
||||
a1 c
|
||||
1 1
|
||||
2 0
|
||||
UPDATE v2 SET c=3;
|
||||
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||
PREPARE t FROM 'UPDATE v2 SET c=3';
|
||||
EXECUTE t;
|
||||
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||
EXECUTE t;
|
||||
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||
INSERT INTO v2(a1, c) VALUES (3, 3);
|
||||
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||
UPDATE v2 SET c=2 WHERE a1=1;
|
||||
SELECT * FROM v2;
|
||||
a1 c
|
||||
1 2
|
||||
2 0
|
||||
SELECT * FROM t1;
|
||||
a1 c
|
||||
1 2
|
||||
2 0
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
End of 5.0 tests.
|
||||
|
@ -86,7 +86,7 @@ drop table t1;
|
||||
create table t1(a tinyint NOT NULL, b tinyint unsigned, c char(5));
|
||||
insert into t1 values(NULL,100,'mysql'),(10,-1,'mysql ab'),(500,256,'open source'),(20,NULL,'test');
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
Warning 1264 Out of range value adjusted for column 'b' at row 2
|
||||
Warning 1265 Data truncated for column 'c' at row 2
|
||||
Warning 1264 Out of range value adjusted for column 'a' at row 3
|
||||
@ -99,7 +99,7 @@ Warning 1265 Data truncated for column 'c' at row 2
|
||||
alter table t1 add d char(2);
|
||||
update t1 set a=NULL where a=10;
|
||||
Warnings:
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
update t1 set c='mysql ab' where c='test';
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'c' at row 4
|
||||
@ -115,7 +115,7 @@ Warnings:
|
||||
Warning 1265 Data truncated for column 'b' at row 1
|
||||
Warning 1265 Data truncated for column 'b' at row 2
|
||||
Warning 1265 Data truncated for column 'b' at row 3
|
||||
Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 4
|
||||
Warning 1048 Column 'a' cannot be null
|
||||
Warning 1265 Data truncated for column 'b' at row 4
|
||||
insert into t2(b) values('mysqlab');
|
||||
Warnings:
|
||||
|
@ -10,7 +10,13 @@ select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
|
||||
select ~5, cast(~5 as signed);
|
||||
explain extended select ~5, cast(~5 as signed);
|
||||
select cast(5 as unsigned) -6.0;
|
||||
select cast(NULL as signed), cast(1/0 as signed);
|
||||
select cast(NULL as signed), cast(1/0 as signed);
|
||||
#
|
||||
# Bug #28250: Run-Time Check Failure #3 - The variable 'value' is being used
|
||||
# without being def
|
||||
#
|
||||
# The following line causes Run-Time Check Failure on
|
||||
# binaries built with Visual C++ 2005
|
||||
select cast(NULL as unsigned), cast(1/0 as unsigned);
|
||||
select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
|
||||
select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
|
||||
|
@ -77,4 +77,14 @@ SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH;
|
||||
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR;
|
||||
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
|
||||
|
||||
#
|
||||
# Bug#28450: The Item_date_add_interval in select list may fail the field
|
||||
# type assertion.
|
||||
#
|
||||
create table t1 (a int, b varchar(10));
|
||||
insert into t1 values (1, '2001-01-01'),(2, '2002-02-02');
|
||||
select '2007-01-01' + interval a day from t1;
|
||||
select b + interval a day from t1;
|
||||
drop table t1;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -249,3 +249,56 @@ select release_lock("lock27563");
|
||||
drop table t1, t2;
|
||||
drop function bug27563;
|
||||
drop procedure proc27563;
|
||||
|
||||
#
|
||||
# Bug#28598: mysqld crash when killing a long-running explain query.
|
||||
#
|
||||
--disable_query_log
|
||||
connection con1;
|
||||
let $ID= `select connection_id()`;
|
||||
let $tab_count= 40;
|
||||
|
||||
let $i= $tab_count;
|
||||
while ($i)
|
||||
{
|
||||
eval CREATE TABLE t$i (a$i int, KEY(a$i));
|
||||
eval INSERT INTO t$i VALUES (1),(2),(3),(4),(5),(6),(7);
|
||||
dec $i ;
|
||||
}
|
||||
set session optimizer_search_depth=0;
|
||||
|
||||
let $i=$tab_count;
|
||||
while ($i)
|
||||
{
|
||||
let $a= a$i;
|
||||
let $t= t$i;
|
||||
dec $i;
|
||||
if ($i)
|
||||
{
|
||||
let $comma=,;
|
||||
let $from=$comma$t$from;
|
||||
let $where=a$i=$a $and $where;
|
||||
}
|
||||
if (!$i)
|
||||
{
|
||||
let $from=FROM $t$from;
|
||||
let $where=WHERE $where;
|
||||
}
|
||||
let $and=AND;
|
||||
}
|
||||
|
||||
--enable_query_log
|
||||
eval PREPARE stmt FROM 'EXPLAIN SELECT * $from $where';
|
||||
send EXECUTE stmt;
|
||||
--disable_query_log
|
||||
|
||||
connection con2;
|
||||
real_sleep 2;
|
||||
eval kill query $ID;
|
||||
let $i= $tab_count;
|
||||
while ($i)
|
||||
{
|
||||
eval DROP TABLE t$i;
|
||||
dec $i ;
|
||||
}
|
||||
--enable_query_log
|
||||
|
@ -81,3 +81,14 @@ drop view v1,v2,v3;
|
||||
--disable_metadata
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Bug #28492: subselect returns LONG in >5.0.24a and LONGLONG in <=5.0.24a
|
||||
#
|
||||
--enable_metadata
|
||||
select a.* from (select 2147483648 as v_large) a;
|
||||
select a.* from (select 214748364 as v_small) a;
|
||||
--disable_metadata
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -149,4 +149,16 @@ drop view v1;
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
#
|
||||
# BUG#28244 CREATE VIEW breaks replication when view exists
|
||||
#
|
||||
connection master;
|
||||
CREATE TABLE t1(a INT);
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
--error ER_TABLE_EXISTS_ERROR
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -7112,3 +7112,23 @@ select count(*) from t1 /* must be 3 */;
|
||||
|
||||
drop table t1,t2;
|
||||
drop function bug27354;
|
||||
|
||||
#
|
||||
# Bug #28605: SHOW CREATE VIEW with views using stored_procedures no longer
|
||||
# showing SP names.
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
CREATE FUNCTION metered(a INT) RETURNS INT RETURN 12;
|
||||
|
||||
CREATE VIEW v1 AS SELECT test.metered(a) as metered FROM t1;
|
||||
|
||||
SHOW CREATE VIEW v1;
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP FUNCTION metered;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -890,11 +890,11 @@ INSERT INTO t1 (col1,col2,col3) VALUES (NULL, '', '2004-01-01');
|
||||
INSERT INTO t1 (col1,col2,col3) VALUES (102, NULL, '2004-01-01');
|
||||
--error 1048
|
||||
INSERT INTO t1 VALUES (103,'',NULL);
|
||||
--error 1263
|
||||
--error 1048
|
||||
UPDATE t1 SET col1=NULL WHERE col1 =100;
|
||||
--error 1263
|
||||
--error 1048
|
||||
UPDATE t1 SET col2 =NULL WHERE col2 ='hello';
|
||||
--error 1263
|
||||
--error 1048
|
||||
UPDATE t1 SET col2 =NULL where col3 IS NOT NULL;
|
||||
INSERT IGNORE INTO t1 values (NULL,NULL,NULL);
|
||||
SELECT * FROM t1;
|
||||
@ -914,7 +914,7 @@ INSERT INTO t1 (col1) VALUES (2);
|
||||
INSERT INTO t1 VALUES(default(col1),default(col2));
|
||||
--error 1364
|
||||
INSERT INTO t1 (col1) SELECT 1;
|
||||
--error 1263
|
||||
--error 1048
|
||||
INSERT INTO t1 SELECT 1,NULL;
|
||||
INSERT IGNORE INTO t1 values (NULL,NULL);
|
||||
INSERT IGNORE INTO t1 (col1) values (3);
|
||||
|
@ -157,3 +157,11 @@ create table t1(exhausting_charset enum('ABCDEFGHIJKLMNOPQRSTUVWXYZ','
|
||||
!"','#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~','xx\','yy\€','zz亗儎厗噲墛媽崕彁憭摂晼棙櫄洔潪煚、¥ウЖ┆<D096><E29486><EFBFBD>辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬<E8B28A><E9BCAC><EFBFBD><EFBFBD>'));
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
# Bug#28729: Field_enum wrongly reported an error while storing an empty string.
|
||||
#
|
||||
create table t1(f1 set('a','b'), index(f1));
|
||||
insert into t1 values(''),(''),('a'),('b');
|
||||
select * from t1 where f1='';
|
||||
drop table t1;
|
||||
|
@ -222,3 +222,11 @@ drop table t1,t2;
|
||||
insert into city 'blah';
|
||||
SHOW COUNT(*) WARNINGS;
|
||||
SHOW COUNT(*) ERRORS;
|
||||
|
||||
#
|
||||
# Bug#28494: Grouping by Item_func_set_user_var produces incorrect result.
|
||||
#
|
||||
create table t1(f1 int);
|
||||
insert into t1 values(1),(1),(2);
|
||||
select @a:=f1, count(f1) from t1 group by 1;
|
||||
drop table t1;
|
||||
|
@ -3233,6 +3233,22 @@ CREATE VIEW v1 AS SELECT CAST(1.23456789 AS DECIMAL(8,0)) AS col;
|
||||
SHOW CREATE VIEW v1;
|
||||
DROP VIEW v1;
|
||||
|
||||
#
|
||||
# Bug #28716: CHECK OPTION expression is evaluated over expired record buffers
|
||||
# when VIEW is updated via temporary tables
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE TABLE t2 (b INT, c INT DEFAULT 0);
|
||||
INSERT INTO t1 (a) VALUES (1), (2);
|
||||
INSERT INTO t2 (b) VALUES (1), (2);
|
||||
CREATE VIEW v1 AS SELECT t2.b,t2.c FROM t1, t2
|
||||
WHERE t1.a=t2.b AND t2.b < 3 WITH CHECK OPTION;
|
||||
SELECT * FROM v1;
|
||||
UPDATE v1 SET c=1 WHERE b=1;
|
||||
SELECT * FROM v1;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #28561: update on multi-table view with CHECK OPTION and
|
||||
# a subquery in WHERE condition
|
||||
@ -3252,4 +3268,56 @@ UPDATE v1 SET c=1;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #27827: CHECK OPTION ignores ON conditions when updating
|
||||
# a multi-table view with CHECK OPTION.
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a1 INT, c INT DEFAULT 0);
|
||||
CREATE TABLE t2 (a2 INT);
|
||||
CREATE TABLE t3 (a3 INT);
|
||||
CREATE TABLE t4 (a4 INT);
|
||||
INSERT INTO t1 (a1) VALUES (1),(2);
|
||||
INSERT INTO t2 (a2) VALUES (1),(2);
|
||||
INSERT INTO t3 (a3) VALUES (1),(2);
|
||||
INSERT INTO t4 (a4) VALUES (1),(2);
|
||||
|
||||
CREATE VIEW v1 AS
|
||||
SELECT t1.a1, t1.c FROM t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3
|
||||
WITH CHECK OPTION;
|
||||
SELECT * FROM v1;
|
||||
--error 1369
|
||||
UPDATE v1 SET c=3;
|
||||
PREPARE t FROM 'UPDATE v1 SET c=3';
|
||||
--error 1369
|
||||
EXECUTE t;
|
||||
--error 1369
|
||||
EXECUTE t;
|
||||
--error 1369
|
||||
INSERT INTO v1(a1, c) VALUES (3, 3);
|
||||
UPDATE v1 SET c=1 WHERE a1=1;
|
||||
SELECT * FROM v1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
CREATE VIEW v2 AS SELECT t1.a1, t1.c
|
||||
FROM (t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3)
|
||||
JOIN (t3 JOIN t4 ON t3.a3=t4.a4)
|
||||
ON t2.a2=t3.a3 WITH CHECK OPTION;
|
||||
SELECT * FROM v2;
|
||||
--error 1369
|
||||
UPDATE v2 SET c=3;
|
||||
PREPARE t FROM 'UPDATE v2 SET c=3';
|
||||
--error 1369
|
||||
EXECUTE t;
|
||||
--error 1369
|
||||
EXECUTE t;
|
||||
--error 1369
|
||||
INSERT INTO v2(a1, c) VALUES (3, 3);
|
||||
UPDATE v2 SET c=2 WHERE a1=1;
|
||||
SELECT * FROM v2;
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -7643,6 +7643,8 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||
tmp=0;
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
if (!table->in_use->count_cuted_fields)
|
||||
err= 0;
|
||||
}
|
||||
else
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
|
@ -675,7 +675,7 @@ public:
|
||||
void sort_string(char *buff,uint length);
|
||||
uint32 pack_length() const { return 4; }
|
||||
void sql_type(String &str) const;
|
||||
uint32 max_display_length() { return 11; }
|
||||
uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -177,8 +177,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
|
||||
}
|
||||
if (current_thd->count_cuted_fields == CHECK_FIELD_WARN)
|
||||
{
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WARN_NULL_TO_NOTNULL, 1);
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
|
||||
return 0;
|
||||
}
|
||||
if (!current_thd->no_errors)
|
||||
|
@ -766,7 +766,12 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
||||
{
|
||||
value= item->val_int();
|
||||
*is_null= item->null_value;
|
||||
if (item->field_type() == MYSQL_TYPE_DATE)
|
||||
/*
|
||||
Item_date_add_interval may return MYSQL_TYPE_STRING as the result
|
||||
field type. To detect that the DATE value has been returned we
|
||||
compare it with 1000000L - any DATE value should be less than it.
|
||||
*/
|
||||
if (item->field_type() == MYSQL_TYPE_DATE || value < 100000000L)
|
||||
value*= 1000000L;
|
||||
}
|
||||
else
|
||||
|
@ -996,6 +996,8 @@ longlong Item_func_unsigned::val_int()
|
||||
my_decimal tmp, *dec= args[0]->val_decimal(&tmp);
|
||||
if (!(null_value= args[0]->null_value))
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value);
|
||||
else
|
||||
value= 0;
|
||||
return value;
|
||||
}
|
||||
else if (args[0]->cast_to_int_type() != STRING_RESULT ||
|
||||
@ -4288,9 +4290,11 @@ void Item_func_set_user_var::make_field(Send_field *tmp_field)
|
||||
TRUE Error
|
||||
*/
|
||||
|
||||
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions)
|
||||
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
|
||||
bool can_use_result_field)
|
||||
{
|
||||
bool use_result_field= (result_field && result_field != field);
|
||||
bool use_result_field= (!can_use_result_field ? 0 :
|
||||
(result_field && result_field != field));
|
||||
int error;
|
||||
|
||||
/* Update the value of the user variable */
|
||||
@ -5213,10 +5217,11 @@ Item_func_sp::func_name() const
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
/* Calculate length to avoid reallocation of string for sure */
|
||||
uint len= ((m_name->m_explicit_name ? m_name->m_db.length : 0 +
|
||||
uint len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
|
||||
m_name->m_name.length)*2 + //characters*quoting
|
||||
2 + // ` and `
|
||||
1 + // .
|
||||
(m_name->m_explicit_name ?
|
||||
3 : 0) + // '`', '`' and '.' for the db
|
||||
1 + // end of string
|
||||
ALIGN_SIZE(1)); // to avoid String reallocation
|
||||
String qname((char *)alloc_root(thd->mem_root, len), len,
|
||||
|
@ -1220,7 +1220,13 @@ public:
|
||||
void print(String *str);
|
||||
void print_as_stmt(String *str);
|
||||
const char *func_name() const { return "set_user_var"; }
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
int save_in_field(Field *field, bool no_conversions,
|
||||
bool can_use_result_field);
|
||||
int save_in_field(Field *field, bool no_conversions)
|
||||
{
|
||||
return save_in_field(field, no_conversions, 1);
|
||||
}
|
||||
void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2180,27 +2180,6 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
|
||||
default:
|
||||
goto null_date;
|
||||
}
|
||||
|
||||
/* Adjust cached_field_type according to the detected type. */
|
||||
if (cached_field_type == MYSQL_TYPE_STRING)
|
||||
{
|
||||
switch (ltime->time_type)
|
||||
{
|
||||
case MYSQL_TIMESTAMP_DATE:
|
||||
cached_field_type= MYSQL_TYPE_DATE;
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_DATETIME:
|
||||
cached_field_type= MYSQL_TYPE_DATETIME;
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_TIME:
|
||||
cached_field_type= MYSQL_TYPE_TIME;
|
||||
break;
|
||||
default:
|
||||
/* Shouldn't get here. */
|
||||
DBUG_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0; // Ok
|
||||
|
||||
invalid_date:
|
||||
|
@ -2283,6 +2283,11 @@ class multi_update :public select_result_interceptor
|
||||
List <Item> *fields, *values;
|
||||
List <Item> **fields_for_table, **values_for_table;
|
||||
uint table_count;
|
||||
/*
|
||||
List of tables referenced in the CHECK OPTION condition of
|
||||
the updated view excluding the updated table.
|
||||
*/
|
||||
List <TABLE> unupdated_check_opt_tables;
|
||||
Copy_field *copy_field;
|
||||
enum enum_duplicates handle_duplicates;
|
||||
bool do_update, trans_safe;
|
||||
|
@ -49,15 +49,15 @@ static int sort_keyuse(KEYUSE *a,KEYUSE *b);
|
||||
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
|
||||
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
table_map used_tables);
|
||||
static void choose_plan(JOIN *join,table_map join_tables);
|
||||
static bool choose_plan(JOIN *join,table_map join_tables);
|
||||
|
||||
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
|
||||
table_map remaining_tables, uint idx,
|
||||
double record_count, double read_time);
|
||||
static void optimize_straight_join(JOIN *join, table_map join_tables);
|
||||
static void greedy_search(JOIN *join, table_map remaining_tables,
|
||||
static bool greedy_search(JOIN *join, table_map remaining_tables,
|
||||
uint depth, uint prune_level);
|
||||
static void best_extension_by_limited_search(JOIN *join,
|
||||
static bool best_extension_by_limited_search(JOIN *join,
|
||||
table_map remaining_tables,
|
||||
uint idx, double record_count,
|
||||
double read_time, uint depth,
|
||||
@ -69,7 +69,7 @@ static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
|
||||
TODO: 'find_best' is here only temporarily until 'greedy_search' is
|
||||
tested and approved.
|
||||
*/
|
||||
static void find_best(JOIN *join,table_map rest_tables,uint index,
|
||||
static bool find_best(JOIN *join,table_map rest_tables,uint index,
|
||||
double record_count,double read_time);
|
||||
static uint cache_record_length(JOIN *join,uint index);
|
||||
static double prev_record_reads(JOIN *join,table_map found_ref);
|
||||
@ -2717,7 +2717,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
if (join->const_tables != join->tables)
|
||||
{
|
||||
optimize_keyuse(join, keyuse_array);
|
||||
choose_plan(join, all_table_map & ~join->const_table_map);
|
||||
if (choose_plan(join, all_table_map & ~join->const_table_map))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4307,11 +4308,12 @@ best_access_path(JOIN *join,
|
||||
the array 'join->best_positions', and the cost of the plan in
|
||||
'join->best_read'.
|
||||
|
||||
RETURN
|
||||
None
|
||||
RETURN VALUES
|
||||
FALSE ok
|
||||
TRUE Fatal error
|
||||
*/
|
||||
|
||||
static void
|
||||
static bool
|
||||
choose_plan(JOIN *join, table_map join_tables)
|
||||
{
|
||||
uint search_depth= join->thd->variables.optimizer_search_depth;
|
||||
@ -4344,14 +4346,16 @@ choose_plan(JOIN *join, table_map join_tables)
|
||||
the greedy version. Will be removed when greedy_search is approved.
|
||||
*/
|
||||
join->best_read= DBL_MAX;
|
||||
find_best(join, join_tables, join->const_tables, 1.0, 0.0);
|
||||
if (find_best(join, join_tables, join->const_tables, 1.0, 0.0))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (search_depth == 0)
|
||||
/* Automatically determine a reasonable value for 'search_depth' */
|
||||
search_depth= determine_search_depth(join);
|
||||
greedy_search(join, join_tables, search_depth, prune_level);
|
||||
if (greedy_search(join, join_tables, search_depth, prune_level))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4361,7 +4365,7 @@ choose_plan(JOIN *join, table_map join_tables)
|
||||
*/
|
||||
if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
|
||||
join->thd->status_var.last_query_cost= join->best_read;
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -4589,11 +4593,12 @@ optimize_straight_join(JOIN *join, table_map join_tables)
|
||||
In the future, 'greedy_search' might be extended to support other
|
||||
implementations of 'best_extension', e.g. some simpler quadratic procedure.
|
||||
|
||||
RETURN
|
||||
None
|
||||
RETURN VALUES
|
||||
FALSE ok
|
||||
TRUE Fatal error
|
||||
*/
|
||||
|
||||
static void
|
||||
static bool
|
||||
greedy_search(JOIN *join,
|
||||
table_map remaining_tables,
|
||||
uint search_depth,
|
||||
@ -4615,8 +4620,9 @@ greedy_search(JOIN *join,
|
||||
do {
|
||||
/* Find the extension of the current QEP with the lowest cost */
|
||||
join->best_read= DBL_MAX;
|
||||
best_extension_by_limited_search(join, remaining_tables, idx, record_count,
|
||||
read_time, search_depth, prune_level);
|
||||
if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
|
||||
read_time, search_depth, prune_level))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (size_remain <= search_depth)
|
||||
{
|
||||
@ -4627,7 +4633,7 @@ greedy_search(JOIN *join,
|
||||
DBUG_EXECUTE("opt", print_plan(join, join->tables,
|
||||
record_count, read_time, read_time,
|
||||
"optimal"););
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/* select the first table in the optimal extension as most promising */
|
||||
@ -4772,11 +4778,12 @@ greedy_search(JOIN *join,
|
||||
The parameter 'search_depth' provides control over the recursion
|
||||
depth, and thus the size of the resulting optimal plan.
|
||||
|
||||
RETURN
|
||||
None
|
||||
RETURN VALUES
|
||||
FALSE ok
|
||||
TRUE Fatal error
|
||||
*/
|
||||
|
||||
static void
|
||||
static bool
|
||||
best_extension_by_limited_search(JOIN *join,
|
||||
table_map remaining_tables,
|
||||
uint idx,
|
||||
@ -4785,11 +4792,11 @@ best_extension_by_limited_search(JOIN *join,
|
||||
uint search_depth,
|
||||
uint prune_level)
|
||||
{
|
||||
DBUG_ENTER("best_extension_by_limited_search");
|
||||
|
||||
THD *thd= join->thd;
|
||||
if (thd->killed) // Abort
|
||||
return;
|
||||
|
||||
DBUG_ENTER("best_extension_by_limited_search");
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/*
|
||||
'join' is a partial plan with lower cost than the best plan so far,
|
||||
@ -4869,15 +4876,14 @@ best_extension_by_limited_search(JOIN *join,
|
||||
if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
|
||||
{ /* Recursively expand the current partial plan */
|
||||
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
|
||||
best_extension_by_limited_search(join,
|
||||
remaining_tables & ~real_table_bit,
|
||||
idx + 1,
|
||||
current_record_count,
|
||||
current_read_time,
|
||||
search_depth - 1,
|
||||
prune_level);
|
||||
if (thd->killed)
|
||||
DBUG_VOID_RETURN;
|
||||
if (best_extension_by_limited_search(join,
|
||||
remaining_tables & ~real_table_bit,
|
||||
idx + 1,
|
||||
current_record_count,
|
||||
current_read_time,
|
||||
search_depth - 1,
|
||||
prune_level))
|
||||
DBUG_RETURN(TRUE);
|
||||
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
|
||||
}
|
||||
else
|
||||
@ -4906,19 +4912,26 @@ best_extension_by_limited_search(JOIN *join,
|
||||
restore_prev_nj_state(s);
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TODO: this function is here only temporarily until 'greedy_search' is
|
||||
tested and accepted.
|
||||
|
||||
RETURN VALUES
|
||||
FALSE ok
|
||||
TRUE Fatal error
|
||||
*/
|
||||
static void
|
||||
static bool
|
||||
find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
||||
double read_time)
|
||||
{
|
||||
DBUG_ENTER("find_best");
|
||||
THD *thd= join->thd;
|
||||
if (thd->killed)
|
||||
DBUG_RETURN(TRUE);
|
||||
if (!rest_tables)
|
||||
{
|
||||
DBUG_PRINT("best",("read_time: %g record_count: %g",read_time,
|
||||
@ -4935,10 +4948,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
||||
sizeof(POSITION)*idx);
|
||||
join->best_read= read_time - 0.001;
|
||||
}
|
||||
return;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
|
||||
return; /* Found better before */
|
||||
DBUG_RETURN(FALSE); /* Found better before */
|
||||
|
||||
JOIN_TAB *s;
|
||||
double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
|
||||
@ -4971,10 +4984,9 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
||||
best_read_time=current_read_time;
|
||||
}
|
||||
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
|
||||
find_best(join,rest_tables & ~real_table_bit,idx+1,
|
||||
current_record_count,current_read_time);
|
||||
if (thd->killed)
|
||||
return;
|
||||
if (find_best(join,rest_tables & ~real_table_bit,idx+1,
|
||||
current_record_count,current_read_time))
|
||||
DBUG_RETURN(TRUE);
|
||||
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
|
||||
}
|
||||
restore_prev_nj_state(s);
|
||||
@ -4982,6 +4994,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
||||
break; // Don't test all combinations
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -8869,8 +8882,13 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
||||
item->name, table, item->decimals, TRUE);
|
||||
break;
|
||||
case INT_RESULT:
|
||||
/* Select an integer type with the minimal fit precision */
|
||||
if (item->max_length > MY_INT32_NUM_DECIMAL_DIGITS)
|
||||
/*
|
||||
Select an integer type with the minimal fit precision.
|
||||
MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
|
||||
Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
|
||||
Field_long : make them Field_longlong.
|
||||
*/
|
||||
if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
|
||||
new_field=new Field_longlong(item->max_length, maybe_null,
|
||||
item->name, table, item->unsigned_flag);
|
||||
else
|
||||
|
@ -970,6 +970,7 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
||||
List_iterator_fast<Item> field_it(*fields);
|
||||
List_iterator_fast<Item> value_it(*values);
|
||||
uint i, max_fields;
|
||||
uint leaf_table_count= 0;
|
||||
DBUG_ENTER("multi_update::prepare");
|
||||
|
||||
thd->count_cuted_fields= CHECK_FIELD_WARN;
|
||||
@ -1003,6 +1004,7 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
||||
{
|
||||
/* TODO: add support of view of join support */
|
||||
TABLE *table=table_ref->table;
|
||||
leaf_table_count++;
|
||||
if (tables_to_update & table->map)
|
||||
{
|
||||
TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
|
||||
@ -1067,7 +1069,7 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
||||
/* Allocate copy fields */
|
||||
max_fields=0;
|
||||
for (i=0 ; i < table_count ; i++)
|
||||
set_if_bigger(max_fields, fields_for_table[i]->elements);
|
||||
set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
|
||||
copy_field= new Copy_field[max_fields];
|
||||
DBUG_RETURN(thd->is_fatal_error != 0);
|
||||
}
|
||||
@ -1160,13 +1162,22 @@ multi_update::initialize_tables(JOIN *join)
|
||||
trans_safe= transactional_tables= main_table->file->has_transactions();
|
||||
table_to_update= 0;
|
||||
|
||||
/* Any update has at least one pair (field, value) */
|
||||
DBUG_ASSERT(fields->elements);
|
||||
/*
|
||||
Only one table may be modified by UPDATE of an updatable view.
|
||||
For an updatable view first_table_for_update indicates this
|
||||
table.
|
||||
For a regular multi-update it refers to some updated table.
|
||||
*/
|
||||
TABLE *first_table_for_update= ((Item_field *) fields->head())->field->table;
|
||||
|
||||
/* Create a temporary table for keys to all tables, except main table */
|
||||
for (table_ref= update_tables; table_ref; table_ref= table_ref->next_local)
|
||||
{
|
||||
TABLE *table=table_ref->table;
|
||||
uint cnt= table_ref->shared;
|
||||
Item_field *ifield;
|
||||
List<Item> temp_fields= *fields_for_table[cnt];
|
||||
List<Item> temp_fields;
|
||||
ORDER group;
|
||||
|
||||
if (ignore)
|
||||
@ -1174,34 +1185,63 @@ multi_update::initialize_tables(JOIN *join)
|
||||
if (table == main_table) // First table in join
|
||||
{
|
||||
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables,
|
||||
&temp_fields))
|
||||
fields_for_table[cnt]))
|
||||
{
|
||||
table_to_update= main_table; // Update table on the fly
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (table == first_table_for_update && table_ref->check_option)
|
||||
{
|
||||
table_map unupdated_tables= table_ref->check_option->used_tables() &
|
||||
~first_table_for_update->map;
|
||||
for (TABLE_LIST *tbl_ref =leaves;
|
||||
unupdated_tables && tbl_ref;
|
||||
tbl_ref= tbl_ref->next_leaf)
|
||||
{
|
||||
if (unupdated_tables & tbl_ref->table->map)
|
||||
unupdated_tables&= ~tbl_ref->table->map;
|
||||
else
|
||||
continue;
|
||||
if (unupdated_check_opt_tables.push_back(tbl_ref->table))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
TMP_TABLE_PARAM *tmp_param= tmp_table_param+cnt;
|
||||
|
||||
/*
|
||||
Create a temporary table to store all fields that are changed for this
|
||||
table. The first field in the temporary table is a pointer to the
|
||||
original row so that we can find and update it
|
||||
original row so that we can find and update it. For the updatable
|
||||
VIEW a few following fields are rowids of tables used in the CHECK
|
||||
OPTION condition.
|
||||
*/
|
||||
|
||||
/* ok to be on stack as this is not referenced outside of this func */
|
||||
Field_string offset(table->file->ref_length, 0, "offset",
|
||||
table, &my_charset_bin);
|
||||
/*
|
||||
The field will be converted to varstring when creating tmp table if
|
||||
table to be updated was created by mysql 4.1. Deny this.
|
||||
*/
|
||||
offset.can_alter_field_type= 0;
|
||||
if (!(ifield= new Item_field(((Field *) &offset))))
|
||||
DBUG_RETURN(1);
|
||||
ifield->maybe_null= 0;
|
||||
if (temp_fields.push_front(ifield))
|
||||
DBUG_RETURN(1);
|
||||
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
|
||||
TABLE *tbl= table;
|
||||
do
|
||||
{
|
||||
Field_string *field= new Field_string(tbl->file->ref_length, 0,
|
||||
tbl->alias,
|
||||
tbl, &my_charset_bin);
|
||||
if (!field)
|
||||
DBUG_RETURN(1);
|
||||
/*
|
||||
The field will be converted to varstring when creating tmp table if
|
||||
table to be updated was created by mysql 4.1. Deny this.
|
||||
*/
|
||||
field->can_alter_field_type= 0;
|
||||
Item_field *ifield= new Item_field((Field *) field);
|
||||
if (!ifield)
|
||||
DBUG_RETURN(1);
|
||||
ifield->maybe_null= 0;
|
||||
if (temp_fields.push_back(ifield))
|
||||
DBUG_RETURN(1);
|
||||
} while ((tbl= tbl_it++));
|
||||
|
||||
temp_fields.concat(fields_for_table[cnt]);
|
||||
|
||||
/* Make an unique key over the first field to avoid duplicated updates */
|
||||
bzero((char*) &group, sizeof(group));
|
||||
@ -1350,10 +1390,26 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
||||
{
|
||||
int error;
|
||||
TABLE *tmp_table= tmp_tables[offset];
|
||||
fill_record(thd, tmp_table->field+1, *values_for_table[offset], 1);
|
||||
/* Store pointer to row */
|
||||
memcpy((char*) tmp_table->field[0]->ptr,
|
||||
(char*) table->file->ref, table->file->ref_length);
|
||||
/* Store regular updated fields in the row. */
|
||||
fill_record(thd,
|
||||
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
|
||||
*values_for_table[offset], 1);
|
||||
/*
|
||||
For updatable VIEW store rowid of the updated table and
|
||||
rowids of tables used in the CHECK OPTION condition.
|
||||
*/
|
||||
uint field_num= 0;
|
||||
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
|
||||
TABLE *tbl= table;
|
||||
do
|
||||
{
|
||||
if (tbl != table)
|
||||
tbl->file->position(tbl->record[0]);
|
||||
memcpy((char*) tmp_table->field[field_num]->ptr,
|
||||
(char*) tbl->file->ref, tbl->file->ref_length);
|
||||
field_num++;
|
||||
} while ((tbl= tbl_it++));
|
||||
|
||||
/* Write row, ignoring duplicated updates to a row */
|
||||
error= tmp_table->file->write_row(tmp_table->record[0]);
|
||||
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
|
||||
@ -1403,9 +1459,10 @@ void multi_update::send_error(uint errcode,const char *err)
|
||||
int multi_update::do_updates(bool from_send_error)
|
||||
{
|
||||
TABLE_LIST *cur_table;
|
||||
int local_error;
|
||||
int local_error= 0;
|
||||
ha_rows org_updated;
|
||||
TABLE *table, *tmp_table;
|
||||
List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
|
||||
DBUG_ENTER("do_updates");
|
||||
|
||||
do_update= 0; // Don't retry this function
|
||||
@ -1413,8 +1470,8 @@ int multi_update::do_updates(bool from_send_error)
|
||||
DBUG_RETURN(0);
|
||||
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
|
||||
{
|
||||
byte *ref_pos;
|
||||
bool can_compare_record;
|
||||
uint offset= cur_table->shared;
|
||||
|
||||
table = cur_table->table;
|
||||
if (table == table_to_update)
|
||||
@ -1425,11 +1482,20 @@ int multi_update::do_updates(bool from_send_error)
|
||||
(void) table->file->ha_rnd_init(0);
|
||||
table->file->extra(HA_EXTRA_NO_CACHE);
|
||||
|
||||
check_opt_it.rewind();
|
||||
while(TABLE *tbl= check_opt_it++)
|
||||
{
|
||||
if (tbl->file->ha_rnd_init(1))
|
||||
goto err;
|
||||
tbl->file->extra(HA_EXTRA_CACHE);
|
||||
}
|
||||
|
||||
/*
|
||||
Setup copy functions to copy fields from temporary table
|
||||
*/
|
||||
List_iterator_fast<Item> field_it(*fields_for_table[cur_table->shared]);
|
||||
Field **field= tmp_table->field+1; // Skip row pointer
|
||||
List_iterator_fast<Item> field_it(*fields_for_table[offset]);
|
||||
Field **field= tmp_table->field +
|
||||
1 + unupdated_check_opt_tables.elements; // Skip row pointers
|
||||
Copy_field *copy_field_ptr= copy_field, *copy_field_end;
|
||||
for ( ; *field ; field++)
|
||||
{
|
||||
@ -1444,7 +1510,6 @@ int multi_update::do_updates(bool from_send_error)
|
||||
can_compare_record= !(table->file->table_flags() &
|
||||
HA_PARTIAL_COLUMN_READ);
|
||||
|
||||
ref_pos= (byte*) tmp_table->field[0]->ptr;
|
||||
for (;;)
|
||||
{
|
||||
if (thd->killed && trans_safe)
|
||||
@ -1457,8 +1522,20 @@ int multi_update::do_updates(bool from_send_error)
|
||||
continue; // May happen on dup key
|
||||
goto err;
|
||||
}
|
||||
if ((local_error= table->file->rnd_pos(table->record[0], ref_pos)))
|
||||
goto err;
|
||||
|
||||
/* call rnd_pos() using rowids from temporary table */
|
||||
check_opt_it.rewind();
|
||||
TABLE *tbl= table;
|
||||
uint field_num= 0;
|
||||
do
|
||||
{
|
||||
if((local_error=
|
||||
tbl->file->rnd_pos(tbl->record[0],
|
||||
(byte *) tmp_table->field[field_num]->ptr)))
|
||||
goto err;
|
||||
field_num++;
|
||||
} while((tbl= check_opt_it++));
|
||||
|
||||
table->status|= STATUS_UPDATED;
|
||||
store_record(table,record[1]);
|
||||
|
||||
@ -1508,6 +1585,10 @@ int multi_update::do_updates(bool from_send_error)
|
||||
}
|
||||
(void) table->file->ha_rnd_end();
|
||||
(void) tmp_table->file->ha_rnd_end();
|
||||
check_opt_it.rewind();
|
||||
while (TABLE *tbl= check_opt_it++)
|
||||
tbl->file->ha_rnd_end();
|
||||
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
||||
@ -1521,6 +1602,9 @@ err:
|
||||
err2:
|
||||
(void) table->file->ha_rnd_end();
|
||||
(void) tmp_table->file->ha_rnd_end();
|
||||
check_opt_it.rewind();
|
||||
while (TABLE *tbl= check_opt_it++)
|
||||
tbl->file->ha_rnd_end();
|
||||
|
||||
if (updated != org_updated)
|
||||
{
|
||||
|
159
sql/sql_view.cc
159
sql/sql_view.cc
@ -692,6 +692,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
bool can_be_merged;
|
||||
char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
|
||||
LEX_STRING dir, file;
|
||||
int error= 0;
|
||||
DBUG_ENTER("mysql_register_view");
|
||||
|
||||
/* print query */
|
||||
@ -702,80 +703,16 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
lex->unit.print(&str);
|
||||
thd->variables.sql_mode|= sql_mode;
|
||||
}
|
||||
str.append('\0');
|
||||
DBUG_PRINT("info", ("View: %s", str.ptr()));
|
||||
|
||||
/* print file name */
|
||||
(void) my_snprintf(dir_buff, FN_REFLEN, "%s/%s/",
|
||||
mysql_data_home, view->db);
|
||||
unpack_filename(dir_buff, dir_buff);
|
||||
dir.str= dir_buff;
|
||||
dir.length= strlen(dir_buff);
|
||||
|
||||
file.str= file_buff;
|
||||
file.length= (strxnmov(file_buff, FN_REFLEN, view->table_name, reg_ext,
|
||||
NullS) - file_buff);
|
||||
/* init timestamp */
|
||||
if (!view->timestamp.str)
|
||||
view->timestamp.str= view->timestamp_buffer;
|
||||
|
||||
/* check old .frm */
|
||||
{
|
||||
char path_buff[FN_REFLEN];
|
||||
LEX_STRING path;
|
||||
File_parser *parser;
|
||||
|
||||
path.str= path_buff;
|
||||
fn_format(path_buff, file.str, dir.str, 0, MY_UNPACK_FILENAME);
|
||||
path.length= strlen(path_buff);
|
||||
|
||||
if (!access(path.str, F_OK))
|
||||
{
|
||||
if (mode == VIEW_CREATE_NEW)
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
if (!(parser= sql_parse_prepare(&path, thd->mem_root, 0)))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (!parser->ok() || !is_equal(&view_type, parser->type()))
|
||||
{
|
||||
my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
read revision number
|
||||
|
||||
TODO: read dependence list, too, to process cascade/restrict
|
||||
TODO: special cascade/restrict procedure for alter?
|
||||
*/
|
||||
if (parser->parse((gptr)view, thd->mem_root,
|
||||
view_parameters + revision_number_position, 1,
|
||||
&file_parser_dummy_hook))
|
||||
{
|
||||
DBUG_RETURN(thd->net.report_error? -1 : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == VIEW_ALTER)
|
||||
{
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* fill structure */
|
||||
view->query.str= (char*)str.ptr();
|
||||
view->query.length= str.length()-1; // we do not need last \0
|
||||
view->query.str= str.c_ptr_safe();
|
||||
view->query.length= str.length();
|
||||
view->source.str= thd->query + thd->lex->create_view_select_start;
|
||||
view->source.length= (char *)skip_rear_comments((char *)view->source.str,
|
||||
(char *)thd->query +
|
||||
thd->query_length) -
|
||||
view->source.str;
|
||||
view->source.length= skip_rear_comments((char *)view->source.str,
|
||||
(char *)thd->query +
|
||||
thd->query_length) -
|
||||
view->source.str;
|
||||
view->file_version= 1;
|
||||
view->calc_md5(md5);
|
||||
view->md5.str= md5;
|
||||
@ -817,6 +754,76 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
}
|
||||
}
|
||||
loop_out:
|
||||
/* print file name */
|
||||
(void) my_snprintf(dir_buff, FN_REFLEN, "%s/%s/",
|
||||
mysql_data_home, view->db);
|
||||
unpack_filename(dir_buff, dir_buff);
|
||||
dir.str= dir_buff;
|
||||
dir.length= strlen(dir_buff);
|
||||
|
||||
file.str= file_buff;
|
||||
file.length= (strxnmov(file_buff, FN_REFLEN, view->table_name, reg_ext,
|
||||
NullS) - file_buff);
|
||||
/* init timestamp */
|
||||
if (!view->timestamp.str)
|
||||
view->timestamp.str= view->timestamp_buffer;
|
||||
|
||||
/* check old .frm */
|
||||
{
|
||||
char path_buff[FN_REFLEN];
|
||||
LEX_STRING path;
|
||||
File_parser *parser;
|
||||
|
||||
path.str= path_buff;
|
||||
fn_format(path_buff, file.str, dir.str, 0, MY_UNPACK_FILENAME);
|
||||
path.length= strlen(path_buff);
|
||||
|
||||
if (!access(path.str, F_OK))
|
||||
{
|
||||
if (mode == VIEW_CREATE_NEW)
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
|
||||
error= -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(parser= sql_parse_prepare(&path, thd->mem_root, 0)))
|
||||
{
|
||||
error= 1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!parser->ok() || !is_equal(&view_type, parser->type()))
|
||||
{
|
||||
my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
|
||||
error= -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
read revision number
|
||||
|
||||
TODO: read dependence list, too, to process cascade/restrict
|
||||
TODO: special cascade/restrict procedure for alter?
|
||||
*/
|
||||
if (parser->parse((gptr)view, thd->mem_root,
|
||||
view_parameters + revision_number_position, 1,
|
||||
&file_parser_dummy_hook))
|
||||
{
|
||||
error= thd->net.report_error? -1 : 0;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == VIEW_ALTER)
|
||||
{
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias);
|
||||
error= -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Check that table of main select do not used in subqueries.
|
||||
|
||||
@ -841,15 +848,23 @@ loop_out:
|
||||
!view->updatable_view)
|
||||
{
|
||||
my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->table_name);
|
||||
DBUG_RETURN(-1);
|
||||
error= -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sql_create_definition_file(&dir, &file, view_file_type,
|
||||
(gptr)view, view_parameters, num_view_backups))
|
||||
{
|
||||
DBUG_RETURN(thd->net.report_error? -1 : 1);
|
||||
error= thd->net.report_error? -1 : 1;
|
||||
goto err;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
view->query.str= NULL;
|
||||
view->query.length= 0;
|
||||
view->md5.str= NULL;
|
||||
view->md5.length= 0;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
|
79
sql/table.cc
79
sql/table.cc
@ -1985,6 +1985,47 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Merge ON expressions for a view
|
||||
|
||||
SYNOPSIS
|
||||
merge_on_conds()
|
||||
thd thread handle
|
||||
table table for the VIEW
|
||||
is_cascaded TRUE <=> merge ON expressions from underlying views
|
||||
|
||||
DESCRIPTION
|
||||
This function returns the result of ANDing the ON expressions
|
||||
of the given view and all underlying views. The ON expressions
|
||||
of the underlying views are added only if is_cascaded is TRUE.
|
||||
|
||||
RETURN
|
||||
Pointer to the built expression if there is any.
|
||||
Otherwise and in the case of a failure NULL is returned.
|
||||
*/
|
||||
|
||||
static Item *
|
||||
merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
|
||||
{
|
||||
DBUG_ENTER("merge_on_conds");
|
||||
|
||||
Item *cond= NULL;
|
||||
DBUG_PRINT("info", ("alias: %s", table->alias));
|
||||
if (table->on_expr)
|
||||
cond= table->on_expr->copy_andor_structure(thd);
|
||||
if (!table->nested_join)
|
||||
DBUG_RETURN(cond);
|
||||
List_iterator<TABLE_LIST> li(table->nested_join->join_list);
|
||||
while (TABLE_LIST *tbl= li++)
|
||||
{
|
||||
if (tbl->view && !is_cascaded)
|
||||
continue;
|
||||
cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
|
||||
}
|
||||
DBUG_RETURN(cond);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Prepare check option expression of table
|
||||
|
||||
@ -2001,8 +2042,8 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
|
||||
VIEW_CHECK_LOCAL option.
|
||||
|
||||
NOTE
|
||||
This method build check options for every call
|
||||
(usual execution or every SP/PS call)
|
||||
This method builds check option condition to use it later on
|
||||
every call (usual execution or every SP/PS call).
|
||||
This method have to be called after WHERE preparation
|
||||
(st_table_list::prep_where)
|
||||
|
||||
@ -2014,38 +2055,42 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
|
||||
bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
|
||||
{
|
||||
DBUG_ENTER("st_table_list::prep_check_option");
|
||||
bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
|
||||
|
||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
||||
{
|
||||
/* see comment of check_opt_type parameter */
|
||||
if (tbl->view &&
|
||||
tbl->prep_check_option(thd,
|
||||
((check_opt_type == VIEW_CHECK_CASCADED) ?
|
||||
VIEW_CHECK_CASCADED :
|
||||
VIEW_CHECK_NONE)))
|
||||
{
|
||||
if (tbl->view && tbl->prep_check_option(thd, (is_cascaded ?
|
||||
VIEW_CHECK_CASCADED :
|
||||
VIEW_CHECK_NONE)))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if (check_opt_type)
|
||||
if (check_opt_type && !check_option_processed)
|
||||
{
|
||||
Item *item= 0;
|
||||
Query_arena *arena= thd->stmt_arena, backup;
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
|
||||
|
||||
if (where)
|
||||
{
|
||||
DBUG_ASSERT(where->fixed);
|
||||
item= where->copy_andor_structure(thd);
|
||||
check_option= where->copy_andor_structure(thd);
|
||||
}
|
||||
if (check_opt_type == VIEW_CHECK_CASCADED)
|
||||
if (is_cascaded)
|
||||
{
|
||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
||||
{
|
||||
if (tbl->check_option)
|
||||
item= and_conds(item, tbl->check_option);
|
||||
check_option= and_conds(check_option, tbl->check_option);
|
||||
}
|
||||
}
|
||||
if (item)
|
||||
thd->change_item_tree(&check_option, item);
|
||||
check_option= and_conds(check_option,
|
||||
merge_on_conds(thd, this, is_cascaded));
|
||||
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
check_option_processed= TRUE;
|
||||
|
||||
}
|
||||
|
||||
if (check_option)
|
||||
@ -2150,7 +2195,7 @@ void st_table_list::cleanup_items()
|
||||
check CHECK OPTION condition
|
||||
|
||||
SYNOPSIS
|
||||
check_option()
|
||||
st_table_list::view_check_option()
|
||||
ignore_failure ignore check option fail
|
||||
|
||||
RETURN
|
||||
|
@ -685,6 +685,8 @@ typedef struct st_table_list
|
||||
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
|
||||
/* view where processed */
|
||||
bool where_processed;
|
||||
/* TRUE <=> VIEW CHECK OPTION expression has been processed */
|
||||
bool check_option_processed;
|
||||
/* FRMTYPE_ERROR if any type is acceptable */
|
||||
enum frm_type_enum required_type;
|
||||
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user