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
b9d49ee8
Commit
b9d49ee8
authored
May 09, 2006
by
dlenev@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-5.0-runtime
into mysql.com:/home/dlenev/mysql-5.0-bg12472
parents
d8bc635e
589daad1
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
201 additions
and
107 deletions
+201
-107
mysql-test/r/sp.result
mysql-test/r/sp.result
+25
-0
mysql-test/t/sp.test
mysql-test/t/sp.test
+23
-0
sql/mysql_priv.h
sql/mysql_priv.h
+2
-7
sql/sql_base.cc
sql/sql_base.cc
+4
-1
sql/sql_insert.cc
sql/sql_insert.cc
+147
-0
sql/sql_table.cc
sql/sql_table.cc
+0
-99
No files found.
mysql-test/r/sp.result
View file @
b9d49ee8
...
...
@@ -4904,4 +4904,29 @@ schema_name
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name routine_schema
drop function if exists bug12472|
create function bug12472() returns int return (select count(*) from t1)|
create table t3 as select bug12472() as i|
show create table t3|
Table Create Table
t3 CREATE TABLE `t3` (
`i` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t3|
i
0
drop table t3|
create view v1 as select bug12472() as j|
create table t3 as select * from v1|
show create table t3|
Table Create Table
t3 CREATE TABLE `t3` (
`j` bigint(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t3|
j
0
drop table t3|
drop view v1|
drop function bug12472|
drop table t1,t2;
mysql-test/t/sp.test
View file @
b9d49ee8
...
...
@@ -5773,6 +5773,29 @@ select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
#
# BUG#12472/BUG#15137 'CREATE TABLE ... SELECT ... which explicitly or
# implicitly uses stored function gives "Table not locked" error'.
#
--disable_warnings
drop function if exists bug12472|
--enable_warnings
create function bug12472() returns int return (select count(*) from t1)|
# Check case when function is used directly
create table t3
as
select
bug12472()
as
i
|
show create table t3|
select * from t3|
drop table t3|
# Check case when function is used indirectly through view
create view v1
as
select
bug12472()
as
j
|
create table t3
as
select
* from v1|
show create table t3|
select * from t3|
drop table t3|
drop view v1|
drop function bug12472|
#
# BUG#NNNN: New bug synopsis
#
...
...
sql/mysql_priv.h
View file @
b9d49ee8
...
...
@@ -718,12 +718,6 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
uint
select_field_count
);
TABLE
*
create_table_from_items
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
create_table
,
List
<
create_field
>
*
extra_fields
,
List
<
Key
>
*
keys
,
List
<
Item
>
*
items
,
MYSQL_LOCK
**
lock
);
bool
mysql_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
table_list
,
...
...
@@ -1315,10 +1309,11 @@ extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
MYSQL_LOCK
*
mysql_lock_tables
(
THD
*
thd
,
TABLE
**
table
,
uint
count
,
uint
flags
,
bool
*
need_reopen
);
/* mysql_lock_tables() flags bits */
/* mysql_lock_tables()
and open_table()
flags bits */
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001
#define MYSQL_LOCK_IGNORE_FLUSH 0x0002
#define MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN 0x0004
#define MYSQL_OPEN_IGNORE_LOCKED_TABLES 0x0008
void
mysql_unlock_tables
(
THD
*
thd
,
MYSQL_LOCK
*
sql_lock
);
void
mysql_unlock_read_tables
(
THD
*
thd
,
MYSQL_LOCK
*
sql_lock
);
...
...
sql/sql_base.cc
View file @
b9d49ee8
...
...
@@ -1160,6 +1160,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
MYSQL_LOCK_IGNORE_FLUSH - Open table even if
someone has done a flush or namelock on it.
No version number checking is done.
MYSQL_OPEN_IGNORE_LOCKED_TABLES - Open table
ignoring set of locked tables and prelocked mode.
IMPLEMENTATION
Uses a cache of open tables to find a table not in use.
...
...
@@ -1219,7 +1221,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
if
(
thd
->
locked_tables
||
thd
->
prelocked_mode
)
if
(
!
(
flags
&
MYSQL_OPEN_IGNORE_LOCKED_TABLES
)
&&
(
thd
->
locked_tables
||
thd
->
prelocked_mode
))
{
// Using table locks
TABLE
*
best_table
=
0
;
int
best_distance
=
INT_MIN
;
...
...
sql/sql_insert.cc
View file @
b9d49ee8
...
...
@@ -2437,6 +2437,153 @@ bool select_insert::send_eof()
CREATE TABLE (SELECT) ...
***************************************************************************/
/*
Create table from lists of fields and items (or open existing table
with same name).
SYNOPSIS
create_table_from_items()
thd in Thread object
create_info in Create information (like MAX_ROWS, ENGINE or
temporary table flag)
create_table in Pointer to TABLE_LIST object providing database
and name for table to be created or to be open
extra_fields in/out Initial list of fields for table to be created
keys in List of keys for table to be created
items in List of items which should be used to produce rest
of fields for the table (corresponding fields will
be added to the end of 'extra_fields' list)
lock out Pointer to the MYSQL_LOCK object for table created
(open) will be returned in this parameter. Since
this table is not included in THD::lock caller is
responsible for explicitly unlocking this table.
NOTES
If 'create_info->options' bitmask has HA_LEX_CREATE_IF_NOT_EXISTS
flag and table with name provided already exists then this function will
simply open existing table.
Also note that create, open and lock sequence in this function is not
atomic and thus contains gap for deadlock and can cause other troubles.
Since this function contains some logic specific to CREATE TABLE ... SELECT
it should be changed before it can be used in other contexts.
RETURN VALUES
non-zero Pointer to TABLE object for table created or opened
0 Error
*/
static
TABLE
*
create_table_from_items
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
create_table
,
List
<
create_field
>
*
extra_fields
,
List
<
Key
>
*
keys
,
List
<
Item
>
*
items
,
MYSQL_LOCK
**
lock
)
{
TABLE
tmp_table
;
// Used during 'create_field()'
TABLE
*
table
=
0
;
uint
select_field_count
=
items
->
elements
;
/* Add selected items to field list */
List_iterator_fast
<
Item
>
it
(
*
items
);
Item
*
item
;
Field
*
tmp_field
;
bool
not_used
;
DBUG_ENTER
(
"create_table_from_items"
);
tmp_table
.
alias
=
0
;
tmp_table
.
timestamp_field
=
0
;
tmp_table
.
s
=
&
tmp_table
.
share_not_to_be_used
;
tmp_table
.
s
->
db_create_options
=
0
;
tmp_table
.
s
->
blob_ptr_size
=
portable_sizeof_char_ptr
;
tmp_table
.
s
->
db_low_byte_first
=
test
(
create_info
->
db_type
==
DB_TYPE_MYISAM
||
create_info
->
db_type
==
DB_TYPE_HEAP
);
tmp_table
.
null_row
=
tmp_table
.
maybe_null
=
0
;
while
((
item
=
it
++
))
{
create_field
*
cr_field
;
Field
*
field
;
if
(
item
->
type
()
==
Item
::
FUNC_ITEM
)
field
=
item
->
tmp_table_field
(
&
tmp_table
);
else
field
=
create_tmp_field
(
thd
,
&
tmp_table
,
item
,
item
->
type
(),
(
Item
***
)
0
,
&
tmp_field
,
0
,
0
,
0
,
0
,
0
);
if
(
!
field
||
!
(
cr_field
=
new
create_field
(
field
,(
item
->
type
()
==
Item
::
FIELD_ITEM
?
((
Item_field
*
)
item
)
->
field
:
(
Field
*
)
0
))))
DBUG_RETURN
(
0
);
if
(
item
->
maybe_null
)
cr_field
->
flags
&=
~
NOT_NULL_FLAG
;
extra_fields
->
push_back
(
cr_field
);
}
/*
create and lock table
We don't log the statement, it will be logged later.
If this is a HEAP table, the automatic DELETE FROM which is written to the
binlog when a HEAP table is opened for the first time since startup, must
not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
don't want to delete from it) 2) it would be written before the CREATE
TABLE, which is a wrong order. So we keep binary logging disabled when we
open_table().
NOTE: By locking table which we just have created (or for which we just have
have found that it already exists) separately from other tables used by the
statement we create potential window for deadlock.
TODO: create and open should be done atomic !
*/
{
tmp_disable_binlog
(
thd
);
if
(
!
mysql_create_table
(
thd
,
create_table
->
db
,
create_table
->
table_name
,
create_info
,
*
extra_fields
,
*
keys
,
0
,
select_field_count
))
{
/*
If we are here in prelocked mode we either create temporary table
or prelocked mode is caused by the SELECT part of this statement.
*/
DBUG_ASSERT
(
!
thd
->
prelocked_mode
||
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
||
thd
->
lex
->
requires_prelocking
());
/*
NOTE: We don't want to ignore set of locked tables here if we are
under explicit LOCK TABLES since it will open gap for deadlock
too wide (and also is not backward compatible).
*/
if
(
!
(
table
=
open_table
(
thd
,
create_table
,
thd
->
mem_root
,
(
bool
*
)
0
,
(
MYSQL_LOCK_IGNORE_FLUSH
|
((
thd
->
prelocked_mode
==
PRELOCKED
)
?
MYSQL_OPEN_IGNORE_LOCKED_TABLES:
0
)))))
quick_rm_table
(
create_info
->
db_type
,
create_table
->
db
,
table_case_name
(
create_info
,
create_table
->
table_name
));
}
reenable_binlog
(
thd
);
if
(
!
table
)
// open failed
DBUG_RETURN
(
0
);
}
/*
FIXME: What happens if trigger manages to be created while we are
obtaining this lock ? May be it is sensible just to disable
trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
save us from that ?
*/
table
->
reginfo
.
lock_type
=
TL_WRITE
;
if
(
!
((
*
lock
)
=
mysql_lock_tables
(
thd
,
&
table
,
1
,
MYSQL_LOCK_IGNORE_FLUSH
,
&
not_used
)))
{
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
hash_delete
(
&
open_cache
,(
byte
*
)
table
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
quick_rm_table
(
create_info
->
db_type
,
create_table
->
db
,
table_case_name
(
create_info
,
create_table
->
table_name
));
DBUG_RETURN
(
0
);
}
table
->
file
->
extra
(
HA_EXTRA_WRITE_CACHE
);
DBUG_RETURN
(
table
);
}
int
select_create
::
prepare
(
List
<
Item
>
&
values
,
SELECT_LEX_UNIT
*
u
)
{
...
...
sql/sql_table.cc
View file @
b9d49ee8
...
...
@@ -1789,105 +1789,6 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
}
/****************************************************************************
** Create table from a list of fields and items
****************************************************************************/
TABLE
*
create_table_from_items
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
create_table
,
List
<
create_field
>
*
extra_fields
,
List
<
Key
>
*
keys
,
List
<
Item
>
*
items
,
MYSQL_LOCK
**
lock
)
{
TABLE
tmp_table
;
// Used during 'create_field()'
TABLE
*
table
=
0
;
uint
select_field_count
=
items
->
elements
;
/* Add selected items to field list */
List_iterator_fast
<
Item
>
it
(
*
items
);
Item
*
item
;
Field
*
tmp_field
;
bool
not_used
;
DBUG_ENTER
(
"create_table_from_items"
);
tmp_table
.
alias
=
0
;
tmp_table
.
timestamp_field
=
0
;
tmp_table
.
s
=
&
tmp_table
.
share_not_to_be_used
;
tmp_table
.
s
->
db_create_options
=
0
;
tmp_table
.
s
->
blob_ptr_size
=
portable_sizeof_char_ptr
;
tmp_table
.
s
->
db_low_byte_first
=
test
(
create_info
->
db_type
==
DB_TYPE_MYISAM
||
create_info
->
db_type
==
DB_TYPE_HEAP
);
tmp_table
.
null_row
=
tmp_table
.
maybe_null
=
0
;
while
((
item
=
it
++
))
{
create_field
*
cr_field
;
Field
*
field
;
if
(
item
->
type
()
==
Item
::
FUNC_ITEM
)
field
=
item
->
tmp_table_field
(
&
tmp_table
);
else
field
=
create_tmp_field
(
thd
,
&
tmp_table
,
item
,
item
->
type
(),
(
Item
***
)
0
,
&
tmp_field
,
0
,
0
,
0
,
0
,
0
);
if
(
!
field
||
!
(
cr_field
=
new
create_field
(
field
,(
item
->
type
()
==
Item
::
FIELD_ITEM
?
((
Item_field
*
)
item
)
->
field
:
(
Field
*
)
0
))))
DBUG_RETURN
(
0
);
if
(
item
->
maybe_null
)
cr_field
->
flags
&=
~
NOT_NULL_FLAG
;
extra_fields
->
push_back
(
cr_field
);
}
/*
create and lock table
We don't log the statement, it will be logged later.
If this is a HEAP table, the automatic DELETE FROM which is written to the
binlog when a HEAP table is opened for the first time since startup, must
not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
don't want to delete from it) 2) it would be written before the CREATE
TABLE, which is a wrong order. So we keep binary logging disabled when we
open_table().
TODO: create and open should be done atomic !
*/
{
tmp_disable_binlog
(
thd
);
if
(
!
mysql_create_table
(
thd
,
create_table
->
db
,
create_table
->
table_name
,
create_info
,
*
extra_fields
,
*
keys
,
0
,
select_field_count
))
{
if
(
!
(
table
=
open_table
(
thd
,
create_table
,
thd
->
mem_root
,
(
bool
*
)
0
,
MYSQL_LOCK_IGNORE_FLUSH
)))
quick_rm_table
(
create_info
->
db_type
,
create_table
->
db
,
table_case_name
(
create_info
,
create_table
->
table_name
));
}
reenable_binlog
(
thd
);
if
(
!
table
)
// open failed
DBUG_RETURN
(
0
);
}
/*
FIXME: What happens if trigger manages to be created while we are
obtaining this lock ? May be it is sensible just to disable
trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
save us from that ?
*/
table
->
reginfo
.
lock_type
=
TL_WRITE
;
if
(
!
((
*
lock
)
=
mysql_lock_tables
(
thd
,
&
table
,
1
,
MYSQL_LOCK_IGNORE_FLUSH
,
&
not_used
)))
{
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
hash_delete
(
&
open_cache
,(
byte
*
)
table
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
quick_rm_table
(
create_info
->
db_type
,
create_table
->
db
,
table_case_name
(
create_info
,
create_table
->
table_name
));
DBUG_RETURN
(
0
);
}
table
->
file
->
extra
(
HA_EXTRA_WRITE_CACHE
);
DBUG_RETURN
(
table
);
}
/****************************************************************************
** Alter a table definition
****************************************************************************/
...
...
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