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 */
|
ib_vector_t* vec, /*!< in: vector */
|
||||||
ulint n); /*!< in: element index to get */
|
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. */
|
Remove the last element from the vector. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
@@ -50,6 +50,35 @@ ib_vector_get(
|
|||||||
return(vec->data[n]);
|
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.
|
Remove the last element from the vector.
|
||||||
@return last vector element */
|
@return last vector element */
|
||||||
|
@@ -3621,6 +3621,80 @@ lock_table_create(
|
|||||||
return(lock);
|
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;
|
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
|
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)
|
if (!lock_get_wait(lock)
|
||||||
&& !ib_vector_is_empty(trx->autoinc_locks)) {
|
&& !ib_vector_is_empty(trx->autoinc_locks)) {
|
||||||
lock_t* autoinc_lock;
|
|
||||||
|
|
||||||
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
|
lock_table_remove_autoinc_lock(lock, trx);
|
||||||
ut_a(autoinc_lock == lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);
|
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);
|
||||||
|
Reference in New Issue
Block a user