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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
221b3578
Commit
221b3578
authored
Feb 07, 2006
by
ramil@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge rkalimullin@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/usr/home/ram/work/5.0.b16511
parents
1b09ce5e
b25b4e9b
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
273 additions
and
87 deletions
+273
-87
mysql-test/r/group_min_max.result
mysql-test/r/group_min_max.result
+27
-0
mysql-test/r/sp-code.result
mysql-test/r/sp-code.result
+1
-1
mysql-test/r/sp-destruct.result
mysql-test/r/sp-destruct.result
+7
-1
mysql-test/r/sp.result
mysql-test/r/sp.result
+5
-2
mysql-test/t/group_min_max.test
mysql-test/t/group_min_max.test
+21
-0
mysql-test/t/sp-destruct.test
mysql-test/t/sp-destruct.test
+10
-1
mysql-test/t/sp.test
mysql-test/t/sp.test
+1
-4
sql/opt_range.cc
sql/opt_range.cc
+1
-0
sql/sp.cc
sql/sp.cc
+45
-8
sql/sp.h
sql/sp.h
+4
-1
sql/sp_head.cc
sql/sp_head.cc
+64
-21
sql/sp_head.h
sql/sp_head.h
+69
-27
sql/sql_acl.cc
sql/sql_acl.cc
+1
-1
sql/sql_parse.cc
sql/sql_parse.cc
+8
-12
sql/sql_yacc.yy
sql/sql_yacc.yy
+9
-8
No files found.
mysql-test/r/group_min_max.result
View file @
221b3578
...
@@ -2043,3 +2043,30 @@ c1 c2
...
@@ -2043,3 +2043,30 @@ c1 c2
30 8
30 8
30 9
30 9
drop table t1;
drop table t1;
CREATE TABLE t1 (a varchar(5), b int(11), PRIMARY KEY (a,b));
INSERT INTO t1 VALUES ('AA',1), ('AA',2), ('AA',3), ('BB',1), ('AA',4);
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
SELECT a FROM t1 WHERE a='AA' GROUP BY a;
a
AA
SELECT a FROM t1 WHERE a='BB' GROUP BY a;
a
BB
EXPLAIN SELECT a FROM t1 WHERE a='AA' GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY PRIMARY 7 const 3 Using where; Using index
EXPLAIN SELECT a FROM t1 WHERE a='BB' GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY PRIMARY 7 const 1 Using where; Using index
SELECT DISTINCT a FROM t1 WHERE a='BB';
a
BB
SELECT DISTINCT a FROM t1 WHERE a LIKE 'B%';
a
BB
SELECT a FROM t1 WHERE a LIKE 'B%' GROUP BY a;
a
BB
DROP TABLE t1;
mysql-test/r/sp-code.result
View file @
221b3578
...
@@ -172,7 +172,7 @@ Pos Instruction
...
@@ -172,7 +172,7 @@ Pos Instruction
17 set v_col@8 NULL
17 set v_col@8 NULL
18 stmt 0 "select row,col into v_row,v_col from ..."
18 stmt 0 "select row,col into v_row,v_col from ..."
19 stmt 0 "select dig into v_dig from sudoku_wor..."
19 stmt 0 "select dig into v_dig from sudoku_wor..."
20 set_case_expr 0 v_dig@4
20 set_case_expr
(34)
0 v_dig@4
21 jump_if_not 25(34) (case_expr@0 = 0)
21 jump_if_not 25(34) (case_expr@0 = 0)
22 set v_dig@4 1
22 set v_dig@4 1
23 stmt 4 "update sudoku_work set dig = 1 where ..."
23 stmt 4 "update sudoku_work set dig = 1 where ..."
...
...
mysql-test/r/sp-destruct.result
View file @
221b3578
...
@@ -72,6 +72,12 @@ drop trigger t1_ai;
...
@@ -72,6 +72,12 @@ drop trigger t1_ai;
create trigger t1_ai after insert on t1 for each row call bug14233_3();
create trigger t1_ai after insert on t1 for each row call bug14233_3();
insert into t1 values (0);
insert into t1 values (0);
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
delete from mysql.proc where name like 'bug14233%';
drop trigger t1_ai;
drop trigger t1_ai;
drop table t1;
drop table t1;
drop function bug14233_1;
drop function bug14233_2;
drop procedure bug14233_3;
show procedure status;
Db Name Type Definer Modified Created Security_type Comment
show function status;
Db Name Type Definer Modified Created Security_type Comment
mysql-test/r/sp.result
View file @
221b3578
...
@@ -4089,8 +4089,6 @@ NULL 1
...
@@ -4089,8 +4089,6 @@ NULL 1
call bug14643_2()|
call bug14643_2()|
Handler
Handler
boo
boo
2
2
Handler
Handler
boo
boo
drop procedure bug14643_1|
drop procedure bug14643_1|
...
@@ -4432,6 +4430,11 @@ Handler
...
@@ -4432,6 +4430,11 @@ Handler
error
error
End
End
done
done
call bug14498_4()|
Handler
error
End
done
call bug14498_5()|
call bug14498_5()|
Handler
Handler
error
error
...
...
mysql-test/t/group_min_max.test
View file @
221b3578
...
@@ -715,3 +715,24 @@ select distinct c1, c2 from t1 order by c2;
...
@@ -715,3 +715,24 @@ select distinct c1, c2 from t1 order by c2;
select c1,min(c2) as c2 from t1 group by c1 order by c2;
select c1,min(c2) as c2 from t1 group by c1 order by c2;
select c1,c2 from t1 group by c1,c2 order by c2;
select c1,c2 from t1 group by c1,c2 order by c2;
drop table t1;
drop table t1;
#
# Bug #16203: Analysis for possible min/max optimization erroneously
# returns impossible range
#
CREATE TABLE t1 (a varchar(5), b int(11), PRIMARY KEY (a,b));
INSERT INTO t1 VALUES ('
AA
',1), ('
AA
',2), ('
AA
',3), ('
BB
',1), ('
AA
',4);
OPTIMIZE TABLE t1;
SELECT a FROM t1 WHERE a='
AA
' GROUP BY a;
SELECT a FROM t1 WHERE a='
BB
' GROUP BY a;
EXPLAIN SELECT a FROM t1 WHERE a='
AA
' GROUP BY a;
EXPLAIN SELECT a FROM t1 WHERE a='
BB
' GROUP BY a;
SELECT DISTINCT a FROM t1 WHERE a='
BB
';
SELECT DISTINCT a FROM t1 WHERE a LIKE '
B
%
';
SELECT a FROM t1 WHERE a LIKE '
B
%
'
GROUP
BY
a
;
DROP
TABLE
t1
;
mysql-test/t/sp-destruct.test
View file @
221b3578
...
@@ -119,6 +119,15 @@ create trigger t1_ai after insert on t1 for each row call bug14233_3();
...
@@ -119,6 +119,15 @@ create trigger t1_ai after insert on t1 for each row call bug14233_3();
insert
into
t1
values
(
0
);
insert
into
t1
values
(
0
);
# Clean-up
# Clean-up
delete
from
mysql
.
proc
where
name
like
'bug14233%'
;
drop
trigger
t1_ai
;
drop
trigger
t1_ai
;
drop
table
t1
;
drop
table
t1
;
#
# BUG#16303: erroneus stored procedures and functions should be droppable
#
drop
function
bug14233_1
;
drop
function
bug14233_2
;
drop
procedure
bug14233_3
;
# Assert: These should show nothing.
show
procedure
status
;
show
function
status
;
mysql-test/t/sp.test
View file @
221b3578
...
@@ -5210,10 +5210,7 @@ end|
...
@@ -5210,10 +5210,7 @@ end|
call
bug14498_1
()
|
call
bug14498_1
()
|
call
bug14498_2
()
|
call
bug14498_2
()
|
call
bug14498_3
()
|
call
bug14498_3
()
|
# We couldn't call this before, due to a known bug (BUG#14643)
call
bug14498_4
()
|
# QQ We still can't since the new set_case_expr instruction breaks
# the semantics of case; it won't crash, but will get the wrong result.
#call bug14498_4()|
call
bug14498_5
()
|
call
bug14498_5
()
|
drop
procedure
bug14498_1
|
drop
procedure
bug14498_1
|
...
...
sql/opt_range.cc
View file @
221b3578
...
@@ -7780,6 +7780,7 @@ void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
...
@@ -7780,6 +7780,7 @@ void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
quick_prefix_selectivity
=
(
double
)
quick_prefix_records
/
quick_prefix_selectivity
=
(
double
)
quick_prefix_records
/
(
double
)
table_records
;
(
double
)
table_records
;
num_groups
=
(
uint
)
rint
(
num_groups
*
quick_prefix_selectivity
);
num_groups
=
(
uint
)
rint
(
num_groups
*
quick_prefix_selectivity
);
set_if_bigger
(
num_groups
,
1
);
}
}
if
(
used_key_parts
>
group_key_parts
)
if
(
used_key_parts
>
group_key_parts
)
...
...
sql/sp.cc
View file @
221b3578
...
@@ -1002,22 +1002,26 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
...
@@ -1002,22 +1002,26 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
}
}
/*
This is used by sql_acl.cc:mysql_routine_grant() and is used to find
the routines in 'routines'.
*/
int
int
sp_exist
s_routine
(
THD
*
thd
,
TABLE_LIST
*
tabl
es
,
bool
any
,
bool
no_error
)
sp_exist
_routines
(
THD
*
thd
,
TABLE_LIST
*
routin
es
,
bool
any
,
bool
no_error
)
{
{
TABLE_LIST
*
tabl
e
;
TABLE_LIST
*
routin
e
;
bool
result
=
0
;
bool
result
=
0
;
DBUG_ENTER
(
"sp_exists_routine"
);
DBUG_ENTER
(
"sp_exists_routine"
);
for
(
table
=
tables
;
table
;
table
=
tabl
e
->
next_global
)
for
(
routine
=
routines
;
routine
;
routine
=
routin
e
->
next_global
)
{
{
sp_name
*
name
;
sp_name
*
name
;
LEX_STRING
lex_db
;
LEX_STRING
lex_db
;
LEX_STRING
lex_name
;
LEX_STRING
lex_name
;
lex_db
.
length
=
strlen
(
tabl
e
->
db
);
lex_db
.
length
=
strlen
(
routin
e
->
db
);
lex_name
.
length
=
strlen
(
tabl
e
->
table_name
);
lex_name
.
length
=
strlen
(
routin
e
->
table_name
);
lex_db
.
str
=
thd
->
strmake
(
tabl
e
->
db
,
lex_db
.
length
);
lex_db
.
str
=
thd
->
strmake
(
routin
e
->
db
,
lex_db
.
length
);
lex_name
.
str
=
thd
->
strmake
(
tabl
e
->
table_name
,
lex_name
.
length
);
lex_name
.
str
=
thd
->
strmake
(
routin
e
->
table_name
,
lex_name
.
length
);
name
=
new
sp_name
(
lex_db
,
lex_name
);
name
=
new
sp_name
(
lex_db
,
lex_name
);
name
->
init_qname
(
thd
);
name
->
init_qname
(
thd
);
if
(
sp_find_routine
(
thd
,
TYPE_ENUM_PROCEDURE
,
name
,
if
(
sp_find_routine
(
thd
,
TYPE_ENUM_PROCEDURE
,
name
,
...
@@ -1034,7 +1038,7 @@ sp_exists_routine(THD *thd, TABLE_LIST *tables, bool any, bool no_error)
...
@@ -1034,7 +1038,7 @@ sp_exists_routine(THD *thd, TABLE_LIST *tables, bool any, bool no_error)
if
(
!
no_error
)
if
(
!
no_error
)
{
{
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"FUNCTION or PROCEDURE"
,
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"FUNCTION or PROCEDURE"
,
tabl
e
->
table_name
);
routin
e
->
table_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -1044,6 +1048,39 @@ sp_exists_routine(THD *thd, TABLE_LIST *tables, bool any, bool no_error)
...
@@ -1044,6 +1048,39 @@ sp_exists_routine(THD *thd, TABLE_LIST *tables, bool any, bool no_error)
}
}
/*
Check if a routine exists in the mysql.proc table, without actually
parsing the definition. (Used for dropping)
SYNOPSIS
sp_routine_exists_in_table()
thd - thread context
name - name of procedure
RETURN VALUE
0 - Success
non-0 - Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
*/
int
sp_routine_exists_in_table
(
THD
*
thd
,
int
type
,
sp_name
*
name
)
{
TABLE
*
table
;
int
ret
;
Open_tables_state
open_tables_state_backup
;
if
(
!
(
table
=
open_proc_table_for_read
(
thd
,
&
open_tables_state_backup
)))
ret
=
SP_OPEN_TABLE_FAILED
;
else
{
if
((
ret
=
db_find_routine_aux
(
thd
,
type
,
name
,
table
))
!=
SP_OK
)
ret
=
SP_KEY_NOT_FOUND
;
close_proc_table
(
thd
,
&
open_tables_state_backup
);
}
return
ret
;
}
int
int
sp_create_procedure
(
THD
*
thd
,
sp_head
*
sp
)
sp_create_procedure
(
THD
*
thd
,
sp_head
*
sp
)
{
{
...
...
sql/sp.h
View file @
221b3578
...
@@ -40,7 +40,10 @@ sp_find_routine(THD *thd, int type, sp_name *name,
...
@@ -40,7 +40,10 @@ sp_find_routine(THD *thd, int type, sp_name *name,
sp_cache
**
cp
,
bool
cache_only
);
sp_cache
**
cp
,
bool
cache_only
);
int
int
sp_exists_routine
(
THD
*
thd
,
TABLE_LIST
*
procs
,
bool
any
,
bool
no_error
);
sp_exist_routines
(
THD
*
thd
,
TABLE_LIST
*
procs
,
bool
any
,
bool
no_error
);
int
sp_routine_exists_in_table
(
THD
*
thd
,
int
type
,
sp_name
*
name
);
int
int
sp_create_procedure
(
THD
*
thd
,
sp_head
*
sp
);
sp_create_procedure
(
THD
*
thd
,
sp_head
*
sp
);
...
...
sql/sp_head.cc
View file @
221b3578
...
@@ -1761,7 +1761,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
...
@@ -1761,7 +1761,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
void
void
sp_head
::
new_cont_backpatch
(
sp_instr_
jump_if_not
*
i
)
sp_head
::
new_cont_backpatch
(
sp_instr_
opt_meta
*
i
)
{
{
m_cont_level
+=
1
;
m_cont_level
+=
1
;
if
(
i
)
if
(
i
)
...
@@ -1773,7 +1773,7 @@ sp_head::new_cont_backpatch(sp_instr_jump_if_not *i)
...
@@ -1773,7 +1773,7 @@ sp_head::new_cont_backpatch(sp_instr_jump_if_not *i)
}
}
void
void
sp_head
::
add_cont_backpatch
(
sp_instr_
jump_if_not
*
i
)
sp_head
::
add_cont_backpatch
(
sp_instr_
opt_meta
*
i
)
{
{
i
->
m_cont_dest
=
m_cont_level
;
i
->
m_cont_dest
=
m_cont_level
;
(
void
)
m_cont_backpatch
.
push_front
(
i
);
(
void
)
m_cont_backpatch
.
push_front
(
i
);
...
@@ -1784,7 +1784,7 @@ sp_head::do_cont_backpatch()
...
@@ -1784,7 +1784,7 @@ sp_head::do_cont_backpatch()
{
{
uint
dest
=
instructions
();
uint
dest
=
instructions
();
uint
lev
=
m_cont_level
--
;
uint
lev
=
m_cont_level
--
;
sp_instr_
jump_if_not
*
i
;
sp_instr_
opt_meta
*
i
;
while
((
i
=
m_cont_backpatch
.
head
())
&&
i
->
m_cont_dest
==
lev
)
while
((
i
=
m_cont_backpatch
.
head
())
&&
i
->
m_cont_dest
==
lev
)
{
{
...
@@ -2049,8 +2049,8 @@ void sp_head::optimize()
...
@@ -2049,8 +2049,8 @@ void sp_head::optimize()
set_dynamic
(
&
m_instr
,
(
gptr
)
&
i
,
dst
);
set_dynamic
(
&
m_instr
,
(
gptr
)
&
i
,
dst
);
while
((
ibp
=
li
++
))
while
((
ibp
=
li
++
))
{
{
sp_instr_jump
*
ji
=
static_cast
<
sp_instr_jump
*>
(
ibp
);
sp_instr_opt_meta
*
im
=
static_cast
<
sp_instr_opt_meta
*>
(
ibp
);
ji
->
set_destination
(
src
,
dst
);
im
->
set_destination
(
src
,
dst
);
}
}
}
}
i
->
opt_move
(
dst
,
&
bp
);
i
->
opt_move
(
dst
,
&
bp
);
...
@@ -2073,6 +2073,10 @@ sp_head::opt_mark(uint ip)
...
@@ -2073,6 +2073,10 @@ sp_head::opt_mark(uint ip)
#ifndef DBUG_OFF
#ifndef DBUG_OFF
/*
Return the routine instructions as a result set.
Returns 0 if ok, !=0 on error.
*/
int
int
sp_head
::
show_routine_code
(
THD
*
thd
)
sp_head
::
show_routine_code
(
THD
*
thd
)
{
{
...
@@ -2100,6 +2104,22 @@ sp_head::show_routine_code(THD *thd)
...
@@ -2100,6 +2104,22 @@ sp_head::show_routine_code(THD *thd)
for
(
ip
=
0
;
(
i
=
get_instr
(
ip
))
;
ip
++
)
for
(
ip
=
0
;
(
i
=
get_instr
(
ip
))
;
ip
++
)
{
{
/*
Consistency check. If these are different something went wrong
during optimization.
*/
if
(
ip
!=
i
->
m_ip
)
{
const
char
*
format
=
"Instruction at position %u has m_ip=%u"
;
char
tmp
[
sizeof
(
format
)
+
2
*
SP_INSTR_UINT_MAXLEN
+
1
];
sprintf
(
tmp
,
format
,
ip
,
i
->
m_ip
);
/*
Since this is for debugging purposes only, we don't bother to
introduce a special error code for it.
*/
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_UNKNOWN_ERROR
,
tmp
);
}
protocol
->
prepare_for_resend
();
protocol
->
prepare_for_resend
();
protocol
->
store
((
longlong
)
ip
);
protocol
->
store
((
longlong
)
ip
);
...
@@ -2524,14 +2544,14 @@ sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
...
@@ -2524,14 +2544,14 @@ sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
void
void
sp_instr_jump_if_not
::
print
(
String
*
str
)
sp_instr_jump_if_not
::
print
(
String
*
str
)
{
{
/* jump_if_not dest ... */
/* jump_if_not dest
(cont)
... */
if
(
str
->
reserve
(
2
*
SP_INSTR_UINT_MAXLEN
+
14
+
32
))
// Add some for the expr. too
if
(
str
->
reserve
(
2
*
SP_INSTR_UINT_MAXLEN
+
14
+
32
))
// Add some for the expr. too
return
;
return
;
str
->
qs_append
(
STRING_WITH_LEN
(
"jump_if_not "
));
str
->
qs_append
(
STRING_WITH_LEN
(
"jump_if_not "
));
str
->
qs_append
(
m_dest
);
str
->
qs_append
(
m_dest
);
str
->
append
(
'('
);
str
->
qs_
append
(
'('
);
str
->
qs_append
(
m_cont_dest
);
str
->
qs_append
(
m_cont_dest
);
str
->
append
(
") "
);
str
->
qs_append
(
STRING_WITH_LEN
(
") "
)
);
m_expr
->
print
(
str
);
m_expr
->
print
(
str
);
}
}
...
@@ -3077,30 +3097,53 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
...
@@ -3077,30 +3097,53 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
spcont
->
clear_handler
();
spcont
->
clear_handler
();
thd
->
spcont
=
spcont
;
thd
->
spcont
=
spcont
;
}
}
*
nextp
=
m_cont_dest
;
/* For continue handler */
}
}
else
*
nextp
=
m_ip
+
1
;
*
nextp
=
m_ip
+
1
;
return
res
;
return
res
;
/* no error */
}
}
void
void
sp_instr_set_case_expr
::
print
(
String
*
str
)
sp_instr_set_case_expr
::
print
(
String
*
str
)
{
{
const
char
CASE_EXPR_TAG
[]
=
"set_case_expr "
;
/* set_case_expr (cont) id ... */
const
int
CASE_EXPR_TAG_LEN
=
sizeof
(
CASE_EXPR_TAG
)
-
1
;
str
->
reserve
(
2
*
SP_INSTR_UINT_MAXLEN
+
18
+
32
);
// Add some extra for expr too
const
int
INT_STRING_MAX_LEN
=
10
;
str
->
qs_append
(
STRING_WITH_LEN
(
"set_case_expr ("
));
str
->
qs_append
(
m_cont_dest
);
/* We must call reserve(), because qs_append() doesn't care about memory. */
str
->
qs_append
(
STRING_WITH_LEN
(
") "
));
str
->
reserve
(
CASE_EXPR_TAG_LEN
+
INT_STRING_MAX_LEN
+
2
);
str
->
qs_append
(
CASE_EXPR_TAG
,
CASE_EXPR_TAG_LEN
);
str
->
qs_append
(
m_case_expr_id
);
str
->
qs_append
(
m_case_expr_id
);
str
->
qs_append
(
' '
);
str
->
qs_append
(
' '
);
m_case_expr
->
print
(
str
);
m_case_expr
->
print
(
str
);
}
}
uint
sp_instr_set_case_expr
::
opt_mark
(
sp_head
*
sp
)
{
sp_instr
*
i
;
marked
=
1
;
if
((
i
=
sp
->
get_instr
(
m_cont_dest
)))
{
m_cont_dest
=
i
->
opt_shortcut_jump
(
sp
,
this
);
m_cont_optdest
=
sp
->
get_instr
(
m_cont_dest
);
}
sp
->
opt_mark
(
m_cont_dest
);
return
m_ip
+
1
;
}
void
sp_instr_set_case_expr
::
opt_move
(
uint
dst
,
List
<
sp_instr
>
*
bp
)
{
if
(
m_cont_dest
>
m_ip
)
bp
->
push_back
(
this
);
// Forward
else
if
(
m_cont_optdest
)
m_cont_dest
=
m_cont_optdest
->
m_ip
;
// Backward
m_ip
=
dst
;
}
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
...
...
sql/sp_head.h
View file @
221b3578
...
@@ -41,6 +41,7 @@ sp_get_flags_for_command(LEX *lex);
...
@@ -41,6 +41,7 @@ sp_get_flags_for_command(LEX *lex);
struct
sp_label
;
struct
sp_label
;
class
sp_instr
;
class
sp_instr
;
class
sp_instr_opt_meta
;
class
sp_instr_jump_if_not
;
class
sp_instr_jump_if_not
;
struct
sp_cond_type
;
struct
sp_cond_type
;
struct
sp_pvar
;
struct
sp_pvar
;
...
@@ -271,11 +272,11 @@ public:
...
@@ -271,11 +272,11 @@ public:
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
void
void
new_cont_backpatch
(
sp_instr_
jump_if_not
*
i
);
new_cont_backpatch
(
sp_instr_
opt_meta
*
i
);
// Add an instruction to the current level
// Add an instruction to the current level
void
void
add_cont_backpatch
(
sp_instr_
jump_if_not
*
i
);
add_cont_backpatch
(
sp_instr_
opt_meta
*
i
);
// Backpatch (and pop) the current level to the current position.
// Backpatch (and pop) the current level to the current position.
void
void
...
@@ -372,15 +373,15 @@ private:
...
@@ -372,15 +373,15 @@ private:
}
bp_t
;
}
bp_t
;
List
<
bp_t
>
m_backpatch
;
// Instructions needing backpatching
List
<
bp_t
>
m_backpatch
;
// Instructions needing backpatching
/*
/*
We need a special list for backpatching of
conditional jump's
continue
We need a special list for backpatching of
instructions with a
continue
destination (in the case of a continue handler catching an error in
destination (in the case of a continue handler catching an error in
the test), since it would otherwise interfere with the normal backpatch
the test), since it would otherwise interfere with the normal backpatch
mechanism -
jump_if_not instructions have two different destination
mechanism -
e.g. jump_if_not instructions have two different destinations
which are to be patched differently.
which are to be patched differently.
Since these occur in a more restricted way (always the same "level" in
Since these occur in a more restricted way (always the same "level" in
the code), we don't need the label.
the code), we don't need the label.
*/
*/
List
<
sp_instr_
jump_if_not
>
m_cont_backpatch
;
List
<
sp_instr_
opt_meta
>
m_cont_backpatch
;
uint
m_cont_level
;
// The current cont. backpatch level
uint
m_cont_level
;
// The current cont. backpatch level
/*
/*
...
@@ -677,21 +678,55 @@ private:
...
@@ -677,21 +678,55 @@ private:
};
// class sp_instr_trigger_field : public sp_instr
};
// class sp_instr_trigger_field : public sp_instr
class
sp_instr_jump
:
public
sp_instr
/*
An abstract class for all instructions with destinations that
needs to be updated by the optimizer.
Even if not all subclasses will use both the normal destination and
the continuation destination, we put them both here for simplicity.
*/
class
sp_instr_opt_meta
:
public
sp_instr
{
public:
uint
m_dest
;
// Where we will go
uint
m_cont_dest
;
// Where continue handlers will go
sp_instr_opt_meta
(
uint
ip
,
sp_pcontext
*
ctx
)
:
sp_instr
(
ip
,
ctx
),
m_dest
(
0
),
m_cont_dest
(
0
),
m_optdest
(
0
),
m_cont_optdest
(
0
)
{}
sp_instr_opt_meta
(
uint
ip
,
sp_pcontext
*
ctx
,
uint
dest
)
:
sp_instr
(
ip
,
ctx
),
m_dest
(
dest
),
m_cont_dest
(
0
),
m_optdest
(
0
),
m_cont_optdest
(
0
)
{}
virtual
~
sp_instr_opt_meta
()
{}
virtual
void
set_destination
(
uint
old_dest
,
uint
new_dest
)
=
0
;
protected:
sp_instr
*
m_optdest
;
// Used during optimization
sp_instr
*
m_cont_optdest
;
// Used during optimization
};
// class sp_instr_opt_meta : public sp_instr
class
sp_instr_jump
:
public
sp_instr_opt_meta
{
{
sp_instr_jump
(
const
sp_instr_jump
&
);
/* Prevent use of these */
sp_instr_jump
(
const
sp_instr_jump
&
);
/* Prevent use of these */
void
operator
=
(
sp_instr_jump
&
);
void
operator
=
(
sp_instr_jump
&
);
public:
public:
uint
m_dest
;
// Where we will go
sp_instr_jump
(
uint
ip
,
sp_pcontext
*
ctx
)
sp_instr_jump
(
uint
ip
,
sp_pcontext
*
ctx
)
:
sp_instr
(
ip
,
ctx
),
m_dest
(
0
),
m_optdest
(
0
)
:
sp_instr
_opt_meta
(
ip
,
ctx
)
{}
{}
sp_instr_jump
(
uint
ip
,
sp_pcontext
*
ctx
,
uint
dest
)
sp_instr_jump
(
uint
ip
,
sp_pcontext
*
ctx
,
uint
dest
)
:
sp_instr
(
ip
,
ctx
),
m_dest
(
dest
),
m_optdest
(
0
)
:
sp_instr
_opt_meta
(
ip
,
ctx
,
dest
)
{}
{}
virtual
~
sp_instr_jump
()
virtual
~
sp_instr_jump
()
...
@@ -722,11 +757,7 @@ public:
...
@@ -722,11 +757,7 @@ public:
m_dest
=
new_dest
;
m_dest
=
new_dest
;
}
}
protected:
};
// class sp_instr_jump : public sp_instr_opt_meta
sp_instr
*
m_optdest
;
// Used during optimization
};
// class sp_instr_jump : public sp_instr
class
sp_instr_jump_if_not
:
public
sp_instr_jump
class
sp_instr_jump_if_not
:
public
sp_instr_jump
...
@@ -736,16 +767,14 @@ class sp_instr_jump_if_not : public sp_instr_jump
...
@@ -736,16 +767,14 @@ class sp_instr_jump_if_not : public sp_instr_jump
public:
public:
uint
m_cont_dest
;
// Where continue handlers will go
sp_instr_jump_if_not
(
uint
ip
,
sp_pcontext
*
ctx
,
Item
*
i
,
LEX
*
lex
)
sp_instr_jump_if_not
(
uint
ip
,
sp_pcontext
*
ctx
,
Item
*
i
,
LEX
*
lex
)
:
sp_instr_jump
(
ip
,
ctx
),
m_
cont_dest
(
0
),
m_
expr
(
i
),
:
sp_instr_jump
(
ip
,
ctx
),
m_expr
(
i
),
m_lex_keeper
(
lex
,
TRUE
)
,
m_cont_optdest
(
0
)
m_lex_keeper
(
lex
,
TRUE
)
{}
{}
sp_instr_jump_if_not
(
uint
ip
,
sp_pcontext
*
ctx
,
Item
*
i
,
uint
dest
,
LEX
*
lex
)
sp_instr_jump_if_not
(
uint
ip
,
sp_pcontext
*
ctx
,
Item
*
i
,
uint
dest
,
LEX
*
lex
)
:
sp_instr_jump
(
ip
,
ctx
,
dest
),
m_
cont_dest
(
0
),
m_
expr
(
i
),
:
sp_instr_jump
(
ip
,
ctx
,
dest
),
m_expr
(
i
),
m_lex_keeper
(
lex
,
TRUE
)
,
m_cont_optdest
(
0
)
m_lex_keeper
(
lex
,
TRUE
)
{}
{}
virtual
~
sp_instr_jump_if_not
()
virtual
~
sp_instr_jump_if_not
()
...
@@ -778,7 +807,6 @@ private:
...
@@ -778,7 +807,6 @@ private:
Item
*
m_expr
;
// The condition
Item
*
m_expr
;
// The condition
sp_lex_keeper
m_lex_keeper
;
sp_lex_keeper
m_lex_keeper
;
sp_instr
*
m_cont_optdest
;
// Used during optimization
};
// class sp_instr_jump_if_not : public sp_instr_jump
};
// class sp_instr_jump_if_not : public sp_instr_jump
...
@@ -912,7 +940,7 @@ private:
...
@@ -912,7 +940,7 @@ private:
uint
m_frame
;
uint
m_frame
;
};
// class sp_instr_hreturn : public sp_instr
};
// class sp_instr_hreturn : public sp_instr
_jump
/* This is DECLARE CURSOR */
/* This is DECLARE CURSOR */
...
@@ -1089,29 +1117,43 @@ private:
...
@@ -1089,29 +1117,43 @@ private:
};
// class sp_instr_error : public sp_instr
};
// class sp_instr_error : public sp_instr
class
sp_instr_set_case_expr
:
public
sp_instr
class
sp_instr_set_case_expr
:
public
sp_instr_opt_meta
{
{
public:
public:
sp_instr_set_case_expr
(
uint
ip
,
sp_pcontext
*
ctx
,
uint
case_expr_id
,
sp_instr_set_case_expr
(
uint
ip
,
sp_pcontext
*
ctx
,
uint
case_expr_id
,
Item
*
case_expr
,
LEX
*
lex
)
Item
*
case_expr
,
LEX
*
lex
)
:
sp_instr
(
ip
,
ctx
),
m_case_expr_id
(
case_expr_id
),
m_case_expr
(
case_expr
),
:
sp_instr_opt_meta
(
ip
,
ctx
),
m_case_expr_id
(
case_expr_id
),
m_case_expr
(
case_expr
),
m_lex_keeper
(
lex
,
TRUE
)
m_lex_keeper
(
lex
,
TRUE
)
{}
{}
virtual
~
sp_instr_set_case_expr
()
{}
virtual
int
execute
(
THD
*
thd
,
uint
*
nextp
);
virtual
int
execute
(
THD
*
thd
,
uint
*
nextp
);
virtual
int
exec_core
(
THD
*
thd
,
uint
*
nextp
);
virtual
int
exec_core
(
THD
*
thd
,
uint
*
nextp
);
virtual
void
print
(
String
*
str
);
virtual
void
print
(
String
*
str
);
virtual
uint
opt_mark
(
sp_head
*
sp
);
virtual
void
opt_move
(
uint
dst
,
List
<
sp_instr
>
*
ibp
);
virtual
void
set_destination
(
uint
old_dest
,
uint
new_dest
)
{
if
(
m_cont_dest
==
old_dest
)
m_cont_dest
=
new_dest
;
}
private:
private:
uint
m_case_expr_id
;
uint
m_case_expr_id
;
Item
*
m_case_expr
;
Item
*
m_case_expr
;
sp_lex_keeper
m_lex_keeper
;
sp_lex_keeper
m_lex_keeper
;
};
// class sp_instr_set_case_expr : public sp_instr
};
// class sp_instr_set_case_expr : public sp_instr
_opt_meta
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
...
...
sql/sql_acl.cc
View file @
221b3578
...
@@ -3030,7 +3030,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
...
@@ -3030,7 +3030,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if
(
!
revoke_grant
)
if
(
!
revoke_grant
)
{
{
if
(
sp_exist
s_routine
(
thd
,
table_list
,
is_proc
,
no_error
)
<
0
)
if
(
sp_exist
_routines
(
thd
,
table_list
,
is_proc
,
no_error
)
<
0
)
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
}
}
...
...
sql/sql_parse.cc
View file @
221b3578
...
@@ -4445,21 +4445,17 @@ end_with_restore_list:
...
@@ -4445,21 +4445,17 @@ end_with_restore_list:
case
SQLCOM_DROP_PROCEDURE
:
case
SQLCOM_DROP_PROCEDURE
:
case
SQLCOM_DROP_FUNCTION
:
case
SQLCOM_DROP_FUNCTION
:
{
{
sp_head
*
sp
;
int
result
;
int
result
;
char
*
db
,
*
name
;
int
type
=
(
lex
->
sql_command
==
SQLCOM_DROP_PROCEDURE
?
TYPE_ENUM_PROCEDURE
:
TYPE_ENUM_FUNCTION
);
if
(
lex
->
sql_command
==
SQLCOM_DROP_PROCEDURE
)
result
=
sp_routine_exists_in_table
(
thd
,
type
,
lex
->
spname
);
sp
=
sp_find_routine
(
thd
,
TYPE_ENUM_PROCEDURE
,
lex
->
spname
,
&
thd
->
sp_proc_cache
,
FALSE
);
else
sp
=
sp_find_routine
(
thd
,
TYPE_ENUM_FUNCTION
,
lex
->
spname
,
&
thd
->
sp_func_cache
,
FALSE
);
mysql_reset_errors
(
thd
,
0
);
mysql_reset_errors
(
thd
,
0
);
if
(
sp
)
if
(
result
==
SP_OK
)
{
{
db
=
thd
->
strdup
(
sp
->
m_db
.
str
);
char
*
db
=
lex
->
spname
->
m_db
.
str
;
name
=
thd
->
strdup
(
sp
->
m_name
.
str
);
char
*
name
=
lex
->
spname
->
m_name
.
str
;
if
(
check_routine_access
(
thd
,
ALTER_PROC_ACL
,
db
,
name
,
if
(
check_routine_access
(
thd
,
ALTER_PROC_ACL
,
db
,
name
,
lex
->
sql_command
==
SQLCOM_DROP_PROCEDURE
,
0
))
lex
->
sql_command
==
SQLCOM_DROP_PROCEDURE
,
0
))
goto
error
;
goto
error
;
...
@@ -4599,7 +4595,7 @@ end_with_restore_list:
...
@@ -4599,7 +4595,7 @@ end_with_restore_list:
else
else
sp
=
sp_find_routine
(
thd
,
TYPE_ENUM_FUNCTION
,
lex
->
spname
,
sp
=
sp_find_routine
(
thd
,
TYPE_ENUM_FUNCTION
,
lex
->
spname
,
&
thd
->
sp_func_cache
,
FALSE
);
&
thd
->
sp_func_cache
,
FALSE
);
if
(
!
sp
||
!
sp
->
show_routine_code
(
thd
))
if
(
!
sp
||
sp
->
show_routine_code
(
thd
))
{
{
/* We don't distinguish between errors for now */
/* We don't distinguish between errors for now */
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
...
...
sql/sql_yacc.yy
View file @
221b3578
...
@@ -2018,17 +2018,18 @@ sp_proc_stmt:
...
@@ -2018,17 +2018,18 @@ sp_proc_stmt:
sp_head *sp= lex->sphead;
sp_head *sp= lex->sphead;
sp_pcontext *parsing_ctx= lex->spcont;
sp_pcontext *parsing_ctx= lex->spcont;
int case_expr_id= parsing_ctx->register_case_expr();
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))
if (parsing_ctx->push_case_expr_id(case_expr_id))
YYABORT;
YYABORT;
sp->add_instr(
i= new sp_instr_set_case_expr(sp->instructions(),
new sp_instr_set_case_expr(sp->instructions(),
parsing_ctx,
parsing_ctx,
case_expr_id,
case_expr_id,
$3,
$3,
lex));
lex);
sp->add_cont_backpatch(i);
sp->add_instr(i);
sp->m_flags|= sp_head::IN_SIMPLE_CASE;
sp->m_flags|= sp_head::IN_SIMPLE_CASE;
sp->restore_lex(YYTHD);
sp->restore_lex(YYTHD);
}
}
...
...
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