mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge from mysql-5.1-security to mysql-5.5-security.
This commit is contained in:
30
mysql-test/suite/innodb/r/innodb-autoinc-56228.result
Normal file
30
mysql-test/suite/innodb/r/innodb-autoinc-56228.result
Normal file
@@ -0,0 +1,30 @@
|
||||
DROP TABLE IF EXISTS t1_56228;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1_56228'
|
||||
DROP TABLE IF EXISTS t2_56228;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't2_56228'
|
||||
DROP FUNCTION IF EXISTS bug56228;
|
||||
Warnings:
|
||||
Note 1305 FUNCTION test.bug56228 does not exist
|
||||
CREATE TEMPORARY TABLE t1_56228(
|
||||
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TEMPORARY TABLE t2_56228(
|
||||
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC
|
||||
BEGIN
|
||||
INSERT INTO t1_56228 VALUES(NULL);
|
||||
INSERT INTO t2_56228 VALUES(NULL);
|
||||
INSERT INTO t1_56228 VALUES(NULL);
|
||||
INSERT INTO t2_56228 VALUES(NULL);
|
||||
DROP TEMPORARY TABLE t1_56228;
|
||||
RETURN 42;
|
||||
END //
|
||||
SELECT bug56228();
|
||||
bug56228()
|
||||
42
|
||||
DROP FUNCTION bug56228;
|
||||
DROP TEMPORARY TABLE t2_56228;
|
||||
DROP TEMPORARY TABLE IF EXISTS t1_56228;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1_56228'
|
@@ -0,0 +1 @@
|
||||
--innodb_autoinc_lock_mode=0
|
33
mysql-test/suite/innodb/t/innodb-autoinc-56228.test
Normal file
33
mysql-test/suite/innodb/t/innodb-autoinc-56228.test
Normal file
@@ -0,0 +1,33 @@
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
##
|
||||
# Bug #56228: dropping tables from within an active statement crashes server
|
||||
#
|
||||
DROP TABLE IF EXISTS t1_56228;
|
||||
DROP TABLE IF EXISTS t2_56228;
|
||||
DROP FUNCTION IF EXISTS bug56228;
|
||||
|
||||
CREATE TEMPORARY TABLE t1_56228(
|
||||
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TEMPORARY TABLE t2_56228(
|
||||
c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
|
||||
DELIMITER //;
|
||||
|
||||
CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC
|
||||
BEGIN
|
||||
INSERT INTO t1_56228 VALUES(NULL);
|
||||
INSERT INTO t2_56228 VALUES(NULL);
|
||||
INSERT INTO t1_56228 VALUES(NULL);
|
||||
INSERT INTO t2_56228 VALUES(NULL);
|
||||
DROP TEMPORARY TABLE t1_56228;
|
||||
RETURN 42;
|
||||
END //
|
||||
|
||||
DELIMITER ;//
|
||||
|
||||
SELECT bug56228();
|
||||
|
||||
DROP FUNCTION bug56228;
|
||||
DROP TEMPORARY TABLE t2_56228;
|
||||
DROP TEMPORARY TABLE IF EXISTS t1_56228;
|
@@ -93,6 +93,25 @@ ib_vector_get(
|
||||
ib_vector_t* vec, /*!< in: vector */
|
||||
ulint n); /*!< in: element index to get */
|
||||
|
||||
/****************************************************************//**
|
||||
Get last element. The vector must not be empty.
|
||||
@return last element */
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ib_vector_get_last(
|
||||
/*===============*/
|
||||
ib_vector_t* vec); /*!< in: vector */
|
||||
|
||||
/****************************************************************//**
|
||||
Set the n'th element. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ib_vector_set(
|
||||
/*==========*/
|
||||
ib_vector_t* vec, /*!< in/out: vector */
|
||||
ulint n, /*!< in: element index to set */
|
||||
void* elem); /*!< in: data element */
|
||||
|
||||
/****************************************************************//**
|
||||
Remove the last element from the vector. */
|
||||
UNIV_INLINE
|
||||
|
@@ -50,6 +50,35 @@ ib_vector_get(
|
||||
return(vec->data[n]);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Get last element. The vector must not be empty.
|
||||
@return last element */
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ib_vector_get_last(
|
||||
/*===============*/
|
||||
ib_vector_t* vec) /*!< in: vector */
|
||||
{
|
||||
ut_a(vec->used > 0);
|
||||
|
||||
return(vec->data[vec->used - 1]);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Set the n'th element. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ib_vector_set(
|
||||
/*==========*/
|
||||
ib_vector_t* vec, /*!< in/out: vector */
|
||||
ulint n, /*!< in: element index to set */
|
||||
void* elem) /*!< in: data element */
|
||||
{
|
||||
ut_a(n < vec->used);
|
||||
|
||||
vec->data[n] = elem;
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Remove the last element from the vector.
|
||||
@return last vector element */
|
||||
|
@@ -3621,6 +3621,80 @@ lock_table_create(
|
||||
return(lock);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Pops autoinc lock requests from the transaction's autoinc_locks. We
|
||||
handle the case where there are gaps in the array and they need to
|
||||
be popped off the stack. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
lock_table_pop_autoinc_locks(
|
||||
/*=========================*/
|
||||
trx_t* trx) /*!< in/out: transaction that owns the AUTOINC locks */
|
||||
{
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad(!ib_vector_is_empty(trx->autoinc_locks));
|
||||
|
||||
/* Skip any gaps, gaps are NULL lock entries in the
|
||||
trx->autoinc_locks vector. */
|
||||
|
||||
do {
|
||||
ib_vector_pop(trx->autoinc_locks);
|
||||
|
||||
if (ib_vector_is_empty(trx->autoinc_locks)) {
|
||||
return;
|
||||
}
|
||||
|
||||
} while (ib_vector_get_last(trx->autoinc_locks) == NULL);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Removes an autoinc lock request from the transaction's autoinc_locks. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
lock_table_remove_autoinc_lock(
|
||||
/*===========================*/
|
||||
lock_t* lock, /*!< in: table lock */
|
||||
trx_t* trx) /*!< in/out: transaction that owns the lock */
|
||||
{
|
||||
lock_t* autoinc_lock;
|
||||
lint i = ib_vector_size(trx->autoinc_locks) - 1;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad(lock_get_mode(lock) == LOCK_AUTO_INC);
|
||||
ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
|
||||
ut_ad(!ib_vector_is_empty(trx->autoinc_locks));
|
||||
|
||||
/* With stored functions and procedures the user may drop
|
||||
a table within the same "statement". This special case has
|
||||
to be handled by deleting only those AUTOINC locks that were
|
||||
held by the table being dropped. */
|
||||
|
||||
autoinc_lock = ib_vector_get(trx->autoinc_locks, i);
|
||||
|
||||
/* This is the default fast case. */
|
||||
|
||||
if (autoinc_lock == lock) {
|
||||
lock_table_pop_autoinc_locks(trx);
|
||||
} else {
|
||||
/* The last element should never be NULL */
|
||||
ut_a(autoinc_lock != NULL);
|
||||
|
||||
/* Handle freeing the locks from within the stack. */
|
||||
|
||||
while (--i >= 0) {
|
||||
autoinc_lock = ib_vector_get(trx->autoinc_locks, i);
|
||||
|
||||
if (UNIV_LIKELY(autoinc_lock == lock)) {
|
||||
ib_vector_set(trx->autoinc_locks, i, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Must find the autoinc lock. */
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Removes a table lock request from the queue and the trx list of locks;
|
||||
this is a low-level function which does NOT check if waiting requests
|
||||
@@ -3660,10 +3734,8 @@ lock_table_remove_low(
|
||||
|
||||
if (!lock_get_wait(lock)
|
||||
&& !ib_vector_is_empty(trx->autoinc_locks)) {
|
||||
lock_t* autoinc_lock;
|
||||
|
||||
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
|
||||
ut_a(autoinc_lock == lock);
|
||||
lock_table_remove_autoinc_lock(lock, trx);
|
||||
}
|
||||
|
||||
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);
|
||||
|
Reference in New Issue
Block a user