List:Commits« Previous MessageNext Message »
From:tim Date:November 6 2007 10:43pm
Subject:bk commit into 5.1 tree (tsmith:1.2604) BUG#30706
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tsmith. When tsmith does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-11-06 15:42:58-07:00, tsmith@stripped +31 -0
  Apply snapshot innodb-5.1-ss1989
  
  Fixes the following bugs:
  
  Bug #30706: SQL thread on slave is allowed to block client queries when slave load is high
    Add (innodb|innobase|srv)_replication_delay MySQL config parameter.
  
  Bug #30888: Innodb table + stored procedure + row deletion = server crash
    While adding code for the low level read of the AUTOINC value from the index,
    the case for MEDIUM ints which are 3 bytes was missed triggering an
    assertion.
  
  Bug #30907: Regression: "--innodb_autoinc_lock_mode=0" (off) not same as older releases
    We don't rely on *first_value to be 0 when checking whether
    get_auto_increment() has been invoked for the first time in a multi-row
    INSERT. We instead use trx_t::n_autoinc_rows. Initialize trx::n_autoinc_rows
    inside ha_innobase::start_stmt() too.
  
  Bug #31444: "InnoDB: Error: MySQL is freeing a thd" in innodb_mysql.test
    ha_innobase::external_lock(): Update prebuilt->mysql_has_locked and
    trx->n_mysql_tables_in_use only after row_lock_table_for_mysql() returns
    DB_SUCCESS.  A timeout on LOCK TABLES would lead to an inconsistent state,
    which would cause trx_free() to print a warning.
  
  Bug #31494: innodb + 5.1 + read committed crash, assertion
    Set an error code when a deadlock occurs in semi-consistent read.

  mysql-test/r/innodb-semi-consistent.result@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +36 -0
    Apply snapshot innodb-5.1-ss1989
    
    
    Revision r1988:
    Set an error code when a deadlock occurs in semi-consistent read.  (Bug #31494)
    
    innodb-semi-consistent: New tests for InnoDB semi-consistent reads.
    Unfortunately, these will not trigger Bug #31494, because there merely
    occur lock wait timeouts, not deadlocks.

  mysql-test/r/innodb-semi-consistent.result@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +0 -0

  mysql-test/r/innodb.result@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +36 -40
    Apply snapshot innodb-5.1-ss1989
    
    Also, a test is moved into the new innodb_autoinc_lock_mode_zero
    test, because it depends on a non-default setting for a read-only
    variable.
    
    Revision r1821:
    Merge a change from MySQL AB:
    
    ChangeSet@stripped  2007-08-02 12:45:56-07:00  igor@stripped
    
    Fixed bug#28404.
    This patch adds cost estimation for the queries with ORDER BY / GROUP BY
    and LIMIT.
    If there was a ref/range access to the table whose rows were required
    to be ordered in the result set the optimizer always employed this access
    though a scan by a different index that was compatible with the required
    order could be cheaper to produce the first L rows of the result set.
    Now for such queries the optimizer makes a choice between the cheapest
    ref/range accesses not compatible with the given order and index scans
    compatible with it.
    
    innodb.result: Adjusted results for test cases affected fy the fix for
    bug #28404.
    
    
    Revision r1781:
    Fix a test case that was broken after Bug#16979 fix. See r1645 and r1735.
    The variable used in the tests below was introduced in r1735.
    
    
    Revision r1792:
    innodb.result: Revert r1655, which should have been reverted as part of r1781.
    
    
    Revision r1843:
    Add test for Bug# 21409, the actual bug was fixed in r1334.

  mysql-test/r/innodb_autoinc_lock_mode_zero.result@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +39 -0
    New test, using read-only setting --innodb-autoinc-lock-mode=0

  mysql-test/r/innodb_autoinc_lock_mode_zero.result@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +0 -0

  mysql-test/t/innodb-semi-consistent-master.opt@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +1 -0
    Apply snapshot innodb-5.1-ss1989
    
    
    Revision r1988:
    Set an error code when a deadlock occurs in semi-consistent read.  (Bug #31494)
    
    innodb-semi-consistent: New tests for InnoDB semi-consistent reads.
    Unfortunately, these will not trigger Bug #31494, because there merely
    occur lock wait timeouts, not deadlocks.

  mysql-test/t/innodb-semi-consistent-master.opt@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +0 -0

  mysql-test/t/innodb-semi-consistent.test@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +46 -0
    Apply snapshot innodb-5.1-ss1989
    
    
    Revision r1988:
    Set an error code when a deadlock occurs in semi-consistent read.  (Bug #31494)
    
    innodb-semi-consistent: New tests for InnoDB semi-consistent reads.
    Unfortunately, these will not trigger Bug #31494, because there merely
    occur lock wait timeouts, not deadlocks.

  mysql-test/t/innodb-semi-consistent.test@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +0 -0

  mysql-test/t/innodb.test@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +42 -33
    Apply snapshot innodb-5.1-ss1989
    
    Also, a test is moved into the new innodb_autoinc_lock_mode_zero
    test, because it depends on a non-default setting for a read-only
    variable.
    
    Revision r1781:
    Fix a test case that was broken after Bug#16979 fix. See r1645 and r1735.
    The variable used in the tests below was introduced in r1735.
    
    
    Revision r1843:
    Add test for Bug# 21409, the actual bug was fixed in r1334.

  mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +1 -0
    New test, using read-only setting --innodb-autoinc-lock-mode=0

  mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +0 -0

  mysql-test/t/innodb_autoinc_lock_mode_zero.test@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +44 -0
    New test, using read-only setting --innodb-autoinc-lock-mode=0

  mysql-test/t/innodb_autoinc_lock_mode_zero.test@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +0 -0

  storage/innobase/buf/buf0lru.c@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +1 -1
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1819:
    Merge r1815:1817 from branches/zip: Improve Valgrind instrumentation.
    
    UNIV_MEM_ASSERT_RW(): New macro, to check that the contents of a memory
    area is defined.
    
    UNIV_MEM_ASSERT_W(): New macro, to check that a memory area is writable.
    
    UNIV_MEM_ASSERT_AND_FREE(): New macro, to check that the memory is
    writable before declaring it free (unwritable).  This replaces UNIV_MEM_FREE()
    in many places.
    
    mem_init_buf(): Check that the memory is writable, and declare it undefined.
    
    mem_erase_buf(): Check that the memory is writable, and declare it freed.

  storage/innobase/dict/dict0dict.c@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +4 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1894:
    Add debug lock checks to autoinc functions. Add lock guards around an
    invocation of dict_table_autoinc_initialize().

  storage/innobase/dict/dict0load.c@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +46 -32
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1974:
    Prevent loading of tables that have unsupported features most notably
    FTS indexes.

  storage/innobase/handler/ha_innodb.cc@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +67 -31
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1850:
    Implement this feature request:
    http://bugs.mysql.com/30706
    
    * Add a function that returns the number of microseconds since
      epoch - ut_time_us().
    
    * Add (innodb|innobase|srv)_replication_delay MySQL config parameter.
    
    * Add UT_WAIT_FOR() macro that waits for a specified condition to occur
      until a timeout elapses.
    
    * Using all of the above, handle the replication thread specially in
      srv_conc_enter_innodb().
    
    Approved by:	Heikki
    
    
    
    Revision r1887:
    Merge changes from MySQL AB:
    
    ChangeSet@stripped  2007-08-27 18:18:14-06:00  tsmith@stripped
    
    Fix some Windows compiler warnings.
    
    dict0mem.c: Fix compiler warning with a cast.
    
    ha_innodb.cc: Change type to fix a compiler warning.
    
    
    Revision r1809:
    ha_innobase::external_lock(): Update prebuilt->mysql_has_locked and
    trx->n_mysql_tables_in_use only after row_lock_table_for_mysql()
    returns DB_SUCCESS.  A timeout on LOCK TABLES would lead to an
    inconsistent state, which would cause trx_free() to print a warning.
    
    This was later reported as Bug #31444.
    
    
    Revision r1833:
    Add /*== ... === */ decoration that was missing around some auto-inc functions.
    Add a missing comment, fix the length of a decoration.  Initialize the *value
    out parameter in ha_innobase::innobase_get_auto_increment().
    
    
    Revision r1866:
    Revert r1850 as MySQL did not approve the addition.
    
    log for r1850:
    
    Implement this feature request:
    http://bugs.mysql.com/30706
    
    * Add a function that returns the number of microseconds since
      epoch - ut_time_us().
    
    * Add (innodb|innobase|srv)_replication_delay MySQL config parameter.
    
    * Add UT_WAIT_FOR() macro that waits for a specified condition to occur
      until a timeout elapses.
    
    * Using all of the above, handle the replication thread specially in
      srv_conc_enter_innodb().
    
    
    Revision r1846:
    Add config option innodb_use_adaptive_hash_indexes to enable/disable
    adaptive hash indexes. It is enabled by default (no change in default
    behavior).
    
    Approved by:	Marko
    
    
    Revision r1974:
    Prevent loading of tables that have unsupported features most notably
    FTS indexes.
    
    
    Revision r1829:
    Add assertion to enforce check of an implicit invariant and add comment about
    retry of autoinc read semantics. We always reread the table's autoinc counter
    after attempting to initialize it i.e., we want to guarantee that a read of
    autoinc valus that is returned to the caller is always covered by the
    AUTOINC locking mechanism.
    
    
    Revision r1787:
    Move the prototype of innobase_print_identifier() from ut0ut.c to
    ha_prototypes.h.  Enclose the definitions in ha_prototypes.h in
    #ifndef UNIV_HOTBACKUP.
    
    
    Revision r1888:
    Merge a change from MySQL AB:
    
    ChangeSet@stripped  2007-08-28 10:17:15-06:00  tsmith@stripped
    
    Fix another compiler warning on Windows in InnoDB.
    
    ha_innodb.cc:
    
    Fix compiler warning: ::get_auto_increment takes a ulonglong
    for nb_desired_values, but InnoDB's trx struct stores it as
    a ulint (unsigned long).  Probably harmless, as a single
    statement won't be asking for more than 2^32 rows.
    
    
    Revision r1987:
    Bug fix: The problem was that when write_row() attempted to update the max
    autoinc value, and if it was rolled back because of a deadlock, the 
    deadlock error (transaction rollback) was not being propagated back to MySQL.
    
    
    Revision r1889:
    Merge a change from MySQL AB:
    
    ChangeSet@stripped  2007-09-21 10:15:16+02:00  gkodinov@local
    
    ha_innodb.cc: fixed type conversion warnings revealed by bug 30639 
    
    
    Revision r1989:
    Suppress printing of deadlock errors while reading the autoinc value.
    DB_DEADLOCK errors are part of normal processing and excessive printing
    of these error messages could be disconcerting for users. 
    
    
    Revision r1828:
    Fix two bugs:
    
    Bug# 30907: We don't rely on *first_value to be 0 when checking whether
    get_auto_increment() has been invoked for the first time in a multi-row
    INSERT. We instead use trx_t::n_autoinc_rows. Initialize trx::n_autoinc_rows
    inside ha_innobase::start_stmt() too.
    
    Bug# 30888: While adding code for the low level read of the AUTOINC value
    from the index, the case for MEDIUM ints which are 3 bytes was missed
    triggering an assertion.

  storage/innobase/handler/ha_innodb.h@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +0 -14
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1844:
    Remove the prototypes of some functions inside #if 0.
    The function definitions were removed in r1746.

  storage/innobase/ibuf/ibuf0ibuf.c@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +2 -2
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1965:
    ibuf_insert_to_index_page(): Fix typos in diagnostic output.

  storage/innobase/include/db0err.h@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +4 -2
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1974:
    Prevent loading of tables that have unsupported features most notably
    FTS indexes.

  storage/innobase/include/ha_prototypes.h@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +16 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1787:
    Move the prototype of innobase_print_identifier() from ut0ut.c to
    ha_prototypes.h.  Enclose the definitions in ha_prototypes.h in
    #ifndef UNIV_HOTBACKUP.

  storage/innobase/include/mach0data.h@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +11 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1779:
    Fix a bug that handles the case where the host specific byte order matches
    the InnoDB storage byte order, which is big-endian.

  storage/innobase/include/mach0data.ic@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +37 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1779:
    Fix a bug that handles the case where the host specific byte order matches
    the InnoDB storage byte order, which is big-endian.

  storage/innobase/include/mem0dbg.h@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +8 -8
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1830:
    Improve memory debugging.  This is follow-up to r1819.
    
    mem_heap_validate(): Compile this function also if UNIV_MEM_DEBUG is
    defined.  Previously, this function was only compiled with UNIV_DEBUG.
    
    mem_heap_free_heap_top(): Flag the memory allocated, not freed, for
    Valgrind.  Otherwise, Valgrind would complain on the second call of
    mem_heap_empty().
    
    UNIV_MEM_ASSERT_RW(), UNIV_MEM_ASSERT_W(): Display additional diagnostics
    for failed Valgrind checks.

  storage/innobase/include/mem0mem.ic@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +9 -7
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1830:
    Improve memory debugging.  This is follow-up to r1819.
    
    mem_heap_validate(): Compile this function also if UNIV_MEM_DEBUG is
    defined.  Previously, this function was only compiled with UNIV_DEBUG.
    
    mem_heap_free_heap_top(): Flag the memory allocated, not freed, for
    Valgrind.  Otherwise, Valgrind would complain on the second call of
    mem_heap_empty().
    
    UNIV_MEM_ASSERT_RW(), UNIV_MEM_ASSERT_W(): Display additional diagnostics
    for failed Valgrind checks.
    
    
    Revision r1937:
    mem_heap_free_top(): Remove a bogus Valgrind warning.
    
    
    Revision r1819:
    Merge r1815:1817 from branches/zip: Improve Valgrind instrumentation.
    
    UNIV_MEM_ASSERT_RW(): New macro, to check that the contents of a memory
    area is defined.
    
    UNIV_MEM_ASSERT_W(): New macro, to check that a memory area is writable.
    
    UNIV_MEM_ASSERT_AND_FREE(): New macro, to check that the memory is
    writable before declaring it free (unwritable).  This replaces UNIV_MEM_FREE()
    in many places.
    
    mem_init_buf(): Check that the memory is writable, and declare it undefined.
    
    mem_erase_buf(): Check that the memory is writable, and declare it freed.

  storage/innobase/include/rem0rec.ic@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +1 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1918:
    Improve Valgrind instrumentation.
    
    rec_offs_set_n_alloc(): Use UNIV_MEM_ASSERT_AND_ALLOC().
    
    UNIV_MEM_ASSERT_AND_ALLOC(): New directive, similar to
    UNIV_MEM_ASSERT_AND_FREE().

  storage/innobase/include/row0mysql.h@stripped, 2007-11-06 15:23:45-07:00, tsmith@stripped +8 -5
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1783:
    Correct the function comments of row_create_table_for_mysql() and
    row_drop_table_for_mysql().

  storage/innobase/include/sync0rw.h@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +2 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1757:
    Enclose rw_lock_validate() in #ifdef UNIV_DEBUG.  It is only called by
    debug assertions.

  storage/innobase/include/univ.i@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +28 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1827:
    Merge r1826 from branches/zip: UNIV_MEM_ASSERT_AND_FREE():
    Use UNIV_MEM_ASSERT_W() instead of UNIV_MEM_ASSERT_RW().
    The memory area need not be initialized.
    This mistake was made in r1815.
    
    
    Revision r1918:
    Improve Valgrind instrumentation.
    
    rec_offs_set_n_alloc(): Use UNIV_MEM_ASSERT_AND_ALLOC().
    
    UNIV_MEM_ASSERT_AND_ALLOC(): New directive, similar to
    UNIV_MEM_ASSERT_AND_FREE().
    
    
    Revision r1830:
    Improve memory debugging.  This is follow-up to r1819.
    
    mem_heap_validate(): Compile this function also if UNIV_MEM_DEBUG is
    defined.  Previously, this function was only compiled with UNIV_DEBUG.
    
    mem_heap_free_heap_top(): Flag the memory allocated, not freed, for
    Valgrind.  Otherwise, Valgrind would complain on the second call of
    mem_heap_empty().
    
    UNIV_MEM_ASSERT_RW(), UNIV_MEM_ASSERT_W(): Display additional diagnostics
    for failed Valgrind checks.
    
    
    Revision r1819:
    Merge r1815:1817 from branches/zip: Improve Valgrind instrumentation.
    
    UNIV_MEM_ASSERT_RW(): New macro, to check that the contents of a memory
    area is defined.
    
    UNIV_MEM_ASSERT_W(): New macro, to check that a memory area is writable.
    
    UNIV_MEM_ASSERT_AND_FREE(): New macro, to check that the memory is
    writable before declaring it free (unwritable).  This replaces UNIV_MEM_FREE()
    in many places.
    
    mem_init_buf(): Check that the memory is writable, and declare it undefined.
    
    mem_erase_buf(): Check that the memory is writable, and declare it freed.
    
    
    Revision r1948:
    UNIV_MEM_ASSERT_RW(), UNIV_MEM_ASSERT_W(): Display also __FILE__ and __LINE__
    when these Valgrind checks fail.

  storage/innobase/include/ut0ut.h@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +18 -0
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1850:
    Implement this feature request:
    http://bugs.mysql.com/30706
    
    * Add a function that returns the number of microseconds since
      epoch - ut_time_us().
    
    * Add (innodb|innobase|srv)_replication_delay MySQL config parameter.
    
    * Add UT_WAIT_FOR() macro that waits for a specified condition to occur
      until a timeout elapses.
    
    * Using all of the above, handle the replication thread specially in
      srv_conc_enter_innodb().
    
    Approved by:	Heikki
    
    
    
    Revision r1862:
    Add ut_snprintf() function. On Windows this needs to be implemented
    using auxiliary functions because there is no snprintf-variant on
    Windows that behaves exactly as specified in the standard:
    
    * Always return the number of characters that would have been printed
      if the size were unlimited (not including the final `\0').
    * Always '\0'-terminate the result
    * Do not touch the buffer if size=0, only return the number of characters
      that would have been printed. Can be used to estimate the size needed
      and to allocate it dynamically.
    
    See http://www.freebsd.org/cgi/query-pr.cgi?pr=87260 for the reason why
    2 ap variables are used.
    
    Approved by:	Heikki
    
    
    Revision r1866:
    Revert r1850 as MySQL did not approve the addition.
    
    log for r1850:
    
    Implement this feature request:
    http://bugs.mysql.com/30706
    
    * Add a function that returns the number of microseconds since
      epoch - ut_time_us().
    
    * Add (innodb|innobase|srv)_replication_delay MySQL config parameter.
    
    * Add UT_WAIT_FOR() macro that waits for a specified condition to occur
      until a timeout elapses.
    
    * Using all of the above, handle the replication thread specially in
      srv_conc_enter_innodb().

  storage/innobase/mem/mem0dbg.c@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +24 -16
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1830:
    Improve memory debugging.  This is follow-up to r1819.
    
    mem_heap_validate(): Compile this function also if UNIV_MEM_DEBUG is
    defined.  Previously, this function was only compiled with UNIV_DEBUG.
    
    mem_heap_free_heap_top(): Flag the memory allocated, not freed, for
    Valgrind.  Otherwise, Valgrind would complain on the second call of
    mem_heap_empty().
    
    UNIV_MEM_ASSERT_RW(), UNIV_MEM_ASSERT_W(): Display additional diagnostics
    for failed Valgrind checks.
    
    
    Revision r1819:
    Merge r1815:1817 from branches/zip: Improve Valgrind instrumentation.
    
    UNIV_MEM_ASSERT_RW(): New macro, to check that the contents of a memory
    area is defined.
    
    UNIV_MEM_ASSERT_W(): New macro, to check that a memory area is writable.
    
    UNIV_MEM_ASSERT_AND_FREE(): New macro, to check that the memory is
    writable before declaring it free (unwritable).  This replaces UNIV_MEM_FREE()
    in many places.
    
    mem_init_buf(): Check that the memory is writable, and declare it undefined.
    
    mem_erase_buf(): Check that the memory is writable, and declare it freed.

  storage/innobase/mem/mem0mem.c@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +3 -3
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1819:
    Merge r1815:1817 from branches/zip: Improve Valgrind instrumentation.
    
    UNIV_MEM_ASSERT_RW(): New macro, to check that the contents of a memory
    area is defined.
    
    UNIV_MEM_ASSERT_W(): New macro, to check that a memory area is writable.
    
    UNIV_MEM_ASSERT_AND_FREE(): New macro, to check that the memory is
    writable before declaring it free (unwritable).  This replaces UNIV_MEM_FREE()
    in many places.
    
    mem_init_buf(): Check that the memory is writable, and declare it undefined.
    
    mem_erase_buf(): Check that the memory is writable, and declare it freed.

  storage/innobase/row/row0mysql.c@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +38 -44
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1786:
    row_create_table_for_mysql(), row_truncate_table_for_mysql(),
    row_drop_table_for_mysql(): Do not mention innodb_force_recovery
    when newraw is set.
    
    
    Revision r1790:
    row_drop_table_for_mysql(): Before calling
    dict_table_remove_from_cache(table) and thus freeing the memory
    allocated for the table, copy the table name.  This avoids reading
    freed memory when name == table->name.
    
    Approved by Sunny.
    
    
    Revision r1783:
    Correct the function comments of row_create_table_for_mysql() and
    row_drop_table_for_mysql().
    
    
    Revision r1894:
    Add debug lock checks to autoinc functions. Add lock guards around an
    invocation of dict_table_autoinc_initialize().

  storage/innobase/row/row0sel.c@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +48 -27
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1782:
    Add comment that the variable dest should be word aligned. After discussion
    on IM with Heikki.
    
    
    Revision r1988:
    Set an error code when a deadlock occurs in semi-consistent read.  (Bug #31494)
    
    innodb-semi-consistent: New tests for InnoDB semi-consistent reads.
    Unfortunately, these will not trigger Bug #31494, because there merely
    occur lock wait timeouts, not deadlocks.
    
    
    Revision r1820:
    Use the clustered index and not the one selected by the optimizer in the plan,
    when building a previous version of the row. This bug is triggered when
    running queries via InnoDB's internal SQL parser; when InnoDB's optimizer
    selects a secondary index for the plan.
    
    
    Revision r1828:
    Fix two bugs:
    
    Bug# 30907: We don't rely on *first_value to be 0 when checking whether
    get_auto_increment() has been invoked for the first time in a multi-row
    INSERT. We instead use trx_t::n_autoinc_rows. Initialize trx::n_autoinc_rows
    inside ha_innobase::start_stmt() too.
    
    Bug# 30888: While adding code for the low level read of the AUTOINC value
    from the index, the case for MEDIUM ints which are 3 bytes was missed
    triggering an assertion.
    
    
    Revision r1779:
    Fix a bug that handles the case where the host specific byte order matches
    the InnoDB storage byte order, which is big-endian.

  storage/innobase/sync/sync0rw.c@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +3 -3
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1757:
    Enclose rw_lock_validate() in #ifdef UNIV_DEBUG.  It is only called by
    debug assertions.

  storage/innobase/ut/ut0ut.c@stripped, 2007-11-06 15:23:46-07:00, tsmith@stripped +51 -20
    Apply snapshot innodb-5.1-ss1989
    
    Revision r1850:
    Implement this feature request:
    http://bugs.mysql.com/30706
    
    * Add a function that returns the number of microseconds since
      epoch - ut_time_us().
    
    * Add (innodb|innobase|srv)_replication_delay MySQL config parameter.
    
    * Add UT_WAIT_FOR() macro that waits for a specified condition to occur
      until a timeout elapses.
    
    * Using all of the above, handle the replication thread specially in
      srv_conc_enter_innodb().
    
    Approved by:	Heikki
    
    
    
    Revision r1873:
    snprintf() should always return non-negative result. According to
    Microsoft documentation about _vscprintf():
    
      If format is a null pointer, the invalid parameter handler is invoked,
      as described in Parameter Validation. If execution is allowed to
      continue, the functions return -1 and set errno to EINVAL.
    
    The UNIX variant of snprintf() segfaults if format is a NULL pointer
    (similar to strlen(NULL) for example), so it is better to conform to
    this behavior and crash our custom Windows version instead of
    returning -1. Noone would expect -1 to be returned from snprintf().
    
    Cosmetic: Add a space after typecast.
    
    Approved by:	Marko
    
    
    Revision r1862:
    Add ut_snprintf() function. On Windows this needs to be implemented
    using auxiliary functions because there is no snprintf-variant on
    Windows that behaves exactly as specified in the standard:
    
    * Always return the number of characters that would have been printed
      if the size were unlimited (not including the final `\0').
    * Always '\0'-terminate the result
    * Do not touch the buffer if size=0, only return the number of characters
      that would have been printed. Can be used to estimate the size needed
      and to allocate it dynamically.
    
    See http://www.freebsd.org/cgi/query-pr.cgi?pr=87260 for the reason why
    2 ap variables are used.
    
    Approved by:	Heikki
    
    
    Revision r1866:
    Revert r1850 as MySQL did not approve the addition.
    
    log for r1850:
    
    Implement this feature request:
    http://bugs.mysql.com/30706
    
    * Add a function that returns the number of microseconds since
      epoch - ut_time_us().
    
    * Add (innodb|innobase|srv)_replication_delay MySQL config parameter.
    
    * Add UT_WAIT_FOR() macro that waits for a specified condition to occur
      until a timeout elapses.
    
    * Using all of the above, handle the replication thread specially in
      srv_conc_enter_innodb().
    
    
    Revision r1787:
    Move the prototype of innobase_print_identifier() from ut0ut.c to
    ha_prototypes.h.  Enclose the definitions in ha_prototypes.h in
    #ifndef UNIV_HOTBACKUP.
    
    
    Revision r1789:
    ut_print_namel(): Do not assume that all '/' are separators between
    database and table names.
    
    Approved by Heikki.
    
    
    Revision r1936:
    ut_print_buf(): Add a Valgrind check that the buffer is wholly defined.

diff -Nrup a/mysql-test/r/innodb-semi-consistent.result b/mysql-test/r/innodb-semi-consistent.result
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/innodb-semi-consistent.result	2007-11-06 15:23:46 -07:00
@@ -0,0 +1,36 @@
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+select * from t1 where a=3 lock in share mode;
+a
+3
+set session transaction isolation level read committed;
+set autocommit=0;
+update t1 set a=10 where a=5;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+update t1 set a=10 where a=5;
+select * from t1 where a=2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select * from t1 where a=2 limit 1 for update;
+a
+2
+update t1 set a=11 where a=6;
+update t1 set a=12 where a=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+update t1 set a=13 where a=1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+update t1 set a=14 where a=1;
+commit;
+select * from t1;
+a
+14
+2
+3
+4
+10
+11
+7
+drop table t1;
diff -Nrup a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
--- a/mysql-test/r/innodb.result	2007-08-27 18:33:52 -06:00
+++ b/mysql-test/r/innodb.result	2007-11-06 15:23:45 -07:00
@@ -472,43 +472,6 @@ a	b
 3	3
 drop table t1,t2;
 CREATE TABLE t1 (
-id int(11) NOT NULL auto_increment,
-ggid varchar(32) binary DEFAULT '' NOT NULL,
-email varchar(64) DEFAULT '' NOT NULL,
-passwd varchar(32) binary DEFAULT '' NOT NULL,
-PRIMARY KEY (id),
-UNIQUE ggid (ggid)
-) ENGINE=innodb;
-insert into t1 (ggid,passwd) values ('test1','xxx');
-insert into t1 (ggid,passwd) values ('test2','yyy');
-insert into t1 (ggid,passwd) values ('test2','this will fail');
-ERROR 23000: Duplicate entry 'test2' for key 'ggid'
-insert into t1 (ggid,id) values ('this will fail',1);
-ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
-select * from t1 where ggid='test1';
-id	ggid	email	passwd
-1	test1		xxx
-select * from t1 where passwd='xxx';
-id	ggid	email	passwd
-1	test1		xxx
-select * from t1 where id=2;
-id	ggid	email	passwd
-2	test2		yyy
-replace into t1 (ggid,id) values ('this will work',1);
-replace into t1 (ggid,passwd) values ('test2','this will work');
-update t1 set id=100,ggid='test2' where id=1;
-ERROR 23000: Duplicate entry 'test2' for key 'ggid'
-select * from t1;
-id	ggid	email	passwd
-1	this will work		
-4	test2		this will work
-select * from t1 where id=1;
-id	ggid	email	passwd
-1	this will work		
-select * from t1 where id=999;
-id	ggid	email	passwd
-drop table t1;
-CREATE TABLE t1 (
 user_name varchar(12),
 password text,
 subscribed char(1),
@@ -1751,13 +1714,13 @@ Variable_name	Value
 Innodb_page_size	16384
 show status like "Innodb_rows_deleted";
 Variable_name	Value
-Innodb_rows_deleted	70
+Innodb_rows_deleted	69
 show status like "Innodb_rows_inserted";
 Variable_name	Value
-Innodb_rows_inserted	1083
+Innodb_rows_inserted	1080
 show status like "Innodb_rows_updated";
 Variable_name	Value
-Innodb_rows_updated	886
+Innodb_rows_updated	885
 show status like "Innodb_row_lock_waits";
 Variable_name	Value
 Innodb_row_lock_waits	0
@@ -3189,3 +3152,36 @@ c25 CHAR(255), c26 CHAR(255), c27 CHAR(2
 c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
 ) ENGINE = InnoDB;
 ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+DROP TABLE IF EXISTS t1, t2;
+Warnings:
+Note	1051	Unknown table 't1'
+Note	1051	Unknown table 't2'
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+SELECT * FROM t2;
+a
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+COMMIT;
+SELECT * FROM t1 WHERE a=1;
+a
+1
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+SELECT * FROM t2;
+a
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (2);
+COMMIT;
+SELECT * FROM t1 WHERE a=2;
+a
+2
+SELECT * FROM t1 WHERE a=2;
+a
+2
+DROP TABLE t1;
+DROP TABLE t2;
diff -Nrup a/mysql-test/r/innodb_autoinc_lock_mode_zero.result b/mysql-test/r/innodb_autoinc_lock_mode_zero.result
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/innodb_autoinc_lock_mode_zero.result	2007-11-06 15:23:46 -07:00
@@ -0,0 +1,39 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+ggid varchar(32) binary DEFAULT '' NOT NULL,
+email varchar(64) DEFAULT '' NOT NULL,
+passwd varchar(32) binary DEFAULT '' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE ggid (ggid)
+) ENGINE=innodb;
+insert into t1 (ggid,passwd) values ('test1','xxx');
+insert into t1 (ggid,passwd) values ('test2','yyy');
+insert into t1 (ggid,passwd) values ('test2','this will fail');
+ERROR 23000: Duplicate entry 'test2' for key 'ggid'
+insert into t1 (ggid,id) values ('this will fail',1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+select * from t1 where ggid='test1';
+id	ggid	email	passwd
+1	test1		xxx
+select * from t1 where passwd='xxx';
+id	ggid	email	passwd
+1	test1		xxx
+select * from t1 where id=2;
+id	ggid	email	passwd
+2	test2		yyy
+replace into t1 (ggid,id) values ('this will work',1);
+replace into t1 (ggid,passwd) values ('test2','this will work');
+update t1 set id=100,ggid='test2' where id=1;
+ERROR 23000: Duplicate entry 'test2' for key 'ggid'
+select * from t1;
+id	ggid	email	passwd
+1	this will work		
+3	test2		this will work
+select * from t1 where id=1;
+id	ggid	email	passwd
+1	this will work		
+select * from t1 where id=999;
+id	ggid	email	passwd
+drop table t1;
+End of tests
diff -Nrup a/mysql-test/t/innodb-semi-consistent-master.opt b/mysql-test/t/innodb-semi-consistent-master.opt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/innodb-semi-consistent-master.opt	2007-11-06 15:23:46 -07:00
@@ -0,0 +1 @@
+--innodb_locks_unsafe_for_binlog=true --innodb_lock_wait_timeout=2
diff -Nrup a/mysql-test/t/innodb-semi-consistent.test b/mysql-test/t/innodb-semi-consistent.test
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/innodb-semi-consistent.test	2007-11-06 15:23:46 -07:00
@@ -0,0 +1,46 @@
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+
+# basic tests of semi-consistent reads
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+# this should lock the entire table
+select * from t1 where a=3 lock in share mode;
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+-- error ER_LOCK_WAIT_TIMEOUT
+update t1 set a=10 where a=5;
+connection a;
+commit;
+connection b;
+update t1 set a=10 where a=5;
+connection a;
+-- error ER_LOCK_WAIT_TIMEOUT
+select * from t1 where a=2 for update;
+# this should lock the records (1),(2)
+select * from t1 where a=2 limit 1 for update;
+connection b;
+update t1 set a=11 where a=6;
+-- error ER_LOCK_WAIT_TIMEOUT
+update t1 set a=12 where a=2;
+-- error ER_LOCK_WAIT_TIMEOUT
+update t1 set a=13 where a=1;
+connection a;
+commit;
+connection b;
+update t1 set a=14 where a=1;
+commit;
+connection a;
+select * from t1;
+drop table t1;
+
+connection default;
+disconnect a;
+disconnect b;
diff -Nrup a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
--- a/mysql-test/t/innodb.test	2007-08-14 15:35:16 -06:00
+++ b/mysql-test/t/innodb.test	2007-11-06 15:23:45 -07:00
@@ -327,39 +327,6 @@ select * from t2;
 drop table t1,t2;
 
 #
-# Search on unique key
-#
-
-CREATE TABLE t1 (
-  id int(11) NOT NULL auto_increment,
-  ggid varchar(32) binary DEFAULT '' NOT NULL,
-  email varchar(64) DEFAULT '' NOT NULL,
-  passwd varchar(32) binary DEFAULT '' NOT NULL,
-  PRIMARY KEY (id),
-  UNIQUE ggid (ggid)
-) ENGINE=innodb;
-
-insert into t1 (ggid,passwd) values ('test1','xxx');
-insert into t1 (ggid,passwd) values ('test2','yyy');
--- error ER_DUP_ENTRY
-insert into t1 (ggid,passwd) values ('test2','this will fail');
--- error ER_DUP_ENTRY
-insert into t1 (ggid,id) values ('this will fail',1);
-
-select * from t1 where ggid='test1';
-select * from t1 where passwd='xxx';
-select * from t1 where id=2;
-
-replace into t1 (ggid,id) values ('this will work',1);
-replace into t1 (ggid,passwd) values ('test2','this will work');
--- error ER_DUP_ENTRY
-update t1 set id=100,ggid='test2' where id=1;
-select * from t1;
-select * from t1 where id=1;
-select * from t1 where id=999;
-drop table t1;
-
-#
 # ORDER BY on not primary key
 #
 
@@ -2322,6 +2289,48 @@ CREATE TABLE t1 (
 	c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
 	c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
 	) ENGINE = InnoDB;
+
+# 
+# Bug #21409 Incorrect result returned when in READ-COMMITTED with
+# query_cache ON
+#
+CONNECT (c1,localhost,root,,);
+CONNECT (c2,localhost,root,,);
+CONNECTION c1;
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+SELECT * FROM t2;
+CONNECTION c2;
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+COMMIT;
+CONNECTION c1;
+SELECT * FROM t1 WHERE a=1;
+DISCONNECT c1;
+DISCONNECT c2;
+CONNECT (c1,localhost,root,,);
+CONNECT (c2,localhost,root,,);
+CONNECTION c1;
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+SELECT * FROM t2;
+CONNECTION c2;
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (2);
+COMMIT;
+CONNECTION c1;
+# The result set below should be the same for both selects
+SELECT * FROM t1 WHERE a=2;
+SELECT * FROM t1 WHERE a=2;
+DROP TABLE t1;
+DROP TABLE t2;
+DISCONNECT c1;
+DISCONNECT c2;
 
 #######################################################################
 #                                                                     #
diff -Nrup a/mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt b/mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt	2007-11-06 15:23:46 -07:00
@@ -0,0 +1 @@
+--innodb-autoinc-lock-mode=0
diff -Nrup a/mysql-test/t/innodb_autoinc_lock_mode_zero.test b/mysql-test/t/innodb_autoinc_lock_mode_zero.test
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/innodb_autoinc_lock_mode_zero.test	2007-11-06 15:23:46 -07:00
@@ -0,0 +1,44 @@
+# This test runs with old-style locking, as:
+# --innodb-autoinc-lock-mode=0
+
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+
+#
+# Search on unique key
+#
+
+CREATE TABLE t1 (
+  id int(11) NOT NULL auto_increment,
+  ggid varchar(32) binary DEFAULT '' NOT NULL,
+  email varchar(64) DEFAULT '' NOT NULL,
+  passwd varchar(32) binary DEFAULT '' NOT NULL,
+  PRIMARY KEY (id),
+  UNIQUE ggid (ggid)
+) ENGINE=innodb;
+
+insert into t1 (ggid,passwd) values ('test1','xxx');
+insert into t1 (ggid,passwd) values ('test2','yyy');
+-- error ER_DUP_ENTRY
+insert into t1 (ggid,passwd) values ('test2','this will fail');
+-- error ER_DUP_ENTRY
+insert into t1 (ggid,id) values ('this will fail',1);
+
+select * from t1 where ggid='test1';
+select * from t1 where passwd='xxx';
+select * from t1 where id=2;
+
+replace into t1 (ggid,id) values ('this will work',1);
+replace into t1 (ggid,passwd) values ('test2','this will work');
+-- error ER_DUP_ENTRY
+update t1 set id=100,ggid='test2' where id=1;
+select * from t1;
+select * from t1 where id=1;
+select * from t1 where id=999;
+drop table t1;
+
+--echo End of tests
diff -Nrup a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
--- a/storage/innobase/buf/buf0lru.c	2007-07-24 19:27:12 -06:00
+++ b/storage/innobase/buf/buf0lru.c	2007-11-06 15:23:45 -07:00
@@ -881,7 +881,7 @@ buf_LRU_block_free_non_file_page(
 	UT_LIST_ADD_FIRST(free, buf_pool->free, block);
 	block->in_free_list = TRUE;
 
-	UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
+	UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
 
 	if (srv_use_awe && block->frame) {
 		/* Add to the list of mapped pages */
diff -Nrup a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
--- a/storage/innobase/dict/dict0dict.c	2007-08-24 19:14:48 -06:00
+++ b/storage/innobase/dict/dict0dict.c	2007-11-06 15:23:45 -07:00
@@ -441,6 +441,8 @@ dict_table_autoinc_initialize(
 	dict_table_t*	table,	/* in: table */
 	ib_longlong	value)	/* in: next value to assign to a row */
 {
+	ut_ad(mutex_own(&table->autoinc_mutex));
+
 	table->autoinc_inited = TRUE;
 	table->autoinc = value;
 }
@@ -456,6 +458,8 @@ dict_table_autoinc_read(
 	dict_table_t*	table)	/* in: table */
 {
 	ib_longlong	value;
+
+	ut_ad(mutex_own(&table->autoinc_mutex));
 
 	if (!table->autoinc_inited) {
 
diff -Nrup a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
--- a/storage/innobase/dict/dict0load.c	2007-08-25 03:55:35 -06:00
+++ b/storage/innobase/dict/dict0load.c	2007-11-06 15:23:45 -07:00
@@ -551,11 +551,13 @@ dict_load_fields(
 Loads definitions for table indexes. Adds them to the data dictionary
 cache. */
 static
-ibool
+ulint
 dict_load_indexes(
 /*==============*/
-				/* out: TRUE if ok, FALSE if corruption
-				of dictionary table */
+				/* out: DB_SUCCESS if ok, DB_CORRUPTION
+				if corruption of dictionary table or
+				DB_UNSUPPORTED if table has unknown index
+				type */
 	dict_table_t*	table,	/* in: table */
 	mem_heap_t*	heap)	/* in: memory heap for temporary storage */
 {
@@ -578,6 +580,7 @@ dict_load_indexes(
 	ibool		is_sys_table;
 	dulint		id;
 	mtr_t		mtr;
+	ulint		error = DB_SUCCESS;
 
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 
@@ -624,10 +627,8 @@ dict_load_indexes(
 			dict_load_report_deleted_index(table->name,
 						       ULINT_UNDEFINED);
 
-			btr_pcur_close(&pcur);
-			mtr_commit(&mtr);
-
-			return(FALSE);
+			error = DB_CORRUPTION;
+			goto func_exit;
 		}
 
 		field = rec_get_nth_field_old(rec, 1, &len);
@@ -653,7 +654,18 @@ dict_load_indexes(
 		field = rec_get_nth_field_old(rec, 8, &len);
 		page_no = mach_read_from_4(field);
 
-		if (page_no == FIL_NULL) {
+		/* We check for unsupported types first, so that the
+		subsequent checks are relevant for the supported types. */
+		if (type & ~(DICT_CLUSTERED | DICT_UNIQUE)) {
+
+			fprintf(stderr,
+				"InnoDB: Error: unknown type %lu"
+				" of index %s of table %s\n",
+				(ulong) type, name_buf, table->name);
+
+			error = DB_UNSUPPORTED;
+			goto func_exit;
+		} else if (page_no == FIL_NULL) {
 
 			fprintf(stderr,
 				"InnoDB: Error: trying to load index %s"
@@ -661,14 +673,10 @@ dict_load_indexes(
 				"InnoDB: but the index tree has been freed!\n",
 				name_buf, table->name);
 
-			btr_pcur_close(&pcur);
-			mtr_commit(&mtr);
-
-			return(FALSE);
-		}
-
-		if ((type & DICT_CLUSTERED) == 0
-		    && NULL == dict_table_get_first_index(table)) {
+			error = DB_CORRUPTION;
+			goto func_exit;
+		} else if ((type & DICT_CLUSTERED) == 0
+			    && NULL == dict_table_get_first_index(table)) {
 
 			fprintf(stderr,
 				"InnoDB: Error: trying to load index %s"
@@ -677,18 +685,14 @@ dict_load_indexes(
 				" is not clustered!\n",
 				name_buf, table->name);
 
-			btr_pcur_close(&pcur);
-			mtr_commit(&mtr);
-
-			return(FALSE);
-		}
-
-		if (is_sys_table
-		    && ((type & DICT_CLUSTERED)
-			|| ((table == dict_sys->sys_tables)
-			    && (name_len == (sizeof "ID_IND") - 1)
-			    && (0 == ut_memcmp(name_buf, "ID_IND",
-					       name_len))))) {
+			error = DB_CORRUPTION;
+			goto func_exit;
+		} else if (is_sys_table
+			   && ((type & DICT_CLUSTERED)
+			       || ((table == dict_sys->sys_tables)
+				   && (name_len == (sizeof "ID_IND") - 1)
+				   && (0 == ut_memcmp(name_buf,
+						      "ID_IND", name_len))))) {
 
 			/* The index was created in memory already at booting
 			of the database server */
@@ -704,10 +708,11 @@ dict_load_indexes(
 		btr_pcur_move_to_next_user_rec(&pcur, &mtr);
 	}
 
+func_exit:
 	btr_pcur_close(&pcur);
 	mtr_commit(&mtr);
 
-	return(TRUE);
+	return(error);
 }
 
 /************************************************************************
@@ -857,11 +862,20 @@ err_exit:
 
 	mem_heap_empty(heap);
 
-	dict_load_indexes(table, heap);
+	err = dict_load_indexes(table, heap);
 
-	err = dict_load_foreigns(table->name, TRUE);
+	/* If the force recovery flag is set, we open the table irrespective
+	of the error condition, since the user may want to dump data from the
+	clustered index. However we load the foreign key information only if
+	all indexes were loaded. */
+	if (err != DB_SUCCESS && !srv_force_recovery) {
+		dict_mem_table_free(table);
+		table = NULL;
+	} else if (err == DB_SUCCESS) {
+		err = dict_load_foreigns(table->name, TRUE);
+	}
 #if 0
-	if (err != DB_SUCCESS) {
+	if (err != DB_SUCCESS && table != NULL) {
 
 		mutex_enter(&dict_foreign_err_mutex);
 
diff -Nrup a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
--- a/storage/innobase/handler/ha_innodb.cc	2007-10-23 09:10:28 -06:00
+++ b/storage/innobase/handler/ha_innodb.cc	2007-11-06 15:23:45 -07:00
@@ -129,6 +129,7 @@ static my_bool	innobase_locks_unsafe_for
 static my_bool	innobase_rollback_on_timeout		= FALSE;
 static my_bool	innobase_create_status_file		= FALSE;
 static my_bool innobase_stats_on_metadata		= TRUE;
+static my_bool	innobase_use_adaptive_hash_indexes	= TRUE;
 
 static char*	internal_innobase_data_file_path	= NULL;
 
@@ -1246,8 +1247,7 @@ innobase_invalidate_query_cache(
 }
 
 /*********************************************************************
-Display an SQL identifier.
-This definition must match the one in innobase/ut/ut0ut.c! */
+Display an SQL identifier. */
 extern "C"
 void
 innobase_print_identifier(
@@ -1635,6 +1635,9 @@ innobase_init(
 
 	srv_stats_on_metadata = (ibool) innobase_stats_on_metadata;
 
+	srv_use_adaptive_hash_indexes =
+		(ibool) innobase_use_adaptive_hash_indexes;
+
 	srv_print_verbose_log = mysqld_embedded ? 0 : 1;
 
 	/* Store the default charset-collation number of this MySQL
@@ -2320,13 +2323,18 @@ ha_innobase::open(
 
 	if (NULL == ib_table) {
 		ut_print_timestamp(stderr);
-		sql_print_error("Cannot find table %s from the internal data "
-				"dictionary\nof InnoDB though the .frm file "
-				"for the table exists. Maybe you\nhave "
-				"deleted and recreated InnoDB data files but "
-				"have forgotten\nto delete the corresponding "
-				".frm files of InnoDB tables, or you\n"
-				"have moved .frm files to another database?\n"
+		sql_print_error("Cannot find or open table %s from\n"
+				"the internal data dictionary of InnoDB "
+				"though the .frm file for the\n"
+				"table exists. Maybe you have deleted and "
+				"recreated InnoDB data\n"
+				"files but have forgotten to delete the "
+				"corresponding .frm files\n"
+				"of InnoDB tables, or you have moved .frm "
+				"files to another database?\n"
+				"or, the table contains indexes that this "
+				"version of the engine\n"
+				"doesn't support.\n"
 				"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
 				"how you can resolve the problem.\n",
 				norm_name);
@@ -3476,6 +3484,7 @@ no_commit:
 
 	/* Handle duplicate key errors */
 	if (auto_inc_used) {
+		ulint		err;
 		ulonglong	auto_inc;
 
 		/* Note the number of rows processed for this statement, used
@@ -3529,7 +3538,11 @@ set_max_autoinc:
 				ut_a(prebuilt->table->autoinc_increment > 0);
 				auto_inc += prebuilt->table->autoinc_increment;
 
-				innobase_set_max_autoinc(auto_inc);
+				err = innobase_set_max_autoinc(auto_inc);
+
+				if (err != DB_SUCCESS) {
+					error = err;
+				}
 			}
 			break;
 		}
@@ -3765,7 +3778,7 @@ ha_innobase::update_row(
 		if (auto_inc != 0) {
 			auto_inc += prebuilt->table->autoinc_increment;
 
-			innobase_set_max_autoinc(auto_inc);
+			error = innobase_set_max_autoinc(auto_inc);
 		}
 	}
 
@@ -6304,6 +6317,9 @@ ha_innobase::start_stmt(
 
 	innobase_release_stat_resources(trx);
 
+	/* Reset the AUTOINC statement level counter for multi-row INSERTs. */
+	trx->n_autoinc_rows = 0;
+
 	prebuilt->sql_stat_start = TRUE;
 	prebuilt->hint_need_to_fetch_extra_cols = 0;
 	reset_template(prebuilt);
@@ -6446,9 +6462,6 @@ ha_innobase::external_lock(
 			innobase_register_stmt(ht, thd);
 		}
 
-		trx->n_mysql_tables_in_use++;
-		prebuilt->mysql_has_locked = TRUE;
-
 		if (trx->isolation_level == TRX_ISO_SERIALIZABLE
 			&& prebuilt->select_lock_type == LOCK_NONE
 			&& thd_test_options(thd,
@@ -6497,6 +6510,9 @@ ha_innobase::external_lock(
 			trx->mysql_n_tables_locked++;
 		}
 
+		trx->n_mysql_tables_in_use++;
+		prebuilt->mysql_has_locked = TRUE;
+
 		DBUG_RETURN(0);
 	}
 
@@ -7120,8 +7136,8 @@ the value of the auto-inc counter. */
 int
 ha_innobase::innobase_read_and_init_auto_inc(
 /*=========================================*/
-						/* out: 0 or error code:
-						deadlock or lock wait timeout */
+						/* out: 0 or generic MySQL
+						error code */
         longlong*	value)			/* out: the autoinc value */
 {
 	longlong	auto_inc;
@@ -7178,9 +7194,9 @@ ha_innobase::innobase_read_and_init_auto
 			++auto_inc;
 			dict_table_autoinc_initialize(innodb_table, auto_inc);
 		} else {
-			fprintf(stderr, "  InnoDB error: Couldn't read the "
-				"max AUTOINC value from index (%s).\n",
-				index->name);
+			fprintf(stderr, " InnoDB error (%lu): Couldn't read "
+				"the max AUTOINC value from the index (%s).\n",
+				error, index->name);
 
 			mysql_error = 1;
 		}
@@ -7217,6 +7233,11 @@ ha_innobase::innobase_get_auto_increment
 {
 	ulong		error;
 
+	*value = 0;
+
+	/* Note: If the table is not initialized when we attempt the
+	read below. We initialize the table's auto-inc counter  and
+	always do a reread of the AUTOINC value. */
 	do {
 		error = innobase_autoinc_lock();
 
@@ -7256,7 +7277,16 @@ ha_innobase::innobase_get_auto_increment
 			} else {
 				*value = (ulonglong) autoinc;
 			}
+		/* A deadlock error during normal processing is OK
+		and can be ignored. */
+		} else if (error != DB_DEADLOCK) {
+
+			ut_print_timestamp(stderr);
+			sql_print_error(" InnoDB Error %lu in "
+					"::innobase_get_auto_increment()",
+					error);
 		}
+
 	} while (*value == 0 && error == DB_SUCCESS);
 
 	return(error);
@@ -7272,7 +7302,7 @@ we have a table-level lock). offset, inc
 
 void
 ha_innobase::get_auto_increment(
-/*=================================*/
+/*============================*/
         ulonglong	offset,              /* in: */
         ulonglong	increment,           /* in: table autoinc increment */
         ulonglong	nb_desired_values,   /* in: number of values reqd */
@@ -7289,13 +7319,6 @@ ha_innobase::get_auto_increment(
 	error = innobase_get_auto_increment(&autoinc);
 
 	if (error != DB_SUCCESS) {
-		/* This should never happen in the code > ver 5.0.6,
-		since we call this function only after the counter
-		has been initialized. */
-
-		ut_print_timestamp(stderr);
-		sql_print_error("Error %lu in ::get_auto_increment()", error);
-
 		*first_value = (~(ulonglong) 0);
 		return;
 	}
@@ -7310,6 +7333,11 @@ ha_innobase::get_auto_increment(
 
 	trx = prebuilt->trx;
 
+	/* Note: We can't rely on *first_value since some MySQL engines,
+	in particular the partition engine, don't initialize it to 0 when
+	invoking this method. So we are not sure if it's guaranteed to
+	be 0 or not. */
+
 	/* Called for the first time ? */
 	if (trx->n_autoinc_rows == 0) {
 
@@ -7318,16 +7346,16 @@ ha_innobase::get_auto_increment(
 		/* It's possible for nb_desired_values to be 0:
 		e.g., INSERT INTO T1(C) SELECT C FROM T2; */
 		if (nb_desired_values == 0) {
-  
+
 			trx->n_autoinc_rows = 1;
 		}
-  
+
 		set_if_bigger(*first_value, autoinc);
 	/* Not in the middle of a mult-row INSERT. */
 	} else if (prebuilt->last_value == 0) {
 		set_if_bigger(*first_value, autoinc);
 	}
-  
+
 	*nb_reserved_values = trx->n_autoinc_rows;
 
 	/* With old style AUTOINC locking we only update the table's
@@ -7359,7 +7387,9 @@ ha_innobase::get_auto_increment(
 
 /* See comment in handler.h */
 int
-ha_innobase::reset_auto_increment(ulonglong value)
+ha_innobase::reset_auto_increment(
+/*==============================*/
+	ulonglong	value)		/* in: new value for table autoinc */
 {
 	DBUG_ENTER("ha_innobase::reset_auto_increment");
 
@@ -7923,6 +7953,11 @@ static MYSQL_SYSVAR_BOOL(stats_on_metada
   "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
   NULL, NULL, TRUE);
 
+static MYSQL_SYSVAR_BOOL(use_adaptive_hash_indexes, innobase_use_adaptive_hash_indexes,
+  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
+  "Enable the InnoDB adaptive hash indexes (enabled by default)",
+  NULL, NULL, TRUE);
+
 static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
   "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
@@ -8051,6 +8086,7 @@ static struct st_mysql_sys_var* innobase
   MYSQL_SYSVAR(open_files),
   MYSQL_SYSVAR(rollback_on_timeout),
   MYSQL_SYSVAR(stats_on_metadata),
+  MYSQL_SYSVAR(use_adaptive_hash_indexes),
   MYSQL_SYSVAR(status_file),
   MYSQL_SYSVAR(support_xa),
   MYSQL_SYSVAR(sync_spin_loops),
diff -Nrup a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
--- a/storage/innobase/handler/ha_innodb.h	2007-10-09 10:59:46 -06:00
+++ b/storage/innobase/handler/ha_innodb.h	2007-11-06 15:23:45 -07:00
@@ -250,17 +250,3 @@ int thd_binlog_format(const MYSQL_THD th
 */
 void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
 }
-
-/*
-  don't delete it - it may be re-enabled later
-  as an optimization for the most common case InnoDB+binlog
-*/
-#if 0
-int innobase_report_binlog_offset_and_commit(
-	THD*	thd,
-	void*	trx_handle,
-	char*	log_file_name,
-	my_off_t end_offset);
-int innobase_commit_complete(void* trx_handle);
-void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
-#endif
diff -Nrup a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
--- a/storage/innobase/ibuf/ibuf0ibuf.c	2007-08-24 19:14:48 -06:00
+++ b/storage/innobase/ibuf/ibuf0ibuf.c	2007-11-06 15:23:45 -07:00
@@ -2900,7 +2900,7 @@ dump:
 				ut_print_timestamp(stderr);
 
 				fprintf(stderr,
-					"InnoDB: Error: Insert buffer insert"
+					"  InnoDB: Error: Insert buffer insert"
 					" fails; page free %lu,"
 					" dtuple size %lu\n",
 					(ulong) page_get_max_insert_size(
@@ -2925,7 +2925,7 @@ dump:
 					buf_frame_get_page_no(page),
 					IBUF_BITMAP_FREE, mtr);
 
-				fprintf(stderr, "Bitmap bits %lu\n",
+				fprintf(stderr, "InnoDB: Bitmap bits %lu\n",
 					(ulong) old_bits);
 
 				fputs("InnoDB: Submit a detailed bug report"
diff -Nrup a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h
--- a/storage/innobase/include/db0err.h	2007-07-09 18:15:59 -06:00
+++ b/storage/innobase/include/db0err.h	2007-11-06 15:23:45 -07:00
@@ -61,12 +61,14 @@ Created 5/24/1996 Heikki Tuuri
 					activated by the operation would
 					lead to a duplicate key in some
 					table */
-
 #define DB_TOO_MANY_CONCURRENT_TRXS 47	/* when InnoDB runs out of the
 					preconfigured undo slots, this can
 					only happen when there are too many
 					concurrent transactions */
-
+#define DB_UNSUPPORTED		48	/* when InnoDB sees any artefact or
+					a feature that it can't recoginize or
+					work with e.g., FT indexes created by
+					a later version of the engine. */
 /* The following are partial failure codes */
 #define DB_FAIL			1000
 #define DB_OVERFLOW		1001
diff -Nrup a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
--- a/storage/innobase/include/ha_prototypes.h	2007-07-09 18:16:00 -06:00
+++ b/storage/innobase/include/ha_prototypes.h	2007-11-06 15:23:45 -07:00
@@ -1,6 +1,8 @@
 #ifndef HA_INNODB_PROTOTYPES_H
 #define HA_INNODB_PROTOTYPES_H
 
+#ifndef UNIV_HOTBACKUP
+
 #include "univ.i" /* ulint, uint */
 #include "m_ctype.h" /* CHARSET_INFO */
 
@@ -22,6 +24,19 @@ innobase_convert_string(
 	CHARSET_INFO*	from_cs,
 	uint*		errors);
 
+/*********************************************************************
+Display an SQL identifier. */
+
+void
+innobase_print_identifier(
+/*======================*/
+	FILE*		f,	/* in: output stream */
+	trx_t*		trx,	/* in: transaction */
+	ibool		table_id,/* in: TRUE=print a table name,
+				FALSE=print other identifier */
+	const char*	name,	/* in: name to print */
+	ulint		namelen);/* in: length of name */
+
 /**********************************************************************
 Returns true if the thread is the replication thread on the slave
 server. Used in srv_conc_enter_innodb() to determine if the thread
@@ -48,4 +63,5 @@ thd_has_edited_nontrans_tables(
 			been edited */
 	void*	thd);	/* in: thread handle (THD*) */
 
+#endif
 #endif
diff -Nrup a/storage/innobase/include/mach0data.h b/storage/innobase/include/mach0data.h
--- a/storage/innobase/include/mach0data.h	2006-03-10 09:22:05 -07:00
+++ b/storage/innobase/include/mach0data.h	2007-11-06 15:23:45 -07:00
@@ -327,6 +327,17 @@ mach_write_to_2_little_endian(
 	byte*	dest,		/* in: where to write */
 	ulint	n);		/* in: unsigned long int to write */
 
+/*************************************************************
+Convert integral type from storage byte order (big endian) to
+host byte order. */
+UNIV_INLINE
+void
+mach_read_int_type(
+/*===============*/
+	byte*		dest,		/* out: where to write */
+	const byte*	src,		/* in: where to read from */
+	ulint		len,		/* in: length of src */
+	ibool		unsigned_type);	/* in: signed or unsigned flag */
 #ifndef UNIV_NONINL
 #include "mach0data.ic"
 #endif
diff -Nrup a/storage/innobase/include/mach0data.ic b/storage/innobase/include/mach0data.ic
--- a/storage/innobase/include/mach0data.ic	2006-09-04 17:16:12 -06:00
+++ b/storage/innobase/include/mach0data.ic	2007-11-06 15:23:45 -07:00
@@ -7,6 +7,8 @@ to the machine format.
 Created 11/28/1995 Heikki Tuuri
 ***********************************************************************/
 
+#include "ut0mem.h"
+
 /***********************************************************
 The following function is used to store data in one byte. */
 UNIV_INLINE
@@ -688,4 +690,39 @@ mach_write_to_2_little_endian(
 	dest++;
 
 	*dest = (byte)(n & 0xFFUL);
+}
+
+/*************************************************************
+Convert integral type from storage byte order (big endian) to
+host byte order. */
+UNIV_INLINE
+void
+mach_read_int_type(
+/*===============*/
+	byte*		dest,		/* out: where to write */
+	const byte*	src,		/* in: where to read from */
+	ulint		len,		/* in: length of src */
+	ibool		unsigned_type)	/* in: signed or unsigned flag */
+{
+#ifdef WORDS_BIGENDIAN
+	memcpy(dest, src, len);
+
+	if (!unsigned_type) {
+		dest[0] ^= 128;
+	}
+#else
+	byte*		ptr;
+
+	/* Convert integer data from Innobase to a little-endian format,
+	sign bit restored to normal. */
+
+	for (ptr = dest + len; ptr != dest; ++src) {
+		--ptr;
+		*ptr = *src;
+	}
+
+	if (!unsigned_type) {
+		dest[len - 1] ^= 128;
+	}
+#endif
 }
diff -Nrup a/storage/innobase/include/mem0dbg.h b/storage/innobase/include/mem0dbg.h
--- a/storage/innobase/include/mem0dbg.h	2006-10-20 12:36:11 -06:00
+++ b/storage/innobase/include/mem0dbg.h	2007-11-06 15:23:45 -07:00
@@ -60,6 +60,14 @@ mem_heap_validate_or_print(
 	ulint*		n_blocks); /* out: number of blocks in the heap,
 				if a NULL pointer is passed as this
 				argument, it is ignored */
+/******************************************************************
+Validates the contents of a memory heap. */
+
+ibool
+mem_heap_validate(
+/*==============*/
+				/* out: TRUE if ok */
+	mem_heap_t*   heap);	/* in: memory heap */
 #endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
 #ifdef UNIV_DEBUG
 /******************************************************************
@@ -71,14 +79,6 @@ mem_heap_check(
 				/* out: TRUE if ok */
 	mem_heap_t*   heap);	/* in: memory heap */
 #endif /* UNIV_DEBUG */
-/******************************************************************
-Validates the contents of a memory heap. */
-
-ibool
-mem_heap_validate(
-/*==============*/
-				/* out: TRUE if ok */
-	mem_heap_t*   heap);	/* in: memory heap */
 #ifdef UNIV_MEM_DEBUG
 /*********************************************************************
 TRUE if no memory is currently allocated. */
diff -Nrup a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
--- a/storage/innobase/include/mem0mem.ic	2007-08-25 03:55:35 -06:00
+++ b/storage/innobase/include/mem0mem.ic	2007-11-06 15:23:45 -07:00
@@ -271,19 +271,16 @@ mem_heap_free_heap_top(
 	ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
 
 	/* In the debug version erase block from top up */
-	{
-		ulint	len = (byte*)block + block->len - old_top;
-		mem_erase_buf(old_top, len);
-		UNIV_MEM_FREE(old_top, len);
-	}
+	mem_erase_buf(old_top, (byte*)block + block->len - old_top);
 
 	/* Update allocated memory count */
 	mutex_enter(&mem_hash_mutex);
 	mem_current_allocated_memory -= (total_size - size);
 	mutex_exit(&mem_hash_mutex);
 #else /* UNIV_MEM_DEBUG */
-	UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top);
+	UNIV_MEM_ASSERT_W(old_top, (byte*)block + block->len - old_top);
 #endif /* UNIV_MEM_DEBUG */
+	UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
 
 	/* If free == start, we may free the block if it is not the first
 	one */
@@ -363,6 +360,7 @@ mem_heap_free_top(
 	/* Subtract the free field of block */
 	mem_block_set_free(block, mem_block_get_free(block)
 			   - MEM_SPACE_NEEDED(n));
+	UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
 #ifdef UNIV_MEM_DEBUG
 
 	ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
@@ -378,7 +376,11 @@ mem_heap_free_top(
 				== mem_block_get_start(block))) {
 		mem_heap_block_free(heap, block);
 	} else {
-		UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
+		/* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a
+		subsequent invocation of mem_heap_free_top().
+		Originally, this was UNIV_MEM_FREE(), to catch writes
+		to freed memory. */
+		UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
 	}
 }
 
diff -Nrup a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
--- a/storage/innobase/include/rem0rec.ic	2007-07-09 18:16:00 -06:00
+++ b/storage/innobase/include/rem0rec.ic	2007-11-06 15:23:45 -07:00
@@ -801,6 +801,7 @@ rec_offs_set_n_alloc(
 {
 	ut_ad(offsets);
 	ut_ad(n_alloc > 0);
+	UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets);
 	offsets[0] = n_alloc;
 }
 
diff -Nrup a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
--- a/storage/innobase/include/row0mysql.h	2007-08-24 19:14:48 -06:00
+++ b/storage/innobase/include/row0mysql.h	2007-11-06 15:23:45 -07:00
@@ -319,9 +319,11 @@ row_mysql_unfreeze_data_dictionary(
 /*===============================*/
 	trx_t*	trx);	/* in: transaction */
 /*************************************************************************
-Does a table creation operation for MySQL. If the name of the created
-table ends to characters INNODB_MONITOR, then this also starts
-printing of monitor output by the master thread. */
+Drops a table for MySQL. If the name of the table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also start the printing of monitor
+output by the master thread. If the table name ends in "innodb_mem_validate",
+InnoDB will try to invoke mem_validate(). */
 
 int
 row_create_table_for_mysql(
@@ -399,8 +401,9 @@ row_truncate_table_for_mysql(
 	dict_table_t*	table,	/* in: table handle */
 	trx_t*		trx);	/* in: transaction handle */
 /*************************************************************************
-Drops a table for MySQL. If the name of the dropped table ends to
-characters INNODB_MONITOR, then this also stops printing of monitor
+Drops a table for MySQL. If the name of the dropped table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also stop the printing of monitor
 output by the master thread. */
 
 int
diff -Nrup a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
--- a/storage/innobase/include/sync0rw.h	2007-01-17 17:18:03 -07:00
+++ b/storage/innobase/include/sync0rw.h	2007-11-06 15:23:46 -07:00
@@ -101,6 +101,7 @@ void
 rw_lock_free(
 /*=========*/
 	rw_lock_t*	lock);	/* in: rw-lock */
+#ifdef UNIV_DEBUG
 /**********************************************************************
 Checks that the rw-lock has been initialized and that there are no
 simultaneous shared and exclusive locks. */
@@ -109,6 +110,7 @@ ibool
 rw_lock_validate(
 /*=============*/
 	rw_lock_t*	lock);
+#endif /* UNIV_DEBUG */
 /******************************************************************
 NOTE! The following macros should be used in rw s-locking, not the
 corresponding function. */
diff -Nrup a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
--- a/storage/innobase/include/univ.i	2007-08-15 17:44:18 -06:00
+++ b/storage/innobase/include/univ.i	2007-11-06 15:23:46 -07:00
@@ -308,11 +308,39 @@ typedef void* os_thread_ret_t;
 # define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
 # define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size)
 # define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
+# define UNIV_MEM_ASSERT_RW(addr, size) do {				\
+	const void* _p = (const void*)					\
+		VALGRIND_CHECK_MEM_IS_DEFINED(addr, size);		\
+	if (UNIV_LIKELY_NULL(_p))					\
+		fprintf(stderr, "%s:%d: %p[%u] undefined at %d\n",	\
+			__FILE__, __LINE__,				\
+			(const void*) (addr), (unsigned) (size),	\
+			((const char*) _p) - ((const char*) (addr)));	\
+	} while (0)
+# define UNIV_MEM_ASSERT_W(addr, size) do {				\
+	const void* _p = (const void*)					\
+		VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size);		\
+	if (UNIV_LIKELY_NULL(_p))					\
+		fprintf(stderr, "%s:%d: %p[%u] unwritable at %d\n",	\
+			__FILE__, __LINE__,				\
+			(const void*) (addr), (unsigned) (size),	\
+			((const char*) _p) - ((const char*) (addr)));	\
+	} while (0)
 #else
 # define UNIV_MEM_VALID(addr, size) do {} while(0)
 # define UNIV_MEM_INVALID(addr, size) do {} while(0)
 # define UNIV_MEM_FREE(addr, size) do {} while(0)
 # define UNIV_MEM_ALLOC(addr, size) do {} while(0)
+# define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0)
+# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
 #endif
+#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do {	\
+	UNIV_MEM_ASSERT_W(addr, size);			\
+	UNIV_MEM_FREE(addr, size);			\
+} while (0)
+#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do {	\
+	UNIV_MEM_ASSERT_W(addr, size);			\
+	UNIV_MEM_ALLOC(addr, size);			\
+} while (0)
 
 #endif
diff -Nrup a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
--- a/storage/innobase/include/ut0ut.h	2007-07-09 18:16:00 -06:00
+++ b/storage/innobase/include/ut0ut.h	2007-11-06 15:23:46 -07:00
@@ -263,6 +263,24 @@ ut_copy_file(
 	FILE*	dest,	/* in: output file */
 	FILE*	src);	/* in: input file to be appended to output */
 
+/**************************************************************************
+snprintf(). */
+
+#ifdef __WIN__
+int
+ut_snprintf(
+				/* out: number of characters that would
+				have been printed if the size were
+				unlimited, not including the terminating
+				'\0'. */
+	char*		str,	/* out: string */
+	size_t		size,	/* in: str size */
+	const char*	fmt,	/* in: format */
+	...);			/* in: format values */
+#else
+#define ut_snprintf	snprintf
+#endif /* __WIN__ */
+
 #ifndef UNIV_NONINL
 #include "ut0ut.ic"
 #endif
diff -Nrup a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c
--- a/storage/innobase/mem/mem0dbg.c	2006-10-20 12:36:12 -06:00
+++ b/storage/innobase/mem/mem0dbg.c	2007-11-06 15:23:46 -07:00
@@ -223,6 +223,8 @@ mem_init_buf(
 {
 	byte*	ptr;
 
+	UNIV_MEM_ASSERT_W(buf, n);
+
 	for (ptr = buf; ptr < buf + n; ptr++) {
 
 		if (ut_rnd_gen_ibool()) {
@@ -231,6 +233,8 @@ mem_init_buf(
 			*ptr = 0xBE;
 		}
 	}
+
+	UNIV_MEM_INVALID(buf, n);
 }
 
 /*******************************************************************
@@ -245,6 +249,8 @@ mem_erase_buf(
 {
 	byte*	ptr;
 
+	UNIV_MEM_ASSERT_W(buf, n);
+
 	for (ptr = buf; ptr < buf + n; ptr++) {
 		if (ut_rnd_gen_ibool()) {
 			*ptr = 0xDE;
@@ -252,6 +258,8 @@ mem_erase_buf(
 			*ptr = 0xAD;
 		}
 	}
+
+	UNIV_MEM_FREE(buf, n);
 }
 
 /*******************************************************************
@@ -546,9 +554,7 @@ completed:
 	}
 	*error = FALSE;
 }
-#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
 
-#ifdef UNIV_DEBUG
 /******************************************************************
 Prints the contents of a memory heap. */
 static
@@ -575,20 +581,6 @@ mem_heap_print(
 }
 
 /******************************************************************
-Checks that an object is a memory heap (or a block of it). */
-
-ibool
-mem_heap_check(
-/*===========*/
-				/* out: TRUE if ok */
-	mem_heap_t*	heap)	/* in: memory heap */
-{
-	ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
-
-	return(TRUE);
-}
-
-/******************************************************************
 Validates the contents of a memory heap. */
 
 ibool
@@ -611,6 +603,22 @@ mem_heap_validate(
 	}
 
 	ut_a(!error);
+
+	return(TRUE);
+}
+#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
+
+#ifdef UNIV_DEBUG
+/******************************************************************
+Checks that an object is a memory heap (or a block of it). */
+
+ibool
+mem_heap_check(
+/*===========*/
+				/* out: TRUE if ok */
+	mem_heap_t*	heap)	/* in: memory heap */
+{
+	ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
 
 	return(TRUE);
 }
diff -Nrup a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c
--- a/storage/innobase/mem/mem0mem.c	2007-07-24 19:27:12 -06:00
+++ b/storage/innobase/mem/mem0mem.c	2007-11-06 15:23:46 -07:00
@@ -512,9 +512,9 @@ mem_heap_block_free(
 	of hex 0xDE and 0xAD. */
 
 	mem_erase_buf((byte*)block, len);
-
-#endif
-	UNIV_MEM_FREE(block, len);
+#else /* UNIV_MEM_DEBUG */
+	UNIV_MEM_ASSERT_AND_FREE(block, len);
+#endif /* UNIV_MEM_DEBUG */
 
 	if (init_block) {
 		/* Do not have to free: do nothing */
diff -Nrup a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
--- a/storage/innobase/row/row0mysql.c	2007-08-24 19:14:48 -06:00
+++ b/storage/innobase/row/row0mysql.c	2007-11-06 15:23:46 -07:00
@@ -1728,10 +1728,11 @@ row_mysql_unlock_data_dictionary(
 }
 
 /*************************************************************************
-Does a table creation operation for MySQL.  If the name of the table
-to be created is equal with one of the predefined magic table names,
-then this also starts printing the corresponding monitor output by
-the master thread. */
+Drops a table for MySQL. If the name of the table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also start the printing of monitor
+output by the master thread. If the table name ends in "innodb_mem_validate",
+InnoDB will try to invoke mem_validate(). */
 
 int
 row_create_table_for_mysql(
@@ -1756,13 +1757,11 @@ row_create_table_for_mysql(
 	ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
 
 	if (srv_created_new_raw) {
-		fputs("InnoDB: A new raw disk partition was initialized or\n"
-		      "InnoDB: innodb_force_recovery is on: we do not allow\n"
-		      "InnoDB: database modifications by the user. Shut down\n"
-		      "InnoDB: mysqld and edit my.cnf so that newraw"
-		      " is replaced\n"
-		      "InnoDB: with raw, and innodb_force_... is removed.\n",
-		      stderr);
+		fputs("InnoDB: A new raw disk partition was initialized:\n"
+		      "InnoDB: we do not allow database modifications"
+		      " by the user.\n"
+		      "InnoDB: Shut down mysqld and edit my.cnf so that newraw"
+		      " is replaced with raw.\n", stderr);
 
 		dict_mem_table_free(table);
 		trx_commit_for_mysql(trx);
@@ -2703,13 +2702,11 @@ row_truncate_table_for_mysql(
 	ut_ad(table);
 
 	if (srv_created_new_raw) {
-		fputs("InnoDB: A new raw disk partition was initialized or\n"
-		      "InnoDB: innodb_force_recovery is on: we do not allow\n"
-		      "InnoDB: database modifications by the user. Shut down\n"
-		      "InnoDB: mysqld and edit my.cnf so that newraw"
-		      " is replaced\n"
-		      "InnoDB: with raw, and innodb_force_... is removed.\n",
-		      stderr);
+		fputs("InnoDB: A new raw disk partition was initialized:\n"
+		      "InnoDB: we do not allow database modifications"
+		      " by the user.\n"
+		      "InnoDB: Shut down mysqld and edit my.cnf so that newraw"
+		      " is replaced with raw.\n", stderr);
 
 		return(DB_ERROR);
 	}
@@ -2898,7 +2895,9 @@ next_rec:
 
 	/* MySQL calls ha_innobase::reset_auto_increment() which does
 	the same thing. */
+	dict_table_autoinc_lock(table);
 	dict_table_autoinc_initialize(table, 0);
+	dict_table_autoinc_unlock(table);
 	dict_update_statistics(table);
 
 	trx_commit_for_mysql(trx);
@@ -2916,9 +2915,10 @@ funct_exit:
 #endif /* !UNIV_HOTBACKUP */
 
 /*************************************************************************
-Drops a table for MySQL. If the name of the table to be dropped is equal
-with one of the predefined magic table names, then this also stops printing
-the corresponding monitor output by the master thread. */
+Drops a table for MySQL. If the name of the dropped table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also stop the printing of monitor
+output by the master thread. */
 
 int
 row_drop_table_for_mysql(
@@ -2934,21 +2934,17 @@ row_drop_table_for_mysql(
 	ulint		err;
 	const char*	table_name;
 	ulint		namelen;
-	char*		dir_path_of_temp_table	= NULL;
-	ibool		success;
 	ibool		locked_dictionary	= FALSE;
 	pars_info_t*    info			= NULL;
 
 	ut_a(name != NULL);
 
 	if (srv_created_new_raw) {
-		fputs("InnoDB: A new raw disk partition was initialized or\n"
-		      "InnoDB: innodb_force_recovery is on: we do not allow\n"
-		      "InnoDB: database modifications by the user. Shut down\n"
-		      "InnoDB: mysqld and edit my.cnf so that newraw"
-		      " is replaced\n"
-		      "InnoDB: with raw, and innodb_force_... is removed.\n",
-		      stderr);
+		fputs("InnoDB: A new raw disk partition was initialized:\n"
+		      "InnoDB: we do not allow database modifications"
+		      " by the user.\n"
+		      "InnoDB: Shut down mysqld and edit my.cnf so that newraw"
+		      " is replaced with raw.\n", stderr);
 
 		return(DB_ERROR);
 	}
@@ -3232,14 +3228,20 @@ check_next_foreign:
 	} else {
 		ibool		is_path;
 		const char*	name_or_path;
+		mem_heap_t*	heap;
+
+		heap = mem_heap_create(200);
 
+		/* Clone the name, in case it has been allocated
+		from table->heap, which will be freed by
+		dict_table_remove_from_cache(table) below. */
+		name = mem_heap_strdup(heap, name);
 		space_id = table->space;
 
 		if (table->dir_path_of_temp_table != NULL) {
-			dir_path_of_temp_table = mem_strdup(
-				table->dir_path_of_temp_table);
 			is_path = TRUE;
-			name_or_path = dir_path_of_temp_table;
+			name_or_path = mem_heap_strdup(
+				heap, table->dir_path_of_temp_table);
 		} else {
 			is_path = FALSE;
 			name_or_path = name;
@@ -3272,13 +3274,7 @@ check_next_foreign:
 					"InnoDB: of table ");
 				ut_print_name(stderr, trx, TRUE, name);
 				fprintf(stderr, ".\n");
-
-				goto funct_exit;
-			}
-
-			success = fil_delete_tablespace(space_id);
-
-			if (!success) {
+			} else if (!fil_delete_tablespace(space_id)) {
 				fprintf(stderr,
 					"InnoDB: We removed now the InnoDB"
 					" internal data dictionary entry\n"
@@ -3296,6 +3292,8 @@ check_next_foreign:
 				err = DB_ERROR;
 			}
 		}
+
+		mem_heap_free(heap);
 	}
 funct_exit:
 
@@ -3303,10 +3301,6 @@ funct_exit:
 
 	if (locked_dictionary) {
 		row_mysql_unlock_data_dictionary(trx);
-	}
-
-	if (dir_path_of_temp_table) {
-		mem_free(dir_path_of_temp_table);
 	}
 
 	trx->op_info = "";
diff -Nrup a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
--- a/storage/innobase/row/row0sel.c	2007-09-08 12:19:31 -06:00
+++ b/storage/innobase/row/row0sel.c	2007-11-06 15:23:46 -07:00
@@ -531,12 +531,13 @@ row_sel_build_prev_vers(
 /*====================*/
 					/* out: DB_SUCCESS or error code */
 	read_view_t*	read_view,	/* in: read view */
-	plan_t*		plan,		/* in: plan node for table */
+	dict_index_t*	index,		/* in: plan node for table */
 	rec_t*		rec,		/* in: record in a clustered index */
 	ulint**		offsets,	/* in/out: offsets returned by
 					rec_get_offsets(rec, plan->index) */
 	mem_heap_t**	offset_heap,	/* in/out: memory heap from which
 					the offsets are allocated */
+	mem_heap_t**    old_vers_heap,  /* out: old version heap to use */
 	rec_t**		old_vers,	/* out: old version, or NULL if the
 					record does not exist in the view:
 					i.e., it was freshly inserted
@@ -545,15 +546,15 @@ row_sel_build_prev_vers(
 {
 	ulint	err;
 
-	if (plan->old_vers_heap) {
-		mem_heap_empty(plan->old_vers_heap);
+	if (*old_vers_heap) {
+		mem_heap_empty(*old_vers_heap);
 	} else {
-		plan->old_vers_heap = mem_heap_create(512);
+		*old_vers_heap = mem_heap_create(512);
 	}
 
 	err = row_vers_build_for_consistent_read(
-		rec, mtr, plan->index, offsets, read_view, offset_heap,
-		plan->old_vers_heap, old_vers);
+		rec, mtr, index, offsets, read_view, offset_heap,
+		*old_vers_heap, old_vers);
 	return(err);
 }
 
@@ -765,9 +766,11 @@ row_sel_get_clust_rec(
 		if (!lock_clust_rec_cons_read_sees(clust_rec, index, offsets,
 						   node->read_view)) {
 
-			err = row_sel_build_prev_vers(node->read_view, plan,
-						      clust_rec, &offsets,
-						      &heap, &old_vers, mtr);
+			err = row_sel_build_prev_vers(
+				node->read_view, index, clust_rec,
+				&offsets, &heap, &plan->old_vers_heap,
+				&old_vers, mtr);
+
 			if (err != DB_SUCCESS) {
 
 				goto err_exit;
@@ -1490,10 +1493,11 @@ skip_lock:
 			if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
 							   node->read_view)) {
 
-				err = row_sel_build_prev_vers(node->read_view,
-							      plan, rec,
-							      &offsets, &heap,
-							      &old_vers, &mtr);
+				err = row_sel_build_prev_vers(
+					node->read_view, index, rec,
+					&offsets, &heap, &plan->old_vers_heap,
+					&old_vers, &mtr);
+
 				if (err != DB_SUCCESS) {
 
 					goto lock_wait_or_error;
@@ -3999,6 +4003,7 @@ no_gap_lock:
 			mutex_enter(&kernel_mutex);
 			if (trx->was_chosen_as_deadlock_victim) {
 				mutex_exit(&kernel_mutex);
+				err = DB_DEADLOCK;
 
 				goto lock_wait_or_error;
 			}
@@ -4536,6 +4541,7 @@ row_search_autoinc_read_column(
 	const byte*	data;
 	ib_longlong	value;
 	mem_heap_t*	heap = NULL;
+	/* Our requirement is that dest should be word aligned. */
 	byte		dest[sizeof(value)];
 	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
 	ulint*		offsets	= offsets_;
@@ -4554,20 +4560,35 @@ row_search_autoinc_read_column(
 	ut_a(len != UNIV_SQL_NULL);
 	ut_a(len <= sizeof value);
 
-	/* Copy integer data and restore sign bit */
-	if (unsigned_type || (data[0] & 128))
-		memset(dest, 0x00, sizeof(dest));
-	else
-		memset(dest, 0xff, sizeof(dest));
-
-	memcpy(dest + (sizeof(value) - len), data, len);
-
-	if (!unsigned_type)
-		dest[sizeof(value) - len] ^= 128;
-
-	/* The assumption here is that the AUTOINC value can't be negative.*/
-	value = (((ib_longlong) mach_read_from_4(dest)) << 32) |
-		 ((ib_longlong) mach_read_from_4(dest + 4));        
+	mach_read_int_type(dest, data, len, unsigned_type);
+
+	/* The assumption here is that the AUTOINC value can't be negative
+	and that dest is word aligned. */
+	switch (len) {
+	case 8:
+		value = *(ib_longlong*) dest;
+		break;
+
+	case 4:
+		value = *(ib_uint32_t*) dest;
+		break;
+
+	case 3:
+		value = *(ib_uint32_t*) dest;
+		value &= 0xFFFFFF;
+		break;
+
+	case 2:
+		value = *(uint16 *) dest;
+		break;
+
+	case 1:
+		value = *dest;
+		break;
+
+	default:
+		ut_error;
+	}
 
 	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
diff -Nrup a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
--- a/storage/innobase/sync/sync0rw.c	2007-07-24 19:27:13 -06:00
+++ b/storage/innobase/sync/sync0rw.c	2007-11-06 15:23:46 -07:00
@@ -174,9 +174,7 @@ rw_lock_free(
 /*=========*/
 	rw_lock_t*	lock)	/* in: rw-lock */
 {
-#ifdef UNIV_DEBUG
-	ut_a(rw_lock_validate(lock));
-#endif /* UNIV_DEBUG */
+	ut_ad(rw_lock_validate(lock));
 	ut_a(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
 	ut_a(rw_lock_get_waiters(lock) == 0);
 	ut_a(rw_lock_get_reader_count(lock) == 0);
@@ -199,6 +197,7 @@ rw_lock_free(
 	mutex_exit(&rw_lock_list_mutex);
 }
 
+#ifdef UNIV_DEBUG
 /**********************************************************************
 Checks that the rw-lock has been initialized and that there are no
 simultaneous shared and exclusive locks. */
@@ -226,6 +225,7 @@ rw_lock_validate(
 
 	return(TRUE);
 }
+#endif /* UNIV_DEBUG */
 
 /**********************************************************************
 Lock an rw-lock in shared mode for the current thread. If the rw-lock is
diff -Nrup a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c
--- a/storage/innobase/ut/ut0ut.c	2007-07-09 18:16:01 -06:00
+++ b/storage/innobase/ut/ut0ut.c	2007-11-06 15:23:46 -07:00
@@ -18,6 +18,7 @@ Created 5/11/1994 Heikki Tuuri
 
 #include "ut0sort.h"
 #include "trx0trx.h"
+#include "ha_prototypes.h"
 
 ibool	ut_always_false	= FALSE;
 
@@ -70,22 +71,6 @@ ut_gettimeofday(
 #define	ut_gettimeofday		gettimeofday
 #endif
 
-#ifndef UNIV_HOTBACKUP
-/*********************************************************************
-Display an SQL identifier.
-This definition must match the one in sql/ha_innodb.cc! */
-extern
-void
-innobase_print_identifier(
-/*======================*/
-	FILE*		f,	/* in: output stream */
-	trx_t*		trx,	/* in: transaction */
-	ibool		table_id,/* in: TRUE=print a table name,
-				FALSE=print other identifier */
-	const char*	name,	/* in: name to print */
-	ulint		namelen);/* in: length of name */
-#endif /* !UNIV_HOTBACKUP */
-
 /************************************************************
 Gets the high 32 bits in a ulint. That is makes a shift >> 32,
 but since there seem to be compiler bugs in both gcc and Visual C++,
@@ -360,6 +345,8 @@ ut_print_buf(
 	const byte*	data;
 	ulint		i;
 
+	UNIV_MEM_ASSERT_RW(buf, len);
+
 	fprintf(file, " len %lu; hex ", len);
 
 	for (data = (const byte*)buf, i = 0; i < len; i++) {
@@ -474,17 +461,20 @@ ut_print_namel(
 #ifdef UNIV_HOTBACKUP
 	fwrite(name, 1, namelen, f);
 #else
-	char*	slash = memchr(name, '/', namelen);
+	if (table_id) {
+		char*	slash = memchr(name, '/', namelen);
+		if (!slash) {
 
-	if (UNIV_LIKELY_NULL(slash)) {
-		/* Print the database name and table name separately. */
-		ut_ad(table_id);
+			goto no_db_name;
+		}
 
+		/* Print the database name and table name separately. */
 		innobase_print_identifier(f, trx, TRUE, name, slash - name);
 		putc('.', f);
 		innobase_print_identifier(f, trx, TRUE, slash + 1,
 					  namelen - (slash - name) - 1);
 	} else {
+no_db_name:
 		innobase_print_identifier(f, trx, table_id, name, namelen);
 	}
 #endif
@@ -515,3 +505,44 @@ ut_copy_file(
 		}
 	} while (len > 0);
 }
+
+/**************************************************************************
+snprintf(). */
+
+#ifdef __WIN__
+#include <stdarg.h>
+int
+ut_snprintf(
+				/* out: number of characters that would
+				have been printed if the size were
+				unlimited, not including the terminating
+				'\0'. */
+	char*		str,	/* out: string */
+	size_t		size,	/* in: str size */
+	const char*	fmt,	/* in: format */
+	...)			/* in: format values */
+{
+	int	res;
+	va_list	ap1;
+	va_list	ap2;
+
+	va_start(ap1, fmt);
+	va_start(ap2, fmt);
+
+	res = _vscprintf(fmt, ap1);
+	ut_a(res != -1);
+
+	if (size > 0) {
+		_vsnprintf(str, size, fmt, ap2);
+
+		if ((size_t) res >= size) {
+			str[size - 1] = '\0';
+		}
+	}
+
+	va_end(ap1);
+	va_end(ap2);
+
+	return(res);
+}
+#endif /* __WIN__ */
Thread
bk commit into 5.1 tree (tsmith:1.2604) BUG#30706tim6 Nov