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
6da6c5be
Commit
6da6c5be
authored
Feb 13, 2005
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed SP processing for mysql_list_fields() command (BUG#6814)
parent
ea8caabb
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
151 additions
and
87 deletions
+151
-87
sql/sql_parse.cc
sql/sql_parse.cc
+114
-87
tests/mysql_client_test.c
tests/mysql_client_test.c
+37
-0
No files found.
sql/sql_parse.cc
View file @
6da6c5be
...
...
@@ -1487,6 +1487,106 @@ bool do_command(THD *thd)
}
#endif
/* EMBEDDED_LIBRARY */
static
void
release_local_lock
(
THD
*
thd
,
TABLE_LIST
*
locked_tables
,
bool
old_innodb_table_locks
)
{
if
(
locked_tables
)
{
#ifdef HAVE_INNOBASE_DB
thd
->
variables
.
innodb_table_locks
=
old_innodb_table_locks
;
#endif
if
(
thd
->
locked_tables
)
sp_unlock_tables
(
thd
);
}
}
static
bool
process_nested_sp
(
THD
*
thd
,
LEX
*
lex
,
TABLE_LIST
**
locked_tables
)
{
DBUG_ENTER
(
"process_nested_sp"
);
while
(
1
)
{
if
(
sp_cache_routines
(
thd
,
lex
,
TYPE_ENUM_FUNCTION
))
DBUG_RETURN
(
TRUE
);
if
(
sp_cache_routines
(
thd
,
lex
,
TYPE_ENUM_PROCEDURE
))
DBUG_RETURN
(
TRUE
);
if
(
!
thd
->
locked_tables
&&
lex
->
sql_command
!=
SQLCOM_CREATE_TABLE
&&
lex
->
sql_command
!=
SQLCOM_CREATE_VIEW
)
{
MEM_ROOT
*
thdmemroot
=
NULL
;
sp_merge_routine_tables
(
thd
,
lex
);
// QQ Preopen tables to find views and triggers.
// This means we open, close and open again, which sucks, but
// right now it's the easiest way to get it to work. A better
// solution will hopefully be found soon...
if
(
lex
->
sptabs
.
records
||
lex
->
query_tables
)
{
uint
procs
,
funs
,
tabs
;
if
(
thd
->
mem_root
!=
thd
->
current_arena
->
mem_root
)
{
thdmemroot
=
thd
->
mem_root
;
thd
->
mem_root
=
thd
->
current_arena
->
mem_root
;
}
if
(
!
sp_merge_table_list
(
thd
,
&
lex
->
sptabs
,
lex
->
query_tables
))
DBUG_RETURN
(
TRUE
);
procs
=
lex
->
spprocs
.
records
;
funs
=
lex
->
spfuns
.
records
;
tabs
=
lex
->
sptabs
.
records
;
if
(((
*
locked_tables
)
=
sp_hash_to_table_list
(
thd
,
&
lex
->
sptabs
)))
{
// We don't want these updated now
uint
ctmpdtabs
=
thd
->
status_var
.
created_tmp_disk_tables
;
uint
ctmptabs
=
thd
->
status_var
.
created_tmp_tables
;
uint
count
;
thd
->
shortcut_make_view
=
TRUE
;
open_tables
(
thd
,
*
locked_tables
,
&
count
);
thd
->
shortcut_make_view
=
FALSE
;
close_thread_tables
(
thd
);
thd
->
status_var
.
created_tmp_disk_tables
=
ctmpdtabs
;
thd
->
status_var
.
created_tmp_tables
=
ctmptabs
;
thd
->
clear_error
();
mysql_reset_errors
(
thd
);
(
*
locked_tables
)
=
NULL
;
}
// A kludge: Decrease all temp. table's query ids to allow a
// second opening.
for
(
TABLE
*
table
=
thd
->
temporary_tables
;
table
;
table
=
table
->
next
)
table
->
query_id
-=
1
;
if
(
procs
<
lex
->
spprocs
.
records
||
funs
<
lex
->
spfuns
.
records
||
tabs
<
lex
->
sptabs
.
records
)
{
if
(
thdmemroot
)
thd
->
mem_root
=
thdmemroot
;
continue
;
// Found more SPs or tabs, try again
}
}
if
(
lex
->
sptabs
.
records
&&
(
lex
->
spfuns
.
records
||
lex
->
spprocs
.
records
)
&&
sp_merge_table_list
(
thd
,
&
lex
->
sptabs
,
lex
->
query_tables
))
{
if
(((
*
locked_tables
)
=
sp_hash_to_table_list
(
thd
,
&
lex
->
sptabs
)))
{
#ifdef HAVE_INNOBASE_DB
thd
->
variables
.
innodb_table_locks
=
FALSE
;
#endif
sp_open_and_lock_tables
(
thd
,
*
locked_tables
);
}
}
if
(
thdmemroot
)
thd
->
mem_root
=
thdmemroot
;
}
break
;
}
// while (1)
DBUG_RETURN
(
FALSE
);
}
/*
Perform one connection-level (COM_XXXX) command.
SYNOPSIS
...
...
@@ -1733,8 +1833,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#else
{
char
*
fields
,
*
pend
;
/* Locked closure of all tables */
TABLE_LIST
*
locked_tables
=
NULL
;
TABLE_LIST
table_list
;
LEX_STRING
conv_name
;
/* Saved variable value */
#ifdef HAVE_INNOBASE_DB
my_bool
old_innodb_table_locks
=
thd
->
variables
.
innodb_table_locks
;
#endif
statistic_increment
(
thd
->
status_var
.
com_stat
[
SQLCOM_SHOW_FIELDS
],
&
LOCK_status
);
...
...
@@ -1778,12 +1885,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd
->
lex
->
select_lex
.
table_list
.
link_in_list
((
byte
*
)
&
table_list
,
(
byte
**
)
&
table_list
.
next_local
);
thd
->
lex
->
query_tables
=
&
table_list
;
thd
->
shortcut_make_view
=
0
;
process_nested_sp
(
thd
,
thd
->
lex
,
&
locked_tables
);
/* switch on VIEW optimisation: do not fill temporary tables */
thd
->
lex
->
sql_command
=
SQLCOM_SHOW_FIELDS
;
mysqld_list_fields
(
thd
,
&
table_list
,
fields
);
thd
->
lex
->
unit
.
cleanup
();
thd
->
cleanup_after_query
();
release_local_lock
(
thd
,
locked_tables
,
old_innodb_table_locks
);
break
;
}
#endif
...
...
@@ -2268,85 +2379,8 @@ mysql_execute_command(THD *thd)
lex
->
sql_command
!=
SQLCOM_LOCK_TABLES
&&
lex
->
sql_command
!=
SQLCOM_UNLOCK_TABLES
)
{
while
(
1
)
{
if
(
sp_cache_routines
(
thd
,
lex
,
TYPE_ENUM_FUNCTION
))
DBUG_RETURN
(
-
1
);
if
(
sp_cache_routines
(
thd
,
lex
,
TYPE_ENUM_PROCEDURE
))
DBUG_RETURN
(
-
1
);
if
(
!
thd
->
locked_tables
&&
lex
->
sql_command
!=
SQLCOM_CREATE_TABLE
&&
lex
->
sql_command
!=
SQLCOM_CREATE_VIEW
)
{
MEM_ROOT
*
thdmemroot
=
NULL
;
sp_merge_routine_tables
(
thd
,
lex
);
// QQ Preopen tables to find views and triggers.
// This means we open, close and open again, which sucks, but
// right now it's the easiest way to get it to work. A better
// solution will hopefully be found soon...
if
(
lex
->
sptabs
.
records
||
lex
->
query_tables
)
{
uint
procs
,
funs
,
tabs
;
if
(
thd
->
mem_root
!=
thd
->
current_arena
->
mem_root
)
{
thdmemroot
=
thd
->
mem_root
;
thd
->
mem_root
=
thd
->
current_arena
->
mem_root
;
}
if
(
!
sp_merge_table_list
(
thd
,
&
lex
->
sptabs
,
lex
->
query_tables
))
DBUG_RETURN
(
-
1
);
procs
=
lex
->
spprocs
.
records
;
funs
=
lex
->
spfuns
.
records
;
tabs
=
lex
->
sptabs
.
records
;
if
((
locked_tables
=
sp_hash_to_table_list
(
thd
,
&
lex
->
sptabs
)))
{
// We don't want these updated now
uint
ctmpdtabs
=
thd
->
status_var
.
created_tmp_disk_tables
;
uint
ctmptabs
=
thd
->
status_var
.
created_tmp_tables
;
uint
count
;
thd
->
shortcut_make_view
=
TRUE
;
open_tables
(
thd
,
locked_tables
,
&
count
);
thd
->
shortcut_make_view
=
FALSE
;
close_thread_tables
(
thd
);
thd
->
status_var
.
created_tmp_disk_tables
=
ctmpdtabs
;
thd
->
status_var
.
created_tmp_tables
=
ctmptabs
;
thd
->
clear_error
();
mysql_reset_errors
(
thd
);
locked_tables
=
NULL
;
}
// A kludge: Decrease all temp. table's query ids to allow a
// second opening.
for
(
TABLE
*
table
=
thd
->
temporary_tables
;
table
;
table
=
table
->
next
)
table
->
query_id
-=
1
;
if
(
procs
<
lex
->
spprocs
.
records
||
funs
<
lex
->
spfuns
.
records
||
tabs
<
lex
->
sptabs
.
records
)
{
if
(
thdmemroot
)
thd
->
mem_root
=
thdmemroot
;
continue
;
// Found more SPs or tabs, try again
}
}
if
(
lex
->
sptabs
.
records
&&
(
lex
->
spfuns
.
records
||
lex
->
spprocs
.
records
)
&&
sp_merge_table_list
(
thd
,
&
lex
->
sptabs
,
lex
->
query_tables
))
{
if
((
locked_tables
=
sp_hash_to_table_list
(
thd
,
&
lex
->
sptabs
)))
{
#ifdef HAVE_INNOBASE_DB
thd
->
variables
.
innodb_table_locks
=
FALSE
;
#endif
sp_open_and_lock_tables
(
thd
,
locked_tables
);
}
}
if
(
thdmemroot
)
thd
->
mem_root
=
thdmemroot
;
}
break
;
}
// while (1)
if
(
process_nested_sp
(
thd
,
lex
,
&
locked_tables
))
DBUG_RETURN
(
TRUE
);
}
/*
...
...
@@ -4362,14 +4396,7 @@ cleanup:
thd
->
lock
=
0
;
}
if
(
locked_tables
)
{
#ifdef HAVE_INNOBASE_DB
thd
->
variables
.
innodb_table_locks
=
old_innodb_table_locks
;
#endif
if
(
thd
->
locked_tables
)
sp_unlock_tables
(
thd
);
}
release_local_lock
(
thd
,
locked_tables
,
old_innodb_table_locks
);
DBUG_RETURN
(
res
||
thd
->
net
.
report_error
);
}
...
...
tests/mysql_client_test.c
View file @
6da6c5be
...
...
@@ -12584,6 +12584,42 @@ static void test_bug7990()
}
static
void
test_view_sp_list_fields
()
{
MYSQL_STMT
*
stmt
;
int
rc
;
MYSQL_RES
*
res
;
myheader
(
"test_view_insert_fields"
);
rc
=
mysql_query
(
mysql
,
"DROP FUNCTION IF EXISTS f1"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE IF EXISTS v1, t1, t2"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"DROP VIEW IF EXISTS v1, t1, t2"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"create function f1 () returns int return 5"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"create table t1 (s1 char,s2 char)"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"create table t2 (s1 int);"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"create view v1 as select s2,sum(s1) - \
count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
from t2);"
);
myquery
(
rc
);
res
=
mysql_list_fields
(
mysql
,
"v1"
,
NullS
);
DIE_UNLESS
(
res
!=
0
&&
mysql_num_fields
(
res
)
!=
0
);
rc
=
mysql_query
(
mysql
,
"DROP FUNCTION f1"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"DROP VIEW v1"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE t1, t2"
);
myquery
(
rc
);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
...
...
@@ -12645,6 +12681,7 @@ and you are welcome to modify and redistribute it under the GPL license\n");
static
struct
my_tests_st
my_tests
[]
=
{
{
"test_view_sp_list_fields"
,
test_view_sp_list_fields
},
{
"client_query"
,
client_query
},
{
"test_prepare_insert_update"
,
test_prepare_insert_update
},
#if NOT_YET_WORKING
...
...
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