Skip to content

Commit d305e2e

Browse files
committed
Bug#19418619 - SELECT QUERY WITH INVALID TIME WORKS FINE
BUT SP FAILS UNDER STRICT MODE Description: STRICT sql mode does not apply to SELECT statement except for invalid arguments to sleep(). SELECT statement gives warning for invalid data in STRICT mode, which is correct behavior. If same SELECT statement is executed from within Stored Procedure, it gives error and abort statement. Statement behavior should not change if executed from Stored Procedure. Same case exist for SET statement. Another issue, CREATE TABLE statement fails while CREATE INDEX statement passes for too long indexes in STRICT mode. Index creation should behave same if executed from CREATE TABLE or CREATE INDEX statement. Analysis: This is a regression from WL#6891. Stored Procedures are executed in the sql mode they were created. When SP was created in STRICT mode, Strict_error_handler was pushed before executing statements inside the Stored Procedure. This upgrades warnings to error for every SELECT statement. Other side effects of above change are: - Changing STRICT sql mode inside Stored Procedure would have no effect. - As documented, evaluation of SP and SF parameters should depend on the current sql mode instead of the mode in which SP/SF was created. Behavior got changed with WL#6891 and parameter evaluation started using sql_mode in which SP/SF were created. Strict_error_handler was missing check for CREATE INDEX statement. So, where CREATE TABLE will give error for too long indexes, CREATE INDEX statement will succeed with warning in STRICT mode. Fix: Fixed code to push Strict_error_handler when required. SELECT inside and outside Stored Procedure will behave same. Exception for this is when we do SELECT on variables declared inside Stored Procedure. Consider the procedure : create procedure proc1() begin declare div_zero integer; select 1/0 into div_zero; end Here, SELECT to assign invalid value to 'div_zero' will fail in STRICT mode as it follows the rules of assigning a value to INTEGER column in a table. There is no behavior change here. Same case applies to SET statement. Now STRICT mode setting can be changed inside Stored Procedures and parameter evaluation will depend on current sql mode. Added check for CREATE INDEX statement in Strict_error_handler.
1 parent cbf5ed8 commit d305e2e

24 files changed

+401
-110
lines changed

mysql-test/r/archive.result

+2
Original file line numberDiff line numberDiff line change
@@ -12878,6 +12878,7 @@ DROP TABLE t1;
1287812878
DROP TABLE IF EXISTS t1;
1287912879
CREATE TABLE t1 (c1 decimal(19,14) NOT NULL) ENGINE=ARCHIVE;
1288012880
CALL mtr.add_suppression("Found wrong key definition in #sql.* Please do \"ALTER TABLE `#sql.*` FORCE \" to fix it!");
12881+
SET sql_mode='NO_ENGINE_SUBSTITUTION';
1288112882
CREATE INDEX i1 ON t1(c1);
1288212883
ERROR HY000: Got error -1 from storage engine
1288312884
SHOW WARNINGS;
@@ -12886,6 +12887,7 @@ Warning 1071 Specified key was too long; max key length is 8 bytes
1288612887
Warning 1194 Found wrong key definition in #sql-temporary; Please do "ALTER TABLE `#sql-temporary` FORCE" to fix it!
1288712888
Warning 1194 Found wrong key definition in #sql-temporary; Please do "ALTER TABLE `#sql-temporary` FORCE" to fix it!
1288812889
Error 1030 Got error -1 from storage engine
12890+
SET sql_mode= default;
1288912891
DROP TABLE t1;
1289012892
#
1289112893
# BUG#11758979 - 51252: ARCHIVE TABLES STILL FAIL UNDER STRESS

mysql-test/r/partition.result

+1-1
Original file line numberDiff line numberDiff line change
@@ -2635,7 +2635,7 @@ CREATE TABLE t1 (d TIME)
26352635
PARTITION BY RANGE COLUMNS (d)
26362636
(PARTITION p0 VALUES LESS THAN ('2000-01-01'),
26372637
PARTITION p1 VALUES LESS THAN ('2040-01-01'));
2638-
ERROR 22007: Incorrect time value: '2000-01-01' for column 'd' at row 1
2638+
ERROR HY000: Partition column values of incorrect type
26392639
SELECT @@sql_mode;
26402640
@@sql_mode
26412641
STRICT_TRANS_TABLES

mysql-test/r/sp-bugs.result

+136
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,139 @@ testf_bug11763507
228228
DROP PROCEDURE testp_bug11763507;
229229
DROP FUNCTION testf_bug11763507;
230230
#END OF BUG#11763507 test.
231+
#
232+
# Bug#19418619 : SELECT QUERY WITH INVALID TIME WORKS FINE BUT SP FAILS UNDER STRICT MODE
233+
#
234+
SET sql_mode='NO_ENGINE_SUBSTITUTION';
235+
CREATE FUNCTION f1(arg TINYINT UNSIGNED) RETURNS TINYINT
236+
BEGIN
237+
RETURN abs('1abcd');
238+
END|
239+
SELECT f1(-25);
240+
f1(-25)
241+
1
242+
Warnings:
243+
Warning 1264 Out of range value for column 'arg' at row 1
244+
Warning 1292 Truncated incorrect DOUBLE value: '1abcd'
245+
SELECT f1(25);
246+
f1(25)
247+
1
248+
Warnings:
249+
Warning 1292 Truncated incorrect DOUBLE value: '1abcd'
250+
SET sql_mode='STRICT_ALL_TABLES,STRICT_TRANS_TABLES';
251+
SELECT f1(-25);
252+
ERROR 22003: Out of range value for column 'arg' at row 1
253+
SELECT f1(10);
254+
f1(10)
255+
1
256+
Warnings:
257+
Warning 1292 Truncated incorrect DOUBLE value: '1abcd'
258+
DROP FUNCTION f1;
259+
SET sql_mode='NO_ENGINE_SUBSTITUTION';
260+
CREATE PROCEDURE f1(IN arg TINYINT UNSIGNED)
261+
BEGIN
262+
DECLARE arg1 TINYINT;
263+
select abs('1abcd') into arg;
264+
END|
265+
CALL f1(-25);
266+
Warnings:
267+
Warning 1264 Out of range value for column 'arg' at row 1
268+
Warning 1292 Truncated incorrect DOUBLE value: '1abcd'
269+
CALL f1(25);
270+
Warnings:
271+
Warning 1292 Truncated incorrect DOUBLE value: '1abcd'
272+
SET sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
273+
CALL f1(-25);
274+
ERROR 22003: Out of range value for column 'arg' at row 1
275+
CALL f1(10);
276+
Warnings:
277+
Warning 1292 Truncated incorrect DOUBLE value: '1abcd'
278+
DROP PROCEDURE f1;
279+
SELECT SUBTIME('2006-07-16' , '05:05:02.040778');
280+
SUBTIME('2006-07-16' , '05:05:02.040778')
281+
-04:44:56.040778
282+
Warnings:
283+
Warning 1292 Truncated incorrect time value: '2006-07-16'
284+
SELECT abs('1bcd');
285+
abs('1bcd')
286+
1
287+
Warnings:
288+
Warning 1292 Truncated incorrect DOUBLE value: '1bcd'
289+
CREATE PROCEDURE sp1()
290+
BEGIN
291+
SELECT SUBTIME('2006-07-16' , '05:05:02.040778');
292+
END|
293+
CREATE PROCEDURE sp2()
294+
BEGIN
295+
DECLARE v1 TINYINT DEFAULT 450000;
296+
END|
297+
CALL sp1();
298+
SUBTIME('2006-07-16' , '05:05:02.040778')
299+
-04:44:56.040778
300+
Warnings:
301+
Warning 1292 Truncated incorrect time value: '2006-07-16'
302+
CALL sp2();
303+
ERROR 22003: Out of range value for column 'v1' at row 1
304+
DROP PROCEDURE sp1;
305+
DROP PROCEDURE sp2;
306+
CREATE FUNCTION fn1(arg TINYINT UNSIGNED) RETURNS float deterministic RETURN abs('1abcd');
307+
CREATE FUNCTION fn2() RETURNS tinyint
308+
BEGIN
309+
DECLARE v1 TINYINT DEFAULT 450000;
310+
RETURN v1;
311+
END|
312+
SELECT fn1(25);
313+
ERROR 22007: Truncated incorrect DOUBLE value: '1abcd'
314+
SELECT fn1(-25);
315+
ERROR 22003: Out of range value for column 'arg' at row 1
316+
SELECT fn2();
317+
ERROR 22003: Out of range value for column 'v1' at row 1
318+
SET sql_mode='NO_ENGINE_SUBSTITUTION';
319+
SELECT fn1(-25);
320+
ERROR 22007: Truncated incorrect DOUBLE value: '1abcd'
321+
DROP FUNCTION fn1;
322+
DROP FUNCTION fn2;
323+
CREATE FUNCTION fn1() RETURNS float deterministic RETURN floor('1.1a');
324+
SET sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
325+
CREATE TABLE t1(a INT);
326+
CREATE FUNCTION fn2() RETURNS float deterministic RETURN floor('1.1a');
327+
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @a=fn2();
328+
INSERT INTO t1 VALUES(1);
329+
ERROR 22007: Truncated incorrect DOUBLE value: '1.1a'
330+
DROP TRIGGER tr1;
331+
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @a=fn1();
332+
INSERT INTO t1 VALUES(1);
333+
DROP FUNCTION fn1;
334+
DROP FUNCTION fn2;
335+
DROP TRIGGER tr1;
336+
DROP TABLE t1;
337+
SET sql_mode=traditional;
338+
SELECT 1/0;
339+
1/0
340+
NULL
341+
Warnings:
342+
Warning 1365 Division by 0
343+
SET sql_mode='';
344+
CREATE PROCEDURE proc_c()
345+
BEGIN
346+
DECLARE div_zero INTEGER;
347+
SET SQL_MODE='TRADITIONAL';
348+
SELECT 1/0;
349+
END|
350+
CALL proc_c();
351+
1/0
352+
NULL
353+
Warnings:
354+
Warning 1365 Division by 0
355+
DROP PROCEDURE proc_c;
356+
SET sql_mode=traditional;
357+
CREATE FUNCTION fn1() RETURNS TINYINT
358+
BEGIN
359+
SET @x=floor('1a');
360+
RETURN 1;
361+
END|
362+
SELECT fn1();
363+
fn1()
364+
1
365+
DROP FUNCTION fn1;
366+
SET sql_mode= default;

mysql-test/r/sp-vars.result

+2-8
Original file line numberDiff line numberDiff line change
@@ -848,10 +848,7 @@ Warnings:
848848
Warning 1264 Out of range value for column 'arg' at row 1
849849
SET @@sql_mode = 'traditional';
850850
SELECT f1(-2500);
851-
f1(-2500)
852-
0
853-
Warnings:
854-
Warning 1264 Out of range value for column 'arg' at row 1
851+
ERROR 22003: Out of range value for column 'arg' at row 1
855852
DROP FUNCTION f1;
856853
CREATE FUNCTION f1(arg TINYINT UNSIGNED) RETURNS TINYINT
857854
BEGIN
@@ -878,10 +875,7 @@ Warnings:
878875
Warning 1264 Out of range value for column 'arg' at row 1
879876
SET @@sql_mode = 'traditional';
880877
SELECT f1(8388699);
881-
f1(8388699)
882-
8388607
883-
Warnings:
884-
Warning 1264 Out of range value for column 'arg' at row 1
878+
ERROR 22003: Out of range value for column 'arg' at row 1
885879
DROP FUNCTION f1;
886880
CREATE FUNCTION f1(arg MEDIUMINT) RETURNS MEDIUMINT
887881
BEGIN

mysql-test/r/sp.result

+2-4
Original file line numberDiff line numberDiff line change
@@ -5407,17 +5407,15 @@ select func_20028_b()|
54075407
func_20028_b()
54085408
0
54095409
select func_20028_c()|
5410-
func_20028_c()
5411-
NULL
5410+
ERROR 22012: Division by 0
54125411
call proc_20028_a()|
54135412
Warnings:
54145413
Warning 1329 No data - zero rows fetched, selected, or processed
54155414
call proc_20028_b()|
54165415
Warnings:
54175416
Warning 1329 No data - zero rows fetched, selected, or processed
54185417
call proc_20028_c()|
5419-
Warnings:
5420-
Warning 1365 Division by 0
5418+
ERROR 22012: Division by 0
54215419
SET sql_mode='TRADITIONAL'|
54225420
drop function func_20028_a|
54235421
drop function func_20028_b|

mysql-test/r/trigger.result

+3-7
Original file line numberDiff line numberDiff line change
@@ -1059,10 +1059,9 @@ SELECT @x;
10591059
NULL
10601060
SET @x=2;
10611061
UPDATE t1 SET i1 = @x;
1062-
ERROR 22012: Division by 0
10631062
SELECT @x;
10641063
@x
1065-
2
1064+
NULL
10661065
SET SQL_MODE='';
10671066
SET @x=3;
10681067
INSERT INTO t1 VALUES (@x);
@@ -1071,10 +1070,9 @@ SELECT @x;
10711070
NULL
10721071
SET @x=4;
10731072
UPDATE t1 SET i1 = @x;
1074-
ERROR 22012: Division by 0
10751073
SELECT @x;
10761074
@x
1077-
4
1075+
NULL
10781076
SET @@sql_mode=@save_sql_mode;
10791077
DROP TRIGGER t1_ai;
10801078
DROP TRIGGER t1_au;
@@ -1182,7 +1180,6 @@ Warnings:
11821180
Warning 1365 Division by 0
11831181
create trigger t1_bi before insert on t1 for each row set @a:=1/0|
11841182
insert into t1 values(20, 20)|
1185-
ERROR 22012: Division by 0
11861183
drop trigger t1_bi|
11871184
create trigger t1_bi before insert on t1 for each row
11881185
begin
@@ -1201,10 +1198,9 @@ set @a:=1/0;
12011198
end|
12021199
set @check=0, @t4_bi_called=0, @t4_bu_called=0|
12031200
insert into t1 values(30, 30)|
1204-
ERROR 22012: Division by 0
12051201
select @check, @t4_bi_called, @t4_bu_called|
12061202
@check @t4_bi_called @t4_bu_called
1207-
1 1 1
1203+
2 1 1
12081204
SET @@sql_mode=@save_sql_mode;
12091205
drop table t1;
12101206
drop table t2;

mysql-test/suite/innodb_zip/r/index_large_prefix.result

+10-7
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,16 @@ create table worklog5743_8(a1 int, a2 TEXT, a3 TEXT) KEY_BLOCK_SIZE=8;
9393
create table worklog5743_16(a1 int, a2 TEXT, a3 TEXT) KEY_BLOCK_SIZE=16;
9494
set global innodb_large_prefix=0;
9595
create index idx1 on worklog5743_1(a2(4000));
96-
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
96+
ERROR 42000: Specified key was too long; max key length is 767 bytes
9797
show warnings;
9898
Level Code Message
99-
Warning 1071 Specified key was too long; max key length is 767 bytes
100-
Error 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
99+
Error 1071 Specified key was too long; max key length is 767 bytes
101100
set global innodb_large_prefix=1;
102-
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
103101
create index idx2 on worklog5743_1(a2(4000));
104-
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
105-
SET sql_mode = default;
102+
ERROR 42000: Specified key was too long; max key length is 3072 bytes
106103
show warnings;
107104
Level Code Message
105+
Error 1071 Specified key was too long; max key length is 3072 bytes
108106
create index idx3 on worklog5743_1(a2(436));
109107
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
110108
show warnings;
@@ -122,6 +120,7 @@ create index idx6 on worklog5743_1(a1, a2(428));
122120
show warnings;
123121
Level Code Message
124122
set global innodb_large_prefix=0;
123+
SET sql_mode= '';
125124
create index idx1 on worklog5743_2(a2(4000));
126125
Warnings:
127126
Warning 1071 Specified key was too long; max key length is 767 bytes
@@ -253,6 +252,7 @@ Error 1071 Specified key was too long; max key length is 3072 bytes
253252
create index idx7 on worklog5743_16(a1, a2(2000), a3(1068));
254253
show warnings;
255254
Level Code Message
255+
set sql_mode= default;
256256
insert into worklog5743_1 values(9, repeat("a", 10000));
257257
insert into worklog5743_2 values(9, repeat("a", 10000));
258258
insert into worklog5743_4 values(9, repeat("a", 10000));
@@ -382,6 +382,7 @@ a4 varchar(3072),
382382
a5 varchar(3069),
383383
a6 varchar(3068))
384384
ROW_FORMAT=DYNAMIC;
385+
SET sql_mode='';
385386
create index idx1 on worklog5743(a2);
386387
Warnings:
387388
Warning 1071 Specified key was too long; max key length is 3072 bytes
@@ -391,11 +392,11 @@ Warning 1071 Specified key was too long; max key length is 3072 bytes
391392
create index idx3 on worklog5743(a4);
392393
show warnings;
393394
Level Code Message
395+
SET sql_mode= default;
394396
create index idx4 on worklog5743(a1, a2);
395397
ERROR 42000: Specified key was too long; max key length is 3072 bytes
396398
show warnings;
397399
Level Code Message
398-
Warning 1071 Specified key was too long; max key length is 3072 bytes
399400
Error 1071 Specified key was too long; max key length is 3072 bytes
400401
create index idx5 on worklog5743(a1, a5);
401402
ERROR 42000: Specified key was too long; max key length is 3072 bytes
@@ -473,6 +474,7 @@ rollback;
473474
drop table worklog5743;
474475
### Test 7 ###
475476
create table worklog5743(a TEXT not null) ROW_FORMAT=DYNAMIC;
477+
SET sql_mode='';
476478
create index idx1 on worklog5743(a(3073));
477479
Warnings:
478480
Warning 1071 Specified key was too long; max key length is 3072 bytes
@@ -487,6 +489,7 @@ worklog5743 CREATE TABLE `worklog5743` (
487489
KEY `idx2` (`a`(3072))
488490
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
489491
drop table worklog5743;
492+
SET sql_mode= default;
490493
create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT;
491494
create index idx on worklog5743(a(768));
492495
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.

mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result

+5-5
Original file line numberDiff line numberDiff line change
@@ -1257,8 +1257,8 @@ WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
12571257
col_1_text = REPEAT("c", 4000)
12581258
DROP INDEX prefix_idx ON worklog5743;
12591259
CREATE INDEX prefix_idx ON worklog5743(col_1_text (4000));
1260-
Warnings:
1261-
Warning 1071 Specified key was too long; max key length is 3072 bytes
1260+
ERROR 42000: Specified key was too long; max key length is 3072 bytes
1261+
CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072));
12621262
INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
12631263
SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
12641264
col_1_text = REPEAT("a", 4000)
@@ -1373,10 +1373,10 @@ PRIMARY KEY (col_1_varchar(767))
13731373
) engine = innodb;
13741374
INSERT INTO worklog5743 VALUES(REPEAT('a',4000),REPEAT('b',4000));
13751375
CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (1000));
1376+
ERROR 42000: Specified key was too long; max key length is 767 bytes
1377+
CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (767));
13761378
affected rows: 0
1377-
info: Records: 0 Duplicates: 0 Warnings: 1
1378-
Warnings:
1379-
Warning 1071 Specified key was too long; max key length is 767 bytes
1379+
info: Records: 0 Duplicates: 0 Warnings: 0
13801380
ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT;
13811381
affected rows: 0
13821382
info: Records: 0 Duplicates: 0 Warnings: 0

0 commit comments

Comments
 (0)