Commit d7189ee8 authored by elliot@mysql.com's avatar elliot@mysql.com

BUG#13900 DATETIME data changes after inserting a new row in a InnoDB table

Applying patch from Marko.
All tests pass in pentium-debug-max build on Linux.
parent 1cb37294
...@@ -312,6 +312,15 @@ rec_offs_nth_extern( ...@@ -312,6 +312,15 @@ rec_offs_nth_extern(
const ulint* offsets,/* in: array returned by rec_get_offsets() */ const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n); /* in: nth field */ ulint n); /* in: nth field */
/********************************************************** /**********************************************************
Returns nonzero if the SQL NULL bit is set in nth field of rec. */
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
/* out: nonzero if SQL NULL */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n); /* in: nth field */
/**********************************************************
Gets the physical size of a field. */ Gets the physical size of a field. */
UNIV_INLINE UNIV_INLINE
ulint ulint
......
...@@ -954,6 +954,22 @@ rec_offs_nth_extern( ...@@ -954,6 +954,22 @@ rec_offs_nth_extern(
& REC_OFFS_EXTERNAL)); & REC_OFFS_EXTERNAL));
} }
/**********************************************************
Returns nonzero if the SQL NULL bit is set in nth field of rec. */
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
/* out: nonzero if SQL NULL */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n) /* in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
return(UNIV_UNLIKELY(rec_offs_base(offsets)[1 + n]
& REC_OFFS_SQL_NULL));
}
/********************************************************** /**********************************************************
Gets the physical size of a field. */ Gets the physical size of a field. */
UNIV_INLINE UNIV_INLINE
......
...@@ -395,6 +395,18 @@ row_upd_changes_field_size_or_external( ...@@ -395,6 +395,18 @@ row_upd_changes_field_size_or_external(
old_len = rec_offs_nth_size(offsets, upd_field->field_no); old_len = rec_offs_nth_size(offsets, upd_field->field_no);
if (rec_offs_comp(offsets)
&& rec_offs_nth_sql_null(offsets, upd_field->field_no)) {
/* Note that in the compact table format, for a
variable length field, an SQL NULL will use zero
bytes in the offset array at the start of the physical
record, but a zero-length value (empty string) will
use one byte! Thus, we cannot use update-in-place
if we update an SQL NULL varchar to an empty string! */
old_len = UNIV_SQL_NULL;
}
if (old_len != new_len) { if (old_len != new_len) {
return(TRUE); return(TRUE);
......
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