summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <ibabaev@bk-internal.mysql.com>2007-05-12 23:44:03 +0200
committerunknown <ibabaev@bk-internal.mysql.com>2007-05-12 23:44:03 +0200
commitac811bf0dd811d3cd296f082ab0a671979b79c1e (patch)
treec7892305de8628f4a79141d621af0d68264aed42
parent4d7824e32d9e5fb1a35fa6d9d6e2862e0e169690 (diff)
parent6fa4fdd29ce40375f9b79fd22a0c703fa8b0fc0f (diff)
downloadmariadb-git-ac811bf0dd811d3cd296f082ab0a671979b79c1e.tar.gz
Merge bk-internal.mysql.com:/data0/bk/mysql-5.1
into bk-internal.mysql.com:/data0/bk/mysql-5.1-opt sql/field.cc: Auto merged
-rw-r--r--mysql-test/include/mix1.inc54
-rw-r--r--mysql-test/r/bigint.result10
-rw-r--r--mysql-test/r/grant.result19
-rw-r--r--mysql-test/r/innodb_mysql.result52
-rw-r--r--mysql-test/r/insert_update.result35
-rw-r--r--mysql-test/r/partition.result2
-rw-r--r--mysql-test/r/subselect3.result31
-rw-r--r--mysql-test/r/type_newdecimal.result35
-rw-r--r--mysql-test/r/view.result13
-rw-r--r--mysql-test/t/bigint.test7
-rw-r--r--mysql-test/t/grant.test25
-rw-r--r--mysql-test/t/insert_update.test26
-rw-r--r--mysql-test/t/partition.test6
-rw-r--r--mysql-test/t/subselect3.test25
-rw-r--r--mysql-test/t/type_newdecimal.test19
-rw-r--r--mysql-test/t/view.test12
-rw-r--r--sql/field.cc3
-rw-r--r--sql/item_create.cc19
-rw-r--r--sql/item_create.h6
-rw-r--r--sql/item_func.cc28
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_subselect.cc6
-rw-r--r--sql/my_decimal.cc11
-rw-r--r--sql/my_decimal.h3
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_prepare.cc5
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_select.h7
-rw-r--r--sql/sql_update.cc5
-rw-r--r--sql/sql_yacc.yy12
30 files changed, 451 insertions, 32 deletions
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 352d5a987a2..4d7d86ccd10 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -554,6 +554,60 @@ select * from t1;
drop table t1;
+#
+# Bug #28189: optimizer erroniously prefers ref access to range access
+# for an InnoDB table
+#
+
+CREATE TABLE t1(
+ id int AUTO_INCREMENT PRIMARY KEY,
+ stat_id int NOT NULL,
+ acct_id int DEFAULT NULL,
+ INDEX idx1 (stat_id, acct_id),
+ INDEX idx2 (acct_id)
+) ENGINE=MyISAM;
+
+CREATE TABLE t2(
+ id int AUTO_INCREMENT PRIMARY KEY,
+ stat_id int NOT NULL,
+ acct_id int DEFAULT NULL,
+ INDEX idx1 (stat_id, acct_id),
+ INDEX idx2 (acct_id)
+) ENGINE=InnoDB;
+
+INSERT INTO t1(stat_id,acct_id) VALUES
+ (1,759), (2,831), (3,785), (4,854), (1,921),
+ (1,553), (2,589), (3,743), (2,827), (2,545),
+ (4,779), (4,783), (1,597), (1,785), (4,832),
+ (1,741), (1,833), (3,788), (2,973), (1,907);
+
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+UPDATE t1 SET acct_id=785
+ WHERE MOD(stat_id,2)=0 AND MOD(id,stat_id)=MOD(acct_id,stat_id);
+OPTIMIZE TABLE t1;
+
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(*) FROM t1 WHERE acct_id=785;
+
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE stat_id IN (1,3) AND acct_id=785;
+
+INSERT INTO t2 SELECT * FROM t1;
+OPTIMIZE TABLE t2;
+
+EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785;
+
+DROP TABLE t1,t2;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index d8f78cd5103..a70c6b3df7d 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -352,3 +352,13 @@ select c1 mod 50 as result from t1;
result
6
drop table t1;
+create table t1 select -9223372036854775808 bi;
+describe t1;
+Field Type Null Key Default Extra
+bi bigint(20) NO 0
+drop table t1;
+create table t1 select -9223372036854775809 bi;
+describe t1;
+Field Type Null Key Default Extra
+bi decimal(19,0) NO 0
+drop table t1;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index 9493413ade9..a68cee5e52e 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1194,6 +1194,25 @@ ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table '
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost;
+use test;
+CREATE TABLE t1 (f1 int, f2 int);
+INSERT INTO t1 VALUES(1,1), (2,2);
+CREATE DATABASE db27878;
+GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost';
+GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost';
+GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost';
+use db27878;
+CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1;
+use db27878;
+UPDATE v1 SET f2 = 4;
+ERROR HY000: View 'db27878.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SELECT * FROM test.t1;
+f1 f2
+1 1
+2 2
+DROP DATABASE db27878;
+use test;
+DROP TABLE t1;
End of 5.0 tests
set names utf8;
grant select on test.* to юзер_юзер@localhost;
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 36d6f62c72c..c4bae224846 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -548,6 +548,58 @@ id c counter
3 b 2
4 a 2
drop table t1;
+CREATE TABLE t1(
+id int AUTO_INCREMENT PRIMARY KEY,
+stat_id int NOT NULL,
+acct_id int DEFAULT NULL,
+INDEX idx1 (stat_id, acct_id),
+INDEX idx2 (acct_id)
+) ENGINE=MyISAM;
+CREATE TABLE t2(
+id int AUTO_INCREMENT PRIMARY KEY,
+stat_id int NOT NULL,
+acct_id int DEFAULT NULL,
+INDEX idx1 (stat_id, acct_id),
+INDEX idx2 (acct_id)
+) ENGINE=InnoDB;
+INSERT INTO t1(stat_id,acct_id) VALUES
+(1,759), (2,831), (3,785), (4,854), (1,921),
+(1,553), (2,589), (3,743), (2,827), (2,545),
+(4,779), (4,783), (1,597), (1,785), (4,832),
+(1,741), (1,833), (3,788), (2,973), (1,907);
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1;
+UPDATE t1 SET acct_id=785
+WHERE MOD(stat_id,2)=0 AND MOD(id,stat_id)=MOD(acct_id,stat_id);
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+40960
+SELECT COUNT(*) FROM t1 WHERE acct_id=785;
+COUNT(*)
+8702
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE stat_id IN (1,3) AND acct_id=785;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 9 NULL 2 Using where; Using index
+INSERT INTO t2 SELECT * FROM t1;
+OPTIMIZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 optimize status OK
+EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range idx1,idx2 idx1 9 NULL 2 Using where; Using index
+DROP TABLE t1,t2;
End of 5.0 tests
CREATE TABLE t1 (a int, b int);
insert into t1 values (1,1),(1,2);
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result
index 98e6878482b..020c587959f 100644
--- a/mysql-test/r/insert_update.result
+++ b/mysql-test/r/insert_update.result
@@ -358,3 +358,38 @@ id c1 cnt
5 Y 1
6 Z 1
DROP TABLE t1;
+CREATE TABLE t1 (
+id INT AUTO_INCREMENT PRIMARY KEY,
+c1 INT NOT NULL,
+cnt INT DEFAULT 1
+);
+INSERT INTO t1 (id,c1) VALUES (1,10);
+SELECT * FROM t1;
+id c1 cnt
+1 10 1
+CREATE TABLE t2 (id INT, c1 INT);
+INSERT INTO t2 VALUES (1,NULL), (2,2);
+INSERT INTO t1 (id,c1) SELECT 1,NULL
+ON DUPLICATE KEY UPDATE c1=NULL;
+ERROR 23000: Column 'c1' cannot be null
+SELECT * FROM t1;
+id c1 cnt
+1 10 1
+INSERT IGNORE INTO t1 (id,c1) SELECT 1,NULL
+ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
+Warnings:
+Warning 1048 Column 'c1' cannot be null
+Error 1048 Column 'c1' cannot be null
+SELECT * FROM t1;
+id c1 cnt
+1 0 2
+INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2
+ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
+Warnings:
+Warning 1048 Column 'c1' cannot be null
+Error 1048 Column 'c1' cannot be null
+SELECT * FROM t1;
+id c1 cnt
+1 0 3
+2 2 1
+DROP TABLE t1;
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 3549e987d73..de477310fe3 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -1233,4 +1233,6 @@ select * from t1;
c1 c2
aaa 2
drop table t1;
+create table t1 (s1 bigint) partition by list (s1) (partition p1 values in (-9223372036854775808));
+drop table t1;
End of 5.1 tests
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index 132c36fbf11..eca6cd3315c 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -711,3 +711,34 @@ a
1
4
DROP TABLE t1,t2;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int PRIMARY KEY);
+CREATE TABLE t3 (id int PRIMARY KEY, name varchar(10));
+INSERT INTO t1 VALUES (2), (NULL), (3), (1);
+INSERT INTO t2 VALUES (234), (345), (457);
+INSERT INTO t3 VALUES (222,'bbb'), (333,'ccc'), (111,'aaa');
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
+WHERE t3.name='xxx' AND t2.id=t3.id);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 func 1 Using where; Using index; Full scan on NULL key
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 Using where; Full scan on NULL key
+SELECT * FROM t1
+WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
+WHERE t3.name='xxx' AND t2.id=t3.id);
+id
+2
+NULL
+3
+1
+SELECT (t1.id IN (SELECT t2.id FROM t2,t3
+WHERE t3.name='xxx' AND t2.id=t3.id)) AS x
+FROM t1;
+x
+0
+0
+0
+0
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 04baa03ce4d..855c452cb21 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1440,6 +1440,41 @@ select * from t1;
a
123456789012345678
drop table t1;
+select cast(11.1234 as DECIMAL(3,2));
+cast(11.1234 as DECIMAL(3,2))
+9.99
+Warnings:
+Error 1264 Out of range value for column 'cast(11.1234 as DECIMAL(3,2))' at row 1
+select * from (select cast(11.1234 as DECIMAL(3,2))) t;
+cast(11.1234 as DECIMAL(3,2))
+9.99
+Warnings:
+Error 1264 Out of range value for column 'cast(11.1234 as DECIMAL(3,2))' at row 1
+select cast(a as DECIMAL(3,2))
+from (select 11.1233 as a
+UNION select 11.1234
+UNION select 12.1234
+) t;
+cast(a as DECIMAL(3,2))
+9.99
+9.99
+9.99
+Warnings:
+Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1
+Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1
+Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1
+select cast(a as DECIMAL(3,2)), count(*)
+from (select 11.1233 as a
+UNION select 11.1234
+UNION select 12.1234
+) t group by 1;
+cast(a as DECIMAL(3,2)) count(*)
+9.99 3
+Warnings:
+Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1
+Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1
+Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1
+Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1
End of 5.0 tests
select cast(143.481 as decimal(4,1));
cast(143.481 as decimal(4,1))
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index cc353f5e1db..d1098020b25 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -3346,6 +3346,19 @@ id select_type table type possible_keys key key_len ref rows Extra
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Using filesort
DROP VIEW v1;
DROP TABLE t1;
+CREATE VIEW v1 AS SELECT CAST( 1.23456789 AS DECIMAL( 7,5 ) ) AS col;
+SELECT * FROM v1;
+col
+1.23457
+DESCRIBE v1;
+Field Type Null Key Default Extra
+col decimal(7,5) NO 0.00000
+DROP VIEW v1;
+CREATE VIEW v1 AS SELECT CAST(1.23456789 AS DECIMAL(8,0)) AS col;
+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;
End of 5.0 tests.
DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`;
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index 6c1229db83f..c2c6f895545 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -288,3 +288,10 @@ insert into t1 values (10000002383263201056);
select c1 mod 50 as result from t1;
drop table t1;
+# Bug #28005 Partitions: can't use -9223372036854775808
+create table t1 select -9223372036854775808 bi;
+describe t1;
+drop table t1;
+create table t1 select -9223372036854775809 bi;
+describe t1;
+drop table t1;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index d2b384b6559..2cc8a0d1489 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -415,6 +415,7 @@ connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection user1;
-- error 1142
alter table t1 rename t2;
+disconnect user1;
connection root;
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
delete from mysql.user where user=_binary'mysqltest_1';
@@ -1235,6 +1236,30 @@ DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost;
+#
+# Bug#27878: Unchecked privileges on a view referring to a table from another
+# database.
+#
+use test;
+CREATE TABLE t1 (f1 int, f2 int);
+INSERT INTO t1 VALUES(1,1), (2,2);
+CREATE DATABASE db27878;
+GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost';
+GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost';
+GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost';
+use db27878;
+CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1;
+connect (user1,localhost,mysqltest_1,,test);
+connection user1;
+use db27878;
+--error 1356
+UPDATE v1 SET f2 = 4;
+SELECT * FROM test.t1;
+disconnect user1;
+connection default;
+DROP DATABASE db27878;
+use test;
+DROP TABLE t1;
--echo End of 5.0 tests
diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test
index de4e73dca93..ff6ddf35c7b 100644
--- a/mysql-test/t/insert_update.test
+++ b/mysql-test/t/insert_update.test
@@ -264,3 +264,29 @@ INSERT INTO t1 (c1) VALUES ('A'), ('X'), ('Y'), ('Z')
ON DUPLICATE KEY UPDATE cnt=cnt+1;
SELECT * FROM t1;
DROP TABLE t1;
+
+#
+# Bug#28000: INSERT IGNORE ... SELECT ... ON DUPLICATE
+# with erroneous UPDATE: NOT NULL field with NULL value.
+#
+CREATE TABLE t1 (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ c1 INT NOT NULL,
+ cnt INT DEFAULT 1
+);
+INSERT INTO t1 (id,c1) VALUES (1,10);
+SELECT * FROM t1;
+CREATE TABLE t2 (id INT, c1 INT);
+INSERT INTO t2 VALUES (1,NULL), (2,2);
+--error 1048
+INSERT INTO t1 (id,c1) SELECT 1,NULL
+ ON DUPLICATE KEY UPDATE c1=NULL;
+SELECT * FROM t1;
+INSERT IGNORE INTO t1 (id,c1) SELECT 1,NULL
+ ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
+SELECT * FROM t1;
+INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2
+ ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
+SELECT * FROM t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 36f3a40503b..68c13c0792a 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -1441,5 +1441,11 @@ insert into t1 values ('aaa','1') on duplicate key update c2 = c2 + 1;
select * from t1;
drop table t1;
+#
+# Bug #28005 Partitions: can't use -9223372036854775808
+#
+
+create table t1 (s1 bigint) partition by list (s1) (partition p1 values in (-9223372036854775808));
+drop table t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index dfe09968fa2..65556012588 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -546,3 +546,28 @@ SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1));
SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1 WHERE a > 4));
DROP TABLE t1,t2;
+
+#
+# Bug #28375: crash for NOT IN subquery predicate when left operand becomes NULL
+#
+
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int PRIMARY KEY);
+CREATE TABLE t3 (id int PRIMARY KEY, name varchar(10));
+INSERT INTO t1 VALUES (2), (NULL), (3), (1);
+INSERT INTO t2 VALUES (234), (345), (457);
+INSERT INTO t3 VALUES (222,'bbb'), (333,'ccc'), (111,'aaa');
+
+EXPLAIN
+SELECT * FROM t1
+ WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
+ WHERE t3.name='xxx' AND t2.id=t3.id);
+SELECT * FROM t1
+ WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
+ WHERE t3.name='xxx' AND t2.id=t3.id);
+
+SELECT (t1.id IN (SELECT t2.id FROM t2,t3
+ WHERE t3.name='xxx' AND t2.id=t3.id)) AS x
+ FROM t1;
+
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index b8c05d62720..0a52bdaa8e6 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1140,6 +1140,25 @@ alter table t1 modify column a decimal(19);
select * from t1;
drop table t1;
+#
+# Bug #27957 cast as decimal does not check overflow, also inconsistent with group, subselect
+#
+
+select cast(11.1234 as DECIMAL(3,2));
+select * from (select cast(11.1234 as DECIMAL(3,2))) t;
+
+select cast(a as DECIMAL(3,2))
+ from (select 11.1233 as a
+ UNION select 11.1234
+ UNION select 12.1234
+ ) t;
+
+select cast(a as DECIMAL(3,2)), count(*)
+ from (select 11.1233 as a
+ UNION select 11.1234
+ UNION select 12.1234
+ ) t group by 1;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index a599f948c1e..51c862f692d 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -3213,6 +3213,18 @@ EXPLAIN SELECT * FROM t1 UNION SELECT * FROM v1 ORDER BY a;
DROP VIEW v1;
DROP TABLE t1;
+#
+# Bug #27921 View ignores precision for CAST()
+#
+CREATE VIEW v1 AS SELECT CAST( 1.23456789 AS DECIMAL( 7,5 ) ) AS col;
+SELECT * FROM v1;
+DESCRIBE v1;
+DROP VIEW v1;
+
+CREATE VIEW v1 AS SELECT CAST(1.23456789 AS DECIMAL(8,0)) AS col;
+SHOW CREATE VIEW v1;
+DROP VIEW v1;
+
--echo End of 5.0 tests.
#
diff --git a/sql/field.cc b/sql/field.cc
index 3ae82fe6182..fa25871fe61 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8772,8 +8772,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
case MYSQL_TYPE_NULL:
break;
case MYSQL_TYPE_NEWDECIMAL:
- if (!fld_length && !decimals)
- length= 10;
+ my_decimal_trim(&length, &decimals);
if (length > DECIMAL_MAX_PRECISION)
{
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
diff --git a/sql/item_create.cc b/sql/item_create.cc
index d11a2f84a0a..62f44996f4b 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -3916,6 +3916,7 @@ Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton;
Item*
Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name,
List<Item> *item_list)
+
{
Item *func= NULL;
int arg_count= 0;
@@ -4970,11 +4971,15 @@ find_qualified_function_builder(THD *thd)
return & Create_sp_func::s_singleton;
}
-Item*
-create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
+
+Item *
+create_func_cast(THD *thd, Item *a, Cast_target cast_type,
+ const char *c_len, const char *c_dec,
CHARSET_INFO *cs)
{
Item *res;
+ ulong len;
+ uint dec;
LINT_INIT(res);
switch (cast_type) {
@@ -4998,18 +5003,21 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
break;
case ITEM_CAST_DECIMAL:
{
- int tmp_len= (len>0) ? len : 10;
- if (tmp_len < dec)
+ len= c_len ? atoi(c_len) : 0;
+ dec= c_dec ? atoi(c_dec) : 0;
+ my_decimal_trim(&len, &dec);
+ if (len < dec)
{
my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
return 0;
}
- res= new (thd->mem_root) Item_decimal_typecast(a, tmp_len, dec);
+ res= new (thd->mem_root) Item_decimal_typecast(a, len, dec);
break;
}
case ITEM_CAST_CHAR:
{
CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection);
+ len= c_len ? atoi(c_len) : -1;
res= new (thd->mem_root) Item_char_typecast(a, len, real_cs);
break;
}
@@ -5022,4 +5030,3 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
}
return res;
}
-
diff --git a/sql/item_create.h b/sql/item_create.h
index 0a668b3e67f..7ace4032515 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -159,9 +159,9 @@ protected:
@param dec TODO
@param cs The character set
*/
-Item*
-create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
+Item *
+create_func_cast(THD *thd, Item *a, Cast_target cast_type,
+ const char *len, const char *dec,
CHARSET_INFO *cs);
-
#endif
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 2251ea3ecf9..712689af451 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1049,6 +1049,8 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
{
my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
bool sign;
+ uint precision;
+
if ((null_value= args[0]->null_value))
return NULL;
my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
@@ -1061,9 +1063,11 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
goto err;
}
}
- if (max_length - 2 - decimals < (uint) my_decimal_intg(dec))
+ precision= my_decimal_length_to_precision(max_length,
+ decimals, unsigned_flag);
+ if (precision - decimals < (uint) my_decimal_intg(dec))
{
- max_my_decimal(dec, max_length - 2, decimals);
+ max_my_decimal(dec, precision, decimals);
dec->sign(sign);
goto err;
}
@@ -1080,9 +1084,25 @@ err:
void Item_decimal_typecast::print(String *str)
{
+ char len_buf[20*3 + 1];
+ char *end;
+
+ uint precision= my_decimal_length_to_precision(max_length, decimals,
+ unsigned_flag);
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str);
- str->append(STRING_WITH_LEN(" as decimal)"));
+ str->append(STRING_WITH_LEN(" as decimal("));
+
+ end=int10_to_str(precision, len_buf,10);
+ str->append(len_buf, (uint32) (end - len_buf));
+
+ str->append(',');
+
+ end=int10_to_str(decimals, len_buf,10);
+ str->append(len_buf, (uint32) (end - len_buf));
+
+ str->append(')');
+ str->append(')');
}
@@ -1501,7 +1521,7 @@ void Item_func_neg::fix_length_and_dec()
*/
if (hybrid_type == INT_RESULT &&
args[0]->type() == INT_ITEM &&
- ((ulonglong) args[0]->val_int() >= (ulonglong) LONGLONG_MIN))
+ ((ulonglong) args[0]->val_int() > (ulonglong) LONGLONG_MIN))
{
/*
Ensure that result is converted to DECIMAL, as longlong can't hold
diff --git a/sql/item_func.h b/sql/item_func.h
index 7607a9353a7..b76877f90bc 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -333,8 +333,8 @@ class Item_decimal_typecast :public Item_func
public:
Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
{
- max_length= len + 2;
decimals= dec;
+ max_length= my_decimal_precision_to_length(len, dec, unsigned_flag);
}
String *val_str(String *str);
double val_real();
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 8f6503810fc..ab4b4eb6796 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1872,6 +1872,8 @@ int subselect_single_select_engine::exec()
if (cond_guard && !*cond_guard)
{
/* Change the access method to full table scan */
+ tab->save_read_first_record= tab->read_first_record;
+ tab->save_read_record= tab->read_record.read_record;
tab->read_first_record= init_read_record_seq;
tab->read_record.record= tab->table->record[0];
tab->read_record.thd= join->thd;
@@ -1892,8 +1894,8 @@ int subselect_single_select_engine::exec()
JOIN_TAB *tab= *ptab;
tab->read_record.record= 0;
tab->read_record.ref_length= 0;
- tab->read_first_record= join_read_always_key_or_null;
- tab->read_record.read_record= join_read_next_same_or_null;
+ tab->read_first_record= tab->save_read_first_record;
+ tab->read_record.read_record= tab->save_read_record;
}
executed= 1;
thd->where= save_where;
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 7b2d271639f..8823fac3393 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -208,6 +208,17 @@ my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec)
}
+void my_decimal_trim(ulong *precision, uint *scale)
+{
+ if (!(*precision) && !(*scale))
+ {
+ *precision= 10;
+ *scale= 0;
+ return;
+ }
+}
+
+
#ifndef DBUG_OFF
/* routines for debugging print */
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index eade029677f..17eb75cfdc5 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -395,5 +395,8 @@ int my_decimal_intg(const my_decimal *a)
}
+void my_decimal_trim(ulong *precision, uint *scale);
+
+
#endif /*my_decimal_h*/
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 30d7b5bc5db..ab9449ad2df 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1276,7 +1276,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
DBUG_ASSERT(info->update_fields->elements ==
info->update_values->elements);
if (fill_record_n_invoke_before_triggers(thd, *info->update_fields,
- *info->update_values, 0,
+ *info->update_values,
+ info->ignore,
table->triggers,
TRG_EVENT_UPDATE))
goto before_trg_err;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 31a6c7af04a..11bf367c254 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1164,8 +1164,9 @@ static int mysql_test_update(Prepared_statement *stmt,
goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- /* TABLE_LIST contain right privilages request */
- want_privilege= table_list->grant.want_privilege;
+ /* Force privilege re-checking for views after they have been opened. */
+ want_privilege= (table_list->view ? UPDATE_ACL :
+ table_list->grant.want_privilege);
#endif
if (mysql_prepare_update(thd, table_list, &select->where,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 20edf37fe1a..ea78e126d9c 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4269,7 +4269,7 @@ best_access_path(JOIN *join,
!(s->quick && best_key && s->quick->index == best_key->key && // (2)
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
!((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
- ! s->table->covering_keys.is_clear_all() && best_key) && // (3)
+ ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3)
!(s->table->force_index && best_key && !s->quick)) // (4)
{ // Check full join
ha_rows rnd_records= s->found_records;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 644224d1bed..971b7caf69d 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -160,6 +160,13 @@ typedef struct st_join_table {
Read_record_func read_first_record;
Next_select_func next_select;
READ_RECORD read_record;
+ /*
+ Currently the following two fields are used only for a [NOT] IN subquery
+ if it is executed by an alternative full table scan when the left operand of
+ the subquery predicate is evaluated to NULL.
+ */
+ Read_record_func save_read_first_record;/* to save read_first_record */
+ int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */
double worst_seeks;
key_map const_keys; /* Keys with constant part */
key_map checked_keys; /* Keys checked in find_best */
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 6c501562b1c..ef384c30b59 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -170,8 +170,9 @@ int mysql_update(THD *thd,
table->quick_keys.clear_all();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- /* TABLE_LIST contain right privilages request */
- want_privilege= table_list->grant.want_privilege;
+ /* Force privilege re-checking for views after they have been opened. */
+ want_privilege= (table_list->view ? UPDATE_ACL :
+ table_list->grant.want_privilege);
#endif
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
DBUG_RETURN(1);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 39ffae53972..2ce2adab8a0 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6503,15 +6503,13 @@ simple_expr:
}
| BINARY simple_expr %prec NEG
{
- $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, -1, 0,
+ $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, NULL, NULL,
&my_charset_bin);
}
| CAST_SYM '(' expr AS cast_type ')'
{
LEX *lex= Lex;
- $$= create_func_cast(YYTHD, $3, $5,
- lex->length ? atoi(lex->length) : -1,
- lex->dec ? atoi(lex->dec) : 0,
+ $$= create_func_cast(YYTHD, $3, $5, lex->length, lex->dec,
lex->charset);
if (!$$)
MYSQL_YYABORT;
@@ -6520,10 +6518,8 @@ simple_expr:
{ $$= new (YYTHD->mem_root) Item_func_case(* $3, $2, $4 ); }
| CONVERT_SYM '(' expr ',' cast_type ')'
{
- $$= create_func_cast(YYTHD, $3, $5,
- Lex->length ? atoi(Lex->length) : -1,
- Lex->dec ? atoi(Lex->dec) : 0,
- Lex->charset);
+ $$= create_func_cast(YYTHD, $3, $5, Lex->length, Lex->dec,
+ Lex->charset);
if (!$$)
MYSQL_YYABORT;
}