Bug #45608 Checksums Without Null Bits
Submitted: 19 Jun 2009 10:41 Modified: 26 Jun 2009 13:45
Reporter: Mikiya Okuno Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: General Severity:S4 (Feature request)
Version:5.1.35 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[19 Jun 2009 10:41] Mikiya Okuno
Description:
CHECKSUM TABLE command is useful when people want to know if two tables are identical or not. However, even if two tables have identical data, checksum may differ when one table has nullable fields and the other doesn't. If there are nullable field, null bits are taken into account, thus checksum may differ.

If the row is fully populated and the user wants to compare data only, MySQL should compare data only without null bytes.

How to repeat:
n/a

Suggested fix:
--- mysql-5.1.34-normal/sql/sql_table.cc	2009-05-31 16:08:04.000000000 +0900
+++ mysql-5.1.34-patched/sql/sql_table.cc	2009-06-19 19:30:05.000000000 +0900
@@ -7503,7 +7503,32 @@
               if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
                 t->record[0][0] |= 1;
 
-	      row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
+              my_bool no_null = TRUE;
+              if(t->s->null_bytes == 1) {
+                /* null_mask | x bit */
+                uchar b_mask = null_mask | 1;
+                if(b_mask != t->record[0][0])
+                  no_null = FALSE;
+              }
+              else
+              {
+                if((t->record[0][0] == 1) &&
+                    (t->record[0][t->s->null_bytes-1] == null_mask))
+                {
+                  for(uint i= 1; i < t->s->null_bytes-1; i++)
+                  {
+                    if(t->record[0][i] != 0)
+                    {
+                      no_null = FALSE;
+                      break;
+                    }
+                  }
+                }
+              }
+              if(!no_null)
+              {
+	              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
+              }
             }
 
 	    for (uint i= 0; i < t->s->fields; i++ )