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( ...@@ -506,8 +506,9 @@ rec_offs_n_extern(
/*************************************************************** /***************************************************************
This is used to modify the value of an already existing field in a record. 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 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 is UNIV_SQL_NULL then the field is treated as an SQL null.
records. For new-style records, len must not be UNIV_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 UNIV_INLINE
void void
rec_set_nth_field( rec_set_nth_field(
...@@ -516,11 +517,7 @@ rec_set_nth_field( ...@@ -516,11 +517,7 @@ rec_set_nth_field(
const ulint* offsets,/* in: array returned by rec_get_offsets() */ const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n, /* in: index number of the field */ ulint n, /* in: index number of the field */
const void* data, /* in: pointer to the data if not SQL null */ const void* data, /* in: pointer to the data if not SQL null */
ulint len); /* in: length of the data or UNIV_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. */
/************************************************************** /**************************************************************
The following function returns the data size of an old-style physical The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields record, that is the sum of field lengths. SQL null fields
......
...@@ -1326,8 +1326,9 @@ rec_get_nth_field_size( ...@@ -1326,8 +1326,9 @@ rec_get_nth_field_size(
/*************************************************************** /***************************************************************
This is used to modify the value of an already existing field in a record. 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 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 is UNIV_SQL_NULL then the field is treated as an SQL null.
records. For new-style records, len must not be UNIV_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 UNIV_INLINE
void void
rec_set_nth_field( rec_set_nth_field(
...@@ -1337,11 +1338,7 @@ rec_set_nth_field( ...@@ -1337,11 +1338,7 @@ rec_set_nth_field(
ulint n, /* in: index number of the field */ ulint n, /* in: index number of the field */
const void* data, /* in: pointer to the data const void* data, /* in: pointer to the data
if not SQL null */ if not SQL null */
ulint len) /* in: length of the data or UNIV_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. */
{ {
byte* data2; byte* data2;
ulint len2; ulint len2;
...@@ -1349,9 +1346,11 @@ rec_set_nth_field( ...@@ -1349,9 +1346,11 @@ rec_set_nth_field(
ut_ad(rec); ut_ad(rec);
ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_offs_validate(rec, NULL, offsets));
if (len == UNIV_SQL_NULL) { if (UNIV_UNLIKELY(len == UNIV_SQL_NULL)) {
ut_ad(!rec_offs_comp(offsets)); if (!rec_offs_nth_sql_null(offsets, n)) {
rec_set_nth_field_sql_null(rec, n); ut_a(!rec_offs_comp(offsets));
rec_set_nth_field_sql_null(rec, n);
}
return; return;
} }
......
...@@ -699,7 +699,10 @@ lock_is_table_exclusive( ...@@ -699,7 +699,10 @@ lock_is_table_exclusive(
const lock_t* lock; const lock_t* lock;
ibool ok = FALSE; 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); for (lock = UT_LIST_GET_FIRST(table->locks);
lock; lock;
...@@ -707,7 +710,7 @@ lock_is_table_exclusive( ...@@ -707,7 +710,7 @@ lock_is_table_exclusive(
if (lock->trx != trx) { if (lock->trx != trx) {
/* A lock on the table is held /* A lock on the table is held
by some other transaction. */ by some other transaction. */
return(FALSE); goto not_ok;
} }
if (!(lock_get_type_low(lock) & LOCK_TABLE)) { if (!(lock_get_type_low(lock) & LOCK_TABLE)) {
...@@ -724,11 +727,16 @@ lock_is_table_exclusive( ...@@ -724,11 +727,16 @@ lock_is_table_exclusive(
auto_increment lock. */ auto_increment lock. */
break; break;
default: default:
not_ok:
/* Other table locks than LOCK_IX are not allowed. */ /* Other table locks than LOCK_IX are not allowed. */
return(FALSE); ok = FALSE;
goto func_exit;
} }
} }
func_exit:
lock_mutex_exit_kernel();
return(ok); 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