summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorJonathan Perkin <jonathan.perkin@oracle.com>2011-02-08 14:59:03 +0100
committerJonathan Perkin <jonathan.perkin@oracle.com>2011-02-08 14:59:03 +0100
commitf13788c9fd8af035dd9a5af446d8a88214760fdc (patch)
treed87bb4b1cece4e1570ba257393e94057e79bd518 /storage
parent8805ecee531f048726382fdd47cb2b59d8d6a711 (diff)
parent31e87bb552b5a36b25cb14c2c6f380a06cfd981c (diff)
downloadmariadb-git-f13788c9fd8af035dd9a5af446d8a88214760fdc.tar.gz
Merge from mysql-5.5.9-release
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/dict/dict0dict.c10
-rw-r--r--storage/innobase/handler/ha_innodb.cc11
-rw-r--r--storage/innobase/handler/i_s.cc11
-rw-r--r--storage/innobase/include/univ.i12
-rw-r--r--storage/innobase/include/ut0vec.h19
-rw-r--r--storage/innobase/include/ut0vec.ic29
-rw-r--r--storage/innobase/lock/lock0lock.c78
-rw-r--r--storage/innobase/row/row0merge.c4
8 files changed, 154 insertions, 20 deletions
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index f98d3dbc639..ebc7747640e 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -949,7 +949,7 @@ dict_table_rename_in_cache(
dict_foreign_t* foreign;
dict_index_t* index;
ulint fold;
- char old_name[MAX_TABLE_NAME_LEN + 1];
+ char old_name[MAX_FULL_NAME_LEN + 1];
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -961,7 +961,7 @@ dict_table_rename_in_cache(
ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", table->name,
- MAX_TABLE_NAME_LEN);
+ MAX_FULL_NAME_LEN);
ut_error;
}
@@ -1011,11 +1011,11 @@ dict_table_rename_in_cache(
ut_fold_string(old_name), table);
if (strlen(new_name) > strlen(table->name)) {
- /* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid
+ /* We allocate MAX_FULL_NAME_LEN + 1 bytes here to avoid
memory fragmentation, we assume a repeated calls of
ut_realloc() with the same size do not cause fragmentation */
- ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN);
- table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1);
+ ut_a(strlen(new_name) <= MAX_FULL_NAME_LEN);
+ table->name = ut_realloc(table->name, MAX_FULL_NAME_LEN + 1);
}
memcpy(table->name, new_name, strlen(new_name) + 1);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 8565809c09f..daeaca90aec 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -6236,6 +6236,17 @@ create_table_def(
DBUG_RETURN(HA_ERR_GENERIC);
}
+ /* MySQL does the name length check. But we do additional check
+ on the name length here */
+ if (strlen(table_name) > MAX_FULL_NAME_LEN) {
+ push_warning_printf(
+ (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TABLE_NAME,
+ "InnoDB: Table Name or Database Name is too long");
+
+ DBUG_RETURN(ER_TABLE_NAME);
+ }
+
n_cols = form->s->fields;
/* We pass 0 as the space id, and determine at a lower level the space
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 709274bab16..00aced180ce 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -767,16 +767,7 @@ fill_innodb_locks_from_cache(
for (i = 0; i < rows_num; i++) {
i_s_locks_row_t* row;
-
- /* note that the decoded database or table name is
- never expected to be longer than NAME_LEN;
- NAME_LEN for database name
- 2 for surrounding quotes around database name
- NAME_LEN for table name
- 2 for surrounding quotes around table name
- 1 for the separating dot (.)
- 9 for the #mysql50# prefix */
- char buf[2 * NAME_LEN + 14];
+ char buf[MAX_FULL_NAME_LEN + 1];
const char* bufend;
char lock_trx_id[TRX_ID_MAX_LEN + 1];
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 6d69082e5b5..f8c2d3c1a18 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -308,6 +308,18 @@ number does not include a terminating '\0'. InnoDB probably can handle
longer names internally */
#define MAX_TABLE_NAME_LEN 192
+/* The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is
+the MySQL's NAME_LEN, see check_and_convert_db_name(). */
+#define MAX_DATABASE_NAME_LEN MAX_TABLE_NAME_LEN
+
+/* MAX_FULL_NAME_LEN defines the full name path including the
+database name and table name. In addition, 14 bytes is added for:
+ 2 for surrounding quotes around table name
+ 1 for the separating dot (.)
+ 9 for the #mysql50# prefix */
+#define MAX_FULL_NAME_LEN \
+ (MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14)
+
/*
UNIVERSAL TYPE DEFINITIONS
==========================
diff --git a/storage/innobase/include/ut0vec.h b/storage/innobase/include/ut0vec.h
index a770f671cfc..0f8b955b098 100644
--- a/storage/innobase/include/ut0vec.h
+++ b/storage/innobase/include/ut0vec.h
@@ -94,6 +94,25 @@ ib_vector_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. */
UNIV_INLINE
void*
diff --git a/storage/innobase/include/ut0vec.ic b/storage/innobase/include/ut0vec.ic
index 02e881f9bca..34c858868ce 100644
--- a/storage/innobase/include/ut0vec.ic
+++ b/storage/innobase/include/ut0vec.ic
@@ -51,6 +51,35 @@ ib_vector_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 */
+{
+ 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 */
UNIV_INLINE
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index f38ef48df4e..ceb4e89c08a 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -3622,6 +3622,80 @@ lock_table_create(
}
/*************************************************************//**
+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
can now be granted. */
@@ -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);
diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c
index 9827141caec..03e37a8c4a4 100644
--- a/storage/innobase/row/row0merge.c
+++ b/storage/innobase/row/row0merge.c
@@ -2388,7 +2388,7 @@ row_merge_rename_tables(
{
ulint err = DB_ERROR;
pars_info_t* info;
- char old_name[MAX_TABLE_NAME_LEN + 1];
+ char old_name[MAX_FULL_NAME_LEN + 1];
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
ut_ad(old_table != new_table);
@@ -2403,7 +2403,7 @@ row_merge_rename_tables(
ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", old_table->name,
- MAX_TABLE_NAME_LEN);
+ MAX_FULL_NAME_LEN);
ut_error;
}