summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <elliot@mysql.com>2005-10-17 14:11:37 -0400
committerunknown <elliot@mysql.com>2005-10-17 14:11:37 -0400
commit955798d26a45203f7e1f4a69021329cb49c32e8a (patch)
tree1760b019111fabfb8eca0e642fae5b751f7e203e
parent06f10b7f05de93024a725731bd085dab94e89a3e (diff)
downloadmariadb-git-955798d26a45203f7e1f4a69021329cb49c32e8a.tar.gz
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. innobase/include/rem0rec.h: BUG#13900 DATETIME data changes after inserting a new row in a InnoDB table Applying patch from Marko. innobase/include/rem0rec.ic: BUG#13900 DATETIME data changes after inserting a new row in a InnoDB table Applying patch from Marko. innobase/row/row0upd.c: BUG#13900 DATETIME data changes after inserting a new row in a InnoDB table Applying patch from Marko.
-rw-r--r--innobase/include/rem0rec.h9
-rw-r--r--innobase/include/rem0rec.ic16
-rw-r--r--innobase/row/row0upd.c12
3 files changed, 37 insertions, 0 deletions
diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h
index 1d15b8d1c77..69b397c9682 100644
--- a/innobase/include/rem0rec.h
+++ b/innobase/include/rem0rec.h
@@ -312,6 +312,15 @@ rec_offs_nth_extern(
const ulint* offsets,/* in: array returned by rec_get_offsets() */
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. */
UNIV_INLINE
ulint
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index e2dceb6bae5..9c24f385f4f 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -955,6 +955,22 @@ rec_offs_nth_extern(
}
/**********************************************************
+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. */
UNIV_INLINE
ulint
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 4f44dbeae67..ff1ad1dfd05 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -395,6 +395,18 @@ row_upd_changes_field_size_or_external(
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) {
return(TRUE);