mirror of
https://github.com/MariaDB/server.git
synced 2025-03-07 03:33:09 +01:00
Merge dfischer@bk-internal.mysql.com:/home/bk/mysql-5.0-build
into kahlann.erinye.com:/home/df/mysql/build/mysql-5.0-build
This commit is contained in:
commit
27f6578f6b
22 changed files with 1343 additions and 191 deletions
configure.in
heap
mysql-test
server-tools/instance-manager
sql
item_func.ccsp_head.ccsp_head.hsql_class.ccsql_class.hsql_lex.ccsql_lex.hsql_prepare.ccsql_string.ccsql_yacc.yy
tests
|
@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
# The Docs Makefile.am parses this line!
|
# The Docs Makefile.am parses this line!
|
||||||
# remember to also change ndb version below and update version.c in ndb
|
# remember to also change ndb version below and update version.c in ndb
|
||||||
AM_INIT_AUTOMAKE(mysql, 5.0.34)
|
AM_INIT_AUTOMAKE(mysql, 5.0.36)
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
PROTOCOL_VERSION=10
|
PROTOCOL_VERSION=10
|
||||||
|
@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
|
||||||
# ndb version
|
# ndb version
|
||||||
NDB_VERSION_MAJOR=5
|
NDB_VERSION_MAJOR=5
|
||||||
NDB_VERSION_MINOR=0
|
NDB_VERSION_MINOR=0
|
||||||
NDB_VERSION_BUILD=34
|
NDB_VERSION_BUILD=36
|
||||||
NDB_VERSION_STATUS=""
|
NDB_VERSION_STATUS=""
|
||||||
|
|
||||||
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
120
mysql-test/r/sp_stress_case.result
Normal file
120
mysql-test/r/sp_stress_case.result
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
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;
|
|
@ -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.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
89
mysql-test/t/sp_stress_case.test
Normal file
89
mysql-test/t/sp_stress_case.test
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#
|
||||||
|
# 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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -187,7 +187,7 @@ void Listener_thread::run()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shutdown(client_fd, SHUT_RDWR);
|
shutdown(client_fd, SHUT_RDWR);
|
||||||
close(client_fd);
|
closesocket(client_fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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]);
|
closesocket(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()
|
||||||
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]);
|
closesocket(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()
|
||||||
{
|
{
|
||||||
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);
|
closesocket(ip_socket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
closesocket(ip_socket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
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()
|
||||||
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()
|
||||||
bp.empty();
|
bp.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void sp_head::add_mark_lead(uint ip, List<sp_instr> *leads)
|
||||||
sp_head::opt_mark(uint ip)
|
|
||||||
{
|
{
|
||||||
sp_instr *i;
|
sp_instr *i= get_instr(ip);
|
||||||
|
|
||||||
while ((i= get_instr(ip)) && !i->marked)
|
if (i && ! i->marked)
|
||||||
ip= i->opt_mark(this);
|
leads->push_front(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_head::opt_mark()
|
||||||
|
{
|
||||||
|
uint ip;
|
||||||
|
sp_instr *i;
|
||||||
|
List<sp_instr> leads;
|
||||||
|
|
||||||
|
/*
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
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,16 +2941,14 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,8 +301,19 @@ public:
|
||||||
|
|
||||||
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 @@ private:
|
||||||
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 @@ public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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 too 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 @@ public:
|
||||||
|
|
||||||
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 @@ public:
|
||||||
|
|
||||||
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 @@ public:
|
||||||
|
|
||||||
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 @@ public:
|
||||||
|
|
||||||
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 @@ public:
|
||||||
|
|
||||||
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 @@ public:
|
||||||
|
|
||||||
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 @@ public:
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
|
@ -1723,7 +1723,14 @@ public:
|
||||||
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 @@ public:
|
||||||
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 @@ public:
|
||||||
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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -517,7 +517,6 @@ public:
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
396
sql/sql_yacc.yy
396
sql/sql_yacc.yy
|
@ -95,6 +95,187 @@ void turn_parser_debug_on()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for a case statement (entering the CASE).
|
||||||
|
This helper is used for both 'simple' and 'searched' cases.
|
||||||
|
This helper, with the other case_stmt_action_..., is executed when
|
||||||
|
the following SQL code is parsed:
|
||||||
|
<pre>
|
||||||
|
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
|
||||||
|
</pre>
|
||||||
|
The actions are used to generate the following code:
|
||||||
|
<pre>
|
||||||
|
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"
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
@param lex the parser lex context
|
||||||
|
*/
|
||||||
|
|
||||||
|
void case_stmt_action_case(LEX *lex)
|
||||||
|
{
|
||||||
|
lex->sphead->new_cont_backpatch(NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
BACKPATCH: Creating target label for the jump to
|
||||||
|
"case_stmt_action_end_case"
|
||||||
|
(Instruction 12 in the example)
|
||||||
|
*/
|
||||||
|
|
||||||
|
lex->spcont->push_label((char *)"", lex->sphead->instructions());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for a case expression statement (the expr in 'CASE expr').
|
||||||
|
This helper is used for 'searched' cases only.
|
||||||
|
@param lex the parser lex context
|
||||||
|
@param expr the parsed expression
|
||||||
|
@return 0 on success
|
||||||
|
*/
|
||||||
|
|
||||||
|
int case_stmt_action_expr(LEX *lex, Item* expr)
|
||||||
|
{
|
||||||
|
sp_head *sp= lex->sphead;
|
||||||
|
sp_pcontext *parsing_ctx= lex->spcont;
|
||||||
|
int case_expr_id= parsing_ctx->register_case_expr();
|
||||||
|
sp_instr_set_case_expr *i;
|
||||||
|
|
||||||
|
if (parsing_ctx->push_case_expr_id(case_expr_id))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
i= new sp_instr_set_case_expr(sp->instructions(),
|
||||||
|
parsing_ctx, case_expr_id, expr, lex);
|
||||||
|
|
||||||
|
sp->add_cont_backpatch(i);
|
||||||
|
sp->add_instr(i);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for a case when condition.
|
||||||
|
This helper is used for both 'simple' and 'searched' cases.
|
||||||
|
@param lex the parser lex context
|
||||||
|
@param when the parsed expression for the WHEN clause
|
||||||
|
@param simple true for simple cases, false for searched cases
|
||||||
|
*/
|
||||||
|
|
||||||
|
void case_stmt_action_when(LEX *lex, Item *when, bool simple)
|
||||||
|
{
|
||||||
|
sp_head *sp= lex->sphead;
|
||||||
|
sp_pcontext *ctx= lex->spcont;
|
||||||
|
uint ip= sp->instructions();
|
||||||
|
sp_instr_jump_if_not *i;
|
||||||
|
Item_case_expr *var;
|
||||||
|
Item *expr;
|
||||||
|
|
||||||
|
if (simple)
|
||||||
|
{
|
||||||
|
var= new Item_case_expr(ctx->get_current_case_expr_id());
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
if (var)
|
||||||
|
{
|
||||||
|
var->m_sp= sp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expr= new Item_func_eq(var, when);
|
||||||
|
i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i= new sp_instr_jump_if_not(ip, ctx, when, lex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
BACKPATCH: Registering forward jump from
|
||||||
|
"case_stmt_action_when" to "case_stmt_action_then"
|
||||||
|
(jump_if_not from instruction 2 to 5, 5 to 8 ... in the example)
|
||||||
|
*/
|
||||||
|
|
||||||
|
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
|
||||||
|
sp->add_cont_backpatch(i);
|
||||||
|
sp->add_instr(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for a case then statements.
|
||||||
|
This helper is used for both 'simple' and 'searched' cases.
|
||||||
|
@param lex the parser lex context
|
||||||
|
*/
|
||||||
|
|
||||||
|
void case_stmt_action_then(LEX *lex)
|
||||||
|
{
|
||||||
|
sp_head *sp= lex->sphead;
|
||||||
|
sp_pcontext *ctx= lex->spcont;
|
||||||
|
uint ip= sp->instructions();
|
||||||
|
sp_instr_jump *i = new sp_instr_jump(ip, ctx);
|
||||||
|
sp->add_instr(i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
BACKPATCH: Resolving forward jump from
|
||||||
|
"case_stmt_action_when" to "case_stmt_action_then"
|
||||||
|
(jump_if_not from instruction 2 to 5, 5 to 8 ... in the example)
|
||||||
|
*/
|
||||||
|
|
||||||
|
sp->backpatch(ctx->pop_label());
|
||||||
|
|
||||||
|
/*
|
||||||
|
BACKPATCH: Registering forward jump from
|
||||||
|
"case_stmt_action_then" to "case_stmt_action_end_case"
|
||||||
|
(jump from instruction 4 to 12, 7 to 12 ... in the example)
|
||||||
|
*/
|
||||||
|
|
||||||
|
sp->push_backpatch(i, ctx->last_label());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for an end case.
|
||||||
|
This helper is used for both 'simple' and 'searched' cases.
|
||||||
|
@param lex the parser lex context
|
||||||
|
@param simple true for simple cases, false for searched cases
|
||||||
|
*/
|
||||||
|
|
||||||
|
void case_stmt_action_end_case(LEX *lex, bool simple)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
BACKPATCH: Resolving forward jump from
|
||||||
|
"case_stmt_action_then" to "case_stmt_action_end_case"
|
||||||
|
(jump from instruction 4 to 12, 7 to 12 ... in the example)
|
||||||
|
*/
|
||||||
|
lex->sphead->backpatch(lex->spcont->pop_label());
|
||||||
|
|
||||||
|
if (simple)
|
||||||
|
lex->spcont->pop_case_expr_id();
|
||||||
|
|
||||||
|
lex->sphead->do_cont_backpatch();
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
%union {
|
%union {
|
||||||
int num;
|
int num;
|
||||||
|
@ -831,7 +1012,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
select_item_list select_item values_list no_braces
|
select_item_list select_item values_list no_braces
|
||||||
opt_limit_clause delete_limit_clause fields opt_values values
|
opt_limit_clause delete_limit_clause fields opt_values values
|
||||||
procedure_list procedure_list2 procedure_item
|
procedure_list procedure_list2 procedure_item
|
||||||
when_list2 expr_list2 udf_expr_list3 handler
|
expr_list2 udf_expr_list3 handler
|
||||||
opt_precision opt_ignore opt_column opt_restrict
|
opt_precision opt_ignore opt_column opt_restrict
|
||||||
grant revoke set lock unlock string_list field_options field_option
|
grant revoke set lock unlock string_list field_options field_option
|
||||||
field_opt_list opt_binary table_lock_list table_lock
|
field_opt_list opt_binary table_lock_list table_lock
|
||||||
|
@ -859,6 +1040,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
view_algorithm view_or_trigger_or_sp view_or_trigger_or_sp_tail
|
view_algorithm view_or_trigger_or_sp view_or_trigger_or_sp_tail
|
||||||
view_suid view_tail view_list_opt view_list view_select
|
view_suid view_tail view_list_opt view_list view_select
|
||||||
view_check_option trigger_tail sp_tail
|
view_check_option trigger_tail sp_tail
|
||||||
|
case_stmt_specification simple_case_stmt searched_case_stmt
|
||||||
END_OF_INPUT
|
END_OF_INPUT
|
||||||
|
|
||||||
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
|
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
|
||||||
|
@ -1993,43 +2175,7 @@ sp_proc_stmt:
|
||||||
{ Lex->sphead->new_cont_backpatch(NULL); }
|
{ Lex->sphead->new_cont_backpatch(NULL); }
|
||||||
sp_if END IF
|
sp_if END IF
|
||||||
{ Lex->sphead->do_cont_backpatch(); }
|
{ Lex->sphead->do_cont_backpatch(); }
|
||||||
| CASE_SYM WHEN_SYM
|
| case_stmt_specification
|
||||||
{
|
|
||||||
Lex->sphead->m_flags&= ~sp_head::IN_SIMPLE_CASE;
|
|
||||||
Lex->sphead->new_cont_backpatch(NULL);
|
|
||||||
}
|
|
||||||
sp_case END CASE_SYM { Lex->sphead->do_cont_backpatch(); }
|
|
||||||
| CASE_SYM
|
|
||||||
{
|
|
||||||
Lex->sphead->reset_lex(YYTHD);
|
|
||||||
Lex->sphead->new_cont_backpatch(NULL);
|
|
||||||
}
|
|
||||||
expr WHEN_SYM
|
|
||||||
{
|
|
||||||
LEX *lex= Lex;
|
|
||||||
sp_head *sp= lex->sphead;
|
|
||||||
sp_pcontext *parsing_ctx= lex->spcont;
|
|
||||||
int case_expr_id= parsing_ctx->register_case_expr();
|
|
||||||
sp_instr_set_case_expr *i;
|
|
||||||
|
|
||||||
if (parsing_ctx->push_case_expr_id(case_expr_id))
|
|
||||||
YYABORT;
|
|
||||||
|
|
||||||
i= new sp_instr_set_case_expr(sp->instructions(),
|
|
||||||
parsing_ctx,
|
|
||||||
case_expr_id,
|
|
||||||
$3,
|
|
||||||
lex);
|
|
||||||
sp->add_cont_backpatch(i);
|
|
||||||
sp->add_instr(i);
|
|
||||||
sp->m_flags|= sp_head::IN_SIMPLE_CASE;
|
|
||||||
sp->restore_lex(YYTHD);
|
|
||||||
}
|
|
||||||
sp_case END CASE_SYM
|
|
||||||
{
|
|
||||||
Lex->spcont->pop_case_expr_id();
|
|
||||||
Lex->sphead->do_cont_backpatch();
|
|
||||||
}
|
|
||||||
| sp_labeled_control
|
| sp_labeled_control
|
||||||
{}
|
{}
|
||||||
| { /* Unlabeled controls get a secret label. */
|
| { /* Unlabeled controls get a secret label. */
|
||||||
|
@ -2240,71 +2386,113 @@ sp_elseifs:
|
||||||
| ELSE sp_proc_stmts1
|
| ELSE sp_proc_stmts1
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_case:
|
case_stmt_specification:
|
||||||
{ Lex->sphead->reset_lex(YYTHD); }
|
simple_case_stmt
|
||||||
expr THEN_SYM
|
| searched_case_stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
simple_case_stmt:
|
||||||
|
CASE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
case_stmt_action_case(lex);
|
||||||
sp_pcontext *ctx= Lex->spcont;
|
lex->sphead->reset_lex(YYTHD); /* For expr $3 */
|
||||||
uint ip= sp->instructions();
|
|
||||||
sp_instr_jump_if_not *i;
|
|
||||||
|
|
||||||
if (! (sp->m_flags & sp_head::IN_SIMPLE_CASE))
|
|
||||||
i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
|
|
||||||
else
|
|
||||||
{ /* Simple case: <caseval> = <whenval> */
|
|
||||||
|
|
||||||
Item_case_expr *var;
|
|
||||||
Item *expr;
|
|
||||||
|
|
||||||
var= new Item_case_expr(ctx->get_current_case_expr_id());
|
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
if (var)
|
|
||||||
var->m_sp= sp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
expr= new Item_func_eq(var, $2);
|
|
||||||
|
|
||||||
i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
|
|
||||||
}
|
}
|
||||||
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
|
expr
|
||||||
sp->add_cont_backpatch(i);
|
|
||||||
sp->add_instr(i);
|
|
||||||
sp->restore_lex(YYTHD);
|
|
||||||
}
|
|
||||||
sp_proc_stmts1
|
|
||||||
{
|
|
||||||
sp_head *sp= Lex->sphead;
|
|
||||||
sp_pcontext *ctx= Lex->spcont;
|
|
||||||
uint ip= sp->instructions();
|
|
||||||
sp_instr_jump *i = new sp_instr_jump(ip, ctx);
|
|
||||||
|
|
||||||
sp->add_instr(i);
|
|
||||||
sp->backpatch(ctx->pop_label());
|
|
||||||
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
|
|
||||||
}
|
|
||||||
sp_whens
|
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
|
if (case_stmt_action_expr(lex, $3))
|
||||||
|
YYABORT;
|
||||||
|
|
||||||
lex->sphead->backpatch(lex->spcont->pop_label());
|
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
|
||||||
|
}
|
||||||
|
simple_when_clause_list
|
||||||
|
else_clause_opt
|
||||||
|
END
|
||||||
|
CASE_SYM
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
case_stmt_action_end_case(lex, true);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_whens:
|
searched_case_stmt:
|
||||||
/* Empty */
|
CASE_SYM
|
||||||
{
|
{
|
||||||
sp_head *sp= Lex->sphead;
|
LEX *lex= Lex;
|
||||||
uint ip= sp->instructions();
|
case_stmt_action_case(lex);
|
||||||
sp_instr_error *i= new sp_instr_error(ip, Lex->spcont,
|
}
|
||||||
ER_SP_CASE_NOT_FOUND);
|
searched_when_clause_list
|
||||||
|
else_clause_opt
|
||||||
|
END
|
||||||
|
CASE_SYM
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
case_stmt_action_end_case(lex, false);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
simple_when_clause_list:
|
||||||
|
simple_when_clause
|
||||||
|
| simple_when_clause_list simple_when_clause
|
||||||
|
;
|
||||||
|
|
||||||
|
searched_when_clause_list:
|
||||||
|
searched_when_clause
|
||||||
|
| searched_when_clause_list searched_when_clause
|
||||||
|
;
|
||||||
|
|
||||||
|
simple_when_clause:
|
||||||
|
WHEN_SYM
|
||||||
|
{
|
||||||
|
Lex->sphead->reset_lex(YYTHD); /* For expr $3 */
|
||||||
|
}
|
||||||
|
expr
|
||||||
|
{
|
||||||
|
/* Simple case: <caseval> = <whenval> */
|
||||||
|
|
||||||
|
LEX *lex= Lex;
|
||||||
|
case_stmt_action_when(lex, $3, true);
|
||||||
|
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
|
||||||
|
}
|
||||||
|
THEN_SYM
|
||||||
|
sp_proc_stmts1
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
case_stmt_action_then(lex);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
searched_when_clause:
|
||||||
|
WHEN_SYM
|
||||||
|
{
|
||||||
|
Lex->sphead->reset_lex(YYTHD); /* For expr $3 */
|
||||||
|
}
|
||||||
|
expr
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
case_stmt_action_when(lex, $3, false);
|
||||||
|
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
|
||||||
|
}
|
||||||
|
THEN_SYM
|
||||||
|
sp_proc_stmts1
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
case_stmt_action_then(lex);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
else_clause_opt:
|
||||||
|
/* empty */
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
sp_head *sp= lex->sphead;
|
||||||
|
uint ip= sp->instructions();
|
||||||
|
sp_instr_error *i= new sp_instr_error(ip, lex->spcont,
|
||||||
|
ER_SP_CASE_NOT_FOUND);
|
||||||
sp->add_instr(i);
|
sp->add_instr(i);
|
||||||
}
|
}
|
||||||
| ELSE sp_proc_stmts1 {}
|
| ELSE sp_proc_stmts1
|
||||||
| WHEN_SYM sp_case {}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_labeled_control:
|
sp_labeled_control:
|
||||||
|
@ -4372,8 +4560,8 @@ simple_expr:
|
||||||
if (!$$)
|
if (!$$)
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
|
| CASE_SYM opt_expr when_list opt_else END
|
||||||
{ $$= new Item_func_case(* $4, $2, $5 ); }
|
{ $$= new Item_func_case(* $3, $2, $4 ); }
|
||||||
| CONVERT_SYM '(' expr ',' cast_type ')'
|
| CONVERT_SYM '(' expr ',' cast_type ')'
|
||||||
{
|
{
|
||||||
$$= create_func_cast($3, $5,
|
$$= create_func_cast($3, $5,
|
||||||
|
@ -5182,23 +5370,19 @@ opt_else:
|
||||||
| ELSE expr { $$= $2; };
|
| ELSE expr { $$= $2; };
|
||||||
|
|
||||||
when_list:
|
when_list:
|
||||||
{ Select->when_list.push_front(new List<Item>); }
|
WHEN_SYM expr THEN_SYM expr
|
||||||
when_list2
|
|
||||||
{ $$= Select->when_list.pop(); };
|
|
||||||
|
|
||||||
when_list2:
|
|
||||||
expr THEN_SYM expr
|
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel=Select;
|
$$= new List<Item>;
|
||||||
sel->when_list.head()->push_back($1);
|
$$->push_back($2);
|
||||||
sel->when_list.head()->push_back($3);
|
$$->push_back($4);
|
||||||
}
|
}
|
||||||
| when_list2 WHEN_SYM expr THEN_SYM expr
|
| when_list WHEN_SYM expr THEN_SYM expr
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel=Select;
|
$1->push_back($3);
|
||||||
sel->when_list.head()->push_back($3);
|
$1->push_back($5);
|
||||||
sel->when_list.head()->push_back($5);
|
$$= $1;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
|
|
||||||
/* Warning - may return NULL in case of incomplete SELECT */
|
/* Warning - may return NULL in case of incomplete SELECT */
|
||||||
table_ref:
|
table_ref:
|
||||||
|
|
|
@ -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[]= {
|
||||||
{ "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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue