Commit f7e8f116 authored by marko's avatar marko

branches/zip: Merge revisions 3930:4005 from branches/5.1:

  ------------------------------------------------------------------------
  r4004 | marko | 2009-01-20 16:19:00 +0200 (Tue, 20 Jan 2009) | 12 lines

  branches/5.1: Merge r4003 from branches/5.0:

  rec_set_nth_field(): When the field already is SQL null,
  do nothing when it is being changed to SQL null. (Bug #41571)

  Normally, MySQL does not pass "do-nothing" updates to the storage engine.
  When it does and a column of an InnoDB table that is in ROW_FORMAT=COMPACT
  is being updated from NULL to NULL, the InnoDB buffer pool will be corrupted
  without this fix.

  rb://81 approved by Heikki Tuuri
  ------------------------------------------------------------------------
  r4005 | marko | 2009-01-20 16:22:36 +0200 (Tue, 20 Jan 2009) | 8 lines

  branches/5.1: lock_is_table_exclusive(): Acquire kernel_mutex before
  accessing table->locks and release kernel_mutex before returning from
  the function.  This fixes a portential race condition in the
  "commit every 10,000 rows" in ALTER TABLE, CREATE INDEX, DROP INDEX,
  and OPTIMIZE TABLE. (Bug #42152)

  rb://80 approved by Heikki Tuuri
  ------------------------------------------------------------------------
parent bdf341a2
......@@ -506,8 +506,9 @@ rec_offs_n_extern(
/***************************************************************
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
is UNIV_SQL_NULL then the field is treated as an SQL null for old-style
records. For new-style records, len must not be UNIV_SQL_NULL. */
is UNIV_SQL_NULL then the field is treated as an SQL null.
For records in ROW_FORMAT=COMPACT (new-style records), len must not be
UNIV_SQL_NULL unless the field already is SQL null. */
UNIV_INLINE
void
rec_set_nth_field(
......@@ -516,11 +517,7 @@ rec_set_nth_field(
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n, /* in: index number of the field */
const void* data, /* in: pointer to the data if not SQL null */
ulint len); /* in: length of the data or UNIV_SQL_NULL.
If not SQL null, must have the same
length as the previous value.
If SQL null, previous value must be
SQL null. */
ulint len); /* in: length of the data or UNIV_SQL_NULL */
/**************************************************************
The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields
......
......@@ -1326,8 +1326,9 @@ rec_get_nth_field_size(
/***************************************************************
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
is UNIV_SQL_NULL then the field is treated as an SQL null for old-style
records. For new-style records, len must not be UNIV_SQL_NULL. */
is UNIV_SQL_NULL then the field is treated as an SQL null.
For records in ROW_FORMAT=COMPACT (new-style records), len must not be
UNIV_SQL_NULL unless the field already is SQL null. */
UNIV_INLINE
void
rec_set_nth_field(
......@@ -1337,11 +1338,7 @@ rec_set_nth_field(
ulint n, /* in: index number of the field */
const void* data, /* in: pointer to the data
if not SQL null */
ulint len) /* in: length of the data or UNIV_SQL_NULL.
If not SQL null, must have the same
length as the previous value.
If SQL null, previous value must be
SQL null. */
ulint len) /* in: length of the data or UNIV_SQL_NULL */
{
byte* data2;
ulint len2;
......@@ -1349,9 +1346,11 @@ rec_set_nth_field(
ut_ad(rec);
ut_ad(rec_offs_validate(rec, NULL, offsets));
if (len == UNIV_SQL_NULL) {
ut_ad(!rec_offs_comp(offsets));
rec_set_nth_field_sql_null(rec, n);
if (UNIV_UNLIKELY(len == UNIV_SQL_NULL)) {
if (!rec_offs_nth_sql_null(offsets, n)) {
ut_a(!rec_offs_comp(offsets));
rec_set_nth_field_sql_null(rec, n);
}
return;
}
......
......@@ -699,7 +699,10 @@ lock_is_table_exclusive(
const lock_t* lock;
ibool ok = FALSE;
ut_ad(table && trx);
ut_ad(table);
ut_ad(trx);
lock_mutex_enter_kernel();
for (lock = UT_LIST_GET_FIRST(table->locks);
lock;
......@@ -707,7 +710,7 @@ lock_is_table_exclusive(
if (lock->trx != trx) {
/* A lock on the table is held
by some other transaction. */
return(FALSE);
goto not_ok;
}
if (!(lock_get_type_low(lock) & LOCK_TABLE)) {
......@@ -724,11 +727,16 @@ lock_is_table_exclusive(
auto_increment lock. */
break;
default:
not_ok:
/* Other table locks than LOCK_IX are not allowed. */
return(FALSE);
ok = FALSE;
goto func_exit;
}
}
func_exit:
lock_mutex_exit_kernel();
return(ok);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment