Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
5a99ffdf
Commit
5a99ffdf
authored
Jan 12, 2007
by
kostja@bodhi.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into bodhi.local:/opt/local/work/mysql-5.0-runtime
parents
6d5cf25d
61a4d6e5
Changes
21
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1338 additions
and
186 deletions
+1338
-186
heap/hp_block.c
heap/hp_block.c
+1
-1
heap/hp_write.c
heap/hp_write.c
+9
-3
mysql-test/r/sp-code.result
mysql-test/r/sp-code.result
+415
-0
mysql-test/r/sp_stress_case.result
mysql-test/r/sp_stress_case.result
+120
-0
mysql-test/r/view.result
mysql-test/r/view.result
+9
-0
mysql-test/t/log.sh
mysql-test/t/log.sh
+1
-1
mysql-test/t/sp-code.test
mysql-test/t/sp-code.test
+235
-0
mysql-test/t/sp_stress_case.test
mysql-test/t/sp_stress_case.test
+89
-0
mysql-test/t/view.test
mysql-test/t/view.test
+15
-0
server-tools/instance-manager/listener.cc
server-tools/instance-manager/listener.cc
+5
-5
sql/item_func.cc
sql/item_func.cc
+3
-2
sql/sp_head.cc
sql/sp_head.cc
+55
-41
sql/sp_head.h
sql/sp_head.h
+28
-11
sql/sql_class.cc
sql/sql_class.cc
+14
-0
sql/sql_class.h
sql/sql_class.h
+10
-2
sql/sql_lex.cc
sql/sql_lex.cc
+0
-1
sql/sql_lex.h
sql/sql_lex.h
+0
-1
sql/sql_prepare.cc
sql/sql_prepare.cc
+1
-2
sql/sql_string.cc
sql/sql_string.cc
+2
-2
sql/sql_yacc.yy
sql/sql_yacc.yy
+298
-114
tests/mysql_client_test.c
tests/mysql_client_test.c
+28
-0
No files found.
heap/hp_block.c
View file @
5a99ffdf
...
@@ -75,7 +75,7 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
...
@@ -75,7 +75,7 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
and my_default_record_cache_size we get about 1/128 unused memory.
and my_default_record_cache_size we get about 1/128 unused memory.
*/
*/
*
alloc_length
=
sizeof
(
HP_PTRS
)
*
i
+
block
->
records_in_block
*
block
->
recbuffer
;
*
alloc_length
=
sizeof
(
HP_PTRS
)
*
i
+
block
->
records_in_block
*
block
->
recbuffer
;
if
(
!
(
root
=
(
HP_PTRS
*
)
my_malloc
(
*
alloc_length
,
MYF
(
0
))))
if
(
!
(
root
=
(
HP_PTRS
*
)
my_malloc
(
*
alloc_length
,
MYF
(
MY_WME
))))
return
1
;
return
1
;
if
(
i
==
0
)
if
(
i
==
0
)
...
...
heap/hp_write.c
View file @
5a99ffdf
...
@@ -67,11 +67,17 @@ int heap_write(HP_INFO *info, const byte *record)
...
@@ -67,11 +67,17 @@ int heap_write(HP_INFO *info, const byte *record)
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
err:
err:
DBUG_PRINT
(
"info"
,(
"Duplicate key: %d"
,
(
int
)
(
keydef
-
share
->
keydef
)));
if
(
my_errno
==
HA_ERR_FOUND_DUPP_KEY
)
DBUG_PRINT
(
"info"
,(
"Duplicate key: %d"
,
keydef
-
share
->
keydef
));
info
->
errkey
=
keydef
-
share
->
keydef
;
info
->
errkey
=
keydef
-
share
->
keydef
;
if
(
keydef
->
algorithm
==
HA_KEY_ALG_BTREE
)
/*
We don't need to delete non-inserted key from rb-tree. Also, if
we got ENOMEM, the key wasn't inserted, so don't try to delete it
either. Otherwise for HASH index on HA_ERR_FOUND_DUPP_KEY the key
was inserted and we have to delete it.
*/
if
(
keydef
->
algorithm
==
HA_KEY_ALG_BTREE
||
my_errno
==
ENOMEM
)
{
{
/* we don't need to delete non-inserted key from rb-tree */
keydef
--
;
keydef
--
;
}
}
while
(
keydef
>=
share
->
keydef
)
while
(
keydef
>=
share
->
keydef
)
...
...
mysql-test/r/sp-code.result
View file @
5a99ffdf
...
@@ -199,6 +199,421 @@ Pos Instruction
...
@@ -199,6 +199,421 @@ Pos Instruction
44 jump 14
44 jump 14
45 stmt 9 "drop temporary table sudoku_work, sud..."
45 stmt 9 "drop temporary table sudoku_work, sud..."
drop procedure sudoku_solve;
drop procedure sudoku_solve;
DROP PROCEDURE IF EXISTS proc_19194_simple;
DROP PROCEDURE IF EXISTS proc_19194_searched;
DROP PROCEDURE IF EXISTS proc_19194_nested_1;
DROP PROCEDURE IF EXISTS proc_19194_nested_2;
DROP PROCEDURE IF EXISTS proc_19194_nested_3;
DROP PROCEDURE IF EXISTS proc_19194_nested_4;
CREATE PROCEDURE proc_19194_simple(i int)
BEGIN
DECLARE str CHAR(10);
CASE i
WHEN 1 THEN SET str="1";
WHEN 2 THEN SET str="2";
WHEN 3 THEN SET str="3";
ELSE SET str="unknown";
END CASE;
SELECT str;
END|
CREATE PROCEDURE proc_19194_searched(i int)
BEGIN
DECLARE str CHAR(10);
CASE
WHEN i=1 THEN SET str="1";
WHEN i=2 THEN SET str="2";
WHEN i=3 THEN SET str="3";
ELSE SET str="unknown";
END CASE;
SELECT str;
END|
CREATE PROCEDURE proc_19194_nested_1(i int, j int)
BEGIN
DECLARE str_i CHAR(10);
DECLARE str_j CHAR(10);
CASE i
WHEN 10 THEN SET str_i="10";
WHEN 20 THEN
BEGIN
set str_i="20";
CASE
WHEN j=1 THEN SET str_j="1";
WHEN j=2 THEN SET str_j="2";
WHEN j=3 THEN SET str_j="3";
ELSE SET str_j="unknown";
END CASE;
select "i was 20";
END;
WHEN 30 THEN SET str_i="30";
WHEN 40 THEN SET str_i="40";
ELSE SET str_i="unknown";
END CASE;
SELECT str_i, str_j;
END|
CREATE PROCEDURE proc_19194_nested_2(i int, j int)
BEGIN
DECLARE str_i CHAR(10);
DECLARE str_j CHAR(10);
CASE
WHEN i=10 THEN SET str_i="10";
WHEN i=20 THEN
BEGIN
set str_i="20";
CASE j
WHEN 1 THEN SET str_j="1";
WHEN 2 THEN SET str_j="2";
WHEN 3 THEN SET str_j="3";
ELSE SET str_j="unknown";
END CASE;
select "i was 20";
END;
WHEN i=30 THEN SET str_i="30";
WHEN i=40 THEN SET str_i="40";
ELSE SET str_i="unknown";
END CASE;
SELECT str_i, str_j;
END|
CREATE PROCEDURE proc_19194_nested_3(i int, j int)
BEGIN
DECLARE str_i CHAR(10);
DECLARE str_j CHAR(10);
CASE i
WHEN 10 THEN SET str_i="10";
WHEN 20 THEN
BEGIN
set str_i="20";
CASE j
WHEN 1 THEN SET str_j="1";
WHEN 2 THEN SET str_j="2";
WHEN 3 THEN SET str_j="3";
ELSE SET str_j="unknown";
END CASE;
select "i was 20";
END;
WHEN 30 THEN SET str_i="30";
WHEN 40 THEN SET str_i="40";
ELSE SET str_i="unknown";
END CASE;
SELECT str_i, str_j;
END|
CREATE PROCEDURE proc_19194_nested_4(i int, j int)
BEGIN
DECLARE str_i CHAR(10);
DECLARE str_j CHAR(10);
CASE
WHEN i=10 THEN SET str_i="10";
WHEN i=20 THEN
BEGIN
set str_i="20";
CASE
WHEN j=1 THEN SET str_j="1";
WHEN j=2 THEN SET str_j="2";
WHEN j=3 THEN SET str_j="3";
ELSE SET str_j="unknown";
END CASE;
select "i was 20";
END;
WHEN i=30 THEN SET str_i="30";
WHEN i=40 THEN SET str_i="40";
ELSE SET str_i="unknown";
END CASE;
SELECT str_i, str_j;
END|
SHOW PROCEDURE CODE proc_19194_simple;
Pos Instruction
0 set str@1 NULL
1 set_case_expr (12) 0 i@0
2 jump_if_not 5(12) (case_expr@0 = 1)
3 set str@1 _latin1'1'
4 jump 12
5 jump_if_not 8(12) (case_expr@0 = 2)
6 set str@1 _latin1'2'
7 jump 12
8 jump_if_not 11(12) (case_expr@0 = 3)
9 set str@1 _latin1'3'
10 jump 12
11 set str@1 _latin1'unknown'
12 stmt 0 "SELECT str"
SHOW PROCEDURE CODE proc_19194_searched;
Pos Instruction
0 set str@1 NULL
1 jump_if_not 4(11) (i@0 = 1)
2 set str@1 _latin1'1'
3 jump 11
4 jump_if_not 7(11) (i@0 = 2)
5 set str@1 _latin1'2'
6 jump 11
7 jump_if_not 10(11) (i@0 = 3)
8 set str@1 _latin1'3'
9 jump 11
10 set str@1 _latin1'unknown'
11 stmt 0 "SELECT str"
SHOW PROCEDURE CODE proc_19194_nested_1;
Pos Instruction
0 set str_i@2 NULL
1 set str_j@3 NULL
2 set_case_expr (27) 0 i@0
3 jump_if_not 6(27) (case_expr@0 = 10)
4 set str_i@2 _latin1'10'
5 jump 27
6 jump_if_not 20(27) (case_expr@0 = 20)
7 set str_i@2 _latin1'20'
8 jump_if_not 11(18) (j@1 = 1)
9 set str_j@3 _latin1'1'
10 jump 18
11 jump_if_not 14(18) (j@1 = 2)
12 set str_j@3 _latin1'2'
13 jump 18
14 jump_if_not 17(18) (j@1 = 3)
15 set str_j@3 _latin1'3'
16 jump 18
17 set str_j@3 _latin1'unknown'
18 stmt 0 "select "i was 20""
19 jump 27
20 jump_if_not 23(27) (case_expr@0 = 30)
21 set str_i@2 _latin1'30'
22 jump 27
23 jump_if_not 26(27) (case_expr@0 = 40)
24 set str_i@2 _latin1'40'
25 jump 27
26 set str_i@2 _latin1'unknown'
27 stmt 0 "SELECT str_i, str_j"
SHOW PROCEDURE CODE proc_19194_nested_2;
Pos Instruction
0 set str_i@2 NULL
1 set str_j@3 NULL
2 jump_if_not 5(27) (i@0 = 10)
3 set str_i@2 _latin1'10'
4 jump 27
5 jump_if_not 20(27) (i@0 = 20)
6 set str_i@2 _latin1'20'
7 set_case_expr (18) 0 j@1
8 jump_if_not 11(18) (case_expr@0 = 1)
9 set str_j@3 _latin1'1'
10 jump 18
11 jump_if_not 14(18) (case_expr@0 = 2)
12 set str_j@3 _latin1'2'
13 jump 18
14 jump_if_not 17(18) (case_expr@0 = 3)
15 set str_j@3 _latin1'3'
16 jump 18
17 set str_j@3 _latin1'unknown'
18 stmt 0 "select "i was 20""
19 jump 27
20 jump_if_not 23(27) (i@0 = 30)
21 set str_i@2 _latin1'30'
22 jump 27
23 jump_if_not 26(27) (i@0 = 40)
24 set str_i@2 _latin1'40'
25 jump 27
26 set str_i@2 _latin1'unknown'
27 stmt 0 "SELECT str_i, str_j"
SHOW PROCEDURE CODE proc_19194_nested_3;
Pos Instruction
0 set str_i@2 NULL
1 set str_j@3 NULL
2 set_case_expr (28) 0 i@0
3 jump_if_not 6(28) (case_expr@0 = 10)
4 set str_i@2 _latin1'10'
5 jump 28
6 jump_if_not 21(28) (case_expr@0 = 20)
7 set str_i@2 _latin1'20'
8 set_case_expr (19) 1 j@1
9 jump_if_not 12(19) (case_expr@1 = 1)
10 set str_j@3 _latin1'1'
11 jump 19
12 jump_if_not 15(19) (case_expr@1 = 2)
13 set str_j@3 _latin1'2'
14 jump 19
15 jump_if_not 18(19) (case_expr@1 = 3)
16 set str_j@3 _latin1'3'
17 jump 19
18 set str_j@3 _latin1'unknown'
19 stmt 0 "select "i was 20""
20 jump 28
21 jump_if_not 24(28) (case_expr@0 = 30)
22 set str_i@2 _latin1'30'
23 jump 28
24 jump_if_not 27(28) (case_expr@0 = 40)
25 set str_i@2 _latin1'40'
26 jump 28
27 set str_i@2 _latin1'unknown'
28 stmt 0 "SELECT str_i, str_j"
SHOW PROCEDURE CODE proc_19194_nested_4;
Pos Instruction
0 set str_i@2 NULL
1 set str_j@3 NULL
2 jump_if_not 5(26) (i@0 = 10)
3 set str_i@2 _latin1'10'
4 jump 26
5 jump_if_not 19(26) (i@0 = 20)
6 set str_i@2 _latin1'20'
7 jump_if_not 10(17) (j@1 = 1)
8 set str_j@3 _latin1'1'
9 jump 17
10 jump_if_not 13(17) (j@1 = 2)
11 set str_j@3 _latin1'2'
12 jump 17
13 jump_if_not 16(17) (j@1 = 3)
14 set str_j@3 _latin1'3'
15 jump 17
16 set str_j@3 _latin1'unknown'
17 stmt 0 "select "i was 20""
18 jump 26
19 jump_if_not 22(26) (i@0 = 30)
20 set str_i@2 _latin1'30'
21 jump 26
22 jump_if_not 25(26) (i@0 = 40)
23 set str_i@2 _latin1'40'
24 jump 26
25 set str_i@2 _latin1'unknown'
26 stmt 0 "SELECT str_i, str_j"
CALL proc_19194_nested_1(10, 1);
str_i str_j
10 NULL
CALL proc_19194_nested_1(25, 1);
str_i str_j
unknown NULL
CALL proc_19194_nested_1(20, 1);
i was 20
i was 20
str_i str_j
20 1
CALL proc_19194_nested_1(20, 2);
i was 20
i was 20
str_i str_j
20 2
CALL proc_19194_nested_1(20, 3);
i was 20
i was 20
str_i str_j
20 3
CALL proc_19194_nested_1(20, 4);
i was 20
i was 20
str_i str_j
20 unknown
CALL proc_19194_nested_1(30, 1);
str_i str_j
30 NULL
CALL proc_19194_nested_1(40, 1);
str_i str_j
40 NULL
CALL proc_19194_nested_1(0, 0);
str_i str_j
unknown NULL
CALL proc_19194_nested_2(10, 1);
str_i str_j
10 NULL
CALL proc_19194_nested_2(25, 1);
str_i str_j
unknown NULL
CALL proc_19194_nested_2(20, 1);
i was 20
i was 20
str_i str_j
20 1
CALL proc_19194_nested_2(20, 2);
i was 20
i was 20
str_i str_j
20 2
CALL proc_19194_nested_2(20, 3);
i was 20
i was 20
str_i str_j
20 3
CALL proc_19194_nested_2(20, 4);
i was 20
i was 20
str_i str_j
20 unknown
CALL proc_19194_nested_2(30, 1);
str_i str_j
30 NULL
CALL proc_19194_nested_2(40, 1);
str_i str_j
40 NULL
CALL proc_19194_nested_2(0, 0);
str_i str_j
unknown NULL
CALL proc_19194_nested_3(10, 1);
str_i str_j
10 NULL
CALL proc_19194_nested_3(25, 1);
str_i str_j
unknown NULL
CALL proc_19194_nested_3(20, 1);
i was 20
i was 20
str_i str_j
20 1
CALL proc_19194_nested_3(20, 2);
i was 20
i was 20
str_i str_j
20 2
CALL proc_19194_nested_3(20, 3);
i was 20
i was 20
str_i str_j
20 3
CALL proc_19194_nested_3(20, 4);
i was 20
i was 20
str_i str_j
20 unknown
CALL proc_19194_nested_3(30, 1);
str_i str_j
30 NULL
CALL proc_19194_nested_3(40, 1);
str_i str_j
40 NULL
CALL proc_19194_nested_3(0, 0);
str_i str_j
unknown NULL
CALL proc_19194_nested_4(10, 1);
str_i str_j
10 NULL
CALL proc_19194_nested_4(25, 1);
str_i str_j
unknown NULL
CALL proc_19194_nested_4(20, 1);
i was 20
i was 20
str_i str_j
20 1
CALL proc_19194_nested_4(20, 2);
i was 20
i was 20
str_i str_j
20 2
CALL proc_19194_nested_4(20, 3);
i was 20
i was 20
str_i str_j
20 3
CALL proc_19194_nested_4(20, 4);
i was 20
i was 20
str_i str_j
20 unknown
CALL proc_19194_nested_4(30, 1);
str_i str_j
30 NULL
CALL proc_19194_nested_4(40, 1);
str_i str_j
40 NULL
CALL proc_19194_nested_4(0, 0);
str_i str_j
unknown NULL
DROP PROCEDURE proc_19194_simple;
DROP PROCEDURE proc_19194_searched;
DROP PROCEDURE proc_19194_nested_1;
DROP PROCEDURE proc_19194_nested_2;
DROP PROCEDURE proc_19194_nested_3;
DROP PROCEDURE proc_19194_nested_4;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1);
CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1);
SHOW PROCEDURE CODE p1;
SHOW PROCEDURE CODE p1;
...
...
mysql-test/r/sp_stress_case.result
0 → 100644
View file @
5a99ffdf
DROP PROCEDURE IF EXISTS proc_19194_codegen;
DROP PROCEDURE IF EXISTS bug_19194_simple;
DROP PROCEDURE IF EXISTS bug_19194_searched;
CREATE PROCEDURE proc_19194_codegen(
IN proc_name VARCHAR(50),
IN count INTEGER,
IN simple INTEGER,
OUT body MEDIUMTEXT)
BEGIN
DECLARE code MEDIUMTEXT;
DECLARE i INT DEFAULT 1;
SET code = concat("CREATE PROCEDURE ", proc_name, "(i INT)\n");
SET code = concat(code, "BEGIN\n");
SET code = concat(code, " DECLARE str CHAR(10);\n");
IF (simple)
THEN
SET code = concat(code, " CASE i\n");
ELSE
SET code = concat(code, " CASE\n");
END IF;
WHILE (i <= count)
DO
IF (simple)
THEN
SET code = concat(code, " WHEN ", i, " THEN SET str=\"", i, "\";\n");
ELSE
SET code = concat(code, " WHEN i=", i, " THEN SET str=\"", i, "\";\n");
END IF;
SET i = i + 1;
END WHILE;
SET code = concat(code, " ELSE SET str=\"unknown\";\n");
SET code = concat(code, " END CASE;\n");
SET code = concat(code, " SELECT str;\n");
SET code = concat(code, "END\n");
SET body = code;
END|
set @body="";
call proc_19194_codegen("test_simple", 10, 1, @body);
select @body;
@body
CREATE PROCEDURE test_simple(i INT)
BEGIN
DECLARE str CHAR(10);
CASE i
WHEN 1 THEN SET str="1";
WHEN 2 THEN SET str="2";
WHEN 3 THEN SET str="3";
WHEN 4 THEN SET str="4";
WHEN 5 THEN SET str="5";
WHEN 6 THEN SET str="6";
WHEN 7 THEN SET str="7";
WHEN 8 THEN SET str="8";
WHEN 9 THEN SET str="9";
WHEN 10 THEN SET str="10";
ELSE SET str="unknown";
END CASE;
SELECT str;
END
call proc_19194_codegen("test_searched", 10, 0, @body);
select @body;
@body
CREATE PROCEDURE test_searched(i INT)
BEGIN
DECLARE str CHAR(10);
CASE
WHEN i=1 THEN SET str="1";
WHEN i=2 THEN SET str="2";
WHEN i=3 THEN SET str="3";
WHEN i=4 THEN SET str="4";
WHEN i=5 THEN SET str="5";
WHEN i=6 THEN SET str="6";
WHEN i=7 THEN SET str="7";
WHEN i=8 THEN SET str="8";
WHEN i=9 THEN SET str="9";
WHEN i=10 THEN SET str="10";
ELSE SET str="unknown";
END CASE;
SELECT str;
END
CALL bug_19194_simple(1);
str
1
CALL bug_19194_simple(2);
str
2
CALL bug_19194_simple(1000);
str
1000
CALL bug_19194_simple(4998);
str
4998
CALL bug_19194_simple(4999);
str
4999
CALL bug_19194_simple(9999);
str
unknown
CALL bug_19194_searched(1);
str
1
CALL bug_19194_searched(2);
str
2
CALL bug_19194_searched(1000);
str
1000
CALL bug_19194_searched(4998);
str
4998
CALL bug_19194_searched(4999);
str
4999
CALL bug_19194_searched(9999);
str
unknown
DROP PROCEDURE proc_19194_codegen;
DROP PROCEDURE bug_19194_simple;
DROP PROCEDURE bug_19194_searched;
mysql-test/r/view.result
View file @
5a99ffdf
...
@@ -3014,4 +3014,13 @@ i j
...
@@ -3014,4 +3014,13 @@ i j
6 3
6 3
DROP VIEW v1, v2;
DROP VIEW v1, v2;
DROP TABLE t1;
DROP TABLE t1;
DROP VIEW IF EXISTS v1;
CREATE VIEW v1 AS SELECT 'The\ZEnd';
SELECT * FROM v1;
TheEnd
TheEnd
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd`
DROP VIEW v1;
End of 5.0 tests.
End of 5.0 tests.
mysql-test/t/log.sh
View file @
5a99ffdf
#!/bin/
ba
sh
#!/bin/sh
###########################################################################
###########################################################################
...
...
mysql-test/t/sp-code.test
View file @
5a99ffdf
...
@@ -191,6 +191,241 @@ show procedure code sudoku_solve;
...
@@ -191,6 +191,241 @@ show procedure code sudoku_solve;
drop
procedure
sudoku_solve
;
drop
procedure
sudoku_solve
;
#
# Bug#19194 (Right recursion in parser for CASE causes excessive stack
# usage, limitation)
# This bug also exposed a flaw in the generated code with nested case
# statements
#
--
disable_warnings
DROP
PROCEDURE
IF
EXISTS
proc_19194_simple
;
DROP
PROCEDURE
IF
EXISTS
proc_19194_searched
;
DROP
PROCEDURE
IF
EXISTS
proc_19194_nested_1
;
DROP
PROCEDURE
IF
EXISTS
proc_19194_nested_2
;
DROP
PROCEDURE
IF
EXISTS
proc_19194_nested_3
;
DROP
PROCEDURE
IF
EXISTS
proc_19194_nested_4
;
--
enable_warnings
delimiter
|
;
CREATE
PROCEDURE
proc_19194_simple
(
i
int
)
BEGIN
DECLARE
str
CHAR
(
10
);
CASE
i
WHEN
1
THEN
SET
str
=
"1"
;
WHEN
2
THEN
SET
str
=
"2"
;
WHEN
3
THEN
SET
str
=
"3"
;
ELSE
SET
str
=
"unknown"
;
END
CASE
;
SELECT
str
;
END
|
CREATE
PROCEDURE
proc_19194_searched
(
i
int
)
BEGIN
DECLARE
str
CHAR
(
10
);
CASE
WHEN
i
=
1
THEN
SET
str
=
"1"
;
WHEN
i
=
2
THEN
SET
str
=
"2"
;
WHEN
i
=
3
THEN
SET
str
=
"3"
;
ELSE
SET
str
=
"unknown"
;
END
CASE
;
SELECT
str
;
END
|
# Outer SIMPLE case, inner SEARCHED case
CREATE
PROCEDURE
proc_19194_nested_1
(
i
int
,
j
int
)
BEGIN
DECLARE
str_i
CHAR
(
10
);
DECLARE
str_j
CHAR
(
10
);
CASE
i
WHEN
10
THEN
SET
str_i
=
"10"
;
WHEN
20
THEN
BEGIN
set
str_i
=
"20"
;
CASE
WHEN
j
=
1
THEN
SET
str_j
=
"1"
;
WHEN
j
=
2
THEN
SET
str_j
=
"2"
;
WHEN
j
=
3
THEN
SET
str_j
=
"3"
;
ELSE
SET
str_j
=
"unknown"
;
END
CASE
;
select
"i was 20"
;
END
;
WHEN
30
THEN
SET
str_i
=
"30"
;
WHEN
40
THEN
SET
str_i
=
"40"
;
ELSE
SET
str_i
=
"unknown"
;
END
CASE
;
SELECT
str_i
,
str_j
;
END
|
# Outer SEARCHED case, inner SIMPLE case
CREATE
PROCEDURE
proc_19194_nested_2
(
i
int
,
j
int
)
BEGIN
DECLARE
str_i
CHAR
(
10
);
DECLARE
str_j
CHAR
(
10
);
CASE
WHEN
i
=
10
THEN
SET
str_i
=
"10"
;
WHEN
i
=
20
THEN
BEGIN
set
str_i
=
"20"
;
CASE
j
WHEN
1
THEN
SET
str_j
=
"1"
;
WHEN
2
THEN
SET
str_j
=
"2"
;
WHEN
3
THEN
SET
str_j
=
"3"
;
ELSE
SET
str_j
=
"unknown"
;
END
CASE
;
select
"i was 20"
;
END
;
WHEN
i
=
30
THEN
SET
str_i
=
"30"
;
WHEN
i
=
40
THEN
SET
str_i
=
"40"
;
ELSE
SET
str_i
=
"unknown"
;
END
CASE
;
SELECT
str_i
,
str_j
;
END
|
# Outer SIMPLE case, inner SIMPLE case
CREATE
PROCEDURE
proc_19194_nested_3
(
i
int
,
j
int
)
BEGIN
DECLARE
str_i
CHAR
(
10
);
DECLARE
str_j
CHAR
(
10
);
CASE
i
WHEN
10
THEN
SET
str_i
=
"10"
;
WHEN
20
THEN
BEGIN
set
str_i
=
"20"
;
CASE
j
WHEN
1
THEN
SET
str_j
=
"1"
;
WHEN
2
THEN
SET
str_j
=
"2"
;
WHEN
3
THEN
SET
str_j
=
"3"
;
ELSE
SET
str_j
=
"unknown"
;
END
CASE
;
select
"i was 20"
;
END
;
WHEN
30
THEN
SET
str_i
=
"30"
;
WHEN
40
THEN
SET
str_i
=
"40"
;
ELSE
SET
str_i
=
"unknown"
;
END
CASE
;
SELECT
str_i
,
str_j
;
END
|
# Outer SEARCHED case, inner SEARCHED case
CREATE
PROCEDURE
proc_19194_nested_4
(
i
int
,
j
int
)
BEGIN
DECLARE
str_i
CHAR
(
10
);
DECLARE
str_j
CHAR
(
10
);
CASE
WHEN
i
=
10
THEN
SET
str_i
=
"10"
;
WHEN
i
=
20
THEN
BEGIN
set
str_i
=
"20"
;
CASE
WHEN
j
=
1
THEN
SET
str_j
=
"1"
;
WHEN
j
=
2
THEN
SET
str_j
=
"2"
;
WHEN
j
=
3
THEN
SET
str_j
=
"3"
;
ELSE
SET
str_j
=
"unknown"
;
END
CASE
;
select
"i was 20"
;
END
;
WHEN
i
=
30
THEN
SET
str_i
=
"30"
;
WHEN
i
=
40
THEN
SET
str_i
=
"40"
;
ELSE
SET
str_i
=
"unknown"
;
END
CASE
;
SELECT
str_i
,
str_j
;
END
|
delimiter
;
|
SHOW
PROCEDURE
CODE
proc_19194_simple
;
SHOW
PROCEDURE
CODE
proc_19194_searched
;
SHOW
PROCEDURE
CODE
proc_19194_nested_1
;
SHOW
PROCEDURE
CODE
proc_19194_nested_2
;
SHOW
PROCEDURE
CODE
proc_19194_nested_3
;
SHOW
PROCEDURE
CODE
proc_19194_nested_4
;
CALL
proc_19194_nested_1
(
10
,
1
);
#
# Before 19194, the generated code was:
# 20 jump_if_not 23(27) 30
# 21 set str_i@2 _latin1'30'
# As opposed to the expected:
# 20 jump_if_not 23(27) (case_expr@0 = 30)
# 21 set str_i@2 _latin1'30'
#
# and as a result, this call returned "30",
# because the expression 30 is always true,
# masking the case 40, case 0 and the else.
#
CALL
proc_19194_nested_1
(
25
,
1
);
CALL
proc_19194_nested_1
(
20
,
1
);
CALL
proc_19194_nested_1
(
20
,
2
);
CALL
proc_19194_nested_1
(
20
,
3
);
CALL
proc_19194_nested_1
(
20
,
4
);
CALL
proc_19194_nested_1
(
30
,
1
);
CALL
proc_19194_nested_1
(
40
,
1
);
CALL
proc_19194_nested_1
(
0
,
0
);
CALL
proc_19194_nested_2
(
10
,
1
);
#
# Before 19194, the generated code was:
# 20 jump_if_not 23(27) (case_expr@0 = (i@0 = 30))
# 21 set str_i@2 _latin1'30'
# As opposed to the expected:
# 20 jump_if_not 23(27) (i@0 = 30)
# 21 set str_i@2 _latin1'30'
# and as a result, this call crashed the server, because there is no
# such variable as "case_expr@0".
#
CALL
proc_19194_nested_2
(
25
,
1
);
CALL
proc_19194_nested_2
(
20
,
1
);
CALL
proc_19194_nested_2
(
20
,
2
);
CALL
proc_19194_nested_2
(
20
,
3
);
CALL
proc_19194_nested_2
(
20
,
4
);
CALL
proc_19194_nested_2
(
30
,
1
);
CALL
proc_19194_nested_2
(
40
,
1
);
CALL
proc_19194_nested_2
(
0
,
0
);
CALL
proc_19194_nested_3
(
10
,
1
);
CALL
proc_19194_nested_3
(
25
,
1
);
CALL
proc_19194_nested_3
(
20
,
1
);
CALL
proc_19194_nested_3
(
20
,
2
);
CALL
proc_19194_nested_3
(
20
,
3
);
CALL
proc_19194_nested_3
(
20
,
4
);
CALL
proc_19194_nested_3
(
30
,
1
);
CALL
proc_19194_nested_3
(
40
,
1
);
CALL
proc_19194_nested_3
(
0
,
0
);
CALL
proc_19194_nested_4
(
10
,
1
);
CALL
proc_19194_nested_4
(
25
,
1
);
CALL
proc_19194_nested_4
(
20
,
1
);
CALL
proc_19194_nested_4
(
20
,
2
);
CALL
proc_19194_nested_4
(
20
,
3
);
CALL
proc_19194_nested_4
(
20
,
4
);
CALL
proc_19194_nested_4
(
30
,
1
);
CALL
proc_19194_nested_4
(
40
,
1
);
CALL
proc_19194_nested_4
(
0
,
0
);
DROP
PROCEDURE
proc_19194_simple
;
DROP
PROCEDURE
proc_19194_searched
;
DROP
PROCEDURE
proc_19194_nested_1
;
DROP
PROCEDURE
proc_19194_nested_2
;
DROP
PROCEDURE
proc_19194_nested_3
;
DROP
PROCEDURE
proc_19194_nested_4
;
#
#
# Bug#19207: Final parenthesis omitted for CREATE INDEX in Stored
# Bug#19207: Final parenthesis omitted for CREATE INDEX in Stored
...
...
mysql-test/t/sp_stress_case.test
0 → 100644
View file @
5a99ffdf
#
# Bug#19194 (Right recursion in parser for CASE causes excessive stack
# usage, limitation)
#
--
disable_warnings
DROP
PROCEDURE
IF
EXISTS
proc_19194_codegen
;
DROP
PROCEDURE
IF
EXISTS
bug_19194_simple
;
DROP
PROCEDURE
IF
EXISTS
bug_19194_searched
;
--
enable_warnings
delimiter
|
;
CREATE
PROCEDURE
proc_19194_codegen
(
IN
proc_name
VARCHAR
(
50
),
IN
count
INTEGER
,
IN
simple
INTEGER
,
OUT
body
MEDIUMTEXT
)
BEGIN
DECLARE
code
MEDIUMTEXT
;
DECLARE
i
INT
DEFAULT
1
;
SET
code
=
concat
(
"CREATE PROCEDURE "
,
proc_name
,
"(i INT)
\n
"
);
SET
code
=
concat
(
code
,
"BEGIN
\n
"
);
SET
code
=
concat
(
code
,
" DECLARE str CHAR(10);
\n
"
);
IF
(
simple
)
THEN
SET
code
=
concat
(
code
,
" CASE i
\n
"
);
ELSE
SET
code
=
concat
(
code
,
" CASE
\n
"
);
END
IF
;
WHILE
(
i
<=
count
)
DO
IF
(
simple
)
THEN
SET
code
=
concat
(
code
,
" WHEN "
,
i
,
" THEN SET str=
\"
"
,
i
,
"
\"
;
\n
"
);
ELSE
SET
code
=
concat
(
code
,
" WHEN i="
,
i
,
" THEN SET str=
\"
"
,
i
,
"
\"
;
\n
"
);
END
IF
;
SET
i
=
i
+
1
;
END
WHILE
;
SET
code
=
concat
(
code
,
" ELSE SET str=
\"
unknown
\"
;
\n
"
);
SET
code
=
concat
(
code
,
" END CASE;
\n
"
);
SET
code
=
concat
(
code
,
" SELECT str;
\n
"
);
SET
code
=
concat
(
code
,
"END
\n
"
);
SET
body
=
code
;
END
|
delimiter
;
|
set
@
body
=
""
;
call
proc_19194_codegen
(
"test_simple"
,
10
,
1
,
@
body
);
select
@
body
;
call
proc_19194_codegen
(
"test_searched"
,
10
,
0
,
@
body
);
select
@
body
;
--
disable_query_log
call
proc_19194_codegen
(
"bug_19194_simple"
,
5000
,
1
,
@
body
);
let
$proc_body
=
`select @body`
;
eval
$proc_body
;
call
proc_19194_codegen
(
"bug_19194_searched"
,
5000
,
1
,
@
body
);
let
$proc_body
=
`select @body`
;
eval
$proc_body
;
--
enable_query_log
CALL
bug_19194_simple
(
1
);
CALL
bug_19194_simple
(
2
);
CALL
bug_19194_simple
(
1000
);
CALL
bug_19194_simple
(
4998
);
CALL
bug_19194_simple
(
4999
);
CALL
bug_19194_simple
(
9999
);
CALL
bug_19194_searched
(
1
);
CALL
bug_19194_searched
(
2
);
CALL
bug_19194_searched
(
1000
);
CALL
bug_19194_searched
(
4998
);
CALL
bug_19194_searched
(
4999
);
CALL
bug_19194_searched
(
9999
);
DROP
PROCEDURE
proc_19194_codegen
;
DROP
PROCEDURE
bug_19194_simple
;
DROP
PROCEDURE
bug_19194_searched
;
mysql-test/t/view.test
View file @
5a99ffdf
...
@@ -2960,4 +2960,19 @@ DROP VIEW v1, v2;
...
@@ -2960,4 +2960,19 @@ DROP VIEW v1, v2;
DROP
TABLE
t1
;
DROP
TABLE
t1
;
#
# BUG#24293: '\Z' token is not handled correctly in views
#
--
disable_warnings
DROP
VIEW
IF
EXISTS
v1
;
--
enable_warnings
CREATE
VIEW
v1
AS
SELECT
'The\ZEnd'
;
SELECT
*
FROM
v1
;
SHOW
CREATE
VIEW
v1
;
DROP
VIEW
v1
;
--
echo
End
of
5.0
tests
.
--
echo
End
of
5.0
tests
.
server-tools/instance-manager/listener.cc
View file @
5a99ffdf
...
@@ -187,7 +187,7 @@ void Listener_thread::run()
...
@@ -187,7 +187,7 @@ void Listener_thread::run()
else
else
{
{
shutdown
(
client_fd
,
SHUT_RDWR
);
shutdown
(
client_fd
,
SHUT_RDWR
);
close
(
client_fd
);
close
socket
(
client_fd
);
}
}
}
}
}
}
...
@@ -199,7 +199,7 @@ void Listener_thread::run()
...
@@ -199,7 +199,7 @@ void Listener_thread::run()
log_info
(
"Listener_thread::run(): shutdown requested, exiting..."
);
log_info
(
"Listener_thread::run(): shutdown requested, exiting..."
);
for
(
i
=
0
;
i
<
num_sockets
;
i
++
)
for
(
i
=
0
;
i
<
num_sockets
;
i
++
)
close
(
sockets
[
i
]);
close
socket
(
sockets
[
i
]);
#ifndef __WIN__
#ifndef __WIN__
unlink
(
unix_socket_address
.
sun_path
);
unlink
(
unix_socket_address
.
sun_path
);
...
@@ -212,7 +212,7 @@ void Listener_thread::run()
...
@@ -212,7 +212,7 @@ void Listener_thread::run()
err:
err:
// we have to close the ip sockets in case of error
// we have to close the ip sockets in case of error
for
(
i
=
0
;
i
<
num_sockets
;
i
++
)
for
(
i
=
0
;
i
<
num_sockets
;
i
++
)
close
(
sockets
[
i
]);
close
socket
(
sockets
[
i
]);
thread_registry
.
unregister_thread
(
&
thread_info
);
thread_registry
.
unregister_thread
(
&
thread_info
);
thread_registry
.
request_shutdown
();
thread_registry
.
request_shutdown
();
...
@@ -259,7 +259,7 @@ int Listener_thread::create_tcp_socket()
...
@@ -259,7 +259,7 @@ int Listener_thread::create_tcp_socket()
{
{
log_error
(
"Listener_thread::run(): bind(ip socket) failed, '%s'"
,
log_error
(
"Listener_thread::run(): bind(ip socket) failed, '%s'"
,
strerror
(
errno
));
strerror
(
errno
));
close
(
ip_socket
);
close
socket
(
ip_socket
);
return
-
1
;
return
-
1
;
}
}
...
@@ -267,7 +267,7 @@ int Listener_thread::create_tcp_socket()
...
@@ -267,7 +267,7 @@ int Listener_thread::create_tcp_socket()
{
{
log_error
(
"Listener_thread::run(): listen(ip socket) failed, %s"
,
log_error
(
"Listener_thread::run(): listen(ip socket) failed, %s"
,
strerror
(
errno
));
strerror
(
errno
));
close
(
ip_socket
);
close
socket
(
ip_socket
);
return
-
1
;
return
-
1
;
}
}
...
...
sql/item_func.cc
View file @
5a99ffdf
...
@@ -3688,8 +3688,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
...
@@ -3688,8 +3688,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
char
*
pos
=
(
char
*
)
entry
+
ALIGN_SIZE
(
sizeof
(
user_var_entry
));
char
*
pos
=
(
char
*
)
entry
+
ALIGN_SIZE
(
sizeof
(
user_var_entry
));
if
(
entry
->
value
==
pos
)
if
(
entry
->
value
==
pos
)
entry
->
value
=
0
;
entry
->
value
=
0
;
if
(
!
(
entry
->
value
=
(
char
*
)
my_realloc
(
entry
->
value
,
length
,
entry
->
value
=
(
char
*
)
my_realloc
(
entry
->
value
,
length
,
MYF
(
MY_ALLOW_ZERO_PTR
))))
MYF
(
MY_ALLOW_ZERO_PTR
|
MY_WME
));
if
(
!
entry
->
value
)
return
1
;
return
1
;
}
}
}
}
...
...
sql/sp_head.cc
View file @
5a99ffdf
...
@@ -605,27 +605,6 @@ sp_head::create(THD *thd)
...
@@ -605,27 +605,6 @@ sp_head::create(THD *thd)
DBUG_PRINT
(
"info"
,
(
"type: %d name: %s params: %s body: %s"
,
DBUG_PRINT
(
"info"
,
(
"type: %d name: %s params: %s body: %s"
,
m_type
,
m_name
.
str
,
m_params
.
str
,
m_body
.
str
));
m_type
,
m_name
.
str
,
m_params
.
str
,
m_body
.
str
));
#ifndef DBUG_OFF
optimize
();
{
String
s
;
sp_instr
*
i
;
uint
ip
=
0
;
while
((
i
=
get_instr
(
ip
)))
{
char
buf
[
8
];
sprintf
(
buf
,
"%4u: "
,
ip
);
s
.
append
(
buf
);
i
->
print
(
&
s
);
s
.
append
(
'\n'
);
ip
+=
1
;
}
s
.
append
(
'\0'
);
DBUG_PRINT
(
"info"
,
(
"Code %s
\n
%s"
,
m_qname
.
str
,
s
.
ptr
()));
}
#endif
if
(
m_type
==
TYPE_ENUM_FUNCTION
)
if
(
m_type
==
TYPE_ENUM_FUNCTION
)
ret
=
sp_create_function
(
thd
,
this
);
ret
=
sp_create_function
(
thd
,
this
);
else
else
...
@@ -2173,7 +2152,7 @@ sp_head::show_create_function(THD *thd)
...
@@ -2173,7 +2152,7 @@ sp_head::show_create_function(THD *thd)
This is the main mark and move loop; it relies on the following methods
This is the main mark and move loop; it relies on the following methods
in sp_instr and its subclasses:
in sp_instr and its subclasses:
opt_mark() Mark instruction as reachable
(will recurse for jumps)
opt_mark() Mark instruction as reachable
opt_shortcut_jump() Shortcut jumps to the final destination;
opt_shortcut_jump() Shortcut jumps to the final destination;
used by opt_mark().
used by opt_mark().
opt_move() Update moved instruction
opt_move() Update moved instruction
...
@@ -2186,7 +2165,7 @@ void sp_head::optimize()
...
@@ -2186,7 +2165,7 @@ void sp_head::optimize()
sp_instr
*
i
;
sp_instr
*
i
;
uint
src
,
dst
;
uint
src
,
dst
;
opt_mark
(
0
);
opt_mark
();
bp
.
empty
();
bp
.
empty
();
src
=
dst
=
0
;
src
=
dst
=
0
;
...
@@ -2220,13 +2199,50 @@ void sp_head::optimize()
...
@@ -2220,13 +2199,50 @@ void sp_head::optimize()
bp
.
empty
();
bp
.
empty
();
}
}
void
sp_head
::
add_mark_lead
(
uint
ip
,
List
<
sp_instr
>
*
leads
)
{
sp_instr
*
i
=
get_instr
(
ip
);
if
(
i
&&
!
i
->
marked
)
leads
->
push_front
(
i
);
}
void
void
sp_head
::
opt_mark
(
uint
ip
)
sp_head
::
opt_mark
()
{
{
uint
ip
;
sp_instr
*
i
;
sp_instr
*
i
;
List
<
sp_instr
>
leads
;
while
((
i
=
get_instr
(
ip
))
&&
!
i
->
marked
)
/*
ip
=
i
->
opt_mark
(
this
);
Forward flow analysis algorithm in the instruction graph:
- first, add the entry point in the graph (the first instruction) to the
'leads' list of paths to explore.
- while there are still leads to explore:
- pick one lead, and follow the path forward. Mark instruction reached.
Stop only if the end of the routine is reached, or the path converge
to code already explored (marked).
- while following a path, collect in the 'leads' list any fork to
another path (caused by conditional jumps instructions), so that these
paths can be explored as well.
*/
/* Add the entry point */
i
=
get_instr
(
0
);
leads
.
push_front
(
i
);
/* For each path of code ... */
while
(
leads
.
elements
!=
0
)
{
i
=
leads
.
pop
();
/* Mark the entire path, collecting new leads. */
while
(
i
&&
!
i
->
marked
)
{
ip
=
i
->
opt_mark
(
this
,
&
leads
);
i
=
get_instr
(
ip
);
}
}
}
}
...
@@ -2619,7 +2635,7 @@ sp_instr_jump::print(String *str)
...
@@ -2619,7 +2635,7 @@ sp_instr_jump::print(String *str)
}
}
uint
uint
sp_instr_jump
::
opt_mark
(
sp_head
*
sp
)
sp_instr_jump
::
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
m_dest
=
opt_shortcut_jump
(
sp
,
this
);
m_dest
=
opt_shortcut_jump
(
sp
,
this
);
if
(
m_dest
!=
m_ip
+
1
)
/* Jumping to following instruction? */
if
(
m_dest
!=
m_ip
+
1
)
/* Jumping to following instruction? */
...
@@ -2713,7 +2729,7 @@ sp_instr_jump_if_not::print(String *str)
...
@@ -2713,7 +2729,7 @@ sp_instr_jump_if_not::print(String *str)
uint
uint
sp_instr_jump_if_not
::
opt_mark
(
sp_head
*
sp
)
sp_instr_jump_if_not
::
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
sp_instr
*
i
;
sp_instr
*
i
;
...
@@ -2723,13 +2739,13 @@ sp_instr_jump_if_not::opt_mark(sp_head *sp)
...
@@ -2723,13 +2739,13 @@ sp_instr_jump_if_not::opt_mark(sp_head *sp)
m_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_optdest
=
sp
->
get_instr
(
m_dest
);
m_optdest
=
sp
->
get_instr
(
m_dest
);
}
}
sp
->
opt_mark
(
m_dest
);
sp
->
add_mark_lead
(
m_dest
,
leads
);
if
((
i
=
sp
->
get_instr
(
m_cont_dest
)))
if
((
i
=
sp
->
get_instr
(
m_cont_dest
)))
{
{
m_cont_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_cont_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_cont_optdest
=
sp
->
get_instr
(
m_cont_dest
);
m_cont_optdest
=
sp
->
get_instr
(
m_cont_dest
);
}
}
sp
->
opt_mark
(
m_cont_dest
);
sp
->
add_mark_lead
(
m_cont_dest
,
leads
);
return
m_ip
+
1
;
return
m_ip
+
1
;
}
}
...
@@ -2850,7 +2866,7 @@ sp_instr_hpush_jump::print(String *str)
...
@@ -2850,7 +2866,7 @@ sp_instr_hpush_jump::print(String *str)
uint
uint
sp_instr_hpush_jump
::
opt_mark
(
sp_head
*
sp
)
sp_instr_hpush_jump
::
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
sp_instr
*
i
;
sp_instr
*
i
;
...
@@ -2860,7 +2876,7 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp)
...
@@ -2860,7 +2876,7 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp)
m_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_optdest
=
sp
->
get_instr
(
m_dest
);
m_optdest
=
sp
->
get_instr
(
m_dest
);
}
}
sp
->
opt_mark
(
m_dest
);
sp
->
add_mark_lead
(
m_dest
,
leads
);
return
m_ip
+
1
;
return
m_ip
+
1
;
}
}
...
@@ -2925,15 +2941,13 @@ sp_instr_hreturn::print(String *str)
...
@@ -2925,15 +2941,13 @@ sp_instr_hreturn::print(String *str)
uint
uint
sp_instr_hreturn
::
opt_mark
(
sp_head
*
sp
)
sp_instr_hreturn
::
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
if
(
m_dest
)
if
(
m_dest
)
return
sp_instr_jump
::
opt_mark
(
sp
);
return
sp_instr_jump
::
opt_mark
(
sp
,
leads
);
else
{
marked
=
1
;
marked
=
1
;
return
UINT_MAX
;
return
UINT_MAX
;
}
}
}
...
@@ -3276,7 +3290,7 @@ sp_instr_set_case_expr::print(String *str)
...
@@ -3276,7 +3290,7 @@ sp_instr_set_case_expr::print(String *str)
}
}
uint
uint
sp_instr_set_case_expr
::
opt_mark
(
sp_head
*
sp
)
sp_instr_set_case_expr
::
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
sp_instr
*
i
;
sp_instr
*
i
;
...
@@ -3286,7 +3300,7 @@ sp_instr_set_case_expr::opt_mark(sp_head *sp)
...
@@ -3286,7 +3300,7 @@ sp_instr_set_case_expr::opt_mark(sp_head *sp)
m_cont_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_cont_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_cont_optdest
=
sp
->
get_instr
(
m_cont_dest
);
m_cont_optdest
=
sp
->
get_instr
(
m_cont_dest
);
}
}
sp
->
opt_mark
(
m_cont_dest
);
sp
->
add_mark_lead
(
m_cont_dest
,
leads
);
return
m_ip
+
1
;
return
m_ip
+
1
;
}
}
...
...
sql/sp_head.h
View file @
5a99ffdf
...
@@ -301,8 +301,19 @@ class sp_head :private Query_arena
...
@@ -301,8 +301,19 @@ class sp_head :private Query_arena
void
restore_thd_mem_root
(
THD
*
thd
);
void
restore_thd_mem_root
(
THD
*
thd
);
/**
Optimize the code.
*/
void
optimize
();
void
optimize
();
void
opt_mark
(
uint
ip
);
/**
Helper used during flow analysis during code optimization.
See the implementation of <code>opt_mark()</code>.
@param ip the instruction to add to the leads list
@param leads the list of remaining paths to explore in the graph that
represents the code, during flow analysis.
*/
void
add_mark_lead
(
uint
ip
,
List
<
sp_instr
>
*
leads
);
void
recursion_level_error
(
THD
*
thd
);
void
recursion_level_error
(
THD
*
thd
);
...
@@ -392,6 +403,12 @@ class sp_head :private Query_arena
...
@@ -392,6 +403,12 @@ class sp_head :private Query_arena
bool
bool
execute
(
THD
*
thd
);
execute
(
THD
*
thd
);
/**
Perform a forward flow analysis in the generated code.
Mark reachable instructions, for the optimizer.
*/
void
opt_mark
();
/*
/*
Merge the list of tables used by query into the multi-set of tables used
Merge the list of tables used by query into the multi-set of tables used
by routine.
by routine.
...
@@ -459,10 +476,10 @@ class sp_instr :public Query_arena, public Sql_alloc
...
@@ -459,10 +476,10 @@ class sp_instr :public Query_arena, public Sql_alloc
/*
/*
Mark this instruction as reachable during optimization and return the
Mark this instruction as reachable during optimization and return the
index to the next instruction. Jump instruction will
mark
their
index to the next instruction. Jump instruction will
add
their
destination to
o recursively
.
destination to
the leads list
.
*/
*/
virtual
uint
opt_mark
(
sp_head
*
sp
)
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
marked
=
1
;
marked
=
1
;
return
m_ip
+
1
;
return
m_ip
+
1
;
...
@@ -734,7 +751,7 @@ class sp_instr_jump : public sp_instr_opt_meta
...
@@ -734,7 +751,7 @@ class sp_instr_jump : public sp_instr_opt_meta
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
);
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
);
virtual
uint
opt_shortcut_jump
(
sp_head
*
sp
,
sp_instr
*
start
);
virtual
uint
opt_shortcut_jump
(
sp_head
*
sp
,
sp_instr
*
start
);
...
@@ -784,7 +801,7 @@ class sp_instr_jump_if_not : public sp_instr_jump
...
@@ -784,7 +801,7 @@ class sp_instr_jump_if_not : public sp_instr_jump
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
);
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
);
/* Override sp_instr_jump's shortcut; we stop here */
/* Override sp_instr_jump's shortcut; we stop here */
virtual
uint
opt_shortcut_jump
(
sp_head
*
sp
,
sp_instr
*
start
)
virtual
uint
opt_shortcut_jump
(
sp_head
*
sp
,
sp_instr
*
start
)
...
@@ -830,7 +847,7 @@ class sp_instr_freturn : public sp_instr
...
@@ -830,7 +847,7 @@ class sp_instr_freturn : public sp_instr
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
)
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
marked
=
1
;
marked
=
1
;
return
UINT_MAX
;
return
UINT_MAX
;
...
@@ -867,7 +884,7 @@ class sp_instr_hpush_jump : public sp_instr_jump
...
@@ -867,7 +884,7 @@ class sp_instr_hpush_jump : public sp_instr_jump
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
);
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
);
/* Override sp_instr_jump's shortcut; we stop here. */
/* Override sp_instr_jump's shortcut; we stop here. */
virtual
uint
opt_shortcut_jump
(
sp_head
*
sp
,
sp_instr
*
start
)
virtual
uint
opt_shortcut_jump
(
sp_head
*
sp
,
sp_instr
*
start
)
...
@@ -932,7 +949,7 @@ class sp_instr_hreturn : public sp_instr_jump
...
@@ -932,7 +949,7 @@ class sp_instr_hreturn : public sp_instr_jump
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
);
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
);
private:
private:
...
@@ -1102,7 +1119,7 @@ class sp_instr_error : public sp_instr
...
@@ -1102,7 +1119,7 @@ class sp_instr_error : public sp_instr
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
)
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
)
{
{
marked
=
1
;
marked
=
1
;
return
UINT_MAX
;
return
UINT_MAX
;
...
@@ -1135,7 +1152,7 @@ class sp_instr_set_case_expr : public sp_instr_opt_meta
...
@@ -1135,7 +1152,7 @@ class sp_instr_set_case_expr : public sp_instr_opt_meta
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
);
virtual
uint
opt_mark
(
sp_head
*
sp
,
List
<
sp_instr
>
*
leads
);
virtual
void
opt_move
(
uint
dst
,
List
<
sp_instr
>
*
ibp
);
virtual
void
opt_move
(
uint
dst
,
List
<
sp_instr
>
*
ibp
);
...
...
sql/sql_class.cc
View file @
5a99ffdf
...
@@ -884,6 +884,13 @@ void select_result::cleanup()
...
@@ -884,6 +884,13 @@ void select_result::cleanup()
/* do nothing */
/* do nothing */
}
}
bool
select_result
::
check_simple_select
()
const
{
my_error
(
ER_SP_BAD_CURSOR_QUERY
,
MYF
(
0
));
return
TRUE
;
}
static
String
default_line_term
(
"
\n
"
,
default_charset_info
);
static
String
default_line_term
(
"
\n
"
,
default_charset_info
);
static
String
default_escaped
(
"
\\
"
,
default_charset_info
);
static
String
default_escaped
(
"
\\
"
,
default_charset_info
);
static
String
default_field_term
(
"
\t
"
,
default_charset_info
);
static
String
default_field_term
(
"
\t
"
,
default_charset_info
);
...
@@ -1521,6 +1528,13 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
...
@@ -1521,6 +1528,13 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
}
}
bool
select_dumpvar
::
check_simple_select
()
const
{
my_error
(
ER_SP_BAD_CURSOR_SELECT
,
MYF
(
0
));
return
TRUE
;
}
void
select_dumpvar
::
cleanup
()
void
select_dumpvar
::
cleanup
()
{
{
row_count
=
0
;
row_count
=
0
;
...
...
sql/sql_class.h
View file @
5a99ffdf
...
@@ -1723,7 +1723,14 @@ class select_result :public Sql_alloc {
...
@@ -1723,7 +1723,14 @@ class select_result :public Sql_alloc {
virtual
bool
initialize_tables
(
JOIN
*
join
=
0
)
{
return
0
;
}
virtual
bool
initialize_tables
(
JOIN
*
join
=
0
)
{
return
0
;
}
virtual
void
send_error
(
uint
errcode
,
const
char
*
err
);
virtual
void
send_error
(
uint
errcode
,
const
char
*
err
);
virtual
bool
send_eof
()
=
0
;
virtual
bool
send_eof
()
=
0
;
virtual
bool
simple_select
()
{
return
0
;
}
/**
Check if this query returns a result set and therefore is allowed in
cursors and set an error message if it is not the case.
@retval FALSE success
@retval TRUE error, an error message is set
*/
virtual
bool
check_simple_select
()
const
;
virtual
void
abort
()
{}
virtual
void
abort
()
{}
/*
/*
Cleanup instance of this class for next execution of a prepared
Cleanup instance of this class for next execution of a prepared
...
@@ -1761,7 +1768,7 @@ class select_send :public select_result {
...
@@ -1761,7 +1768,7 @@ class select_send :public select_result {
bool
send_fields
(
List
<
Item
>
&
list
,
uint
flags
);
bool
send_fields
(
List
<
Item
>
&
list
,
uint
flags
);
bool
send_data
(
List
<
Item
>
&
items
);
bool
send_data
(
List
<
Item
>
&
items
);
bool
send_eof
();
bool
send_eof
();
bool
simple_select
()
{
return
1
;
}
virtual
bool
check_simple_select
()
const
{
return
FALSE
;
}
void
abort
();
void
abort
();
};
};
...
@@ -2200,6 +2207,7 @@ class select_dumpvar :public select_result_interceptor {
...
@@ -2200,6 +2207,7 @@ class select_dumpvar :public select_result_interceptor {
int
prepare
(
List
<
Item
>
&
list
,
SELECT_LEX_UNIT
*
u
);
int
prepare
(
List
<
Item
>
&
list
,
SELECT_LEX_UNIT
*
u
);
bool
send_data
(
List
<
Item
>
&
items
);
bool
send_data
(
List
<
Item
>
&
items
);
bool
send_eof
();
bool
send_eof
();
virtual
bool
check_simple_select
()
const
;
void
cleanup
();
void
cleanup
();
};
};
...
...
sql/sql_lex.cc
View file @
5a99ffdf
...
@@ -1163,7 +1163,6 @@ void st_select_lex::init_select()
...
@@ -1163,7 +1163,6 @@ void st_select_lex::init_select()
options
=
0
;
options
=
0
;
sql_cache
=
SQL_CACHE_UNSPECIFIED
;
sql_cache
=
SQL_CACHE_UNSPECIFIED
;
braces
=
0
;
braces
=
0
;
when_list
.
empty
();
expr_list
.
empty
();
expr_list
.
empty
();
udf_list
.
empty
();
udf_list
.
empty
();
interval_list
.
empty
();
interval_list
.
empty
();
...
...
sql/sql_lex.h
View file @
5a99ffdf
...
@@ -517,7 +517,6 @@ class st_select_lex: public st_select_lex_node
...
@@ -517,7 +517,6 @@ class st_select_lex: public st_select_lex_node
SQL_LIST
order_list
;
/* ORDER clause */
SQL_LIST
order_list
;
/* ORDER clause */
List
<
List_item
>
expr_list
;
List
<
List_item
>
expr_list
;
List
<
List_item
>
when_list
;
/* WHEN clause (expression) */
SQL_LIST
*
gorder_list
;
SQL_LIST
*
gorder_list
;
Item
*
select_limit
,
*
offset_limit
;
/* LIMIT clause parameters */
Item
*
select_limit
,
*
offset_limit
;
/* LIMIT clause parameters */
// Arrays of pointers to top elements of all_fields list
// Arrays of pointers to top elements of all_fields list
...
...
sql/sql_prepare.cc
View file @
5a99ffdf
...
@@ -2902,10 +2902,9 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
...
@@ -2902,10 +2902,9 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
in INSERT ... SELECT and similar commands.
in INSERT ... SELECT and similar commands.
*/
*/
if
(
open_cursor
&&
lex
->
result
&&
!
lex
->
result
->
simple_select
())
if
(
open_cursor
&&
lex
->
result
&&
lex
->
result
->
check_
simple_select
())
{
{
DBUG_PRINT
(
"info"
,(
"Cursor asked for not SELECT stmt"
));
DBUG_PRINT
(
"info"
,(
"Cursor asked for not SELECT stmt"
));
my_error
(
ER_SP_BAD_CURSOR_QUERY
,
MYF
(
0
));
return
TRUE
;
return
TRUE
;
}
}
...
...
sql/sql_string.cc
View file @
5a99ffdf
...
@@ -1032,8 +1032,8 @@ void String::print(String *str)
...
@@ -1032,8 +1032,8 @@ void String::print(String *str)
case
'\r'
:
case
'\r'
:
str
->
append
(
STRING_WITH_LEN
(
"
\\
r"
));
str
->
append
(
STRING_WITH_LEN
(
"
\\
r"
));
break
;
break
;
case
26
:
//
Ctrl-Z
case
'\032'
:
//
Ctrl-Z
str
->
append
(
STRING_WITH_LEN
(
"
\\
z
"
));
str
->
append
(
STRING_WITH_LEN
(
"
\\
Z
"
));
break
;
break
;
default:
default:
str
->
append
(
c
);
str
->
append
(
c
);
...
...
sql/sql_yacc.yy
View file @
5a99ffdf
This diff is collapsed.
Click to expand it.
tests/mysql_client_test.c
View file @
5a99ffdf
...
@@ -15455,6 +15455,33 @@ static void test_bug21635()
...
@@ -15455,6 +15455,33 @@ static void test_bug21635()
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/*
Bug#24179 "select b into $var" fails with --cursor_protocol"
The failure is correct, check that the returned message is meaningful.
*/
static
void
test_bug24179
()
{
int
rc
;
MYSQL_STMT
*
stmt
;
DBUG_ENTER
(
"test_bug24179"
);
myheader
(
"test_bug24179"
);
stmt
=
open_cursor
(
"select 1 into @a"
);
rc
=
mysql_stmt_execute
(
stmt
);
DIE_UNLESS
(
rc
);
if
(
!
opt_silent
)
{
printf
(
"Got error (as expected): %d %s
\n
"
,
mysql_stmt_errno
(
stmt
),
mysql_stmt_error
(
stmt
));
}
DIE_UNLESS
(
mysql_stmt_errno
(
stmt
)
==
1323
);
DBUG_VOID_RETURN
;
}
/*
/*
Read and parse arguments and MySQL options from my.cnf
Read and parse arguments and MySQL options from my.cnf
...
@@ -15734,6 +15761,7 @@ static struct my_tests_st my_tests[]= {
...
@@ -15734,6 +15761,7 @@ static struct my_tests_st my_tests[]= {
{
"test_bug21726"
,
test_bug21726
},
{
"test_bug21726"
,
test_bug21726
},
{
"test_bug23383"
,
test_bug23383
},
{
"test_bug23383"
,
test_bug23383
},
{
"test_bug21635"
,
test_bug21635
},
{
"test_bug21635"
,
test_bug21635
},
{
"test_bug24179"
,
test_bug24179
},
{
0
,
0
}
{
0
,
0
}
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment