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
8d63e069
Commit
8d63e069
authored
Dec 21, 2004
by
joreland@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/jonas/src/mysql-5.0
parents
1071273b
348c2ea8
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
327 additions
and
56 deletions
+327
-56
client/mysqltest.c
client/mysqltest.c
+1
-1
innobase/include/lock0lock.h
innobase/include/lock0lock.h
+2
-0
innobase/include/trx0trx.h
innobase/include/trx0trx.h
+4
-0
innobase/lock/lock0lock.c
innobase/lock/lock0lock.c
+32
-8
innobase/row/row0mysql.c
innobase/row/row0mysql.c
+9
-3
innobase/trx/trx0trx.c
innobase/trx/trx0trx.c
+10
-3
mysql-test/r/derived.result
mysql-test/r/derived.result
+5
-0
mysql-test/t/derived.test
mysql-test/t/derived.test
+13
-0
sql/ha_innodb.cc
sql/ha_innodb.cc
+93
-3
sql/ha_innodb.h
sql/ha_innodb.h
+1
-0
sql/handler.h
sql/handler.h
+7
-0
sql/lock.cc
sql/lock.cc
+75
-5
sql/mysql_priv.h
sql/mysql_priv.h
+1
-0
sql/sql_base.cc
sql/sql_base.cc
+1
-2
sql/sql_lex.cc
sql/sql_lex.cc
+25
-9
sql/sql_lex.h
sql/sql_lex.h
+4
-4
sql/sql_parse.cc
sql/sql_parse.cc
+21
-13
sql/sql_yacc.yy
sql/sql_yacc.yy
+16
-5
sql/tztime.cc
sql/tztime.cc
+6
-0
sql/tztime.h
sql/tztime.h
+1
-0
No files found.
client/mysqltest.c
View file @
8d63e069
...
...
@@ -2896,7 +2896,7 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags)
/* Allocate array with bind structs, lengths and NULL flags */
bind
=
(
MYSQL_BIND
*
)
my_malloc
(
num_fields
*
sizeof
(
MYSQL_BIND
),
MYF
(
MY_WME
|
MY_FAE
));
MYF
(
MY_WME
|
MY_FAE
|
MY_ZEROFILL
));
length
=
(
unsigned
long
*
)
my_malloc
(
num_fields
*
sizeof
(
unsigned
long
),
MYF
(
MY_WME
|
MY_FAE
));
is_null
=
(
my_bool
*
)
my_malloc
(
num_fields
*
sizeof
(
my_bool
),
...
...
innobase/include/lock0lock.h
View file @
8d63e069
...
...
@@ -612,6 +612,8 @@ extern lock_sys_t* lock_sys;
#define LOCK_TABLE 16
/* these type values should be so high that */
#define LOCK_REC 32
/* they can be ORed to the lock mode */
#define LOCK_TABLE_EXP 80
/* explicit table lock (80 = 16 + 64) */
#define LOCK_TABLE_TRANSACTIONAL 144
/* transactional table lock (144 = 16 + 128)*/
#define LOCK_TYPE_MASK 0xF0UL
/* mask used to extract lock type from the
type_mode field in a lock */
/* Waiting lock flag */
...
...
innobase/include/trx0trx.h
View file @
8d63e069
...
...
@@ -464,6 +464,10 @@ struct trx_struct{
ulint
n_lock_table_exp
;
/* number of explicit table locks
(LOCK TABLES) reserved by the
transaction, stored in trx_locks */
ulint
n_lock_table_transactional
;
/* number of transactional table locks
(LOCK TABLES..WHERE ENGINE) reserved by
the transaction, stored in trx_locks */
UT_LIST_NODE_T
(
trx_t
)
trx_list
;
/* list of transactions */
UT_LIST_NODE_T
(
trx_t
)
...
...
innobase/lock/lock0lock.c
View file @
8d63e069
...
...
@@ -2207,7 +2207,8 @@ lock_grant(
release it at the end of the SQL statement */
lock
->
trx
->
auto_inc_lock
=
lock
;
}
else
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
)
{
}
else
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
||
lock_get_type
(
lock
)
==
LOCK_TABLE_TRANSACTIONAL
)
{
ut_a
(
lock_get_mode
(
lock
)
==
LOCK_S
||
lock_get_mode
(
lock
)
==
LOCK_X
);
}
...
...
@@ -3421,6 +3422,10 @@ lock_table_create(
lock
->
trx
->
n_lock_table_exp
++
;
}
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_TRANSACTIONAL
)
{
lock
->
trx
->
n_lock_table_transactional
++
;
}
lock
->
un_member
.
tab_lock
.
table
=
table
;
UT_LIST_ADD_LAST
(
un_member
.
tab_lock
.
locks
,
table
->
locks
,
lock
);
...
...
@@ -3458,7 +3463,11 @@ lock_table_remove_low(
}
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
)
{
lock
->
trx
->
n_lock_table_exp
--
;
trx
->
n_lock_table_exp
--
;
}
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_TRANSACTIONAL
)
{
trx
->
n_lock_table_transactional
--
;
}
UT_LIST_REMOVE
(
trx_locks
,
trx
->
trx_locks
,
lock
);
...
...
@@ -3592,7 +3601,8 @@ lock_table(
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
ulint
flags
,
/* in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing;
if LOCK_TABLE_EXP bits are set,
if LOCK_TABLE_EXP|LOCK_TABLE_TRANSACTIONAL
bits are set,
creates an explicit table lock */
dict_table_t
*
table
,
/* in: database table in dictionary cache */
ulint
mode
,
/* in: lock mode */
...
...
@@ -3608,7 +3618,8 @@ lock_table(
return
(
DB_SUCCESS
);
}
ut_a
(
flags
==
0
||
flags
==
LOCK_TABLE_EXP
);
ut_a
(
flags
==
0
||
flags
==
LOCK_TABLE_EXP
||
flags
==
LOCK_TABLE_TRANSACTIONAL
);
trx
=
thr_get_trx
(
thr
);
...
...
@@ -3631,7 +3642,7 @@ lock_table(
/* Another trx has a request on the table in an incompatible
mode: this trx may have to wait */
err
=
lock_table_enqueue_waiting
(
mode
,
table
,
thr
);
err
=
lock_table_enqueue_waiting
(
mode
|
flags
,
table
,
thr
);
lock_mutex_exit_kernel
();
...
...
@@ -3722,7 +3733,8 @@ lock_table_dequeue(
ut_ad
(
mutex_own
(
&
kernel_mutex
));
#endif
/* UNIV_SYNC_DEBUG */
ut_a
(
lock_get_type
(
in_lock
)
==
LOCK_TABLE
||
lock_get_type
(
in_lock
)
==
LOCK_TABLE_EXP
);
lock_get_type
(
in_lock
)
==
LOCK_TABLE_EXP
||
lock_get_type
(
in_lock
)
==
LOCK_TABLE_TRANSACTIONAL
);
lock
=
UT_LIST_GET_NEXT
(
un_member
.
tab_lock
.
locks
,
in_lock
);
...
...
@@ -3826,7 +3838,9 @@ lock_release_off_kernel(
}
lock_table_dequeue
(
lock
);
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
)
{
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
||
lock_get_type
(
lock
)
==
LOCK_TABLE_TRANSACTIONAL
)
{
ut_a
(
lock_get_mode
(
lock
)
==
LOCK_S
||
lock_get_mode
(
lock
)
==
LOCK_X
);
}
...
...
@@ -3850,6 +3864,7 @@ lock_release_off_kernel(
ut_a
(
trx
->
auto_inc_lock
==
NULL
);
ut_a
(
trx
->
n_lock_table_exp
==
0
);
ut_a
(
trx
->
n_lock_table_transactional
==
0
);
}
/*************************************************************************
...
...
@@ -3915,6 +3930,7 @@ lock_release_tables_off_kernel(
}
ut_a
(
trx
->
n_lock_table_exp
==
0
);
ut_a
(
trx
->
n_lock_table_transactional
==
0
);
}
/*************************************************************************
...
...
@@ -4028,11 +4044,15 @@ lock_table_print(
ut_ad
(
mutex_own
(
&
kernel_mutex
));
#endif
/* UNIV_SYNC_DEBUG */
ut_a
(
lock_get_type
(
lock
)
==
LOCK_TABLE
||
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
);
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
||
lock_get_type
(
lock
)
==
LOCK_TABLE_TRANSACTIONAL
);
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_EXP
)
{
fputs
(
"EXPLICIT "
,
file
);
}
else
if
(
lock_get_type
(
lock
)
==
LOCK_TABLE_TRANSACTIONAL
)
{
fputs
(
"TRANSACTIONAL "
,
file
);
}
fputs
(
"TABLE LOCK table "
,
file
);
ut_print_name
(
file
,
lock
->
trx
,
lock
->
un_member
.
tab_lock
.
table
->
name
);
fprintf
(
file
,
" trx id %lu %lu"
,
...
...
@@ -4418,6 +4438,7 @@ lock_table_queue_validate(
while
(
lock
)
{
ut_a
(((
lock
->
trx
)
->
conc_state
==
TRX_ACTIVE
)
||
((
lock
->
trx
)
->
conc_state
==
TRX_PREPARED
)
||
((
lock
->
trx
)
->
conc_state
==
TRX_COMMITTED_IN_MEMORY
));
if
(
!
lock_get_wait
(
lock
))
{
...
...
@@ -4465,6 +4486,7 @@ lock_rec_queue_validate(
while
(
lock
)
{
ut_a
(
lock
->
trx
->
conc_state
==
TRX_ACTIVE
||
lock
->
trx
->
conc_state
==
TRX_PREPARED
||
lock
->
trx
->
conc_state
==
TRX_COMMITTED_IN_MEMORY
);
...
...
@@ -4519,6 +4541,7 @@ lock_rec_queue_validate(
while
(
lock
)
{
ut_a
(
lock
->
trx
->
conc_state
==
TRX_ACTIVE
||
lock
->
trx
->
conc_state
==
TRX_PREPARED
||
lock
->
trx
->
conc_state
==
TRX_COMMITTED_IN_MEMORY
);
ut_a
(
trx_in_trx_list
(
lock
->
trx
));
...
...
@@ -4601,6 +4624,7 @@ loop:
ut_a
(
trx_in_trx_list
(
lock
->
trx
));
ut_a
(
lock
->
trx
->
conc_state
==
TRX_ACTIVE
||
lock
->
trx
->
conc_state
==
TRX_PREPARED
||
lock
->
trx
->
conc_state
==
TRX_COMMITTED_IN_MEMORY
);
for
(
i
=
nth_bit
;
i
<
lock_rec_get_n_bits
(
lock
);
i
++
)
{
...
...
innobase/row/row0mysql.c
View file @
8d63e069
...
...
@@ -784,7 +784,7 @@ row_lock_table_for_mysql(
table handle */
dict_table_t
*
table
,
/* in: table to lock, or NULL
if prebuilt->table should be
locked
as LOCK_TABLE_EXP |
locked
or a
prebuilt->select_lock_type */
ulint
mode
)
/* in: lock mode of table */
{
...
...
@@ -822,8 +822,14 @@ run_again:
if
(
table
)
{
err
=
lock_table
(
0
,
table
,
mode
,
thr
);
}
else
{
err
=
lock_table
(
LOCK_TABLE_EXP
,
prebuilt
->
table
,
prebuilt
->
select_lock_type
,
thr
);
if
(
mode
==
LOCK_TABLE_TRANSACTIONAL
)
{
err
=
lock_table
(
LOCK_TABLE_TRANSACTIONAL
,
prebuilt
->
table
,
prebuilt
->
select_lock_type
,
thr
);
}
else
{
err
=
lock_table
(
LOCK_TABLE_EXP
,
prebuilt
->
table
,
prebuilt
->
select_lock_type
,
thr
);
}
}
trx
->
error_state
=
err
;
...
...
innobase/trx/trx0trx.c
View file @
8d63e069
...
...
@@ -153,6 +153,7 @@ trx_create(
trx
->
auto_inc_lock
=
NULL
;
trx
->
n_lock_table_exp
=
0
;
trx
->
n_lock_table_transactional
=
0
;
trx
->
read_view_heap
=
mem_heap_create
(
256
);
trx
->
read_view
=
NULL
;
...
...
@@ -285,6 +286,7 @@ trx_free(
ut_a
(
!
trx
->
has_search_latch
);
ut_a
(
!
trx
->
auto_inc_lock
);
ut_a
(
!
trx
->
n_lock_table_exp
);
ut_a
(
!
trx
->
n_lock_table_transactional
);
ut_a
(
trx
->
dict_operation_lock_mode
==
0
);
...
...
@@ -1645,10 +1647,15 @@ trx_print(
putc
(
'\n'
,
f
);
if
(
trx
->
n_mysql_tables_in_use
>
0
||
trx
->
mysql_n_tables_locked
>
0
)
{
fprintf
(
f
,
"mysql tables in use %lu, locked %lu
\n
"
,
(
ulong
)
trx
->
n_mysql_tables_in_use
,
(
ulong
)
trx
->
mysql_n_tables_locked
);
}
fprintf
(
f
,
"mysql tables in use %lu, locked %lu
\n
"
,
(
ulong
)
trx
->
n_mysql_tables_in_use
,
(
ulong
)
trx
->
mysql_n_tables_locked
);
if
(
trx
->
n_lock_table_transactional
>
0
||
trx
->
n_lock_table_exp
>
0
)
{
fprintf
(
f
,
"mysql explicit table locks %lu, transactional table locks %lu
\n
"
,
(
ulong
)
trx
->
n_lock_table_exp
,
(
ulong
)
trx
->
n_lock_table_transactional
);
}
newline
=
TRUE
;
...
...
mysql-test/r/derived.result
View file @
8d63e069
...
...
@@ -330,3 +330,8 @@ SELECT MIN(price) min, MAX(price) max, AVG(price) avg FROM (SELECT SUBSTRING( MA
min max avg
10.00 10.00 10
DROP TABLE t1;
CREATE TABLE t1 (a char(10), b char(10));
INSERT INTO t1 VALUES ('root','localhost'), ('root','%');
SELECT * FROM (SELECT (SELECT a.a FROM t1 AS a WHERE a.a = b.a) FROM t1 AS b) AS c;
ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1;
mysql-test/t/derived.test
View file @
8d63e069
...
...
@@ -214,3 +214,16 @@ CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) N
insert
into
t1
values
(
128
,
'rozn'
,
2
,
now
(),
10
),(
128
,
'rozn'
,
1
,
now
(),
10
);
SELECT
MIN
(
price
)
min
,
MAX
(
price
)
max
,
AVG
(
price
)
avg
FROM
(
SELECT
SUBSTRING
(
MAX
(
concat
(
date_
,
";"
,
price
)),
12
)
price
FROM
t1
WHERE
itemid
=
128
AND
grpid
=
'rozn'
GROUP
BY
itemid
,
grpid
,
vendor
)
lastprices
;
DROP
TABLE
t1
;
#
# Test for bug #7413 "Subquery with non-scalar results participating in
# select list of derived table crashes server" aka "VIEW with sub query can
# cause the MySQL server to crash". If we have encountered problem during
# filling of derived table we should report error and perform cleanup
# properly.
#
CREATE
TABLE
t1
(
a
char
(
10
),
b
char
(
10
));
INSERT
INTO
t1
VALUES
(
'root'
,
'localhost'
),
(
'root'
,
'%'
);
--
error
1242
SELECT
*
FROM
(
SELECT
(
SELECT
a
.
a
FROM
t1
AS
a
WHERE
a
.
a
=
b
.
a
)
FROM
t1
AS
b
)
AS
c
;
DROP
TABLE
t1
;
sql/ha_innodb.cc
View file @
8d63e069
...
...
@@ -1356,7 +1356,8 @@ innobase_commit(
3. innobase_query_caching_of_table_permitted(),
4. innobase_savepoint(),
5. ::init_table_handle_for_HANDLER(),
6. innobase_start_trx_and_assign_read_view()
6. innobase_start_trx_and_assign_read_view(),
7. ::transactional_table_lock()
and it is only set to 0 in a commit or a rollback. If it is 0 we know
there cannot be resources to be freed and we could return immediately.
...
...
@@ -5134,8 +5135,9 @@ ha_innobase::start_stmt(
select_lock_type value. The value of
stored_select_lock_type was decided in:
1) ::store_lock(),
2) ::external_lock(), and
3) ::init_table_handle_for_HANDLER(). */
2) ::external_lock(),
3) ::init_table_handle_for_HANDLER(), and
4) :.transactional_table_lock(). */
prebuilt
->
select_lock_type
=
prebuilt
->
stored_select_lock_type
;
...
...
@@ -5326,6 +5328,94 @@ ha_innobase::external_lock(
DBUG_RETURN
(
0
);
}
/**********************************************************************
With this function MySQL request a transactional lock to a table when
user issued query LOCK TABLES..WHERE ENGINE = InnoDB. */
int
ha_innobase
::
transactional_table_lock
(
/*==================================*/
/* out: 0 */
THD
*
thd
,
/* in: handle to the user thread */
int
lock_type
)
/* in: lock type */
{
row_prebuilt_t
*
prebuilt
=
(
row_prebuilt_t
*
)
innobase_prebuilt
;
trx_t
*
trx
;
DBUG_ENTER
(
"ha_innobase::transactional_table_lock"
);
DBUG_PRINT
(
"enter"
,(
"lock_type: %d"
,
lock_type
));
/* We do not know if MySQL can call this function before calling
external_lock(). To be safe, update the thd of the current table
handle. */
update_thd
(
thd
);
if
(
prebuilt
->
table
->
ibd_file_missing
&&
!
current_thd
->
tablespace_op
)
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB error:
\n
"
"MySQL is trying to use a table handle but the .ibd file for
\n
"
"table %s does not exist.
\n
"
"Have you deleted the .ibd file from the database directory under
\n
"
"the MySQL datadir?"
"Look from section 15.1 of http://www.innodb.com/ibman.html
\n
"
"how you can resolve the problem.
\n
"
,
prebuilt
->
table
->
name
);
DBUG_RETURN
(
HA_ERR_CRASHED
);
}
trx
=
prebuilt
->
trx
;
prebuilt
->
sql_stat_start
=
TRUE
;
prebuilt
->
hint_need_to_fetch_extra_cols
=
0
;
prebuilt
->
read_just_key
=
0
;
prebuilt
->
keep_other_fields_on_keyread
=
FALSE
;
if
(
lock_type
==
F_WRLCK
)
{
prebuilt
->
select_lock_type
=
LOCK_X
;
prebuilt
->
stored_select_lock_type
=
LOCK_X
;
}
else
if
(
lock_type
==
F_RDLCK
)
{
prebuilt
->
select_lock_type
=
LOCK_S
;
prebuilt
->
stored_select_lock_type
=
LOCK_S
;
}
else
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB error:
\n
"
"MySQL is trying to set transactional table lock with corrupted lock type
\n
"
"to table %s, lock type %d does not exist.
\n
"
,
prebuilt
->
table
->
name
,
lock_type
);
DBUG_RETURN
(
HA_ERR_CRASHED
);
}
/* MySQL is setting a new transactional table lock */
/* Set the MySQL flag to mark that there is an active transaction */
thd
->
transaction
.
all
.
innodb_active_trans
=
1
;
if
(
thd
->
in_lock_tables
&&
thd
->
variables
.
innodb_table_locks
)
{
ulint
error
=
DB_SUCCESS
;
error
=
row_lock_table_for_mysql
(
prebuilt
,
NULL
,
LOCK_TABLE_TRANSACTIONAL
);
if
(
error
!=
DB_SUCCESS
)
{
error
=
convert_error_code_to_mysql
(
error
,
user_thd
);
DBUG_RETURN
(
error
);
}
if
(
thd
->
options
&
(
OPTION_NOT_AUTOCOMMIT
|
OPTION_BEGIN
))
{
/* Store the current undo_no of the transaction
so that we know where to roll back if we have
to roll back the next SQL statement */
trx_mark_sql_stat_end
(
trx
);
}
}
DBUG_RETURN
(
0
);
}
/****************************************************************************
Here we export InnoDB status variables to MySQL. */
...
...
sql/ha_innodb.h
View file @
8d63e069
...
...
@@ -150,6 +150,7 @@ class ha_innobase: public handler
int
discard_or_import_tablespace
(
my_bool
discard
);
int
extra
(
enum
ha_extra_function
operation
);
int
external_lock
(
THD
*
thd
,
int
lock_type
);
int
transactional_table_lock
(
THD
*
thd
,
int
lock_type
);
int
start_stmt
(
THD
*
thd
);
void
position
(
byte
*
record
);
...
...
sql/handler.h
View file @
8d63e069
...
...
@@ -454,6 +454,13 @@ public:
{
return
extra
(
operation
);
}
virtual
int
reset
()
{
return
extra
(
HA_EXTRA_RESET
);
}
virtual
int
external_lock
(
THD
*
thd
,
int
lock_type
)
{
return
0
;
}
/*
This is called to set transactional table lock to a table.
If the handler don't support this, then this function will
return HA_ERR_WRONG_COMMAND and MySQL will give
ER_ILLEGAL_HA error message.
*/
virtual
int
transactional_table_lock
(
THD
*
thd
,
int
lock_type
)
{
return
HA_ERR_WRONG_COMMAND
;}
virtual
void
unlock_row
()
{}
virtual
int
start_stmt
(
THD
*
thd
)
{
return
0
;}
/*
...
...
sql/lock.cc
View file @
8d63e069
...
...
@@ -79,7 +79,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
bool
unlock
,
TABLE
**
write_locked
);
static
int
lock_external
(
THD
*
thd
,
TABLE
**
table
,
uint
count
);
static
int
unlock_external
(
THD
*
thd
,
TABLE
**
table
,
uint
count
);
static
void
print_lock_error
(
int
error
);
static
void
print_lock_error
(
int
error
,
const
char
*
);
MYSQL_LOCK
*
mysql_lock_tables
(
THD
*
thd
,
TABLE
**
tables
,
uint
count
)
...
...
@@ -187,7 +187,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
(
*
tables
)
->
file
->
external_lock
(
thd
,
F_UNLCK
);
(
*
tables
)
->
current_lock
=
F_UNLCK
;
}
print_lock_error
(
error
);
print_lock_error
(
error
,
(
*
tables
)
->
file
->
table_type
()
);
DBUG_RETURN
(
error
);
}
else
...
...
@@ -380,7 +380,7 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
table
++
;
}
while
(
--
count
);
if
(
error_code
)
print_lock_error
(
error_code
);
print_lock_error
(
error_code
,
(
*
table
)
->
file
->
table_type
()
);
DBUG_RETURN
(
error_code
);
}
...
...
@@ -683,7 +683,7 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
}
static
void
print_lock_error
(
int
error
)
static
void
print_lock_error
(
int
error
,
const
char
*
table
)
{
int
textno
;
DBUG_ENTER
(
"print_lock_error"
);
...
...
@@ -695,11 +695,22 @@ static void print_lock_error(int error)
case
HA_ERR_READ_ONLY_TRANSACTION
:
textno
=
ER_READ_ONLY_TRANSACTION
;
break
;
case
HA_ERR_LOCK_DEADLOCK
:
textno
=
ER_LOCK_DEADLOCK
;
break
;
case
HA_ERR_WRONG_COMMAND
:
textno
=
ER_ILLEGAL_HA
;
break
;
default:
textno
=
ER_CANT_LOCK
;
break
;
}
my_error
(
textno
,
MYF
(
ME_BELL
+
ME_OLDWIN
+
ME_WAITTANG
),
error
);
if
(
textno
==
ER_ILLEGAL_HA
)
my_error
(
textno
,
MYF
(
ME_BELL
+
ME_OLDWIN
+
ME_WAITTANG
),
table
);
else
my_error
(
textno
,
MYF
(
ME_BELL
+
ME_OLDWIN
+
ME_WAITTANG
),
error
);
DBUG_VOID_RETURN
;
}
...
...
@@ -927,3 +938,62 @@ bool make_global_read_lock_block_commit(THD *thd)
thd
->
exit_cond
(
old_message
);
DBUG_RETURN
(
error
);
}
/*
Take transactional table lock for all tables in the list
SYNOPSIS
transactional_lock_tables
thd Thread THD
tables list of tables
counter number of tables in the list
NOTES
RETURN
0 - OK
-1 - error
*/
int
transactional_lock_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
,
uint
counter
)
{
uint
i
;
int
lock_type
,
error
=
0
;
TABLE_LIST
*
table
;
TABLE
**
start
,
**
ptr
;
DBUG_ENTER
(
"transactional_lock_tables"
);
if
(
!
(
ptr
=
start
=
(
TABLE
**
)
sql_alloc
(
sizeof
(
TABLE
*
)
*
counter
)))
return
-
1
;
for
(
table
=
tables
;
table
;
table
=
table
->
next_global
)
{
if
(
!
table
->
placeholder
()
&&
!
table
->
schema_table
)
*
(
ptr
++
)
=
table
->
table
;
}
for
(
i
=
1
;
i
<=
counter
;
i
++
,
start
++
)
{
DBUG_ASSERT
((
*
start
)
->
reginfo
.
lock_type
>=
TL_READ
);
lock_type
=
F_WRLCK
;
/* Lock exclusive */
if
((
*
start
)
->
db_stat
&
HA_READ_ONLY
||
((
*
start
)
->
reginfo
.
lock_type
>=
TL_READ
&&
(
*
start
)
->
reginfo
.
lock_type
<=
TL_READ_NO_INSERT
))
lock_type
=
F_RDLCK
;
if
((
error
=
(
*
start
)
->
file
->
transactional_table_lock
(
thd
,
lock_type
)))
{
print_lock_error
(
error
,
(
*
start
)
->
file
->
table_type
());
DBUG_RETURN
(
-
1
);
}
else
{
(
*
start
)
->
db_stat
&=
~
HA_BLOCK_LOCK
;
(
*
start
)
->
current_lock
=
lock_type
;
}
}
DBUG_RETURN
(
0
);
}
sql/mysql_priv.h
View file @
8d63e069
...
...
@@ -828,6 +828,7 @@ int open_tables(THD *thd, TABLE_LIST *tables, uint *counter);
int
simple_open_n_lock_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
);
bool
open_and_lock_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
);
int
lock_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
,
uint
counter
);
int
transactional_lock_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
,
uint
counter
);
TABLE
*
open_temporary_table
(
THD
*
thd
,
const
char
*
path
,
const
char
*
db
,
const
char
*
table_name
,
bool
link_in_list
);
bool
rm_temporary_table
(
enum
db_type
base
,
char
*
path
);
...
...
sql/sql_base.cc
View file @
8d63e069
...
...
@@ -1864,8 +1864,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
static
void
relink_tables_for_multidelete
(
THD
*
thd
)
{
if
(
thd
->
lex
->
all_selects_list
->
next_select_in_list
()
||
thd
->
lex
->
time_zone_tables_used
)
if
(
thd
->
lex
->
all_selects_list
->
next_select_in_list
())
{
for
(
SELECT_LEX
*
sl
=
thd
->
lex
->
all_selects_list
;
sl
;
...
...
sql/sql_lex.cc
View file @
8d63e069
...
...
@@ -30,15 +30,6 @@
*/
sys_var_long_ptr
trg_new_row_fake_var
(
0
,
0
);
/*
Fake table list object, pointer to which is used as special value for
st_lex::time_zone_tables_used indicating that we implicitly use time
zone tables in this statement but real table list was not yet created.
Pointer to it is also returned by my_tz_get_tables_list() as indication
of transient error;
*/
TABLE_LIST
fake_time_zone_tables_list
;
/* Macros to look like lex */
#define yyGet() *(lex->ptr++)
...
...
@@ -1911,6 +1902,31 @@ void st_lex::first_lists_tables_same()
}
/*
Add implicitly used time zone description tables to global table list
(if needed).
SYNOPSYS
st_lex::add_time_zone_tables_to_query_tables()
thd - pointer to current thread context
RETURN VALUE
TRUE - error
FALSE - success
*/
bool
st_lex
::
add_time_zone_tables_to_query_tables
(
THD
*
thd
)
{
/* We should not add these tables twice */
if
(
!
time_zone_tables_used
)
{
time_zone_tables_used
=
my_tz_get_table_list
(
thd
,
&
query_tables_last
);
if
(
time_zone_tables_used
==
&
fake_time_zone_tables_list
)
return
TRUE
;
}
return
FALSE
;
}
/*
Link table back that was unlinked with unlink_first_table()
...
...
sql/sql_lex.h
View file @
8d63e069
...
...
@@ -87,6 +87,7 @@ enum enum_sql_command {
SQLCOM_PREPARE
,
SQLCOM_EXECUTE
,
SQLCOM_DEALLOCATE_PREPARE
,
SQLCOM_CREATE_VIEW
,
SQLCOM_DROP_VIEW
,
SQLCOM_CREATE_TRIGGER
,
SQLCOM_DROP_TRIGGER
,
SQLCOM_LOCK_TABLES_TRANSACTIONAL
,
/* This should be the last !!! */
SQLCOM_END
};
...
...
@@ -735,9 +736,8 @@ typedef struct st_lex
/* Names of user variables holding parameters (in EXECUTE) */
List
<
LEX_STRING
>
prepared_stmt_params
;
/*
If points to fake_time_zone_tables_list indicates that time zone
tables are implicitly used by statement, also is used for holding
list of those tables after they are opened.
Points to part of global table list which contains time zone tables
implicitly used by the statement.
*/
TABLE_LIST
*
time_zone_tables_used
;
sp_head
*
sphead
;
...
...
@@ -802,6 +802,7 @@ typedef struct st_lex
*
(
table
->
prev_global
=
query_tables_last
)
=
table
;
query_tables_last
=
&
table
->
next_global
;
}
bool
add_time_zone_tables_to_query_tables
(
THD
*
thd
);
bool
can_be_merged
();
bool
can_use_merged
();
...
...
@@ -810,7 +811,6 @@ typedef struct st_lex
bool
need_correct_ident
();
}
LEX
;
extern
TABLE_LIST
fake_time_zone_tables_list
;
struct
st_lex_local
:
public
st_lex
{
static
void
*
operator
new
(
size_t
size
)
...
...
sql/sql_parse.cc
View file @
8d63e069
...
...
@@ -2123,19 +2123,6 @@ mysql_execute_command(THD *thd)
}
#endif
/* !HAVE_REPLICATION */
if
(
lex
->
time_zone_tables_used
)
{
TABLE_LIST
*
tmp
;
if
((
tmp
=
my_tz_get_table_list
(
thd
,
&
lex
->
query_tables_last
))
==
&
fake_time_zone_tables_list
)
{
DBUG_RETURN
(
-
1
);
}
lex
->
time_zone_tables_used
=
tmp
;
if
(
!
all_tables
)
all_tables
=
tmp
;
}
/*
When option readonly is set deny operations which change tables.
Except for the replication thread and the 'super' users.
...
...
@@ -3266,6 +3253,27 @@ create_error:
thd
->
options
&=
~
(
ulong
)
(
OPTION_TABLE_LOCK
);
thd
->
in_lock_tables
=
0
;
break
;
case
SQLCOM_LOCK_TABLES_TRANSACTIONAL
:
{
uint
counter
=
0
;
if
(
check_db_used
(
thd
,
all_tables
))
goto
error
;
if
(
check_table_access
(
thd
,
LOCK_TABLES_ACL
|
SELECT_ACL
,
all_tables
,
0
))
goto
error
;
thd
->
in_lock_tables
=
1
;
thd
->
options
|=
OPTION_TABLE_LOCK
;
if
(
open_tables
(
thd
,
all_tables
,
&
counter
)
==
0
&&
transactional_lock_tables
(
thd
,
all_tables
,
counter
)
==
0
)
send_ok
(
thd
);
else
thd
->
options
&=
~
(
ulong
)
(
OPTION_TABLE_LOCK
);
thd
->
in_lock_tables
=
0
;
break
;
}
case
SQLCOM_CREATE_DB
:
{
char
*
alias
;
...
...
sql/sql_yacc.yy
View file @
8d63e069
...
...
@@ -4269,7 +4269,8 @@ simple_expr:
{ $$= create_func_contains($3, $5); }
| CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
{
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
if (Lex->add_time_zone_tables_to_query_tables(YYTHD))
YYABORT;
$$= new Item_func_convert_tz($3, $5, $7);
}
| CURDATE optional_braces
...
...
@@ -7307,8 +7308,9 @@ internal_variable_name:
If this is time_zone variable we should open time zone
describing tables
*/
if (tmp == &sys_time_zone)
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
if (tmp == &sys_time_zone &&
lex->add_time_zone_tables_to_query_tables(YYTHD))
YYABORT;
}
else
{
...
...
@@ -7413,8 +7415,8 @@ lock:
{
Lex->sql_command=SQLCOM_LOCK_TABLES;
}
table_lock_list
{}
table_lock_list
lock_engine_opt
{}
;
table_or_tables:
...
...
@@ -7440,6 +7442,15 @@ lock_option:
| READ_SYM LOCAL_SYM { $$= TL_READ; }
;
lock_engine_opt:
/* empty */
| WHERE
{
Lex->sql_command=SQLCOM_LOCK_TABLES_TRANSACTIONAL;
}
ENGINE_SYM opt_equal storage_engines
;
unlock:
UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; }
;
...
...
sql/tztime.cc
View file @
8d63e069
...
...
@@ -1439,6 +1439,12 @@ tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
}
/*
Fake table list object, pointer to which is returned by
my_tz_get_tables_list() as indication of error.
*/
TABLE_LIST
fake_time_zone_tables_list
;
/*
Create table list with time zone related tables and add it to the end
of global table list.
...
...
sql/tztime.h
View file @
8d63e069
...
...
@@ -64,6 +64,7 @@ extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables);
extern
my_bool
my_tz_init
(
THD
*
org_thd
,
const
char
*
default_tzname
,
my_bool
bootstrap
);
extern
void
my_tz_free
();
extern
TABLE_LIST
fake_time_zone_tables_list
;
/*
Check if we have pointer to the beggining of list of implictly used
...
...
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