From 1d94461365a9bd97d22ead3a2d339af6b741f916 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Dec 2011 12:22:47 +0100 Subject: Raise version number after cloning 5.0.95 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index a06f726c738..908171ca857 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.95) +AM_INIT_AUTOMAKE(mysql, 5.0.96) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=95 +NDB_VERSION_BUILD=96 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? -- cgit v1.2.1 From c67d63ca5baecb84426d584a07a571c97f448bb7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Dec 2011 12:24:05 +0100 Subject: Raise version number after cloning 5.1.61 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 080de523c1b..fb6155aa0be 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.61], [], [mysql]) +AC_INIT([MySQL Server], [5.1.62], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM -- cgit v1.2.1 From 2d63ea643b82ea6ed673a3bf42f02197edca98fe Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Fri, 16 Dec 2011 12:31:57 +0100 Subject: Raise version number after cloning --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 080de523c1b..fb6155aa0be 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.61], [], [mysql]) +AC_INIT([MySQL Server], [5.1.62], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM -- cgit v1.2.1 From b42c3932f83afc80015a1800465548b646d9e749 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Fri, 16 Dec 2011 12:33:54 +0100 Subject: Raise version number after cloning --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index a06f726c738..908171ca857 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.95) +AM_INIT_AUTOMAKE(mysql, 5.0.96) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=95 +NDB_VERSION_BUILD=96 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? -- cgit v1.2.1 From 3953b489714ee5eaf329894256e7fa56a7698d6b Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Wed, 21 Dec 2011 21:33:13 -0500 Subject: Bug#11866367 FPE WHEN SETTING INNODB_SPIN_WAIT_DELAY rb://865 approved by: Jimmy Integer overflow causes division by zero. --- storage/innobase/include/ut0rnd.ic | 2 +- storage/innodb_plugin/include/ut0rnd.ic | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic index dc4c0d62f56..b54f629de37 100644 --- a/storage/innobase/include/ut0rnd.ic +++ b/storage/innobase/include/ut0rnd.ic @@ -96,7 +96,7 @@ ut_rnd_interval( rnd = ut_rnd_gen_ulint(); - return(low + (rnd % (high - low + 1))); + return(low + (rnd % (high - low))); } /************************************************************* diff --git a/storage/innodb_plugin/include/ut0rnd.ic b/storage/innodb_plugin/include/ut0rnd.ic index a33813037ea..3ae12f69186 100644 --- a/storage/innodb_plugin/include/ut0rnd.ic +++ b/storage/innodb_plugin/include/ut0rnd.ic @@ -114,7 +114,7 @@ ut_rnd_interval( rnd = ut_rnd_gen_ulint(); - return(low + (rnd % (high - low + 1))); + return(low + (rnd % (high - low))); } /*********************************************************//** -- cgit v1.2.1 From 564d4a65bda21e36a408036723137d14a1aa1372 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Wed, 21 Dec 2011 21:36:52 -0500 Subject: Add ChangeLog message. --- storage/innodb_plugin/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 5fc0cce3ff2..1385da94bfb 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2011-12-21 The InnoDB Team + + * include/ut0rnd.ic: + Fix Bug#11866367:FPE WHEN SETTING INNODB_SPIN_WAIT_DELAY + 2011-12-13 The InnoDB Team * handler/ha_innodb.cc, innodb.test, innodb.result: -- cgit v1.2.1 From 86505c3c545d3866a85464b0762b452d85599993 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 22 Dec 2011 12:55:44 +0200 Subject: Fix Bug#13510739 63775: SERVER CRASH ON HANDLER READ NEXT AFTER DELETE RECORD. CREATE TABLE bug13510739 (c INTEGER NOT NULL, PRIMARY KEY (c)) ENGINE=INNODB; INSERT INTO bug13510739 VALUES (1), (2), (3), (4); DELETE FROM bug13510739 WHERE c=2; HANDLER bug13510739 OPEN; HANDLER bug13510739 READ `primary` = (2); HANDLER bug13510739 READ `primary` NEXT; <-- crash The bug is that in the particular testcase row_search_for_mysql() picked up a delete-marked record and quit, leaving the cursor non-positioned state and on the subsequent 'get next' call the code crashed because of the non-positioned cursor. In row0sel.cc (line numbers from mysql-trunk): 4653 if (rec_get_deleted_flag(rec, comp)) { ... 4679 if (index == clust_index && unique_search) { 4680 4681 err = DB_RECORD_NOT_FOUND; 4682 4683 goto normal_return; 4684 } it quit from here, not storing the cursor position. In contrast, if the record=2 is not found at all (e.g. sleep(1) after DELETE to let the purge wipe it away completely) then 'get = 2' does find record=3 and quits from here: 4366 if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) { ... 4394 btr_pcur_store_position(pcur, &mtr); 4395 4396 err = DB_RECORD_NOT_FOUND; 4397 #if 0 4398 ut_print_name(stderr, trx, FALSE, index->name); 4399 fputs(" record not found 3\n", stderr); 4400 #endif 4401 4402 goto normal_return; Another fix could be to extend the condition on line 4366 to hold only if seach_tuple matches rec AND if rec is not delete marked. Notice that in the above test case if we wait about 1 second somewhere after DELETE and before 'get = 2', then the testcase does not crash and returns 4 instead. Not sure if this is the correct behavior, but this bugfix removes the crash and makes the code return what it also returns in the non-crashing case (if rec=2 is not found during 'get = 2', e.g. we have sleep(1) there). Approved by: Marko (http://bur03.no.oracle.com/rb/r/863/) --- mysql-test/suite/innodb/r/innodb_bug13510739.result | 10 ++++++++++ mysql-test/suite/innodb/t/innodb_bug13510739.test | 20 ++++++++++++++++++++ .../suite/innodb_plugin/r/innodb_bug13510739.result | 10 ++++++++++ .../suite/innodb_plugin/t/innodb_bug13510739.test | 20 ++++++++++++++++++++ storage/innobase/row/row0sel.c | 4 +++- storage/innodb_plugin/ChangeLog | 5 +++++ storage/innodb_plugin/row/row0sel.c | 4 +++- 7 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug13510739.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug13510739.test create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug13510739.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug13510739.test diff --git a/mysql-test/suite/innodb/r/innodb_bug13510739.result b/mysql-test/suite/innodb/r/innodb_bug13510739.result new file mode 100644 index 00000000000..8aa4323eeb0 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug13510739.result @@ -0,0 +1,10 @@ +CREATE TABLE bug13510739 (c INTEGER NOT NULL, PRIMARY KEY (c)) ENGINE=INNODB; +INSERT INTO bug13510739 VALUES (1), (2), (3), (4); +DELETE FROM bug13510739 WHERE c=2; +HANDLER bug13510739 OPEN; +HANDLER bug13510739 READ `primary` = (2); +c +HANDLER bug13510739 READ `primary` NEXT; +c +4 +DROP TABLE bug13510739; diff --git a/mysql-test/suite/innodb/t/innodb_bug13510739.test b/mysql-test/suite/innodb/t/innodb_bug13510739.test new file mode 100644 index 00000000000..f10bcd8e272 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug13510739.test @@ -0,0 +1,20 @@ +# +# Bug#13510739 63775: SERVER CRASH ON HANDLER READ NEXT AFTER DELETE RECORD. +# + +-- source include/have_innodb.inc + +CREATE TABLE bug13510739 (c INTEGER NOT NULL, PRIMARY KEY (c)) ENGINE=INNODB; + +INSERT INTO bug13510739 VALUES (1), (2), (3), (4); + +DELETE FROM bug13510739 WHERE c=2; + +HANDLER bug13510739 OPEN; + +HANDLER bug13510739 READ `primary` = (2); + +# this one crashes the server if the bug is present +HANDLER bug13510739 READ `primary` NEXT; + +DROP TABLE bug13510739; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug13510739.result b/mysql-test/suite/innodb_plugin/r/innodb_bug13510739.result new file mode 100644 index 00000000000..8aa4323eeb0 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug13510739.result @@ -0,0 +1,10 @@ +CREATE TABLE bug13510739 (c INTEGER NOT NULL, PRIMARY KEY (c)) ENGINE=INNODB; +INSERT INTO bug13510739 VALUES (1), (2), (3), (4); +DELETE FROM bug13510739 WHERE c=2; +HANDLER bug13510739 OPEN; +HANDLER bug13510739 READ `primary` = (2); +c +HANDLER bug13510739 READ `primary` NEXT; +c +4 +DROP TABLE bug13510739; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug13510739.test b/mysql-test/suite/innodb_plugin/t/innodb_bug13510739.test new file mode 100644 index 00000000000..b8ffcc7b22b --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug13510739.test @@ -0,0 +1,20 @@ +# +# Bug#13510739 63775: SERVER CRASH ON HANDLER READ NEXT AFTER DELETE RECORD. +# + +-- source include/have_innodb_plugin.inc + +CREATE TABLE bug13510739 (c INTEGER NOT NULL, PRIMARY KEY (c)) ENGINE=INNODB; + +INSERT INTO bug13510739 VALUES (1), (2), (3), (4); + +DELETE FROM bug13510739 WHERE c=2; + +HANDLER bug13510739 OPEN; + +HANDLER bug13510739 READ `primary` = (2); + +# this one crashes the server if the bug is present +HANDLER bug13510739 READ `primary` NEXT; + +DROP TABLE bug13510739; diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 9ab6424a012..915cc8339d4 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -4208,7 +4208,9 @@ no_gap_lock: applicable to unique secondary indexes. Current behaviour is to widen the scope of a lock on an already delete marked record if the same record is deleted twice by the same transaction */ - if (index == clust_index && unique_search) { + if (index == clust_index && unique_search + && !prebuilt->used_in_HANDLER) { + err = DB_RECORD_NOT_FOUND; goto normal_return; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index d836b390c52..ab0c68ee297 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2011-12-22 The InnoDB Team + + * row/row0sel.c: + Fix Bug#63775 Server crash on handler read next after delete record. + 2011-12-13 The InnoDB Team * handler/ha_innodb.cc, innodb.test, innodb.result: diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index 32f21dbe198..54172e71a47 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -4362,7 +4362,9 @@ no_gap_lock: applicable to unique secondary indexes. Current behaviour is to widen the scope of a lock on an already delete marked record if the same record is deleted twice by the same transaction */ - if (index == clust_index && unique_search) { + if (index == clust_index && unique_search + && !prebuilt->used_in_HANDLER) { + err = DB_RECORD_NOT_FOUND; goto normal_return; -- cgit v1.2.1 From 790a3a46f38ca1040f756fd64c0cca7b78b50f67 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 23 Dec 2011 17:22:48 +0400 Subject: Fix for bug#11758931 - 51196: SLAVE SQL: GOT AN ERROR WRITING COMMUNICATION PACKETS, ERROR_CODE: 1160 If idle FEDERATED table is evicted from the table cache when a connection to remote server is lost, query that initiated eviction may fail. If this query is executed by slave SQL thread it may fail as well. An error of close was stored in diagnostics area, which was later attributed to the statement that caused eviction. With this patch FEDERATED clears an error of close. --- storage/federated/ha_federated.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 21c0b7b178d..64d5af446d8 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1651,6 +1651,15 @@ int ha_federated::close(void) mysql_close(mysql); mysql= NULL; + /* + mysql_close() might return an error if a remote server's gone + for some reason. If that happens while removing a table from + the table cache, the error will be propagated to a client even + if the original query was not issued against the FEDERATED table. + So, don't propagate errors from mysql_close(). + */ + table->in_use->clear_error(); + DBUG_RETURN(free_share(share)); } -- cgit v1.2.1 From 289af2579b5084d554b71a9307ec705afbba8ae7 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 23 Dec 2011 18:52:44 +0400 Subject: Fix for bug#11758931 - 51196: SLAVE SQL: GOT AN ERROR WRITING COMMUNICATION PACKETS, ERROR_CODE: 1160 Addendum: for some queries table->in_use might be NULL - check it. --- storage/federated/ha_federated.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 64d5af446d8..f53066a4b22 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1658,7 +1658,8 @@ int ha_federated::close(void) if the original query was not issued against the FEDERATED table. So, don't propagate errors from mysql_close(). */ - table->in_use->clear_error(); + if (table->in_use) + table->in_use->clear_error(); DBUG_RETURN(free_share(share)); } -- cgit v1.2.1 From e498a1bf65101878f51d0b2ca3eb0d05a8d3d01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 28 Dec 2011 12:19:30 +0200 Subject: Bug#13418934 REMOVE HAVE_PURIFY DEPENDENCES FROM INNODB InnoDB: Remove HAVE_purify, UNIV_INIT_MEM_TO_ZERO, UNIV_SET_MEM_TO_ZERO. The compile-time setting HAVE_purify can mask potential bugs. It is being set in PB2 Valgrind runs. We should simply get rid of it, and replace it with UNIV_MEM_INVALID() to declare uninitialized memory as such in Valgrind-instrumented binaries. os_mem_alloc_large(), ut_malloc_low(): Remove the parameter set_to_zero. ut_malloc(): Define as a macro that invokes ut_malloc_low(). buf_pool_init(): Never initialize the buffer pool frames. All pages must be initialized before flushing them to disk. mem_heap_alloc(): Never initialize the allocated memory block. os_mem_alloc_nocache(), ut_test_malloc(): Unused function, remove. rb:813 approved by Jimmy Yang --- storage/innobase/buf/buf0buf.c | 8 +--- storage/innobase/include/mem0mem.ic | 4 -- storage/innobase/include/os0proc.h | 11 ----- storage/innobase/include/univ.i | 17 ------- storage/innobase/include/ut0mem.h | 26 ++-------- storage/innobase/mem/mem0pool.c | 6 +-- storage/innobase/os/os0proc.c | 33 +------------ storage/innobase/ut/ut0mem.c | 65 +------------------------ storage/innodb_plugin/buf/buf0buf.c | 5 +- storage/innodb_plugin/include/mem0mem.ic | 4 -- storage/innodb_plugin/include/univ.i | 17 ------- storage/innodb_plugin/include/ut0mem.h | 31 ++---------- storage/innodb_plugin/mem/mem0pool.c | 6 +-- storage/innodb_plugin/os/os0proc.c | 3 -- storage/innodb_plugin/ut/ut0mem.c | 82 +------------------------------- 15 files changed, 16 insertions(+), 302 deletions(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 78b39812cff..5463098a654 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -634,7 +634,7 @@ buf_pool_init( /*----------------------------------------*/ } else { buf_pool->frame_mem = os_mem_alloc_large( - UNIV_PAGE_SIZE * (n_frames + 1), TRUE, FALSE); + UNIV_PAGE_SIZE * (n_frames + 1), FALSE); } if (buf_pool->frame_mem == NULL) { @@ -756,12 +756,8 @@ buf_pool_init( block = buf_pool_get_nth_block(buf_pool, i); if (block->frame) { - /* Wipe contents of frame to eliminate a Purify - warning */ + UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); -#ifdef HAVE_purify - memset(block->frame, '\0', UNIV_PAGE_SIZE); -#endif if (srv_use_awe) { /* Add to the list of blocks mapped to frames */ diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic index 782672dbc18..0191e9a3ffd 100644 --- a/storage/innobase/include/mem0mem.ic +++ b/storage/innobase/include/mem0mem.ic @@ -194,10 +194,6 @@ mem_heap_alloc( caller */ buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; -#endif -#ifdef UNIV_SET_MEM_TO_ZERO - UNIV_MEM_ALLOC(buf, n); - memset(buf, '\0', n); #endif UNIV_MEM_ALLOC(buf, n); return(buf); diff --git a/storage/innobase/include/os0proc.h b/storage/innobase/include/os0proc.h index f54e08de7ee..8c169f92431 100644 --- a/storage/innobase/include/os0proc.h +++ b/storage/innobase/include/os0proc.h @@ -104,14 +104,6 @@ ulint os_proc_get_number(void); /*====================*/ /******************************************************************** -Allocates non-cacheable memory. */ - -void* -os_mem_alloc_nocache( -/*=================*/ - /* out: allocated memory */ - ulint n); /* in: number of bytes */ -/******************************************************************** Allocates large pages memory. */ void* @@ -119,9 +111,6 @@ os_mem_alloc_large( /*===============*/ /* out: allocated memory */ ulint n, /* in: number of bytes */ - ibool set_to_zero, /* in: TRUE if allocated memory - should be set to zero if - UNIV_SET_MEM_TO_ZERO is defined */ ibool assert_on_error);/* in: if TRUE, we crash mysqld if the memory cannot be allocated */ /******************************************************************** diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index a67b1b3895e..4ac0809bcd2 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -72,14 +72,6 @@ Microsoft Visual C++ */ /* DEBUG VERSION CONTROL ===================== */ -/* The following flag will make InnoDB to initialize -all memory it allocates to zero. It hides Purify -warnings about reading unallocated memory unless -memory is read outside the allocated blocks. */ -/* -#define UNIV_INIT_MEM_TO_ZERO -*/ - /* Make a non-inline debug version */ #if defined HAVE_VALGRIND @@ -112,15 +104,6 @@ operations (very slow); also UNIV_DEBUG must be defined */ #define UNIV_BTR_DEBUG /* check B-tree links */ #define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */ -#ifdef HAVE_purify -/* The following sets all new allocated memory to zero before use: -this can be used to eliminate unnecessary Purify warnings, but note that -it also masks many bugs Purify could detect. For detailed Purify analysis it -is best to remove the define below and look through the warnings one -by one. */ -#define UNIV_SET_MEM_TO_ZERO -#endif - /* #define UNIV_SQL_DEBUG #define UNIV_LOG_DEBUG diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h index cb369e85c39..0dff70abc3a 100644 --- a/storage/innobase/include/ut0mem.h +++ b/storage/innobase/include/ut0mem.h @@ -30,38 +30,18 @@ ut_memcmp(const void* str1, const void* str2, ulint n); /************************************************************************** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined and set_to_zero is TRUE. */ +Allocates memory. */ void* ut_malloc_low( /*==========*/ /* out, own: allocated memory */ ulint n, /* in: number of bytes to allocate */ - ibool set_to_zero, /* in: TRUE if allocated memory - should be set to zero if - UNIV_SET_MEM_TO_ZERO is defined */ ibool assert_on_error); /* in: if TRUE, we crash mysqld if the memory cannot be allocated */ /************************************************************************** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined. */ - -void* -ut_malloc( -/*======*/ - /* out, own: allocated memory */ - ulint n); /* in: number of bytes to allocate */ -/************************************************************************** -Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs -out. It cannot be used if we want to return an error message. Prints to -stderr a message if fails. */ - -ibool -ut_test_malloc( -/*===========*/ - /* out: TRUE if succeeded */ - ulint n); /* in: try to allocate this many bytes */ +Allocates memory. */ +#define ut_malloc(n) ut_malloc_low(n, TRUE) /************************************************************************** Frees a memory block allocated with ut_malloc. */ diff --git a/storage/innobase/mem/mem0pool.c b/storage/innobase/mem/mem0pool.c index 27da86a0309..6740ff04a4f 100644 --- a/storage/innobase/mem/mem0pool.c +++ b/storage/innobase/mem/mem0pool.c @@ -196,11 +196,7 @@ mem_pool_create( pool = ut_malloc(sizeof(mem_pool_t)); - /* We do not set the memory to zero (FALSE) in the pool, - but only when allocated at a higher level in mem0mem.c. - This is to avoid masking useful Purify warnings. */ - - pool->buf = ut_malloc_low(size, FALSE, TRUE); + pool->buf = ut_malloc_low(size, TRUE); pool->size = size; mutex_create(&pool->mutex, SYNC_MEM_POOL); diff --git a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c index f00475fc528..6092392616f 100644 --- a/storage/innobase/os/os0proc.c +++ b/storage/innobase/os/os0proc.c @@ -531,28 +531,6 @@ os_proc_get_number(void) #endif } -/******************************************************************** -Allocates non-cacheable memory. */ - -void* -os_mem_alloc_nocache( -/*=================*/ - /* out: allocated memory */ - ulint n) /* in: number of bytes */ -{ -#ifdef __WIN__ - void* ptr; - - ptr = VirtualAlloc(NULL, n, MEM_COMMIT, - PAGE_READWRITE | PAGE_NOCACHE); - ut_a(ptr); - - return(ptr); -#else - return(ut_malloc(n)); -#endif -} - /******************************************************************** Allocates large pages memory. */ @@ -561,9 +539,6 @@ os_mem_alloc_large( /*===============*/ /* out: allocated memory */ ulint n, /* in: number of bytes */ - ibool set_to_zero, /* in: TRUE if allocated memory - should be set to zero if - UNIV_SET_MEM_TO_ZERO is defined */ ibool assert_on_error)/* in: if TRUE, we crash mysqld if the memory cannot be allocated */ { @@ -602,12 +577,6 @@ os_mem_alloc_large( #endif if (ptr) { - if (set_to_zero) { -#ifdef UNIV_SET_MEM_TO_ZERO - memset(ptr, '\0', size); -#endif - } - return(ptr); } @@ -616,7 +585,7 @@ os_mem_alloc_large( skip: #endif /* HAVE_LARGE_PAGES */ - return(ut_malloc_low(n, set_to_zero, assert_on_error)); + return(ut_malloc_low(n, assert_on_error)); } /******************************************************************** diff --git a/storage/innobase/ut/ut0mem.c b/storage/innobase/ut/ut0mem.c index 2e0dd27edf4..55f1c8593b8 100644 --- a/storage/innobase/ut/ut0mem.c +++ b/storage/innobase/ut/ut0mem.c @@ -54,17 +54,13 @@ ut_mem_block_list_init(void) } /************************************************************************** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined and set_to_zero is TRUE. */ +Allocates memory. */ void* ut_malloc_low( /*==========*/ /* out, own: allocated memory */ ulint n, /* in: number of bytes to allocate */ - ibool set_to_zero, /* in: TRUE if allocated memory should be - set to zero if UNIV_SET_MEM_TO_ZERO is - defined */ ibool assert_on_error)/* in: if TRUE, we crash mysqld if the memory cannot be allocated */ { @@ -156,12 +152,6 @@ retry: #endif } - if (set_to_zero) { -#ifdef UNIV_SET_MEM_TO_ZERO - memset(ret, '\0', n + sizeof(ut_mem_block_t)); -#endif - } - UNIV_MEM_ALLOC(ret, n + sizeof(ut_mem_block_t)); ((ut_mem_block_t*)ret)->size = n + sizeof(ut_mem_block_t); @@ -176,59 +166,6 @@ retry: return((void*)((byte*)ret + sizeof(ut_mem_block_t))); } -/************************************************************************** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined. */ - -void* -ut_malloc( -/*======*/ - /* out, own: allocated memory */ - ulint n) /* in: number of bytes to allocate */ -{ - return(ut_malloc_low(n, TRUE, TRUE)); -} - -/************************************************************************** -Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs -out. It cannot be used if we want to return an error message. Prints to -stderr a message if fails. */ - -ibool -ut_test_malloc( -/*===========*/ - /* out: TRUE if succeeded */ - ulint n) /* in: try to allocate this many bytes */ -{ - void* ret; - - ret = malloc(n); - - if (ret == NULL) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: cannot allocate" - " %lu bytes of memory for\n" - "InnoDB: a BLOB with malloc! Total allocated memory\n" - "InnoDB: by InnoDB %lu bytes." - " Operating system errno: %d\n" - "InnoDB: Check if you should increase" - " the swap file or\n" - "InnoDB: ulimits of your operating system.\n" - "InnoDB: On FreeBSD check you have" - " compiled the OS with\n" - "InnoDB: a big enough maximum process size.\n", - (ulong) n, - (ulong) ut_total_allocated_memory, - (int) errno); - return(FALSE); - } - - free(ret); - - return(TRUE); -} - /************************************************************************** Frees a memory block allocated with ut_malloc. */ diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index d88860b807b..6daaacb0ac0 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -750,11 +750,8 @@ buf_chunk_init( for (i = chunk->size; i--; ) { buf_block_init(block, frame); + UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); -#ifdef HAVE_purify - /* Wipe contents of frame to eliminate a Purify warning */ - memset(block->frame, '\0', UNIV_PAGE_SIZE); -#endif /* Add the block to the free list */ UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page)); ut_d(block->page.in_free_list = TRUE); diff --git a/storage/innodb_plugin/include/mem0mem.ic b/storage/innodb_plugin/include/mem0mem.ic index cbce2edc661..bf7b1c20cb4 100644 --- a/storage/innodb_plugin/include/mem0mem.ic +++ b/storage/innodb_plugin/include/mem0mem.ic @@ -208,10 +208,6 @@ mem_heap_alloc( caller */ buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; -#endif -#ifdef UNIV_SET_MEM_TO_ZERO - UNIV_MEM_ALLOC(buf, n); - memset(buf, '\0', n); #endif UNIV_MEM_ALLOC(buf, n); return(buf); diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index 5e36867f05a..c3aa3d25e36 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -146,14 +146,6 @@ Sun Studio */ /* DEBUG VERSION CONTROL ===================== */ -/* The following flag will make InnoDB to initialize -all memory it allocates to zero. It hides Purify -warnings about reading unallocated memory unless -memory is read outside the allocated blocks. */ -/* -#define UNIV_INIT_MEM_TO_ZERO -*/ - /* When this macro is defined then additional test functions will be compiled. These functions live at the end of each relevant source file and have "test_" prefix. These functions are not called from anywhere in @@ -218,15 +210,6 @@ operations (very slow); also UNIV_DEBUG must be defined */ #define UNIV_BTR_DEBUG /* check B-tree links */ #define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */ -#ifdef HAVE_purify -/* The following sets all new allocated memory to zero before use: -this can be used to eliminate unnecessary Purify warnings, but note that -it also masks many bugs Purify could detect. For detailed Purify analysis it -is best to remove the define below and look through the warnings one -by one. */ -#define UNIV_SET_MEM_TO_ZERO -#endif - /* #define UNIV_SQL_DEBUG #define UNIV_LOG_DEBUG diff --git a/storage/innodb_plugin/include/ut0mem.h b/storage/innodb_plugin/include/ut0mem.h index 9c6ee9049ec..5002c9e3801 100644 --- a/storage/innodb_plugin/include/ut0mem.h +++ b/storage/innodb_plugin/include/ut0mem.h @@ -78,40 +78,19 @@ ut_mem_init(void); /*=============*/ /**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined and set_to_zero is TRUE. +Allocates memory. @return own: allocated memory */ UNIV_INTERN void* ut_malloc_low( /*==========*/ ulint n, /*!< in: number of bytes to allocate */ - ibool set_to_zero, /*!< in: TRUE if allocated memory - should be set to zero if - UNIV_SET_MEM_TO_ZERO is defined */ - ibool assert_on_error); /*!< in: if TRUE, we crash mysqld if + ibool assert_on_error) /*!< in: if TRUE, we crash mysqld if the memory cannot be allocated */ + __attribute__((malloc)); /**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined. -@return own: allocated memory */ -UNIV_INTERN -void* -ut_malloc( -/*======*/ - ulint n); /*!< in: number of bytes to allocate */ -#ifndef UNIV_HOTBACKUP -/**********************************************************************//** -Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs -out. It cannot be used if we want to return an error message. Prints to -stderr a message if fails. -@return TRUE if succeeded */ -UNIV_INTERN -ibool -ut_test_malloc( -/*===========*/ - ulint n); /*!< in: try to allocate this many bytes */ -#endif /* !UNIV_HOTBACKUP */ +Allocates memory. */ +#define ut_malloc(n) ut_malloc_low(n, TRUE) /**********************************************************************//** Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is a nop. */ diff --git a/storage/innodb_plugin/mem/mem0pool.c b/storage/innodb_plugin/mem/mem0pool.c index 3291453eeb5..8a01be66506 100644 --- a/storage/innodb_plugin/mem/mem0pool.c +++ b/storage/innodb_plugin/mem/mem0pool.c @@ -223,11 +223,7 @@ mem_pool_create( pool = ut_malloc(sizeof(mem_pool_t)); - /* We do not set the memory to zero (FALSE) in the pool, - but only when allocated at a higher level in mem0mem.c. - This is to avoid masking useful Purify warnings. */ - - pool->buf = ut_malloc_low(size, FALSE, TRUE); + pool->buf = ut_malloc_low(size, TRUE); pool->size = size; mutex_create(&pool->mutex, SYNC_MEM_POOL); diff --git a/storage/innodb_plugin/os/os0proc.c b/storage/innodb_plugin/os/os0proc.c index 48922886f23..a0679e31570 100644 --- a/storage/innodb_plugin/os/os0proc.c +++ b/storage/innodb_plugin/os/os0proc.c @@ -111,9 +111,6 @@ os_mem_alloc_large( os_fast_mutex_lock(&ut_list_mutex); ut_total_allocated_memory += size; os_fast_mutex_unlock(&ut_list_mutex); -# ifdef UNIV_SET_MEM_TO_ZERO - memset(ptr, '\0', size); -# endif UNIV_MEM_ALLOC(ptr, size); return(ptr); } diff --git a/storage/innodb_plugin/ut/ut0mem.c b/storage/innodb_plugin/ut/ut0mem.c index 95fb2187b79..9f9eb1c4d49 100644 --- a/storage/innodb_plugin/ut/ut0mem.c +++ b/storage/innodb_plugin/ut/ut0mem.c @@ -84,17 +84,13 @@ ut_mem_init(void) #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined and set_to_zero is TRUE. +Allocates memory. @return own: allocated memory */ UNIV_INTERN void* ut_malloc_low( /*==========*/ ulint n, /*!< in: number of bytes to allocate */ - ibool set_to_zero, /*!< in: TRUE if allocated memory should be - set to zero if UNIV_SET_MEM_TO_ZERO is - defined */ ibool assert_on_error)/*!< in: if TRUE, we crash mysqld if the memory cannot be allocated */ { @@ -106,12 +102,6 @@ ut_malloc_low( ret = malloc(n); ut_a(ret || !assert_on_error); -#ifdef UNIV_SET_MEM_TO_ZERO - if (set_to_zero) { - memset(ret, '\0', n); - UNIV_MEM_ALLOC(ret, n); - } -#endif return(ret); } @@ -199,12 +189,6 @@ retry: #endif } - if (set_to_zero) { -#ifdef UNIV_SET_MEM_TO_ZERO - memset(ret, '\0', n + sizeof(ut_mem_block_t)); -#endif - } - UNIV_MEM_ALLOC(ret, n + sizeof(ut_mem_block_t)); ((ut_mem_block_t*)ret)->size = n + sizeof(ut_mem_block_t); @@ -221,74 +205,10 @@ retry: void* ret = malloc(n); ut_a(ret || !assert_on_error); -# ifdef UNIV_SET_MEM_TO_ZERO - if (set_to_zero) { - memset(ret, '\0', n); - } -# endif return(ret); #endif /* !UNIV_HOTBACKUP */ } -/**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined. -@return own: allocated memory */ -UNIV_INTERN -void* -ut_malloc( -/*======*/ - ulint n) /*!< in: number of bytes to allocate */ -{ -#ifndef UNIV_HOTBACKUP - return(ut_malloc_low(n, TRUE, TRUE)); -#else /* !UNIV_HOTBACKUP */ - return(malloc(n)); -#endif /* !UNIV_HOTBACKUP */ -} - -#ifndef UNIV_HOTBACKUP -/**********************************************************************//** -Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs -out. It cannot be used if we want to return an error message. Prints to -stderr a message if fails. -@return TRUE if succeeded */ -UNIV_INTERN -ibool -ut_test_malloc( -/*===========*/ - ulint n) /*!< in: try to allocate this many bytes */ -{ - void* ret; - - ret = malloc(n); - - if (ret == NULL) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: cannot allocate" - " %lu bytes of memory for\n" - "InnoDB: a BLOB with malloc! Total allocated memory\n" - "InnoDB: by InnoDB %lu bytes." - " Operating system errno: %d\n" - "InnoDB: Check if you should increase" - " the swap file or\n" - "InnoDB: ulimits of your operating system.\n" - "InnoDB: On FreeBSD check you have" - " compiled the OS with\n" - "InnoDB: a big enough maximum process size.\n", - (ulong) n, - (ulong) ut_total_allocated_memory, - (int) errno); - return(FALSE); - } - - free(ret); - - return(TRUE); -} -#endif /* !UNIV_HOTBACKUP */ - /**********************************************************************//** Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is a nop. */ -- cgit v1.2.1 From 251fa88afacbd03a00894c04037d987b62f3ca58 Mon Sep 17 00:00:00 2001 From: Tatjana Azundris Nuernberg Date: Mon, 2 Jan 2012 06:25:48 +0000 Subject: BUG#11755281/47032: ERROR 2006 / ERROR 2013 INSTEAD OF PROPER ERROR MESSAGE If init_command was incorrect, we couldn't let users execute queries, but we couldn't report the issue to the client either as it does not expect error messages before even sending a command. Thus, we simply disconnected them without throwing a clear error. We now go through the proper sequence once (without executing any user statements) so we can report back what the problem is. Only then do we disconnect the user. As always, root remains unaffected by this as init_command is (still) not executed for them. mysql-test/r/init_connect.result: We now report a proper error if init_command fails. Expect as much. mysql-test/t/init_connect.test: We now report a proper error if init_command fails. Expect as much. sql/sql_connect.cc: If init_command fails, throw an error explaining this to the user. --- mysql-test/r/init_connect.result | 2 ++ mysql-test/t/init_connect.test | 8 ++++++++ sql/sql_connect.cc | 29 +++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/init_connect.result b/mysql-test/r/init_connect.result index f5ec0bdc932..0ff6c206422 100644 --- a/mysql-test/r/init_connect.result +++ b/mysql-test/r/init_connect.result @@ -20,6 +20,8 @@ hex(a) 616263 set GLOBAL init_connect="adsfsdfsdfs"; select @a; +ERROR 08S01: Aborted connection to db: 'test' user: 'user_1' host: 'localhost' (init_connect command failed) +select @a; Got one of the listed errors drop table t1; End of 4.1 tests diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test index b6bac5f65fa..e96d02fe0d1 100644 --- a/mysql-test/t/init_connect.test +++ b/mysql-test/t/init_connect.test @@ -36,6 +36,14 @@ connection con0; set GLOBAL init_connect="adsfsdfsdfs"; connect (con5,localhost,user_1,,); connection con5; +# BUG#11755281/47032: ERROR 2006 / ERROR 2013 INSTEAD OF PROPER ERROR MESSAGE +# We now throw a proper error message here: +--replace_regex /connection .* to/connection to/ +--error ER_NEW_ABORTING_CONNECTION +select @a; +# We got disconnected after receiving the above error message; any further +# requests should fail with a notice that no one's listening to us. +# --error CR_SERVER_GONE_ERROR,CR_SERVER_LOST --error 2013,2006 select @a; connection con0; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 44b4af74ef1..03f9d1e2732 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1342,13 +1342,38 @@ static void prepare_new_connection_state(THD* thd) execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect); if (thd->is_error()) { - thd->killed= THD::KILL_CONNECTION; + ulong packet_length; + NET *net= &thd->net; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), - thd->thread_id,(thd->db ? thd->db : "unconnected"), + thd->thread_id, + thd->db ? thd->db : "unconnected", sctx->user ? sctx->user : "unauthenticated", sctx->host_or_ip, "init_connect command failed"); sql_print_warning("%s", thd->main_da.message()); + + thd->lex->current_select= 0; + my_net_set_read_timeout(net, thd->variables.net_wait_timeout); + thd->clear_error(); + net_new_transaction(net); + packet_length= my_net_read(net); + /* + If my_net_read() failed, my_error() has been already called, + and the main Diagnostics Area contains an error condition. + */ + if (packet_length != packet_error) + my_error(ER_NEW_ABORTING_CONNECTION, MYF(0), + thd->thread_id, + thd->db ? thd->db : "unconnected", + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, "init_connect command failed"); + + thd->server_status&= ~SERVER_STATUS_CLEAR_SET; + net_end_statement(thd); + thd->killed = THD::KILL_CONNECTION; + return; } + thd->proc_info=0; thd->set_time(); thd->init_for_queries(); -- cgit v1.2.1 From b03c15413f1fd6b244f8d8a2a57948d0df265ecb Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Fri, 6 Jan 2012 15:46:03 +0530 Subject: Bug#12872804 - 62155: BINLOG.BINLOG_STM_UNSAFE_WARNING FAILS WHEN RUN WITH --REPEAT=2 Fixed the testcase using timestamp logic while doing grep from the error file. --- .../binlog/r/binlog_stm_unsafe_warning.result | 6 +++--- .../suite/binlog/t/binlog_stm_unsafe_warning.test | 23 +++++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result index edbd878982b..08f193c9f5f 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result +++ b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result @@ -34,13 +34,13 @@ USE test; # SET @old_log_warnings = @@log_warnings; DROP TABLE IF EXISTS t1; -CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(10)); +CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(15)); SET GLOBAL LOG_WARNINGS = 0; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +INSERT INTO t1 VALUES(UUID(), 'timestamp'); Warnings: Note 1592 Statement may not be safe to log in statement format. SET GLOBAL LOG_WARNINGS = 1; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +INSERT INTO t1 VALUES(UUID(), 'timestamp'); Warnings: Note 1592 Statement may not be safe to log in statement format. DROP TABLE t1; diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test index 21c11d5a3df..e5424a911bb 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test @@ -80,22 +80,33 @@ eval USE $old_db; --echo # Bug#46265: Can not disable warning about unsafe statements for binary logging --echo # +# Here introducing a sleep of one Second, just to make sure +# that when this test executes with "--repeat" option, +# the timestamp value is different and hence the Occcurrence count is one. +--sleep 1 + SET @old_log_warnings = @@log_warnings; --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings -CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(10)); +let BINLOG_COUNTER1= `select CONVERT(NOW(),UNSIGNED) as timestmap from dual`; + +CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(15)); SET GLOBAL LOG_WARNINGS = 0; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +# Replacing the result file content here. +# Instead of writing $BINLOG_COUNTER1 value to result file, writing a fixed string timestamp to it. +--replace_result $BINLOG_COUNTER1 timestamp +eval INSERT INTO t1 VALUES(UUID(), '$BINLOG_COUNTER1'); SET GLOBAL LOG_WARNINGS = 1; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +--replace_result $BINLOG_COUNTER1 timestamp +eval INSERT INTO t1 VALUES(UUID(), '$BINLOG_COUNTER1'); DROP TABLE t1; SET GLOBAL log_warnings = @old_log_warnings; let $log_error_= `SELECT @@GLOBAL.log_error`; -if(!`select LENGTH('$log_error_')`) +if(!$log_error_) { # MySQL Server on windows is started with --console and thus # does not know the location of its .err log, use default location @@ -111,7 +122,9 @@ perl; use strict; my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set"; open(FILE, "$log_error") or die("Unable to open $log_error: $!\n"); - my $count = () = grep(/Bug#46265/g,); + my $binlog_counter= $ENV{'BINLOG_COUNTER1'} or die "BINLOG_COUNTER1 not set"; + my $count = () = grep(/$binlog_counter/g,); + # Grep the timestamp value from the error file. print "Occurrences: $count\n"; close(FILE); EOF -- cgit v1.2.1 From 13b265483e0aeefdc6de8bd227ca0dfc7cd91736 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Fri, 6 Jan 2012 16:28:24 +0530 Subject: Bug#12872803 - 62154: FEDERATED.FEDERATED_SERVER TEST FAILS WITH RUN --REPEAT=2 Fixed it to work with "--repeat" option. --- mysql-test/suite/federated/federated_server.result | 4 ++-- mysql-test/suite/federated/federated_server.test | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/federated/federated_server.result b/mysql-test/suite/federated/federated_server.result index 2c20d1c1d57..6b37277b5a9 100644 --- a/mysql-test/suite/federated/federated_server.result +++ b/mysql-test/suite/federated/federated_server.result @@ -54,7 +54,7 @@ PASSWORD '', PORT SLAVE_PORT, SOCKET '', OWNER 'root'); -select * from mysql.servers; +select * from mysql.servers order by Server_name; Server_name Host Db Username Password Port Socket Wrapper Owner server_one 127.0.0.1 first_db root SLAVE_PORT mysql root server_two 127.0.0.1 second_db root SLAVE_PORT mysql root @@ -154,7 +154,7 @@ id name drop table federated.t1; drop server 'server_one'; drop server 'server_two'; -select * from mysql.servers; +select * from mysql.servers order by Server_name; Server_name Host Db Username Password Port Socket Wrapper Owner drop table first_db.t1; drop table second_db.t1; diff --git a/mysql-test/suite/federated/federated_server.test b/mysql-test/suite/federated/federated_server.test index ec952d071f2..64ee74edb16 100644 --- a/mysql-test/suite/federated/federated_server.test +++ b/mysql-test/suite/federated/federated_server.test @@ -62,7 +62,9 @@ eval create server 'server_two' foreign data wrapper 'mysql' options OWNER 'root'); --replace_result $SLAVE_MYPORT SLAVE_PORT -eval select * from mysql.servers; +# Adding 'order by' clause here, in order to maintain consistent result out of the select query. +#eval select * from mysql.servers; +eval select * from mysql.servers order by Server_name; DROP TABLE IF EXISTS federated.old; --replace_result $SLAVE_MYPORT SLAVE_PORT @@ -147,7 +149,9 @@ drop table federated.t1; drop server 'server_one'; drop server 'server_two'; -select * from mysql.servers; +# Adding 'order by' clause here, in order to maintain consistent result out of the select query. +#select * from mysql.servers; +eval select * from mysql.servers order by Server_name; connection slave; drop table first_db.t1; -- cgit v1.2.1 From b8291e2b60b311b621b15aff1dfec817da1bbf4c Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 9 Jan 2012 11:28:02 +0100 Subject: Backport from mysql-trunk of: ------------------------------------------------------------ revno: 3258 committer: Jon Olav Hauglid branch nick: mysql-trunk-bug12663165 timestamp: Thu 2011-07-14 10:05:12 +0200 message: Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS When stored routines are loaded, a simple optimizer tries to locate and remove dead code. The problem was that this dead code removal did not work correctly with CONTINUE handlers. If a statement triggers a CONTINUE handler, the following statement will be executed after the handler statement has completed. This means that the following statement is not dead code even if the previous statement unconditionally alters control flow. This fact was lost on the dead code removal routine, which ended up with removing instructions that could have been executed. This could then lead to assertions, crashes and generally bad behavior when the stored routine was executed. This patch fixes the problem by marking as live code all stored routine instructions that are in the same scope as a CONTINUE handler. Test case added to sp.test. --- mysql-test/r/sp.result | 20 ++++++++++++++++++++ mysql-test/t/sp.test | 29 +++++++++++++++++++++++++++++ sql/sp_head.cc | 17 +++++++++++++++++ sql/sp_head.h | 12 +++++++++++- sql/sql_yacc.yy | 12 +++++++++--- 5 files changed, 86 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index f5ed4fbd901..11d6ff02756 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -7087,6 +7087,26 @@ COUNT(DISTINCT d) 2 DROP FUNCTION f1; DROP TABLE t1, t2; +# +# Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS +# +DROP FUNCTION IF EXISTS f1; +CREATE FUNCTION f1() RETURNS INT +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1(); +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1(); +RETURN f1(); +END; +END; +RETURN 1; +END $ +SELECT f1(); +f1() +1 +DROP FUNCTION f1; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 141d1604065..ae4e1dd588e 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8397,6 +8397,35 @@ DROP FUNCTION f1; DROP TABLE t1, t2; +--echo # +--echo # Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS +--echo # + +--disable_warnings +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +delimiter $; +CREATE FUNCTION f1() RETURNS INT +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1(); + BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1(); + RETURN f1(); + END; + END; +RETURN 1; +END $ +delimiter ;$ + +# This used to cause an assertion. +SELECT f1(); + +DROP FUNCTION f1; + + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8bea0be0f56..dec76615ec7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3356,6 +3356,23 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp, List *leads) m_optdest= sp->get_instr(m_dest); } sp->add_mark_lead(m_dest, leads); + + /* + For continue handlers, all instructions in the scope of the handler + are possible leads. For example, the instruction after freturn might + be executed if the freturn triggers the condition handled by the + continue handler. + + m_dest marks the start of the handler scope. It's added as a lead + above, so we start on m_dest+1 here. + m_opt_hpop is the hpop marking the end of the handler scope. + */ + if (m_type == SP_HANDLER_CONTINUE) + { + for (uint scope_ip= m_dest+1; scope_ip <= m_opt_hpop; scope_ip++) + sp->add_mark_lead(scope_ip, leads); + } + return m_ip+1; } diff --git a/sql/sp_head.h b/sql/sp_head.h index da490527f42..a026ac47221 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1000,7 +1000,7 @@ class sp_instr_hpush_jump : public sp_instr_jump public: sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp) - : sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp) + : sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp), m_opt_hpop(0) { m_cond.empty(); } @@ -1022,6 +1022,15 @@ public: return m_ip; } + virtual void backpatch(uint dest, sp_pcontext *dst_ctx) + { + DBUG_ASSERT(!m_dest || !m_opt_hpop); + if (!m_dest) + m_dest= dest; + else + m_opt_hpop= dest; + } + inline void add_condition(struct sp_cond_type *cond) { m_cond.push_front(cond); @@ -1031,6 +1040,7 @@ private: int m_type; ///< Handler type uint m_frame; + uint m_opt_hpop; // hpop marking end of handler scope. List m_cond; }; // class sp_instr_hpush_jump : public sp_instr_jump diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index facbc6d3e95..7e7ff7e91ca 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2532,9 +2532,15 @@ sp_decl: sp_instr_hpush_jump *i= new sp_instr_hpush_jump(sp->instructions(), ctx, $2, ctx->current_var_count()); - if (i == NULL || - sp->add_instr(i) || - sp->push_backpatch(i, ctx->push_label((char *)"", 0))) + if (i == NULL || sp->add_instr(i)) + MYSQL_YYABORT; + + /* For continue handlers, mark end of handler scope. */ + if ($2 == SP_HANDLER_CONTINUE && + sp->push_backpatch(i, ctx->last_label())) + MYSQL_YYABORT; + + if (sp->push_backpatch(i, ctx->push_label(empty_c_string, 0))) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt -- cgit v1.2.1 From 115f5e8551b9243ef3ca98ce882993fb78c426e1 Mon Sep 17 00:00:00 2001 From: Yasufumi Kinoshita Date: Tue, 10 Jan 2012 14:18:58 +0900 Subject: Bug#12400341 INNODB CAN LEAVE ORPHAN IBD FILES AROUND If we meet DB_TOO_MANY_CONCURRENT_TRXS during the execution tab_create_graph from row_create_table_for_mysql(), .ibd file for the table should be created already but was not deleted for the error handling. rb:875 approved by Jimmy Yang --- .../suite/innodb/r/innodb_bug12400341.result | 25 +++++ .../suite/innodb/t/innodb_bug12400341-master.opt | 1 + mysql-test/suite/innodb/t/innodb_bug12400341.test | 103 +++++++++++++++++++++ .../innodb_plugin/r/innodb_bug12400341.result | 25 +++++ .../innodb_plugin/t/innodb_bug12400341-master.opt | 1 + .../suite/innodb_plugin/t/innodb_bug12400341.test | 103 +++++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 10 ++ storage/innobase/include/trx0rseg.ic | 9 +- storage/innobase/include/trx0sys.h | 5 + storage/innobase/row/row0mysql.c | 12 +++ storage/innobase/trx/trx0sys.c | 4 + storage/innodb_plugin/ChangeLog | 5 + storage/innodb_plugin/handler/ha_innodb.cc | 10 ++ storage/innodb_plugin/include/trx0rseg.ic | 9 +- storage/innodb_plugin/include/trx0sys.h | 6 ++ storage/innodb_plugin/row/row0mysql.c | 14 +++ storage/innodb_plugin/trx/trx0sys.c | 5 + 17 files changed, 345 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug12400341.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug12400341-master.opt create mode 100644 mysql-test/suite/innodb/t/innodb_bug12400341.test create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug12400341.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug12400341-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug12400341.test diff --git a/mysql-test/suite/innodb/r/innodb_bug12400341.result b/mysql-test/suite/innodb/r/innodb_bug12400341.result new file mode 100644 index 00000000000..551e94f5e77 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug12400341.result @@ -0,0 +1,25 @@ +call mtr.add_suppression("InnoDB: Warning: cannot find a free slot for an undo log. Do you have too"); +show variables like "max_connections"; +Variable_name Value +max_connections 64 +show variables like "innodb_thread_concurrency"; +Variable_name Value +innodb_thread_concurrency 0 +show variables like "innodb_file_per_table"; +Variable_name Value +innodb_file_per_table ON +drop database if exists mysqltest; +create database mysqltest; +CREATE TABLE mysqltest.transtable (id int unsigned NOT NULL PRIMARY KEY, val int DEFAULT 0) ENGINE=InnoDB; +select count(*) from information_schema.processlist; +count(*) +33 +CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; +ERROR HY000: Can't create table 'mysqltest.testtable' (errno: 177) +select count(*) from information_schema.processlist; +count(*) +33 +select count(*) from information_schema.processlist; +count(*) +33 +drop database mysqltest; diff --git a/mysql-test/suite/innodb/t/innodb_bug12400341-master.opt b/mysql-test/suite/innodb/t/innodb_bug12400341-master.opt new file mode 100644 index 00000000000..2e85b082c68 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug12400341-master.opt @@ -0,0 +1 @@ +--max_connections=64 --innodb_thread_concurrency=0 --innodb_file_per_table diff --git a/mysql-test/suite/innodb/t/innodb_bug12400341.test b/mysql-test/suite/innodb/t/innodb_bug12400341.test new file mode 100644 index 00000000000..2ab1be81f6d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug12400341.test @@ -0,0 +1,103 @@ +# Test for bug #12400341: INNODB CAN LEAVE ORPHAN IBD FILES AROUND + +-- source include/have_innodb.inc + +if (`select count(*)=0 from information_schema.global_variables where variable_name = 'INNODB_TRX_RSEG_N_SLOTS_DEBUG'`) +{ + --skip Test requires InnoDB built with UNIV_DEBUG definition. +} + +call mtr.add_suppression("InnoDB: Warning: cannot find a free slot for an undo log. Do you have too"); + +--disable_query_log +set @old_innodb_trx_rseg_n_slots_debug = @@innodb_trx_rseg_n_slots_debug; +set global innodb_trx_rseg_n_slots_debug = 32; +--enable_query_log + +show variables like "max_connections"; +show variables like "innodb_thread_concurrency"; +show variables like "innodb_file_per_table"; + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings + +create database mysqltest; +CREATE TABLE mysqltest.transtable (id int unsigned NOT NULL PRIMARY KEY, val int DEFAULT 0) ENGINE=InnoDB; + +--disable_query_log +# +# Insert in 1 transaction which needs over 1 page undo record to avoid the insert_undo cached, +# because the cached insert_undo can be reused at "CREATE TABLE" statement later. +# +START TRANSACTION; +let $c = 1024; +while ($c) +{ + eval INSERT INTO mysqltest.transtable (id) VALUES ($c); + dec $c; +} +COMMIT; + +let $c = 32; +while ($c) +{ + # if failed at here, it might be shortage of file descriptors limit. + connect (con$c,localhost,root,,); + dec $c; +} +--enable_query_log + +select count(*) from information_schema.processlist; + +# +# fill the all undo slots +# +--disable_query_log +let $c = 32; +while ($c) +{ + connection con$c; + START TRANSACTION; + eval UPDATE mysqltest.transtable SET val = 1 WHERE id = 33 - $c; + dec $c; +} +--enable_query_log + +connection default; + +--error ER_CANT_CREATE_TABLE +CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; + +select count(*) from information_schema.processlist; + +--disable_query_log +let $c = 32; +while ($c) +{ + connection con$c; + ROLLBACK; + dec $c; +} +--enable_query_log + +connection default; +select count(*) from information_schema.processlist; + +--disable_query_log +let $c = 32; +while ($c) +{ + disconnect con$c; + dec $c; +} +--enable_query_log + +# +# If the isolated .ibd file remained, the drop database should fail. +# +drop database mysqltest; + +--disable_query_log +set global innodb_trx_rseg_n_slots_debug = @old_innodb_trx_rseg_n_slots_debug; +--enable_query_log diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug12400341.result b/mysql-test/suite/innodb_plugin/r/innodb_bug12400341.result new file mode 100644 index 00000000000..551e94f5e77 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug12400341.result @@ -0,0 +1,25 @@ +call mtr.add_suppression("InnoDB: Warning: cannot find a free slot for an undo log. Do you have too"); +show variables like "max_connections"; +Variable_name Value +max_connections 64 +show variables like "innodb_thread_concurrency"; +Variable_name Value +innodb_thread_concurrency 0 +show variables like "innodb_file_per_table"; +Variable_name Value +innodb_file_per_table ON +drop database if exists mysqltest; +create database mysqltest; +CREATE TABLE mysqltest.transtable (id int unsigned NOT NULL PRIMARY KEY, val int DEFAULT 0) ENGINE=InnoDB; +select count(*) from information_schema.processlist; +count(*) +33 +CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; +ERROR HY000: Can't create table 'mysqltest.testtable' (errno: 177) +select count(*) from information_schema.processlist; +count(*) +33 +select count(*) from information_schema.processlist; +count(*) +33 +drop database mysqltest; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug12400341-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_bug12400341-master.opt new file mode 100644 index 00000000000..2e85b082c68 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug12400341-master.opt @@ -0,0 +1 @@ +--max_connections=64 --innodb_thread_concurrency=0 --innodb_file_per_table diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug12400341.test b/mysql-test/suite/innodb_plugin/t/innodb_bug12400341.test new file mode 100644 index 00000000000..b9e40e0dff3 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug12400341.test @@ -0,0 +1,103 @@ +# Test for bug #12400341: INNODB CAN LEAVE ORPHAN IBD FILES AROUND + +-- source include/have_innodb_plugin.inc + +if (`select count(*)=0 from information_schema.global_variables where variable_name = 'INNODB_TRX_RSEG_N_SLOTS_DEBUG'`) +{ + --skip Test requires InnoDB built with UNIV_DEBUG definition. +} + +call mtr.add_suppression("InnoDB: Warning: cannot find a free slot for an undo log. Do you have too"); + +--disable_query_log +set @old_innodb_trx_rseg_n_slots_debug = @@innodb_trx_rseg_n_slots_debug; +set global innodb_trx_rseg_n_slots_debug = 32; +--enable_query_log + +show variables like "max_connections"; +show variables like "innodb_thread_concurrency"; +show variables like "innodb_file_per_table"; + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings + +create database mysqltest; +CREATE TABLE mysqltest.transtable (id int unsigned NOT NULL PRIMARY KEY, val int DEFAULT 0) ENGINE=InnoDB; + +--disable_query_log +# +# Insert in 1 transaction which needs over 1 page undo record to avoid the insert_undo cached, +# because the cached insert_undo can be reused at "CREATE TABLE" statement later. +# +START TRANSACTION; +let $c = 1024; +while ($c) +{ + eval INSERT INTO mysqltest.transtable (id) VALUES ($c); + dec $c; +} +COMMIT; + +let $c = 32; +while ($c) +{ + # if failed at here, it might be shortage of file descriptors limit. + connect (con$c,localhost,root,,); + dec $c; +} +--enable_query_log + +select count(*) from information_schema.processlist; + +# +# fill the all undo slots +# +--disable_query_log +let $c = 32; +while ($c) +{ + connection con$c; + START TRANSACTION; + eval UPDATE mysqltest.transtable SET val = 1 WHERE id = 33 - $c; + dec $c; +} +--enable_query_log + +connection default; + +--error ER_CANT_CREATE_TABLE +CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; + +select count(*) from information_schema.processlist; + +--disable_query_log +let $c = 32; +while ($c) +{ + connection con$c; + ROLLBACK; + dec $c; +} +--enable_query_log + +connection default; +select count(*) from information_schema.processlist; + +--disable_query_log +let $c = 32; +while ($c) +{ + disconnect con$c; + dec $c; +} +--enable_query_log + +# +# If the isolated .ibd file remained, the drop database should fail. +# +drop database mysqltest; + +--disable_query_log +set global innodb_trx_rseg_n_slots_debug = @old_innodb_trx_rseg_n_slots_debug; +--enable_query_log diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a4d79a5934e..573e0a4455a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9060,6 +9060,13 @@ static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, NULL, NULL, 0, 0, 1, 0); #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ +#ifdef UNIV_DEBUG +static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()", + NULL, NULL, 0, 0, 1024, 0); +#endif /* UNIV_DEBUG */ + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), @@ -9105,6 +9112,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG MYSQL_SYSVAR(change_buffering_debug), #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ +#ifdef UNIV_DEBUG + MYSQL_SYSVAR(trx_rseg_n_slots_debug), +#endif /* UNIV_DEBUG */ NULL }; diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic index 577cd0dee7b..5b01b2f197d 100644 --- a/storage/innobase/include/trx0rseg.ic +++ b/storage/innobase/include/trx0rseg.ic @@ -8,6 +8,7 @@ Created 3/26/1996 Heikki Tuuri #include "srv0srv.h" #include "mtr0log.h" +#include "trx0sys.h" /********************************************************************** Gets a rollback segment header. */ @@ -113,7 +114,13 @@ trx_rsegf_undo_find_free( ulint i; ulint page_no; - for (i = 0; i < TRX_RSEG_N_SLOTS; i++) { + for (i = 0; +#ifndef UNIV_DEBUG + i < TRX_RSEG_N_SLOTS; +#else + i < (trx_rseg_n_slots_debug ? trx_rseg_n_slots_debug : TRX_RSEG_N_SLOTS); +#endif + i++) { page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr); diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 7ea981eb85c..aedeb51d3b3 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -47,6 +47,11 @@ extern ibool trx_doublewrite_buf_is_being_created; extern ibool trx_doublewrite_must_reset_space_ids; extern ibool trx_sys_multiple_tablespace_format; +#ifdef UNIV_DEBUG +/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ +extern uint trx_rseg_n_slots_debug; +#endif + /******************************************************************** Creates the doublewrite buffer to a new InnoDB installation. The header of the doublewrite buffer is placed on the trx system header page. */ diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index cee97871470..6148b01af9d 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1948,6 +1948,18 @@ row_create_table_for_mysql( FALSE); } + } else if (err == DB_TOO_MANY_CONCURRENT_TRXS) { + /* We already have .ibd file here. it should be deleted. */ + if (table->space + && !fil_delete_tablespace(table->space)) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: not able to" + " delete tablespace %lu of table ", + (ulong) table->space); + ut_print_name(stderr, trx, TRUE, table->name); + fputs("!\n", stderr); + } } else if (err == DB_DUPLICATE_KEY) { ut_print_timestamp(stderr); diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index 137771b71ed..09b1b5d8198 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -54,6 +54,10 @@ InnoDB. */ char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN]; ib_longlong trx_sys_mysql_bin_log_pos = -1; +#ifdef UNIV_DEBUG +/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ +uint trx_rseg_n_slots_debug = 0; +#endif /******************************************************************** Determines if a page number is located inside the doublewrite buffer. */ diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 1385da94bfb..d33dfd33043 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2012-01-04 The InnoDB Team + + * row/row0mysql.c: + Fix Bug#12400341: INNODB CAN LEAVE ORPHAN IBD FILES AROUND + 2011-12-21 The InnoDB Team * include/ut0rnd.ic: diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 122bf1f7846..149e660e36e 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -11033,6 +11033,13 @@ static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold, "trigger a readahead.", NULL, NULL, 56, 0, 64, 0); +#ifdef UNIV_DEBUG +static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()", + NULL, NULL, 0, 0, 1024, 0); +#endif /* UNIV_DEBUG */ + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), @@ -11094,6 +11101,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(random_read_ahead), MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(io_capacity), +#ifdef UNIV_DEBUG + MYSQL_SYSVAR(trx_rseg_n_slots_debug), +#endif /* UNIV_DEBUG */ NULL }; diff --git a/storage/innodb_plugin/include/trx0rseg.ic b/storage/innodb_plugin/include/trx0rseg.ic index daffa92fc7d..5e8d2b41120 100644 --- a/storage/innodb_plugin/include/trx0rseg.ic +++ b/storage/innodb_plugin/include/trx0rseg.ic @@ -25,6 +25,7 @@ Created 3/26/1996 Heikki Tuuri #include "srv0srv.h" #include "mtr0log.h" +#include "trx0sys.h" /******************************************************************//** Gets a rollback segment header. @@ -131,7 +132,13 @@ trx_rsegf_undo_find_free( ulint i; ulint page_no; - for (i = 0; i < TRX_RSEG_N_SLOTS; i++) { + for (i = 0; +#ifndef UNIV_DEBUG + i < TRX_RSEG_N_SLOTS; +#else + i < (trx_rseg_n_slots_debug ? trx_rseg_n_slots_debug : TRX_RSEG_N_SLOTS); +#endif + i++) { page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr); diff --git a/storage/innodb_plugin/include/trx0sys.h b/storage/innodb_plugin/include/trx0sys.h index 78bb6fc349b..56fb801ee42 100644 --- a/storage/innodb_plugin/include/trx0sys.h +++ b/storage/innodb_plugin/include/trx0sys.h @@ -229,6 +229,12 @@ trx_id_t trx_sys_get_new_trx_no(void); /*========================*/ #endif /* !UNIV_HOTBACKUP */ + +#ifdef UNIV_DEBUG +/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ +extern uint trx_rseg_n_slots_debug; +#endif + /*****************************************************************//** Writes a trx id to an index page. In case that the id size changes in some future version, this function should be used instead of diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 6f689f9909d..36aad4f8ca2 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -1900,6 +1900,20 @@ err_exit: } break; + case DB_TOO_MANY_CONCURRENT_TRXS: + /* We already have .ibd file here. it should be deleted. */ + + if (table->space && !fil_delete_tablespace(table->space)) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: not able to" + " delete tablespace %lu of table ", + (ulong) table->space); + ut_print_name(stderr, trx, TRUE, table->name); + fputs("!\n", stderr); + } + /* fall through */ + case DB_DUPLICATE_KEY: default: /* We may also get err == DB_ERROR if the .ibd file for the diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c index 352fa6af219..e9328b27bba 100644 --- a/storage/innodb_plugin/trx/trx0sys.c +++ b/storage/innodb_plugin/trx/trx0sys.c @@ -127,6 +127,11 @@ static const char* file_format_name_map[] = { static const ulint FILE_FORMAT_NAME_N = sizeof(file_format_name_map) / sizeof(file_format_name_map[0]); +#ifdef UNIV_DEBUG +/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ +uint trx_rseg_n_slots_debug = 0; +#endif + #ifndef UNIV_HOTBACKUP /** This is used to track the maximum file format id known to InnoDB. It's updated via SET GLOBAL innodb_file_format_check = 'x' or when we open -- cgit v1.2.1 From 99e462ab0b308e629f4604adc3a33e2cf817be82 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Tue, 10 Jan 2012 13:33:45 +0530 Subject: BUG#11760384 - 52792: mysqldump in XML mode does not dump routines. mysqldump in xml mode did not dump routines, events or triggers. This patch fixes this issue by fixing the if conditions that disallowed the dump of above mentioned objects in xml mode, and added the required code to enable dump in xml format. client/mysqldump.c: BUG#11760384 - 52792: mysqldump in XML mode does not dump routines. Fixed some if conditions to allow execution of dump methods for xml and further added the relevant code at places to produce the dump in xml format. mysql-test/r/mysqldump.result: Added a test case for Bug#11760384. mysql-test/t/mysqldump.test: Added a test case for Bug#11760384. --- client/mysqldump.c | 461 ++++++++++++++++++++++++++++++------------ mysql-test/r/mysqldump.result | 439 ++++++++++++++++++++++++++++++++++++++++ mysql-test/t/mysqldump.test | 112 ++++++++++ 3 files changed, 884 insertions(+), 128 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 31d4ba40109..27a593ff592 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -76,6 +76,9 @@ /* Size of buffer for dump's select query */ #define QUERY_LENGTH 1536 +/* Size of comment buffer. */ +#define COMMENT_LENGTH 2048 + /* ignore table flags */ #define IGNORE_NONE 0x00 /* no ignore */ #define IGNORE_DATA 0x01 /* don't dump data for this table */ @@ -102,7 +105,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_complete_insert= 0, opt_drop_database= 0, opt_replace_into= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1, - opt_events= 0, + opt_events= 0, opt_comments_used= 0, opt_alltspcs=0, opt_notspcs= 0; static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; @@ -509,6 +512,8 @@ static int dump_all_tablespaces(); static int dump_tablespaces_for_tables(char *db, char **table_names, int tables); static int dump_tablespaces_for_databases(char** databases); static int dump_tablespaces(char* ts_where); +static void print_comment(FILE *sql_file, my_bool is_error, const char *format, + ...); #include @@ -606,19 +611,19 @@ static void write_header(FILE *sql_file, char *db_name) } else if (!opt_compact) { - if (opt_comments) - { - fprintf(sql_file, - "-- MySQL dump %s Distrib %s, for %s (%s)\n--\n", - DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); - fprintf(sql_file, "-- Host: %s Database: %s\n", - current_host ? current_host : "localhost", db_name ? db_name : - ""); - fputs("-- ------------------------------------------------------\n", - sql_file); - fprintf(sql_file, "-- Server version\t%s\n", - mysql_get_server_info(&mysql_connection)); - } + print_comment(sql_file, 0, + "-- MySQL dump %s Distrib %s, for %s (%s)\n--\n", + DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, + MACHINE_TYPE); + print_comment(sql_file, 0, "-- Host: %s Database: %s\n", + current_host ? current_host : "localhost", + db_name ? db_name : ""); + print_comment(sql_file, 0, + "-- ------------------------------------------------------\n" + ); + print_comment(sql_file, 0, "-- Server version\t%s\n", + mysql_get_server_info(&mysql_connection)); + if (opt_set_charset) fprintf(sql_file, "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" @@ -676,18 +681,16 @@ static void write_footer(FILE *sql_file) fprintf(sql_file, "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n"); fputs("\n", sql_file); - if (opt_comments) + + if (opt_dump_date) { - if (opt_dump_date) - { - char time_str[20]; - get_date(time_str, GETDATE_DATE_TIME, 0); - fprintf(sql_file, "-- Dump completed on %s\n", - time_str); - } - else - fprintf(sql_file, "-- Dump completed\n"); + char time_str[20]; + get_date(time_str, GETDATE_DATE_TIME, 0); + print_comment(sql_file, 0, "-- Dump completed on %s\n", time_str); } + else + print_comment(sql_file, 0, "-- Dump completed\n"); + check_io(sql_file); } } /* write_footer */ @@ -772,6 +775,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), extended_insert= opt_drop= opt_lock= opt_disable_keys= opt_autocommit= opt_create_db= 0; break; + case 'i': + opt_comments_used= 1; + break; case 'I': case '?': usage(); @@ -798,11 +804,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_disable_keys= lock_tables= opt_set_charset= 0; break; case (int) OPT_COMPACT: - if (opt_compact) - { - opt_comments= opt_drop= opt_disable_keys= opt_lock= 0; - opt_set_charset= 0; - } + if (opt_compact) + { + opt_comments= opt_drop= opt_disable_keys= opt_lock= 0; + opt_set_charset= 0; + } + break; case (int) OPT_TABLES: opt_databases=0; break; @@ -1660,20 +1667,20 @@ static char *quote_for_like(const char *name, char *buff) } -/* +/** Quote and print a string. - SYNOPSIS - print_quoted_xml() - xml_file - output file - str - string to print - len - its length + @param xml_file - Output file. + @param str - String to print. + @param len - Its length. + @param is_attribute_name - A check for attribute name or value. - DESCRIPTION + @description Quote '<' '>' '&' '\"' chars and print a string to the xml_file. */ -static void print_quoted_xml(FILE *xml_file, const char *str, ulong len) +static void print_quoted_xml(FILE *xml_file, const char *str, ulong len, + my_bool is_attribute_name) { const char *end; @@ -1692,6 +1699,14 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len) case '\"': fputs(""", xml_file); break; + case ' ': + /* Attribute names cannot contain spaces. */ + if (is_attribute_name) + { + fputs("_", xml_file); + break; + } + /* fall through */ default: fputc(*str, xml_file); break; @@ -1752,7 +1767,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg, fputs(attribute_name, xml_file); fputc('\"', xml_file); - print_quoted_xml(xml_file, attribute_value, strlen(attribute_value)); + print_quoted_xml(xml_file, attribute_value, strlen(attribute_value), 0); fputc('\"', xml_file); attribute_name= va_arg(arg_list, char *); @@ -1792,13 +1807,52 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg, fputs("<", xml_file); fputs(stag_atr, xml_file); fputs("\"", xml_file); - print_quoted_xml(xml_file, sval, strlen(sval)); + print_quoted_xml(xml_file, sval, strlen(sval), 0); fputs("\" xsi:nil=\"true\" />", xml_file); fputs(line_end, xml_file); check_io(xml_file); } +/** + Print xml CDATA section. + + @param xml_file - output file + @param str - string to print + @param len - length of the string + + @note + This function also takes care of the presence of '[[>' + string in the str. If found, the CDATA section is broken + into two CDATA sections, and ]]. +*/ + +static void print_xml_cdata(FILE *xml_file, const char *str, ulong len) +{ + const char *end; + + fputs("')) + { + fputs("]]]]>", xml_file); + str += 2; + continue; + } + /* fall through */ + default: + fputc(*str, xml_file); + break; + } + } + fputs("\n]]>\n", xml_file); + check_io(xml_file); +} + + /* Print xml tag with many attributes. @@ -1808,6 +1862,7 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg, row_name - xml tag name tableRes - query result row - result row + str_create - create statement header string DESCRIPTION Print tag with many attribute to the xml_file. Format is: @@ -1817,9 +1872,13 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg, */ static void print_xml_row(FILE *xml_file, const char *row_name, - MYSQL_RES *tableRes, MYSQL_ROW *row) + MYSQL_RES *tableRes, MYSQL_ROW *row, + const char *str_create) { uint i; + my_bool body_found= 0; + char *create_stmt_ptr; + ulong create_stmt_len= 0; MYSQL_FIELD *field; ulong *lengths= mysql_fetch_lengths(tableRes); @@ -1830,19 +1889,109 @@ static void print_xml_row(FILE *xml_file, const char *row_name, { if ((*row)[i]) { - fputc(' ', xml_file); - print_quoted_xml(xml_file, field->name, field->name_length); - fputs("=\"", xml_file); - print_quoted_xml(xml_file, (*row)[i], lengths[i]); - fputc('"', xml_file); - check_io(xml_file); + /* For 'create' statements, dump using CDATA. */ + if ((str_create) && (strcmp(str_create, field->name) == 0)) + { + create_stmt_ptr= (*row)[i]; + create_stmt_len= lengths[i]; + body_found= 1; + } + else + { + fputc(' ', xml_file); + print_quoted_xml(xml_file, field->name, field->name_length, 1); + fputs("=\"", xml_file); + print_quoted_xml(xml_file, (*row)[i], lengths[i], 0); + fputc('"', xml_file); + check_io(xml_file); + } + } + } + + if (create_stmt_len) + { + DBUG_ASSERT(body_found); + fputs(">\n", xml_file); + print_xml_cdata(xml_file, create_stmt_ptr, create_stmt_len); + fprintf(xml_file, "\t\t\n", row_name); + } + else + fputs(" />\n", xml_file); + + check_io(xml_file); +} + + +/** + Print xml comments. + + @param xml_file - output file + @param len - length of comment message + @param comment_string - comment message + + @description + Print the comment message in the format: + "\n" + + @note + Any occurrence of continuous hyphens will be + squeezed to a single hyphen. +*/ + +static void print_xml_comment(FILE *xml_file, ulong len, + const char *comment_string) +{ + const char* end; + + fputs("\n", xml_file); check_io(xml_file); } + +/* A common printing function for xml and non-xml modes. */ + +static void print_comment(FILE *sql_file, my_bool is_error, const char *format, + ...) +{ + static char comment_buff[COMMENT_LENGTH]; + va_list args; + + /* If its an error message, print it ignoring opt_comments. */ + if (!is_error && !opt_comments) + return; + + va_start(args, format); + my_vsnprintf(comment_buff, COMMENT_LENGTH, format, args); + va_end(args); + + if (!opt_xml) + { + fputs(comment_buff, sql_file); + check_io(sql_file); + return; + } + + print_xml_comment(sql_file, strlen(comment_buff), comment_buff); +} + + /* create_delimiter Generate a new (null-terminated) string that does not exist in query @@ -1909,8 +2058,8 @@ static uint dump_events_for_db(char *db) mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); /* nice comments */ - if (opt_comments) - fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db); + print_comment(sql_file, 0, + "\n--\n-- Dumping events for database '%s'\n--\n", db); /* not using "mysql_query_with_error_report" because we may have not @@ -1925,12 +2074,17 @@ static uint dump_events_for_db(char *db) strcpy(delimiter, ";"); if (mysql_num_rows(event_list_res) > 0) { - fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n"); + if (opt_xml) + fputs("\t\n", sql_file); + else + { + fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n"); - /* Get database collation. */ + /* Get database collation. */ - if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name))) - DBUG_RETURN(1); + if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name))) + DBUG_RETURN(1); + } if (switch_character_set_results(mysql, "binary")) DBUG_RETURN(1); @@ -1947,6 +2101,13 @@ static uint dump_events_for_db(char *db) while ((row= mysql_fetch_row(event_res)) != NULL) { + if (opt_xml) + { + print_xml_row(sql_file, "event", event_res, &row, + "Create Event"); + continue; + } + /* if the user has EXECUTE privilege he can see event names, but not the event body! @@ -2025,8 +2186,16 @@ static uint dump_events_for_db(char *db) mysql_free_result(event_res); } /* end of list of events */ - fprintf(sql_file, "DELIMITER ;\n"); - fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n"); + if (opt_xml) + { + fputs("\t\n", sql_file); + check_io(sql_file); + } + else + { + fprintf(sql_file, "DELIMITER ;\n"); + fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n"); + } if (switch_character_set_results(mysql, default_charset)) DBUG_RETURN(1); @@ -2080,6 +2249,7 @@ static uint dump_routines_for_db(char *db) const char *routine_type[]= {"FUNCTION", "PROCEDURE"}; char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; char *routine_name; + char *query_str; int i; FILE *sql_file= md_result_file; MYSQL_RES *routine_res, *routine_list_res; @@ -2094,8 +2264,8 @@ static uint dump_routines_for_db(char *db) mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); /* nice comments */ - if (opt_comments) - fprintf(sql_file, "\n--\n-- Dumping routines for database '%s'\n--\n", db); + print_comment(sql_file, 0, + "\n--\n-- Dumping routines for database '%s'\n--\n", db); /* not using "mysql_query_with_error_report" because we may have not @@ -2112,6 +2282,9 @@ static uint dump_routines_for_db(char *db) if (switch_character_set_results(mysql, "binary")) DBUG_RETURN(1); + if (opt_xml) + fputs("\t\n", sql_file); + /* 0, retrieve and dump functions, 1, procedures */ for (i= 0; i <= 1; i++) { @@ -2147,13 +2320,25 @@ static uint dump_routines_for_db(char *db) row[2] ? (int) strlen(row[2]) : 0)); if (row[2] == NULL) { - fprintf(sql_file, "\n-- insufficient privileges to %s\n", query_buff); - fprintf(sql_file, "-- does %s have permissions on mysql.proc?\n\n", current_user); + print_comment(sql_file, 1, "\n-- insufficient privileges to %s\n", + query_buff); + print_comment(sql_file, 1, + "-- does %s have permissions on mysql.proc?\n\n", + current_user); maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff); } else if (strlen(row[2])) { - char *query_str; + if (opt_xml) + { + if (i) // Procedures. + print_xml_row(sql_file, "routine", routine_res, &row, + "Create Procedure"); + else // Functions. + print_xml_row(sql_file, "routine", routine_res, &row, + "Create Function"); + continue; + } if (opt_drop) fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n", routine_type[i], routine_name); @@ -2224,6 +2409,12 @@ static uint dump_routines_for_db(char *db) mysql_free_result(routine_list_res); } /* end of for i (0 .. 1) */ + if (opt_xml) + { + fputs("\t\n", sql_file); + check_io(sql_file); + } + if (switch_character_set_results(mysql, default_charset)) DBUG_RETURN(1); @@ -2336,16 +2527,16 @@ static uint get_table_structure(char *table, char *db, char *table_type, write_header(sql_file, db); } - if (!opt_xml && opt_comments) - { + if (strcmp (table_type, "VIEW") == 0) /* view */ - fprintf(sql_file, "\n--\n-- Temporary table structure for view %s\n--\n\n", - result_table); + print_comment(sql_file, 0, + "\n--\n-- Temporary table structure for view %s\n--\n\n", + result_table); else - fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", - result_table); - check_io(sql_file); - } + print_comment(sql_file, 0, + "\n--\n-- Table structure for table %s\n--\n\n", + result_table); + if (opt_drop) { /* @@ -2546,9 +2737,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, DBUG_RETURN(0); write_header(sql_file, db); } - if (!opt_xml && opt_comments) - fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", - result_table); + + print_comment(sql_file, 0, + "\n--\n-- Table structure for table %s\n--\n\n", + result_table); if (opt_drop) fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table); if (!opt_xml) @@ -2599,7 +2791,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (opt_xml) { - print_xml_row(sql_file, "field", result, &row); + print_xml_row(sql_file, "field", result, &row, NullS); continue; } @@ -2671,7 +2863,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (opt_xml) { - print_xml_row(sql_file, "key", result, &row); + print_xml_row(sql_file, "key", result, &row, NullS); continue; } @@ -2730,7 +2922,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, else { if (opt_xml) - print_xml_row(sql_file, "options", result, &row); + print_xml_row(sql_file, "options", result, &row, NullS); else { fputs("/*!",sql_file); @@ -2774,9 +2966,19 @@ static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs, char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1); char name_buff[NAME_LEN * 4 + 3]; + const char *xml_msg= "\nWarning! mysqldump being run against old server " + "that does not\nsupport 'SHOW CREATE TRIGGERS' " + "statement. Skipping..\n"; DBUG_ENTER("dump_trigger_old"); + if (opt_xml) + { + print_xml_comment(sql_file, strlen(xml_msg), xml_msg); + check_io(sql_file); + DBUG_VOID_RETURN; + } + fprintf(sql_file, "--\n" "-- WARNING: old server version. " @@ -2840,13 +3042,22 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs, const char *db_cl_name) { MYSQL_ROW row; + char *query_str; int db_cl_altered= FALSE; DBUG_ENTER("dump_trigger"); while ((row= mysql_fetch_row(show_create_trigger_rs))) { - char *query_str= cover_definer_clause_in_trigger(row[2], strlen(row[2])); + if (opt_xml) + { + print_xml_row(sql_file, "trigger", show_create_trigger_rs, &row, + "SQL Original Statement"); + check_io(sql_file); + continue; + } + + query_str= cover_definer_clause_in_trigger(row[2], strlen(row[2])); if (switch_db_collation(sql_file, db_name, ";", @@ -2936,6 +3147,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name) /* Dump triggers. */ + if (! mysql_num_rows(show_triggers_rs)) + goto skip; + + if (opt_xml) + print_xml_tag(sql_file, "\t", "\n", "triggers", "name=", + table_name, NullS); + while ((row= mysql_fetch_row(show_triggers_rs))) { @@ -2968,6 +3186,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name) } + if (opt_xml) + { + fputs("\t\n", sql_file); + check_io(sql_file); + } + +skip: mysql_free_result(show_triggers_rs); if (switch_character_set_results(mysql, default_charset)) @@ -3216,34 +3441,24 @@ static void dump_table(char *table, char *db) } else { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n", - result_table); - check_io(md_result_file); - } + print_comment(md_result_file, 0, + "\n--\n-- Dumping data for table %s\n--\n", + result_table); dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); dynstr_append_checked(&query_string, result_table); if (where) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- WHERE: %s\n", where); - check_io(md_result_file); - } - + print_comment(md_result_file, 0, "-- WHERE: %s\n", where); + dynstr_append_checked(&query_string, " WHERE "); dynstr_append_checked(&query_string, where); } if (order_by) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); - check_io(md_result_file); - } + print_comment(md_result_file, 0, "-- ORDER BY: %s\n", order_by); + dynstr_append_checked(&query_string, " ORDER BY "); dynstr_append_checked(&query_string, order_by); } @@ -3439,7 +3654,7 @@ static void dump_table(char *table, char *db) { print_xml_tag(md_result_file, "\t\t", "", "field", "name=", field->name, NullS); - print_quoted_xml(md_result_file, row[i], length); + print_quoted_xml(md_result_file, row[i], length, 0); } fputs("\n", md_result_file); } @@ -3743,11 +3958,9 @@ static int dump_tablespaces(char* ts_where) first= 1; if (first) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file,"\n--\n-- Logfile group: %s\n--\n", row[0]); - check_io(md_result_file); - } + print_comment(md_result_file, 0, "\n--\n-- Logfile group: %s\n--\n", + row[0]); + fprintf(md_result_file, "\nCREATE"); } else @@ -3815,11 +4028,7 @@ static int dump_tablespaces(char* ts_where) first= 1; if (first) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file,"\n--\n-- Tablespace: %s\n--\n", row[0]); - check_io(md_result_file); - } + print_comment(md_result_file, 0, "\n--\n-- Tablespace: %s\n--\n", row[0]); fprintf(md_result_file, "\nCREATE"); } else @@ -4009,11 +4218,9 @@ static int init_dumping(char *database, int init_func(char*)) */ char quoted_database_buf[NAME_LEN*2+3]; char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted); - if (opt_comments) - { - fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase); - check_io(md_result_file); - } + + print_comment(md_result_file, 0, + "\n--\n-- Current Database: %s\n--\n", qdatabase); /* Call the view or table specific function */ init_func(qdatabase); @@ -4087,8 +4294,7 @@ static int dump_all_tables_in_db(char *database) dump_table(table,database); my_free(order_by, MYF(MY_ALLOW_ZERO_PTR)); order_by= 0; - if (opt_dump_triggers && ! opt_xml && - mysql_get_server_version(mysql) >= 50009) + if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009) { if (dump_triggers_for_table(table, database)) { @@ -4099,14 +4305,12 @@ static int dump_all_tables_in_db(char *database) } } } - if (opt_events && !opt_xml && - mysql_get_server_version(mysql) >= 50106) + if (opt_events && mysql_get_server_version(mysql) >= 50106) { DBUG_PRINT("info", ("Dumping events for database %s", database)); dump_events_for_db(database); } - if (opt_routines && !opt_xml && - mysql_get_server_version(mysql) >= 50009) + if (opt_routines && mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", database)); dump_routines_for_db(database); @@ -4341,15 +4545,13 @@ static int dump_selected_tables(char *db, char **table_names, int tables) for (pos= dump_tables; pos < end; pos++) get_view_structure(*pos, db); } - if (opt_events && !opt_xml && - mysql_get_server_version(mysql) >= 50106) + if (opt_events && mysql_get_server_version(mysql) >= 50106) { DBUG_PRINT("info", ("Dumping events for database %s", db)); dump_events_for_db(db); } /* obtain dump of routines (procs/functions) */ - if (opt_routines && !opt_xml && - mysql_get_server_version(mysql) >= 50009) + if (opt_routines && mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", db)); dump_routines_for_db(db); @@ -4384,10 +4586,9 @@ static int do_show_master_status(MYSQL *mysql_con) if (row && row[0] && row[1]) { /* SHOW MASTER STATUS reports file and position */ - if (opt_comments) - fprintf(md_result_file, - "\n--\n-- Position to start replication or point-in-time " - "recovery from\n--\n\n"); + print_comment(md_result_file, 0, + "\n--\n-- Position to start replication or point-in-time " + "recovery from\n--\n\n"); fprintf(md_result_file, "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", comment_prefix, row[0], row[1]); @@ -4850,12 +5051,10 @@ static my_bool get_view_structure(char *table, char* db) write_header(sql_file, db); } - if (!opt_xml && opt_comments) - { - fprintf(sql_file, "\n--\n-- Final view structure for view %s\n--\n\n", - result_table); - check_io(sql_file); - } + print_comment(sql_file, 0, + "\n--\n-- Final view structure for view %s\n--\n\n", + result_table); + /* Table might not exist if this view was dumped with --tab. */ fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table); if (opt_drop) @@ -5052,6 +5251,12 @@ int main(int argc, char **argv) exit(exit_code); } + /* + Disable comments in xml mode if 'comments' option is not explicitly used. + */ + if (opt_xml && !opt_comments_used) + opt_comments= 0; + if (log_error_file) { if(!(stderror_file= freopen(log_error_file, "a+", stderr))) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index a337c0384f6..1d4a5783c3f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -4628,5 +4628,444 @@ ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; DROP DATABASE `test-database`; USE `test`; # +# BUG#11760384 : 52792: mysqldump in XML mode does not dump routines. +# +CREATE DATABASE BUG52792; +USE BUG52792; +CREATE TABLE t1 (c1 INT, c2 VARCHAR(20)); +CREATE TABLE t2 (c1 INT); +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); +INSERT INTO t2 VALUES (1),(2),(3); +# Stored Procedures. +CREATE PROCEDURE simpleproc1 (OUT param1 INT) +BEGIN +SELECT COUNT(*) INTO param1 FROM t1; +END// +CREATE PROCEDURE simpleproc2 (OUT param1 INT) +BEGIN +SELECT COUNT(*) INTO param1 FROM t2; +END// +# Events. +CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; +CREATE EVENT e2 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; +# Functions. +CREATE FUNCTION `hello1` (s CHAR(20)) +RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT('Hello, ' ,s ,'!'); +CREATE FUNCTION `hello2` (s CHAR(20)) +RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ' , s ,'!'); +# Triggers. +CREATE TRIGGER trig1 BEFORE INSERT ON t2 +FOR EACH ROW BEGIN +INSERT INTO t2 VALUES(1); +END; +| +CREATE TRIGGER trig2 AFTER INSERT ON t2 +FOR EACH ROW BEGIN +INSERT INTO t2 VALUES(1, ']]>'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END; +| +# Views +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT * FROM t2; + +# Dumping BUG52792 database in xml format. + +# Running 'replace_regex on timestamp' + + + + + + + + + + + 1 + aaa + + + 2 + bbb + + + 3 + ccc + + + + + + + + + 1 + + + 2 + + + 3 + + + + + + + +'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END +]]> + + + + + + + + + + + + + + + + + + + + + + + + +, ' , s ,'!') +]]> + + + + + + + + + + + +# Dumping BUG52792 database in xml format with comments. + +# Running 'replace_regex on timestamp' + + + + + + + + + + + + + 1 + aaa + + + 2 + bbb + + + 3 + ccc + + + + + + + + + + + 1 + + + 2 + + + 3 + + + + + + + +'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +, ' , s ,'!') +]]> + + + + + + + + + + + +# Test to check 'Insufficient privileges' error. + +GRANT ALL PRIVILEGES ON BUG52792.* TO user1; +# Running 'replace_regex on timestamp' + + + + + + + + + + + 1 + aaa + + + 2 + bbb + + + 3 + ccc + + + + + + + + + 1 + + + 2 + + + 3 + + + + + + + +'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END +]]> + + + + + + + + + + + + + + + + + + + + + + +DROP USER user1; +DROP DATABASE BUG52792; +# UTF-8 +CREATE DATABASE BUG52792; +USE BUG52792; +SET NAMES utf8; +CREATE FUNCTION `straße` ( c1 CHAR(20)) +RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ', s, '!'); + + + + + +, ', s, '!') +]]> + + + + +DROP DATABASE BUG52792; +USE test; +# # End of 5.1 tests # diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 8ecf8187ff9..20c788e3b9a 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2196,6 +2196,118 @@ DROP DATABASE `test-database`; # Switching back to test database. USE `test`; +--echo # +--echo # BUG#11760384 : 52792: mysqldump in XML mode does not dump routines. +--echo # +CREATE DATABASE BUG52792; +USE BUG52792; +CREATE TABLE t1 (c1 INT, c2 VARCHAR(20)); +CREATE TABLE t2 (c1 INT); +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); +INSERT INTO t2 VALUES (1),(2),(3); + +--echo # Stored Procedures. + +DELIMITER //; +CREATE PROCEDURE simpleproc1 (OUT param1 INT) +BEGIN + SELECT COUNT(*) INTO param1 FROM t1; +END// +DELIMITER ;// + +DELIMITER //; +CREATE PROCEDURE simpleproc2 (OUT param1 INT) +BEGIN + SELECT COUNT(*) INTO param1 FROM t2; +END// +DELIMITER ;// + +--echo # Events. + +CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; +CREATE EVENT e2 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; + +--echo # Functions. + +CREATE FUNCTION `hello1` (s CHAR(20)) + RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT('Hello, ' ,s ,'!'); + +CREATE FUNCTION `hello2` (s CHAR(20)) + RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ' , s ,'!'); + +--echo # Triggers. + +DELIMITER |; +CREATE TRIGGER trig1 BEFORE INSERT ON t2 + FOR EACH ROW BEGIN + INSERT INTO t2 VALUES(1); +END; +| +DELIMITER ;| + +DELIMITER |; +CREATE TRIGGER trig2 AFTER INSERT ON t2 + FOR EACH ROW BEGIN + INSERT INTO t2 VALUES(1, ']]>'); + INSERT INTO t2 VALUES(2, ''); + INSERT INTO t2 VALUES(3, ' & \ " _'); +END; +| +DELIMITER ;| + +--echo # Views + +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT * FROM t2; +--echo +--echo # Dumping BUG52792 database in xml format. +--echo +--echo # Running 'replace_regex on timestamp' +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--exec $MYSQL_DUMP --user=root --compact -R -E --triggers -X BUG52792 +--echo +--echo # Dumping BUG52792 database in xml format with comments. +--echo +--echo # Running 'replace_regex on timestamp' +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--exec $MYSQL_DUMP --comments --user=root -R -E --triggers -X BUG52792 + +--echo +--echo # Test to check 'Insufficient privileges' error. +--echo + +GRANT ALL PRIVILEGES ON BUG52792.* TO user1; + +connect (conn_1, localhost, user1, , BUG52792, $MASTER_MYPORT, $MASTER_MYSOCK); +connection conn_1; + +--echo # Running 'replace_regex on timestamp' +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--error 2 +--exec $MYSQL_DUMP --user=user1 -R -E --triggers -X BUG52792 + +connection default; +disconnect conn_1; + +DROP USER user1; +DROP DATABASE BUG52792; +--echo # UTF-8 +CREATE DATABASE BUG52792; +USE BUG52792; +SET NAMES utf8; +CREATE FUNCTION `straße` ( c1 CHAR(20)) + RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ', s, '!'); + +--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 -R -X BUG52792 + +DROP DATABASE BUG52792; + +USE test; + --echo # --echo # End of 5.1 tests --echo # -- cgit v1.2.1 From 020f3914a2602ff8c7052154c7df64de916fb2c1 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Mon, 16 Jan 2012 09:58:31 +0530 Subject: Bug #11765438 58406: ISSUES WITH COPYING PARTITIONED INNODB TABLES FROM LINUX TO WINDOWS This problem was already fixed in mysql-trunk as part of bug #11755924. I am backporting the fix to mysql-5.1. --- storage/innobase/handler/ha_innodb.cc | 120 +++++++++++++++++++++++++--- storage/innobase/include/univ.i | 18 +++++ storage/innodb_plugin/ChangeLog | 6 ++ storage/innodb_plugin/handler/ha_innodb.cc | 122 ++++++++++++++++++++++++++--- 4 files changed, 244 insertions(+), 22 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 573e0a4455a..b229354ce88 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -948,6 +948,19 @@ innobase_get_charset( return(thd_charset((THD*) mysql_thd)); } +/**********************************************************************//** +Get the current setting of the lower_case_table_names global parameter from +mysqld.cc. We do a dirty read because for one there is no synchronization +object and secondly there is little harm in doing so even if we get a torn +read. +@return value of lower_case_table_names */ +ulint +innobase_get_lower_case_table_names(void) +/*=====================================*/ +{ + return(lower_case_table_names); +} + #if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list; /*******************************************************************//** @@ -2579,19 +2592,29 @@ ha_innobase::bas_ext() const return ha_innobase_exts; } +/** Always normalize table name to lower case on Windows */ +#ifdef __WIN__ +#define normalize_table_name(norm_name, name) \ + normalize_table_name_low(norm_name, name, TRUE) +#else +#define normalize_table_name(norm_name, name) \ + normalize_table_name_low(norm_name, name, FALSE) +#endif /* __WIN__ */ /********************************************************************* Normalizes a table name string. A normalized name consists of the database name catenated to '/' and table name. An example: test/mytable. On Windows normalization puts both the database name and the -table name always to lower case. */ +table name always to lower case if "set_lower_case" is set to TRUE. */ static void -normalize_table_name( -/*=================*/ +normalize_table_name_low( +/*=====================*/ char* norm_name, /* out: normalized name as a null-terminated string */ - const char* name) /* in: table name string */ + const char* name, /* in: table name string */ + ibool set_lower_case) /* in: TRUE if we want to set + name to lower case */ { char* name_ptr; char* db_ptr; @@ -2621,9 +2644,9 @@ normalize_table_name( norm_name[name_ptr - db_ptr - 1] = '/'; -#ifdef __WIN__ - innobase_casedn_str(norm_name); -#endif + if (set_lower_case) { + innobase_casedn_str(norm_name); + } } /************************************************************************ @@ -2806,6 +2829,8 @@ ha_innobase::open( THD* thd; ulint retries = 0; char* is_part = NULL; + ibool par_case_name_set = FALSE; + char par_case_name[MAX_FULL_NAME_LEN + 1]; DBUG_ENTER("ha_innobase::open"); @@ -2852,16 +2877,87 @@ ha_innobase::open( workaround for http://bugs.mysql.com/bug.php?id=33349. Look at support issue https://support.mysql.com/view.php?id=21080 for more details. */ +#ifdef __WIN__ + is_part = strstr(norm_name, "#p#"); +#else is_part = strstr(norm_name, "#P#"); +#endif /* __WIN__ */ + retry: /* Get pointer to a table object in InnoDB dictionary cache */ ib_table = dict_table_get(norm_name, TRUE); - + if (NULL == ib_table) { if (is_part && retries < 10) { - ++retries; - os_thread_sleep(100000); - goto retry; + /* MySQL partition engine hard codes the file name + separator as "#P#". The text case is fixed even if + lower_case_table_names is set to 1 or 2. This is true + for sub-partition names as well. InnoDB always + normalises file names to lower case on Windows, this + can potentially cause problems when copying/moving + tables between platforms. + + 1) If boot against an installation from Windows + platform, then its partition table name could + be all be in lower case in system tables. So we + will need to check lower case name when load table. + + 2) If we boot an installation from other case + sensitive platform in Windows, we might need to + check the existence of table name without lowering + case them in the system table. */ + if (innobase_get_lower_case_table_names() == 1) { + + if (!par_case_name_set) { +#ifndef __WIN__ + /* Check for the table using lower + case name, including the partition + separator "P" */ + memcpy(par_case_name, norm_name, + strlen(norm_name)); + par_case_name[strlen(norm_name)] = 0; + innobase_casedn_str(par_case_name); +#else + /* On Windows platfrom, check + whether there exists table name in + system table whose name is + not being normalized to lower case */ + normalize_table_name_low( + par_case_name, name, FALSE); +#endif + par_case_name_set = TRUE; + } + + ib_table = dict_table_get( + par_case_name, FALSE); + } + if (!ib_table) { + ++retries; + os_thread_sleep(100000); + goto retry; + } else { +#ifndef __WIN__ + sql_print_warning("Partition table %s opened " + "after converting to lower " + "case. The table may have " + "been moved from a case " + "in-sensitive file system. " + "Please recreate table in " + "the current file system\n", + norm_name); +#else + sql_print_warning("Partition table %s opened " + "after skipping the step to " + "lower case the table name. " + "The table may have been " + "moved from a case sensitive " + "file system. Please " + "recreate table in the " + "current file system\n", + norm_name); +#endif + goto table_opened; + } } if (is_part) { @@ -2892,6 +2988,8 @@ retry: DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } +table_opened: + if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) { sql_print_error("MySQL is trying to open a table handle but " "the .ibd file for\ntable %s does not exist.\n" diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 4ac0809bcd2..804f0e35605 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -160,6 +160,24 @@ management to ensure correct alignment for doubles etc. */ /* Maximum number of parallel threads in a parallelized operation */ #define UNIV_MAX_PARALLELISM 32 +/** The maximum length of a table name. This is the MySQL limit and is +defined in mysql_com.h like NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN, the +number does not include a terminating '\0'. InnoDB probably can handle +longer names internally */ +#define MAX_TABLE_NAME_LEN 192 + +/** The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is +the MySQL's NAME_LEN, see check_and_convert_db_name(). */ +#define MAX_DATABASE_NAME_LEN MAX_TABLE_NAME_LEN + +/** MAX_FULL_NAME_LEN defines the full name path including the +database name and table name. In addition, 14 bytes is added for: + 2 for surrounding quotes around table name + 1 for the separating dot (.) + 9 for the #mysql50# prefix */ +#define MAX_FULL_NAME_LEN \ + (MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14) + /* UNIVERSAL TYPE DEFINITIONS ========================== diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 5b1e2181e42..61de897bed4 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2012-01-16 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug#11765438: 58406: ISSUES WITH COPYING PARTITIONED INNODB + TABLES FROM LINUX TO WINDOWS + 2012-01-04 The InnoDB Team * row/row0mysql.c: diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 149e660e36e..abb7180b0d0 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -1038,6 +1038,20 @@ innobase_get_charset( return(thd_charset((THD*) mysql_thd)); } +/**********************************************************************//** +Get the current setting of the lower_case_table_names global parameter from +mysqld.cc. We do a dirty read because for one there is no synchronization +object and secondly there is little harm in doing so even if we get a torn +read. +@return value of lower_case_table_names */ +ulint +innobase_get_lower_case_table_names(void) +/*=====================================*/ +{ + return(lower_case_table_names); +} + + /**********************************************************************//** Determines the current SQL statement. @return SQL statement string */ @@ -3008,18 +3022,29 @@ ha_innobase::primary_key_is_clustered() return(true); } +/** Always normalize table name to lower case on Windows */ +#ifdef __WIN__ +#define normalize_table_name(norm_name, name) \ + normalize_table_name_low(norm_name, name, TRUE) +#else +#define normalize_table_name(norm_name, name) \ + normalize_table_name_low(norm_name, name, FALSE) +#endif /* __WIN__ */ + /*****************************************************************//** Normalizes a table name string. A normalized name consists of the database name catenated to '/' and table name. An example: test/mytable. On Windows normalization puts both the database name and the -table name always to lower case. */ +table name always to lower case if "set_lower_case" is set to TRUE. */ static void -normalize_table_name( -/*=================*/ +normalize_table_name_low( +/*=====================*/ char* norm_name, /*!< out: normalized name as a null-terminated string */ - const char* name) /*!< in: table name string */ + const char* name, /*!< in: table name string */ + ibool set_lower_case) /*!< in: TRUE if we want to set + name to lower case */ { char* name_ptr; char* db_ptr; @@ -3049,9 +3074,9 @@ normalize_table_name( norm_name[name_ptr - db_ptr - 1] = '/'; -#ifdef __WIN__ - innobase_casedn_str(norm_name); -#endif + if (set_lower_case) { + innobase_casedn_str(norm_name); + } } /********************************************************************//** @@ -3445,6 +3470,8 @@ ha_innobase::open( THD* thd; ulint retries = 0; char* is_part = NULL; + ibool par_case_name_set = FALSE; + char par_case_name[MAX_FULL_NAME_LEN + 1]; DBUG_ENTER("ha_innobase::open"); @@ -3491,16 +3518,87 @@ ha_innobase::open( workaround for http://bugs.mysql.com/bug.php?id=33349. Look at support issue https://support.mysql.com/view.php?id=21080 for more details. */ +#ifdef __WIN__ + is_part = strstr(norm_name, "#p#"); +#else is_part = strstr(norm_name, "#P#"); +#endif /* __WIN__ */ + retry: /* Get pointer to a table object in InnoDB dictionary cache */ ib_table = dict_table_get(norm_name, TRUE); - + if (NULL == ib_table) { if (is_part && retries < 10) { - ++retries; - os_thread_sleep(100000); - goto retry; + /* MySQL partition engine hard codes the file name + separator as "#P#". The text case is fixed even if + lower_case_table_names is set to 1 or 2. This is true + for sub-partition names as well. InnoDB always + normalises file names to lower case on Windows, this + can potentially cause problems when copying/moving + tables between platforms. + + 1) If boot against an installation from Windows + platform, then its partition table name could + be all be in lower case in system tables. So we + will need to check lower case name when load table. + + 2) If we boot an installation from other case + sensitive platform in Windows, we might need to + check the existence of table name without lowering + case them in the system table. */ + if (innobase_get_lower_case_table_names() == 1) { + + if (!par_case_name_set) { +#ifndef __WIN__ + /* Check for the table using lower + case name, including the partition + separator "P" */ + memcpy(par_case_name, norm_name, + strlen(norm_name)); + par_case_name[strlen(norm_name)] = 0; + innobase_casedn_str(par_case_name); +#else + /* On Windows platfrom, check + whether there exists table name in + system table whose name is + not being normalized to lower case */ + normalize_table_name_low( + par_case_name, name, FALSE); +#endif + par_case_name_set = TRUE; + } + + ib_table = dict_table_get( + par_case_name, FALSE); + } + if (!ib_table) { + ++retries; + os_thread_sleep(100000); + goto retry; + } else { +#ifndef __WIN__ + sql_print_warning("Partition table %s opened " + "after converting to lower " + "case. The table may have " + "been moved from a case " + "in-sensitive file system. " + "Please recreate table in " + "the current file system\n", + norm_name); +#else + sql_print_warning("Partition table %s opened " + "after skipping the step to " + "lower case the table name. " + "The table may have been " + "moved from a case sensitive " + "file system. Please " + "recreate table in the " + "current file system\n", + norm_name); +#endif + goto table_opened; + } } if (is_part) { @@ -3531,6 +3629,8 @@ retry: DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } +table_opened: + if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) { sql_print_error("MySQL is trying to open a table handle but " "the .ibd file for\ntable %s does not exist.\n" -- cgit v1.2.1 From a0ba966db7576569bd0b8e26d44ba9d86ca8f53c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Jan 2012 09:55:12 +0200 Subject: buf_page_get_known_nowait(): Relax a bogus debug assertion. When mode==BUF_KEEP_OLD, buffered inserts are being merged to the page. It is possible that a read request for a page was pending while the page was freed in DROP INDEX or DROP TABLE. In these cases, it is OK (although useless) to merge the buffered changes to the freed page. --- storage/innodb_plugin/buf/buf0buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 6daaacb0ac0..c2000d67303 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -2148,7 +2148,7 @@ buf_page_get_known_nowait( ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG - ut_a(block->page.file_page_was_freed == FALSE); + ut_a(mode == BUF_KEEP_OLD || !block->page.file_page_was_freed); #endif #ifdef UNIV_IBUF_COUNT_DEBUG -- cgit v1.2.1 From 9b0fdd650f5939fcfc70d8c3f1b3b42ea533071f Mon Sep 17 00:00:00 2001 From: Nuno Carvalho Date: Mon, 16 Jan 2012 09:17:40 +0000 Subject: BUG#11893288 60542: RPL.RPL_EXTRA_COL_MASTER_* DOESN'T TEST WHAT WAS INTENDED Test extra/rpl_tests/rpl_extra_col_master.test (used by rpl_extra_col_master_*) ends with the active connection pointing to the slave. Thus, the two last tests never succeed in changing the binlog format of the master away from 'row'. With correct active connection (master) tests fail for binlog 'statement' and 'mixed' formats. Tests rpl_extra_col_master_* only run when binary log format is row. Statement and mix replication do not make sense in this tests since it will try to execute statements on columns that do not exist. This fix is basically a backport from mysql-5.5, see changes done as part of BUG 39934. --- .../extra/rpl_tests/rpl_extra_col_master.test | 4 + .../suite/rpl/r/rpl_extra_col_master_innodb.result | 1743 -------------------- .../suite/rpl/r/rpl_extra_col_master_myisam.result | 1743 -------------------- .../suite/rpl/t/rpl_extra_col_master_innodb.test | 12 +- .../suite/rpl/t/rpl_extra_col_master_myisam.test | 10 +- 5 files changed, 9 insertions(+), 3503 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_extra_col_master.test b/mysql-test/extra/rpl_tests/rpl_extra_col_master.test index 1c103512318..07a0f2c9557 100644 --- a/mysql-test/extra/rpl_tests/rpl_extra_col_master.test +++ b/mysql-test/extra/rpl_tests/rpl_extra_col_master.test @@ -59,6 +59,8 @@ #VARCHAR(M) # +--let $_saved_conn= $CURRENT_CONNECTION + let $binformat = `SHOW VARIABLES LIKE '%binlog_format%'`; --echo --echo *********************************************************** @@ -1018,3 +1020,5 @@ SELECT c1,hex(c4),c5 FROM t5 ORDER BY c1; connection master; DROP TABLE t5; sync_slave_with_master; + +--connection $_saved_conn diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result b/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result index affb179d50e..8684701738a 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result @@ -1,6 +1,5 @@ include/master-slave.inc [connection master] -set binlog_format=row; *********************************************************** *********************************************************** @@ -832,1748 +831,6 @@ c1 hex(c4) c5 DROP TABLE t18; -***************************************************** -* - Insert UUID column on Master not on slave * -* Expect: Rows inserted * -***************************************************** - -*** Create t5 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t5 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t5 on Master *** -CREATE TABLE t5 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 LONG, -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -INSERT INTO t5 () VALUES(1,@b1,'Kyle',UUID(),DEFAULT), -(2,@b1,'JOE',UUID(),DEFAULT), -(3,@b1,'QA',UUID(),DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t5 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 6231623162316231 Kyle UUID TIME -2 6231623162316231 JOE UUID TIME -3 6231623162316231 QA UUID TIME - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t5 ORDER BY c1; -c1 hex(c4) c5 -1 6231623162316231 Kyle -2 6231623162316231 JOE -3 6231623162316231 QA -DROP TABLE t5; -set binlog_format=statement; - -*********************************************************** -*********************************************************** -***************** Start of Testing ************************ -*********************************************************** -*********************************************************** -* This test format == binlog_format STATEMENT and engine == 'InnoDB' -*********************************************************** -*********************************************************** - -***** Testing more columns on the Master ***** - -CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 FLOAT DEFAULT '2.00', -f6 CHAR(4) DEFAULT 'TEST', -f7 INT DEFAULT '0', -f8 TEXT, -f9 LONGBLOB, -f10 BIT(63), -f11 VARBINARY(64))ENGINE='InnoDB'; - -* Alter Table on Slave and drop columns f5 through f11 * - -alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; - -* Insert data in Master then update and delete some rows* - -* Select count and 20 rows from Master * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT f1,f2,f3,f4,f5,f6,f7,f8,f9, -hex(f10),hex(f11) FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 f5 f6 f7 f8 f9 hex(f10) hex(f11) -2 2 2 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -3 3 3 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -5 5 5 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -6 6 6 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -8 8 8 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -9 9 9 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -11 11 11 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -12 12 12 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -14 14 14 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -15 15 15 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -17 17 17 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -18 18 18 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -20 20 20 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -21 21 21 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -23 23 23 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -24 24 24 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -26 26 26 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -27 27 27 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -29 29 29 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -30 30 30 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 - -* Select count and 20 rows from Slave * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT * FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -include/check_slave_is_running.inc - -***** Testing Altering table def scenario ***** - -CREATE TABLE t2 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f7 DECIMAL(17,9) default '1000.00', -f8 MEDIUMBLOB, -f9 NUMERIC(6,4) default '2000.00', -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='InnoDB'; -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 - -CREATE TABLE t3 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f8 MEDIUMBLOB, -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='InnoDB'; - -CREATE TABLE t4 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 DECIMAL(17,9) default '1000.00', -f7 MEDIUMBLOB, -f8 NUMERIC(6,4) default '2000.00', -f9 VARCHAR(1024), -f10 BINARY(20) not null default '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f11 CHAR(255)) -ENGINE='InnoDB'; -Warnings: -Warning 1264 Out of range value for column 'f8' at row 1 - -CREATE TABLE t31 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 BIGINT, -f6 BLOB, -f7 DATE, -f8 DATETIME, -f9 FLOAT, -f10 INT, -f11 LONGBLOB, -f12 LONGTEXT, -f13 MEDIUMBLOB, -f14 MEDIUMINT, -f15 MEDIUMTEXT, -f16 REAL, -f17 SMALLINT, -f18 TEXT, -f19 TIME, -f20 TIMESTAMP, -f21 TINYBLOB, -f22 TINYINT, -f23 TINYTEXT, -f24 YEAR, -f25 BINARY(255), -f26 BIT(64), -f27 CHAR(255), -f28 DECIMAL(30,7), -f29 DOUBLE, -f30 ENUM ('a','b', 'c') default 'a', -f31 FLOAT, -f32 NUMERIC(17,9), -f33 SET ('a', 'b', 'c') default 'b', -f34 VARBINARY(1025), -f35 VARCHAR(257) -) ENGINE='InnoDB'; - -** Alter tables on slave and drop columns ** - -alter table t2 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, drop -f12; -alter table t3 drop f5, drop f6, drop f8, drop f10, drop f11, drop f12; -alter table t4 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; -alter table t31 -drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, -drop f12, drop f13, drop f14, drop f15, drop f16, drop f17, drop f18, -drop f19, drop f20, drop f21, drop f22, drop f23, drop f24, drop f25, -drop f26, drop f27, drop f28, drop f29, drop f30, drop f31, drop f32, -drop f33, drop f34, drop f35; - -** Insert Data into Master ** -INSERT into t2 set f1=1, f2=1, f3=1, f4='first', f8='f8: medium size blob', f10='f10: -some var char'; -INSERT into t2 values (2, 2, 2, 'second', -2.0, 'b', 2000.0002, 'f8: medium size blob', 2000, 'f10: some var char', -'01234567', 'c'), -(3, 3, 3, 'third', -3.0, 'b', 3000.0003, 'f8: medium size blob', 3000, 'f10: some var char', -'01234567', 'c'); -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 -Warning 1264 Out of range value for column 'f9' at row 2 -INSERT into t3 set f1=1, f2=1, f3=1, f4='first', f10='f10: some var char'; -INSERT into t4 set f1=1, f2=1, f3=1, f4='first', f7='f7: medium size blob', f10='f10: -binary data'; -INSERT into t31 set f1=1, f2=1, f3=1, f4='first'; -INSERT into t31 set f1=1, f2=1, f3=2, f4='second', -f9=2.2, f10='seven samurai', f28=222.222, f35='222'; -Warnings: -Warning 1366 Incorrect integer value: 'seven samurai' for column 'f10' at row 1 -INSERT into t31 values (1, 1, 3, 'third', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -INSERT into t31 values (1, 1, 4, 'fourth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 5, 'fifth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 6, 'sixth', -/* f5 BIGINT, */ NULL, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ NULL -); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -Warning 1264 Out of range value for column 'f5' at row 2 -Warning 1264 Out of range value for column 'f24' at row 2 -Warning 1264 Out of range value for column 'f24' at row 3 - -** Sync slave with master ** -** Do selects from tables ** - -select * from t1 order by f3; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -31 31 31 second -32 32 32 second -33 33 33 second -34 34 34 second -35 35 35 second -36 36 36 second -37 37 37 second -38 38 38 second -39 39 39 second -40 40 40 second -41 41 41 second -42 42 42 second -43 43 43 second -44 44 44 second -45 45 45 second -46 46 46 second -47 47 47 second -48 48 48 second -49 49 49 second -50 50 50 second -select * from t2 order by f1; -f1 f2 f3 f4 -1 1 1 first -2 2 2 second -3 3 3 third -select * from t3 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t4 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t31 order by f3; -f1 f2 f3 f4 -1 1 1 first -1 1 2 second -1 1 3 third -1 1 4 fourth -1 1 5 fifth -1 1 6 sixth - -** Do updates master ** - -update t31 set f5=555555555555555 where f3=6; -update t31 set f2=2 where f3=2; -update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null - -** Delete from Master ** - -delete from t1; -delete from t2; -delete from t3; -delete from t4; -delete from t31; -select * from t31; -f1 f2 f3 f4 - -** Check slave status ** - -include/check_slave_is_running.inc - -**************************************** -* columns in master at middle of table * -* Expect: Proper error message * -**************************************** - -** Stop and Reset Slave ** - -STOP SLAVE; -RESET SLAVE; - -** create table slave side ** -CREATE TABLE t10 (a INT PRIMARY KEY, b BLOB, c CHAR(5) -) ENGINE='InnoDB'; - -** Connect to master and create table ** - -CREATE TABLE t10 (a INT KEY, b BLOB, f DOUBLE DEFAULT '233', -c CHAR(5), e INT DEFAULT '1')ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT), -(2,@b1,DEFAULT,'JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254' - -*** Drop t10 *** -DROP TABLE t10; - -********************************************* -* More columns in master at middle of table * -* Expect: Proper error message * -********************************************* - -*** Create t11 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t11 (a INT PRIMARY KEY, b BLOB, c VARCHAR(254) -) ENGINE='InnoDB'; - -*** Create t11 on Master *** -CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT), -(2,@b1,'Testing is cool','JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15' - -*** Drop t11 *** -DROP TABLE t11; - -********************************************* -* More columns in master at middle of table * -* Expect: This one should pass blob-text * -********************************************* - -*** Create t12 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t12 (a INT PRIMARY KEY, b BLOB, c BLOB -) ENGINE='InnoDB'; - -*** Create t12 on Master *** -CREATE TABLE t12 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t12 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',DEFAULT,DEFAULT), -(3,@b1,'QA',DEFAULT,DEFAULT); - -SELECT a,hex(b),f,c,e FROM t12 ORDER BY a; -a hex(b) f c e -1 62316231623162316231623162316231 Kyle test 1 -2 62316231623162316231623162316231 JOE test 1 -3 62316231623162316231623162316231 QA test 1 - -*** Select on Slave *** -SELECT a,hex(b),c FROM t12 ORDER BY a; -a hex(b) c -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -*** Drop t12 *** -DROP TABLE t12; - -**************************************************** -* - Alter Master adding columns at middle of table * -* Expect: columns added * -**************************************************** - - -*** Create t14 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t14 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t14 on Master *** -CREATE TABLE t14 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t14 ADD COLUMN c2 DECIMAL(8,2) AFTER c1; -ALTER TABLE t14 ADD COLUMN c3 TEXT AFTER c2; - -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t14 () VALUES(1,1.00,'Replication Testing Extra Col',@b1,'Kyle',DEFAULT,DEFAULT), -(2,2.00,'This Test Should work',@b1,'JOE',DEFAULT,DEFAULT), -(3,3.00,'If is does not, I will open a bug',@b1,'QA',DEFAULT,DEFAULT); - -SELECT c1,c2,c3,hex(c4),c5,c6,c7 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 c6 c7 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 2.00 This Test Should work 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP - -*** Select on Slave **** -SELECT c1,c2,c3,hex(c4),c5 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle -2 2.00 This Test Should work 62316231623162316231623162316231 JOE -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA - -**************************************************** -* - Alter Master Dropping columns from the middle. * -* Expect: columns dropped * -**************************************************** - -*** connect to master and drop columns *** -ALTER TABLE t14 DROP COLUMN c2; -ALTER TABLE t14 DROP COLUMN c7; - -*** Select from Master *** -SELECT c1,c3,hex(c4),c5,c6 FROM t14 ORDER BY c1; -c1 c3 hex(c4) c5 c6 -1 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 -2 This Test Should work 62316231623162316231623162316231 JOE 1 -3 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 - -************ -* Bug30415 * -************ -include/wait_for_slave_sql_error.inc [errno=1091] -Last_SQL_Error = 'Error 'Can't DROP 'c7'; check that column/key exists' on query. Default database: 'test'. Query: 'ALTER TABLE t14 DROP COLUMN c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t14 *** -DROP TABLE t14; -DROP TABLE t14; -RESET MASTER; -START SLAVE; - -************************************************* -* - Alter Master adding columns at end of table * -* Expect: Error 1054 * -************************************************* - -*** Create t15 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t15 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t15 on Master *** -CREATE TABLE t15 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7; -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t15 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT,3.00), -(2,@b1,'JOE',DEFAULT,DEFAULT,3.00), -(3,@b1,'QA',DEFAULT,DEFAULT,3.00); -SELECT c1,hex(c4),c5,c6,c7,c2 FROM t15 ORDER BY c1; -c1 hex(c4) c5 c6 c7 c2 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 3.00 -2 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP 3.00 -3 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP 3.00 - -******************************************** -*** Expect slave to fail with Error 1054 *** -******************************************** - -include/wait_for_slave_sql_error.inc [errno=1054] -Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t15 *** -DROP TABLE t15; -DROP TABLE t15; -RESET MASTER; -START SLAVE; - -************************************************ -* - Create index on Master column not on slave * -* Expect:Warning * -************************************************ - -*** Create t16 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t16 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t16 on Master *** -CREATE TABLE t16 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Create Index and Data Insert *** -CREATE INDEX part_of_c6 ON t16 (c6); -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t16 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t16 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -***************** -*** BUG 30434 *** -***************** - -include/wait_for_slave_sql_error.inc [errno=1072] -Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Default database: 'test'. Query: 'CREATE INDEX part_of_c6 ON t16 (c6)'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t16 *** -DROP TABLE t16; -DROP TABLE t16; -RESET MASTER; -START SLAVE; - -***************************************************** -* - Delete rows using column on Master not on slave * -* Expect: Rows Deleted * -***************************************************** - -*** Create t17 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t17 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t17 on Master *** -CREATE TABLE t17 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t17 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** Delete from master ** -DELETE FROM t17 WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -DROP TABLE t17; - - -***************************************************** -* - Update row using column on Master not on slave * -* Expect: Rows updated * -***************************************************** - -** Bug30674 ** - -*** Create t18 on slave *** - -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t18 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t18 on Master *** -CREATE TABLE t18 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t18 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** update from master ** -UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 TEST -DROP TABLE t18; - - -***************************************************** -* - Insert UUID column on Master not on slave * -* Expect: Rows inserted * -***************************************************** - -*** Create t5 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t5 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t5 on Master *** -CREATE TABLE t5 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 LONG, -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -INSERT INTO t5 () VALUES(1,@b1,'Kyle',UUID(),DEFAULT), -(2,@b1,'JOE',UUID(),DEFAULT), -(3,@b1,'QA',UUID(),DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t5 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 6231623162316231 Kyle UUID TIME -2 6231623162316231 JOE UUID TIME -3 6231623162316231 QA UUID TIME - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t5 ORDER BY c1; -c1 hex(c4) c5 -1 6231623162316231 Kyle -2 6231623162316231 JOE -3 6231623162316231 QA -DROP TABLE t5; -set binlog_format=mixed; - -*********************************************************** -*********************************************************** -***************** Start of Testing ************************ -*********************************************************** -*********************************************************** -* This test format == binlog_format MIXED and engine == 'InnoDB' -*********************************************************** -*********************************************************** - -***** Testing more columns on the Master ***** - -CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 FLOAT DEFAULT '2.00', -f6 CHAR(4) DEFAULT 'TEST', -f7 INT DEFAULT '0', -f8 TEXT, -f9 LONGBLOB, -f10 BIT(63), -f11 VARBINARY(64))ENGINE='InnoDB'; - -* Alter Table on Slave and drop columns f5 through f11 * - -alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; - -* Insert data in Master then update and delete some rows* - -* Select count and 20 rows from Master * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT f1,f2,f3,f4,f5,f6,f7,f8,f9, -hex(f10),hex(f11) FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 f5 f6 f7 f8 f9 hex(f10) hex(f11) -2 2 2 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -3 3 3 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -5 5 5 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -6 6 6 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -8 8 8 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -9 9 9 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -11 11 11 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -12 12 12 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -14 14 14 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -15 15 15 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -17 17 17 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -18 18 18 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -20 20 20 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -21 21 21 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -23 23 23 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -24 24 24 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -26 26 26 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -27 27 27 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -29 29 29 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -30 30 30 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 - -* Select count and 20 rows from Slave * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT * FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -include/check_slave_is_running.inc - -***** Testing Altering table def scenario ***** - -CREATE TABLE t2 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f7 DECIMAL(17,9) default '1000.00', -f8 MEDIUMBLOB, -f9 NUMERIC(6,4) default '2000.00', -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='InnoDB'; -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 - -CREATE TABLE t3 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f8 MEDIUMBLOB, -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='InnoDB'; - -CREATE TABLE t4 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 DECIMAL(17,9) default '1000.00', -f7 MEDIUMBLOB, -f8 NUMERIC(6,4) default '2000.00', -f9 VARCHAR(1024), -f10 BINARY(20) not null default '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f11 CHAR(255)) -ENGINE='InnoDB'; -Warnings: -Warning 1264 Out of range value for column 'f8' at row 1 - -CREATE TABLE t31 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 BIGINT, -f6 BLOB, -f7 DATE, -f8 DATETIME, -f9 FLOAT, -f10 INT, -f11 LONGBLOB, -f12 LONGTEXT, -f13 MEDIUMBLOB, -f14 MEDIUMINT, -f15 MEDIUMTEXT, -f16 REAL, -f17 SMALLINT, -f18 TEXT, -f19 TIME, -f20 TIMESTAMP, -f21 TINYBLOB, -f22 TINYINT, -f23 TINYTEXT, -f24 YEAR, -f25 BINARY(255), -f26 BIT(64), -f27 CHAR(255), -f28 DECIMAL(30,7), -f29 DOUBLE, -f30 ENUM ('a','b', 'c') default 'a', -f31 FLOAT, -f32 NUMERIC(17,9), -f33 SET ('a', 'b', 'c') default 'b', -f34 VARBINARY(1025), -f35 VARCHAR(257) -) ENGINE='InnoDB'; - -** Alter tables on slave and drop columns ** - -alter table t2 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, drop -f12; -alter table t3 drop f5, drop f6, drop f8, drop f10, drop f11, drop f12; -alter table t4 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; -alter table t31 -drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, -drop f12, drop f13, drop f14, drop f15, drop f16, drop f17, drop f18, -drop f19, drop f20, drop f21, drop f22, drop f23, drop f24, drop f25, -drop f26, drop f27, drop f28, drop f29, drop f30, drop f31, drop f32, -drop f33, drop f34, drop f35; - -** Insert Data into Master ** -INSERT into t2 set f1=1, f2=1, f3=1, f4='first', f8='f8: medium size blob', f10='f10: -some var char'; -INSERT into t2 values (2, 2, 2, 'second', -2.0, 'b', 2000.0002, 'f8: medium size blob', 2000, 'f10: some var char', -'01234567', 'c'), -(3, 3, 3, 'third', -3.0, 'b', 3000.0003, 'f8: medium size blob', 3000, 'f10: some var char', -'01234567', 'c'); -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 -Warning 1264 Out of range value for column 'f9' at row 2 -INSERT into t3 set f1=1, f2=1, f3=1, f4='first', f10='f10: some var char'; -INSERT into t4 set f1=1, f2=1, f3=1, f4='first', f7='f7: medium size blob', f10='f10: -binary data'; -INSERT into t31 set f1=1, f2=1, f3=1, f4='first'; -INSERT into t31 set f1=1, f2=1, f3=2, f4='second', -f9=2.2, f10='seven samurai', f28=222.222, f35='222'; -Warnings: -Warning 1366 Incorrect integer value: 'seven samurai' for column 'f10' at row 1 -INSERT into t31 values (1, 1, 3, 'third', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -INSERT into t31 values (1, 1, 4, 'fourth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 5, 'fifth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 6, 'sixth', -/* f5 BIGINT, */ NULL, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ NULL -); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -Warning 1264 Out of range value for column 'f5' at row 2 -Warning 1264 Out of range value for column 'f24' at row 2 -Warning 1264 Out of range value for column 'f24' at row 3 - -** Sync slave with master ** -** Do selects from tables ** - -select * from t1 order by f3; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -31 31 31 second -32 32 32 second -33 33 33 second -34 34 34 second -35 35 35 second -36 36 36 second -37 37 37 second -38 38 38 second -39 39 39 second -40 40 40 second -41 41 41 second -42 42 42 second -43 43 43 second -44 44 44 second -45 45 45 second -46 46 46 second -47 47 47 second -48 48 48 second -49 49 49 second -50 50 50 second -select * from t2 order by f1; -f1 f2 f3 f4 -1 1 1 first -2 2 2 second -3 3 3 third -select * from t3 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t4 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t31 order by f3; -f1 f2 f3 f4 -1 1 1 first -1 1 2 second -1 1 3 third -1 1 4 fourth -1 1 5 fifth -1 1 6 sixth - -** Do updates master ** - -update t31 set f5=555555555555555 where f3=6; -update t31 set f2=2 where f3=2; -update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null - -** Delete from Master ** - -delete from t1; -delete from t2; -delete from t3; -delete from t4; -delete from t31; -select * from t31; -f1 f2 f3 f4 - -** Check slave status ** - -include/check_slave_is_running.inc - -**************************************** -* columns in master at middle of table * -* Expect: Proper error message * -**************************************** - -** Stop and Reset Slave ** - -STOP SLAVE; -RESET SLAVE; - -** create table slave side ** -CREATE TABLE t10 (a INT PRIMARY KEY, b BLOB, c CHAR(5) -) ENGINE='InnoDB'; - -** Connect to master and create table ** - -CREATE TABLE t10 (a INT KEY, b BLOB, f DOUBLE DEFAULT '233', -c CHAR(5), e INT DEFAULT '1')ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT), -(2,@b1,DEFAULT,'JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254' - -*** Drop t10 *** -DROP TABLE t10; - -********************************************* -* More columns in master at middle of table * -* Expect: Proper error message * -********************************************* - -*** Create t11 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t11 (a INT PRIMARY KEY, b BLOB, c VARCHAR(254) -) ENGINE='InnoDB'; - -*** Create t11 on Master *** -CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT), -(2,@b1,'Testing is cool','JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15' - -*** Drop t11 *** -DROP TABLE t11; - -********************************************* -* More columns in master at middle of table * -* Expect: This one should pass blob-text * -********************************************* - -*** Create t12 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t12 (a INT PRIMARY KEY, b BLOB, c BLOB -) ENGINE='InnoDB'; - -*** Create t12 on Master *** -CREATE TABLE t12 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t12 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',DEFAULT,DEFAULT), -(3,@b1,'QA',DEFAULT,DEFAULT); - -SELECT a,hex(b),f,c,e FROM t12 ORDER BY a; -a hex(b) f c e -1 62316231623162316231623162316231 Kyle test 1 -2 62316231623162316231623162316231 JOE test 1 -3 62316231623162316231623162316231 QA test 1 - -*** Select on Slave *** -SELECT a,hex(b),c FROM t12 ORDER BY a; -a hex(b) c -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -*** Drop t12 *** -DROP TABLE t12; - -**************************************************** -* - Alter Master adding columns at middle of table * -* Expect: columns added * -**************************************************** - - -*** Create t14 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t14 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t14 on Master *** -CREATE TABLE t14 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t14 ADD COLUMN c2 DECIMAL(8,2) AFTER c1; -ALTER TABLE t14 ADD COLUMN c3 TEXT AFTER c2; - -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t14 () VALUES(1,1.00,'Replication Testing Extra Col',@b1,'Kyle',DEFAULT,DEFAULT), -(2,2.00,'This Test Should work',@b1,'JOE',DEFAULT,DEFAULT), -(3,3.00,'If is does not, I will open a bug',@b1,'QA',DEFAULT,DEFAULT); - -SELECT c1,c2,c3,hex(c4),c5,c6,c7 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 c6 c7 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 2.00 This Test Should work 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP - -*** Select on Slave **** -SELECT c1,c2,c3,hex(c4),c5 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle -2 2.00 This Test Should work 62316231623162316231623162316231 JOE -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA - -**************************************************** -* - Alter Master Dropping columns from the middle. * -* Expect: columns dropped * -**************************************************** - -*** connect to master and drop columns *** -ALTER TABLE t14 DROP COLUMN c2; -ALTER TABLE t14 DROP COLUMN c7; - -*** Select from Master *** -SELECT c1,c3,hex(c4),c5,c6 FROM t14 ORDER BY c1; -c1 c3 hex(c4) c5 c6 -1 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 -2 This Test Should work 62316231623162316231623162316231 JOE 1 -3 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 - -************ -* Bug30415 * -************ -include/wait_for_slave_sql_error.inc [errno=1091] -Last_SQL_Error = 'Error 'Can't DROP 'c7'; check that column/key exists' on query. Default database: 'test'. Query: 'ALTER TABLE t14 DROP COLUMN c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t14 *** -DROP TABLE t14; -DROP TABLE t14; -RESET MASTER; -START SLAVE; - -************************************************* -* - Alter Master adding columns at end of table * -* Expect: Error 1054 * -************************************************* - -*** Create t15 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t15 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t15 on Master *** -CREATE TABLE t15 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7; -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t15 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT,3.00), -(2,@b1,'JOE',DEFAULT,DEFAULT,3.00), -(3,@b1,'QA',DEFAULT,DEFAULT,3.00); -SELECT c1,hex(c4),c5,c6,c7,c2 FROM t15 ORDER BY c1; -c1 hex(c4) c5 c6 c7 c2 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 3.00 -2 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP 3.00 -3 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP 3.00 - -******************************************** -*** Expect slave to fail with Error 1054 *** -******************************************** - -include/wait_for_slave_sql_error.inc [errno=1054] -Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t15 *** -DROP TABLE t15; -DROP TABLE t15; -RESET MASTER; -START SLAVE; - -************************************************ -* - Create index on Master column not on slave * -* Expect:Warning * -************************************************ - -*** Create t16 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t16 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t16 on Master *** -CREATE TABLE t16 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Create Index and Data Insert *** -CREATE INDEX part_of_c6 ON t16 (c6); -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t16 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t16 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -***************** -*** BUG 30434 *** -***************** - -include/wait_for_slave_sql_error.inc [errno=1072] -Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Default database: 'test'. Query: 'CREATE INDEX part_of_c6 ON t16 (c6)'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t16 *** -DROP TABLE t16; -DROP TABLE t16; -RESET MASTER; -START SLAVE; - -***************************************************** -* - Delete rows using column on Master not on slave * -* Expect: Rows Deleted * -***************************************************** - -*** Create t17 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t17 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t17 on Master *** -CREATE TABLE t17 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t17 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** Delete from master ** -DELETE FROM t17 WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -DROP TABLE t17; - - -***************************************************** -* - Update row using column on Master not on slave * -* Expect: Rows updated * -***************************************************** - -** Bug30674 ** - -*** Create t18 on slave *** - -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t18 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='InnoDB'; - -*** Create t18 on Master *** -CREATE TABLE t18 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='InnoDB'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t18 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** update from master ** -UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 TEST -DROP TABLE t18; - - ***************************************************** * - Insert UUID column on Master not on slave * * Expect: Rows inserted * diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result b/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result index 8aeb5bdc1c9..c390f0858d6 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result @@ -1,6 +1,5 @@ include/master-slave.inc [connection master] -set binlog_format=row; *********************************************************** *********************************************************** @@ -832,1748 +831,6 @@ c1 hex(c4) c5 DROP TABLE t18; -***************************************************** -* - Insert UUID column on Master not on slave * -* Expect: Rows inserted * -***************************************************** - -*** Create t5 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t5 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t5 on Master *** -CREATE TABLE t5 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 LONG, -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -INSERT INTO t5 () VALUES(1,@b1,'Kyle',UUID(),DEFAULT), -(2,@b1,'JOE',UUID(),DEFAULT), -(3,@b1,'QA',UUID(),DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t5 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 6231623162316231 Kyle UUID TIME -2 6231623162316231 JOE UUID TIME -3 6231623162316231 QA UUID TIME - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t5 ORDER BY c1; -c1 hex(c4) c5 -1 6231623162316231 Kyle -2 6231623162316231 JOE -3 6231623162316231 QA -DROP TABLE t5; -set binlog_format=statement; - -*********************************************************** -*********************************************************** -***************** Start of Testing ************************ -*********************************************************** -*********************************************************** -* This test format == binlog_format STATEMENT and engine == 'MyISAM' -*********************************************************** -*********************************************************** - -***** Testing more columns on the Master ***** - -CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 FLOAT DEFAULT '2.00', -f6 CHAR(4) DEFAULT 'TEST', -f7 INT DEFAULT '0', -f8 TEXT, -f9 LONGBLOB, -f10 BIT(63), -f11 VARBINARY(64))ENGINE='MyISAM'; - -* Alter Table on Slave and drop columns f5 through f11 * - -alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; - -* Insert data in Master then update and delete some rows* - -* Select count and 20 rows from Master * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT f1,f2,f3,f4,f5,f6,f7,f8,f9, -hex(f10),hex(f11) FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 f5 f6 f7 f8 f9 hex(f10) hex(f11) -2 2 2 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -3 3 3 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -5 5 5 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -6 6 6 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -8 8 8 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -9 9 9 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -11 11 11 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -12 12 12 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -14 14 14 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -15 15 15 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -17 17 17 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -18 18 18 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -20 20 20 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -21 21 21 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -23 23 23 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -24 24 24 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -26 26 26 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -27 27 27 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -29 29 29 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -30 30 30 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 - -* Select count and 20 rows from Slave * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT * FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -include/check_slave_is_running.inc - -***** Testing Altering table def scenario ***** - -CREATE TABLE t2 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f7 DECIMAL(17,9) default '1000.00', -f8 MEDIUMBLOB, -f9 NUMERIC(6,4) default '2000.00', -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='MyISAM'; -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 - -CREATE TABLE t3 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f8 MEDIUMBLOB, -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='MyISAM'; - -CREATE TABLE t4 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 DECIMAL(17,9) default '1000.00', -f7 MEDIUMBLOB, -f8 NUMERIC(6,4) default '2000.00', -f9 VARCHAR(1024), -f10 BINARY(20) not null default '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f11 CHAR(255)) -ENGINE='MyISAM'; -Warnings: -Warning 1264 Out of range value for column 'f8' at row 1 - -CREATE TABLE t31 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 BIGINT, -f6 BLOB, -f7 DATE, -f8 DATETIME, -f9 FLOAT, -f10 INT, -f11 LONGBLOB, -f12 LONGTEXT, -f13 MEDIUMBLOB, -f14 MEDIUMINT, -f15 MEDIUMTEXT, -f16 REAL, -f17 SMALLINT, -f18 TEXT, -f19 TIME, -f20 TIMESTAMP, -f21 TINYBLOB, -f22 TINYINT, -f23 TINYTEXT, -f24 YEAR, -f25 BINARY(255), -f26 BIT(64), -f27 CHAR(255), -f28 DECIMAL(30,7), -f29 DOUBLE, -f30 ENUM ('a','b', 'c') default 'a', -f31 FLOAT, -f32 NUMERIC(17,9), -f33 SET ('a', 'b', 'c') default 'b', -f34 VARBINARY(1025), -f35 VARCHAR(257) -) ENGINE='MyISAM'; - -** Alter tables on slave and drop columns ** - -alter table t2 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, drop -f12; -alter table t3 drop f5, drop f6, drop f8, drop f10, drop f11, drop f12; -alter table t4 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; -alter table t31 -drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, -drop f12, drop f13, drop f14, drop f15, drop f16, drop f17, drop f18, -drop f19, drop f20, drop f21, drop f22, drop f23, drop f24, drop f25, -drop f26, drop f27, drop f28, drop f29, drop f30, drop f31, drop f32, -drop f33, drop f34, drop f35; - -** Insert Data into Master ** -INSERT into t2 set f1=1, f2=1, f3=1, f4='first', f8='f8: medium size blob', f10='f10: -some var char'; -INSERT into t2 values (2, 2, 2, 'second', -2.0, 'b', 2000.0002, 'f8: medium size blob', 2000, 'f10: some var char', -'01234567', 'c'), -(3, 3, 3, 'third', -3.0, 'b', 3000.0003, 'f8: medium size blob', 3000, 'f10: some var char', -'01234567', 'c'); -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 -Warning 1264 Out of range value for column 'f9' at row 2 -INSERT into t3 set f1=1, f2=1, f3=1, f4='first', f10='f10: some var char'; -INSERT into t4 set f1=1, f2=1, f3=1, f4='first', f7='f7: medium size blob', f10='f10: -binary data'; -INSERT into t31 set f1=1, f2=1, f3=1, f4='first'; -INSERT into t31 set f1=1, f2=1, f3=2, f4='second', -f9=2.2, f10='seven samurai', f28=222.222, f35='222'; -Warnings: -Warning 1366 Incorrect integer value: 'seven samurai' for column 'f10' at row 1 -INSERT into t31 values (1, 1, 3, 'third', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -INSERT into t31 values (1, 1, 4, 'fourth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 5, 'fifth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 6, 'sixth', -/* f5 BIGINT, */ NULL, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ NULL -); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -Warning 1264 Out of range value for column 'f5' at row 2 -Warning 1264 Out of range value for column 'f24' at row 2 -Warning 1264 Out of range value for column 'f24' at row 3 - -** Sync slave with master ** -** Do selects from tables ** - -select * from t1 order by f3; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -31 31 31 second -32 32 32 second -33 33 33 second -34 34 34 second -35 35 35 second -36 36 36 second -37 37 37 second -38 38 38 second -39 39 39 second -40 40 40 second -41 41 41 second -42 42 42 second -43 43 43 second -44 44 44 second -45 45 45 second -46 46 46 second -47 47 47 second -48 48 48 second -49 49 49 second -50 50 50 second -select * from t2 order by f1; -f1 f2 f3 f4 -1 1 1 first -2 2 2 second -3 3 3 third -select * from t3 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t4 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t31 order by f3; -f1 f2 f3 f4 -1 1 1 first -1 1 2 second -1 1 3 third -1 1 4 fourth -1 1 5 fifth -1 1 6 sixth - -** Do updates master ** - -update t31 set f5=555555555555555 where f3=6; -update t31 set f2=2 where f3=2; -update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null - -** Delete from Master ** - -delete from t1; -delete from t2; -delete from t3; -delete from t4; -delete from t31; -select * from t31; -f1 f2 f3 f4 - -** Check slave status ** - -include/check_slave_is_running.inc - -**************************************** -* columns in master at middle of table * -* Expect: Proper error message * -**************************************** - -** Stop and Reset Slave ** - -STOP SLAVE; -RESET SLAVE; - -** create table slave side ** -CREATE TABLE t10 (a INT PRIMARY KEY, b BLOB, c CHAR(5) -) ENGINE='MyISAM'; - -** Connect to master and create table ** - -CREATE TABLE t10 (a INT KEY, b BLOB, f DOUBLE DEFAULT '233', -c CHAR(5), e INT DEFAULT '1')ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT), -(2,@b1,DEFAULT,'JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254' - -*** Drop t10 *** -DROP TABLE t10; - -********************************************* -* More columns in master at middle of table * -* Expect: Proper error message * -********************************************* - -*** Create t11 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t11 (a INT PRIMARY KEY, b BLOB, c VARCHAR(254) -) ENGINE='MyISAM'; - -*** Create t11 on Master *** -CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT), -(2,@b1,'Testing is cool','JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15' - -*** Drop t11 *** -DROP TABLE t11; - -********************************************* -* More columns in master at middle of table * -* Expect: This one should pass blob-text * -********************************************* - -*** Create t12 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t12 (a INT PRIMARY KEY, b BLOB, c BLOB -) ENGINE='MyISAM'; - -*** Create t12 on Master *** -CREATE TABLE t12 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t12 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',DEFAULT,DEFAULT), -(3,@b1,'QA',DEFAULT,DEFAULT); - -SELECT a,hex(b),f,c,e FROM t12 ORDER BY a; -a hex(b) f c e -1 62316231623162316231623162316231 Kyle test 1 -2 62316231623162316231623162316231 JOE test 1 -3 62316231623162316231623162316231 QA test 1 - -*** Select on Slave *** -SELECT a,hex(b),c FROM t12 ORDER BY a; -a hex(b) c -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -*** Drop t12 *** -DROP TABLE t12; - -**************************************************** -* - Alter Master adding columns at middle of table * -* Expect: columns added * -**************************************************** - - -*** Create t14 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t14 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t14 on Master *** -CREATE TABLE t14 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t14 ADD COLUMN c2 DECIMAL(8,2) AFTER c1; -ALTER TABLE t14 ADD COLUMN c3 TEXT AFTER c2; - -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t14 () VALUES(1,1.00,'Replication Testing Extra Col',@b1,'Kyle',DEFAULT,DEFAULT), -(2,2.00,'This Test Should work',@b1,'JOE',DEFAULT,DEFAULT), -(3,3.00,'If is does not, I will open a bug',@b1,'QA',DEFAULT,DEFAULT); - -SELECT c1,c2,c3,hex(c4),c5,c6,c7 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 c6 c7 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 2.00 This Test Should work 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP - -*** Select on Slave **** -SELECT c1,c2,c3,hex(c4),c5 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle -2 2.00 This Test Should work 62316231623162316231623162316231 JOE -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA - -**************************************************** -* - Alter Master Dropping columns from the middle. * -* Expect: columns dropped * -**************************************************** - -*** connect to master and drop columns *** -ALTER TABLE t14 DROP COLUMN c2; -ALTER TABLE t14 DROP COLUMN c7; - -*** Select from Master *** -SELECT c1,c3,hex(c4),c5,c6 FROM t14 ORDER BY c1; -c1 c3 hex(c4) c5 c6 -1 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 -2 This Test Should work 62316231623162316231623162316231 JOE 1 -3 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 - -************ -* Bug30415 * -************ -include/wait_for_slave_sql_error.inc [errno=1091] -Last_SQL_Error = 'Error 'Can't DROP 'c7'; check that column/key exists' on query. Default database: 'test'. Query: 'ALTER TABLE t14 DROP COLUMN c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t14 *** -DROP TABLE t14; -DROP TABLE t14; -RESET MASTER; -START SLAVE; - -************************************************* -* - Alter Master adding columns at end of table * -* Expect: Error 1054 * -************************************************* - -*** Create t15 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t15 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t15 on Master *** -CREATE TABLE t15 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7; -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t15 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT,3.00), -(2,@b1,'JOE',DEFAULT,DEFAULT,3.00), -(3,@b1,'QA',DEFAULT,DEFAULT,3.00); -SELECT c1,hex(c4),c5,c6,c7,c2 FROM t15 ORDER BY c1; -c1 hex(c4) c5 c6 c7 c2 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 3.00 -2 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP 3.00 -3 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP 3.00 - -******************************************** -*** Expect slave to fail with Error 1054 *** -******************************************** - -include/wait_for_slave_sql_error.inc [errno=1054] -Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t15 *** -DROP TABLE t15; -DROP TABLE t15; -RESET MASTER; -START SLAVE; - -************************************************ -* - Create index on Master column not on slave * -* Expect:Warning * -************************************************ - -*** Create t16 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t16 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t16 on Master *** -CREATE TABLE t16 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Create Index and Data Insert *** -CREATE INDEX part_of_c6 ON t16 (c6); -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t16 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t16 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -***************** -*** BUG 30434 *** -***************** - -include/wait_for_slave_sql_error.inc [errno=1072] -Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Default database: 'test'. Query: 'CREATE INDEX part_of_c6 ON t16 (c6)'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t16 *** -DROP TABLE t16; -DROP TABLE t16; -RESET MASTER; -START SLAVE; - -***************************************************** -* - Delete rows using column on Master not on slave * -* Expect: Rows Deleted * -***************************************************** - -*** Create t17 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t17 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t17 on Master *** -CREATE TABLE t17 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t17 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** Delete from master ** -DELETE FROM t17 WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -DROP TABLE t17; - - -***************************************************** -* - Update row using column on Master not on slave * -* Expect: Rows updated * -***************************************************** - -** Bug30674 ** - -*** Create t18 on slave *** - -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t18 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t18 on Master *** -CREATE TABLE t18 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t18 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** update from master ** -UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 TEST -DROP TABLE t18; - - -***************************************************** -* - Insert UUID column on Master not on slave * -* Expect: Rows inserted * -***************************************************** - -*** Create t5 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t5 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t5 on Master *** -CREATE TABLE t5 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 LONG, -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -INSERT INTO t5 () VALUES(1,@b1,'Kyle',UUID(),DEFAULT), -(2,@b1,'JOE',UUID(),DEFAULT), -(3,@b1,'QA',UUID(),DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t5 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 6231623162316231 Kyle UUID TIME -2 6231623162316231 JOE UUID TIME -3 6231623162316231 QA UUID TIME - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t5 ORDER BY c1; -c1 hex(c4) c5 -1 6231623162316231 Kyle -2 6231623162316231 JOE -3 6231623162316231 QA -DROP TABLE t5; -set binlog_format=mixed; - -*********************************************************** -*********************************************************** -***************** Start of Testing ************************ -*********************************************************** -*********************************************************** -* This test format == binlog_format MIXED and engine == 'MyISAM' -*********************************************************** -*********************************************************** - -***** Testing more columns on the Master ***** - -CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 FLOAT DEFAULT '2.00', -f6 CHAR(4) DEFAULT 'TEST', -f7 INT DEFAULT '0', -f8 TEXT, -f9 LONGBLOB, -f10 BIT(63), -f11 VARBINARY(64))ENGINE='MyISAM'; - -* Alter Table on Slave and drop columns f5 through f11 * - -alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; - -* Insert data in Master then update and delete some rows* - -* Select count and 20 rows from Master * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT f1,f2,f3,f4,f5,f6,f7,f8,f9, -hex(f10),hex(f11) FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 f5 f6 f7 f8 f9 hex(f10) hex(f11) -2 2 2 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -3 3 3 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -5 5 5 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -6 6 6 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -8 8 8 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -9 9 9 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -11 11 11 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -12 12 12 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -14 14 14 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -15 15 15 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -17 17 17 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -18 18 18 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -20 20 20 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -21 21 21 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -23 23 23 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -24 24 24 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -26 26 26 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -27 27 27 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -29 29 29 second 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 -30 30 30 next 2 kaks 2 got stolen from the paradise very fat blob 1555 123456 - -* Select count and 20 rows from Slave * - -SELECT COUNT(*) FROM t1; -COUNT(*) -40 - -SELECT * FROM t1 ORDER BY f3 LIMIT 20; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -include/check_slave_is_running.inc - -***** Testing Altering table def scenario ***** - -CREATE TABLE t2 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f7 DECIMAL(17,9) default '1000.00', -f8 MEDIUMBLOB, -f9 NUMERIC(6,4) default '2000.00', -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='MyISAM'; -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 - -CREATE TABLE t3 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 ENUM('a', 'b', 'c') default 'a', -f8 MEDIUMBLOB, -f10 VARCHAR(1024), -f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f12 SET('a', 'b', 'c') default 'b') -ENGINE='MyISAM'; - -CREATE TABLE t4 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 DOUBLE DEFAULT '2.00', -f6 DECIMAL(17,9) default '1000.00', -f7 MEDIUMBLOB, -f8 NUMERIC(6,4) default '2000.00', -f9 VARCHAR(1024), -f10 BINARY(20) not null default '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', -f11 CHAR(255)) -ENGINE='MyISAM'; -Warnings: -Warning 1264 Out of range value for column 'f8' at row 1 - -CREATE TABLE t31 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), -/* extra */ -f5 BIGINT, -f6 BLOB, -f7 DATE, -f8 DATETIME, -f9 FLOAT, -f10 INT, -f11 LONGBLOB, -f12 LONGTEXT, -f13 MEDIUMBLOB, -f14 MEDIUMINT, -f15 MEDIUMTEXT, -f16 REAL, -f17 SMALLINT, -f18 TEXT, -f19 TIME, -f20 TIMESTAMP, -f21 TINYBLOB, -f22 TINYINT, -f23 TINYTEXT, -f24 YEAR, -f25 BINARY(255), -f26 BIT(64), -f27 CHAR(255), -f28 DECIMAL(30,7), -f29 DOUBLE, -f30 ENUM ('a','b', 'c') default 'a', -f31 FLOAT, -f32 NUMERIC(17,9), -f33 SET ('a', 'b', 'c') default 'b', -f34 VARBINARY(1025), -f35 VARCHAR(257) -) ENGINE='MyISAM'; - -** Alter tables on slave and drop columns ** - -alter table t2 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, drop -f12; -alter table t3 drop f5, drop f6, drop f8, drop f10, drop f11, drop f12; -alter table t4 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; -alter table t31 -drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, -drop f12, drop f13, drop f14, drop f15, drop f16, drop f17, drop f18, -drop f19, drop f20, drop f21, drop f22, drop f23, drop f24, drop f25, -drop f26, drop f27, drop f28, drop f29, drop f30, drop f31, drop f32, -drop f33, drop f34, drop f35; - -** Insert Data into Master ** -INSERT into t2 set f1=1, f2=1, f3=1, f4='first', f8='f8: medium size blob', f10='f10: -some var char'; -INSERT into t2 values (2, 2, 2, 'second', -2.0, 'b', 2000.0002, 'f8: medium size blob', 2000, 'f10: some var char', -'01234567', 'c'), -(3, 3, 3, 'third', -3.0, 'b', 3000.0003, 'f8: medium size blob', 3000, 'f10: some var char', -'01234567', 'c'); -Warnings: -Warning 1264 Out of range value for column 'f9' at row 1 -Warning 1264 Out of range value for column 'f9' at row 2 -INSERT into t3 set f1=1, f2=1, f3=1, f4='first', f10='f10: some var char'; -INSERT into t4 set f1=1, f2=1, f3=1, f4='first', f7='f7: medium size blob', f10='f10: -binary data'; -INSERT into t31 set f1=1, f2=1, f3=1, f4='first'; -INSERT into t31 set f1=1, f2=1, f3=2, f4='second', -f9=2.2, f10='seven samurai', f28=222.222, f35='222'; -Warnings: -Warning 1366 Incorrect integer value: 'seven samurai' for column 'f10' at row 1 -INSERT into t31 values (1, 1, 3, 'third', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -INSERT into t31 values (1, 1, 4, 'fourth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 5, 'fifth', -/* f5 BIGINT, */ 333333333333333333333333, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ 'three times three' - ), -(1, 1, 6, 'sixth', -/* f5 BIGINT, */ NULL, -/* f6 BLOB, */ '3333333333333333333333', -/* f7 DATE, */ '2007-07-18', -/* f8 DATETIME, */ "2007-07-18", -/* f9 FLOAT, */ 3.33333333, -/* f10 INT, */ 333333333, -/* f11 LONGBLOB, */ '3333333333333333333', -/* f12 LONGTEXT, */ '3333333333333333333', -/* f13 MEDIUMBLOB, */ '3333333333333333333', -/* f14 MEDIUMINT, */ 33, -/* f15 MEDIUMTEXT, */ 3.3, -/* f16 REAL, */ 3.3, -/* f17 SMALLINT, */ 3, -/* f18 TEXT, */ '33', -/* f19 TIME, */ '2:59:58.999', -/* f20 TIMESTAMP, */ 20000303000000, -/* f21 TINYBLOB, */ '3333', -/* f22 TINYINT, */ 3, -/* f23 TINYTEXT, */ '3', -/* f24 YEAR, */ 3000, -/* f25 BINARY(255), */ 'three_33333', -/* f26 BIT(64), */ b'011', -/* f27 CHAR(255), */ 'three', -/* f28 DECIMAL(30,7), */ 3.333, -/* f29 DOUBLE, */ 3.333333333333333333333333333, -/* f30 ENUM ('a','b','c')*/ 'c', -/* f31 FLOAT, */ 3.0, -/* f32 NUMERIC(17,9), */ 3.3333, -/* f33 SET ('a','b','c'),*/ 'c', -/*f34 VARBINARY(1025),*/ '3333 minus 3', -/*f35 VARCHAR(257),*/ NULL -); -Warnings: -Warning 1264 Out of range value for column 'f5' at row 1 -Warning 1264 Out of range value for column 'f24' at row 1 -Warning 1264 Out of range value for column 'f5' at row 2 -Warning 1264 Out of range value for column 'f24' at row 2 -Warning 1264 Out of range value for column 'f24' at row 3 - -** Sync slave with master ** -** Do selects from tables ** - -select * from t1 order by f3; -f1 f2 f3 f4 -2 2 2 second -3 3 3 next -5 5 5 second -6 6 6 next -8 8 8 second -9 9 9 next -11 11 11 second -12 12 12 next -14 14 14 second -15 15 15 next -17 17 17 second -18 18 18 next -20 20 20 second -21 21 21 next -23 23 23 second -24 24 24 next -26 26 26 second -27 27 27 next -29 29 29 second -30 30 30 next -31 31 31 second -32 32 32 second -33 33 33 second -34 34 34 second -35 35 35 second -36 36 36 second -37 37 37 second -38 38 38 second -39 39 39 second -40 40 40 second -41 41 41 second -42 42 42 second -43 43 43 second -44 44 44 second -45 45 45 second -46 46 46 second -47 47 47 second -48 48 48 second -49 49 49 second -50 50 50 second -select * from t2 order by f1; -f1 f2 f3 f4 -1 1 1 first -2 2 2 second -3 3 3 third -select * from t3 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t4 order by f1; -f1 f2 f3 f4 -1 1 1 first -select * from t31 order by f3; -f1 f2 f3 f4 -1 1 1 first -1 1 2 second -1 1 3 third -1 1 4 fourth -1 1 5 fifth -1 1 6 sixth - -** Do updates master ** - -update t31 set f5=555555555555555 where f3=6; -update t31 set f2=2 where f3=2; -update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null - -** Delete from Master ** - -delete from t1; -delete from t2; -delete from t3; -delete from t4; -delete from t31; -select * from t31; -f1 f2 f3 f4 - -** Check slave status ** - -include/check_slave_is_running.inc - -**************************************** -* columns in master at middle of table * -* Expect: Proper error message * -**************************************** - -** Stop and Reset Slave ** - -STOP SLAVE; -RESET SLAVE; - -** create table slave side ** -CREATE TABLE t10 (a INT PRIMARY KEY, b BLOB, c CHAR(5) -) ENGINE='MyISAM'; - -** Connect to master and create table ** - -CREATE TABLE t10 (a INT KEY, b BLOB, f DOUBLE DEFAULT '233', -c CHAR(5), e INT DEFAULT '1')ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT), -(2,@b1,DEFAULT,'JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254' - -*** Drop t10 *** -DROP TABLE t10; - -********************************************* -* More columns in master at middle of table * -* Expect: Proper error message * -********************************************* - -*** Create t11 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t11 (a INT PRIMARY KEY, b BLOB, c VARCHAR(254) -) ENGINE='MyISAM'; - -*** Create t11 on Master *** -CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT), -(2,@b1,'Testing is cool','JOE',DEFAULT), -(3,@b1,DEFAULT,'QA',DEFAULT); - -******************************************** -*** Expect slave to fail with Error 1535 *** -******************************************** - -include/wait_for_slave_sql_error_and_skip.inc [errno=1535] -Last_SQL_Error = 'Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15' - -*** Drop t11 *** -DROP TABLE t11; - -********************************************* -* More columns in master at middle of table * -* Expect: This one should pass blob-text * -********************************************* - -*** Create t12 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t12 (a INT PRIMARY KEY, b BLOB, c BLOB -) ENGINE='MyISAM'; - -*** Create t12 on Master *** -CREATE TABLE t12 (a INT KEY, b BLOB, f TEXT, -c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t12 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',DEFAULT,DEFAULT), -(3,@b1,'QA',DEFAULT,DEFAULT); - -SELECT a,hex(b),f,c,e FROM t12 ORDER BY a; -a hex(b) f c e -1 62316231623162316231623162316231 Kyle test 1 -2 62316231623162316231623162316231 JOE test 1 -3 62316231623162316231623162316231 QA test 1 - -*** Select on Slave *** -SELECT a,hex(b),c FROM t12 ORDER BY a; -a hex(b) c -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -*** Drop t12 *** -DROP TABLE t12; - -**************************************************** -* - Alter Master adding columns at middle of table * -* Expect: columns added * -**************************************************** - - -*** Create t14 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t14 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t14 on Master *** -CREATE TABLE t14 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t14 ADD COLUMN c2 DECIMAL(8,2) AFTER c1; -ALTER TABLE t14 ADD COLUMN c3 TEXT AFTER c2; - -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t14 () VALUES(1,1.00,'Replication Testing Extra Col',@b1,'Kyle',DEFAULT,DEFAULT), -(2,2.00,'This Test Should work',@b1,'JOE',DEFAULT,DEFAULT), -(3,3.00,'If is does not, I will open a bug',@b1,'QA',DEFAULT,DEFAULT); - -SELECT c1,c2,c3,hex(c4),c5,c6,c7 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 c6 c7 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 2.00 This Test Should work 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP - -*** Select on Slave **** -SELECT c1,c2,c3,hex(c4),c5 FROM t14 ORDER BY c1; -c1 c2 c3 hex(c4) c5 -1 1.00 Replication Testing Extra Col 62316231623162316231623162316231 Kyle -2 2.00 This Test Should work 62316231623162316231623162316231 JOE -3 3.00 If is does not, I will open a bug 62316231623162316231623162316231 QA - -**************************************************** -* - Alter Master Dropping columns from the middle. * -* Expect: columns dropped * -**************************************************** - -*** connect to master and drop columns *** -ALTER TABLE t14 DROP COLUMN c2; -ALTER TABLE t14 DROP COLUMN c7; - -*** Select from Master *** -SELECT c1,c3,hex(c4),c5,c6 FROM t14 ORDER BY c1; -c1 c3 hex(c4) c5 c6 -1 Replication Testing Extra Col 62316231623162316231623162316231 Kyle 1 -2 This Test Should work 62316231623162316231623162316231 JOE 1 -3 If is does not, I will open a bug 62316231623162316231623162316231 QA 1 - -************ -* Bug30415 * -************ -include/wait_for_slave_sql_error.inc [errno=1091] -Last_SQL_Error = 'Error 'Can't DROP 'c7'; check that column/key exists' on query. Default database: 'test'. Query: 'ALTER TABLE t14 DROP COLUMN c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t14 *** -DROP TABLE t14; -DROP TABLE t14; -RESET MASTER; -START SLAVE; - -************************************************* -* - Alter Master adding columns at end of table * -* Expect: Error 1054 * -************************************************* - -*** Create t15 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t15 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t15 on Master *** -CREATE TABLE t15 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7; -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t15 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT,3.00), -(2,@b1,'JOE',DEFAULT,DEFAULT,3.00), -(3,@b1,'QA',DEFAULT,DEFAULT,3.00); -SELECT c1,hex(c4),c5,c6,c7,c2 FROM t15 ORDER BY c1; -c1 hex(c4) c5 c6 c7 c2 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 3.00 -2 62316231623162316231623162316231 JOE 1 CURRENT_TIMESTAMP 3.00 -3 62316231623162316231623162316231 QA 1 CURRENT_TIMESTAMP 3.00 - -******************************************** -*** Expect slave to fail with Error 1054 *** -******************************************** - -include/wait_for_slave_sql_error.inc [errno=1054] -Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t15 *** -DROP TABLE t15; -DROP TABLE t15; -RESET MASTER; -START SLAVE; - -************************************************ -* - Create index on Master column not on slave * -* Expect:Warning * -************************************************ - -*** Create t16 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t16 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t16 on Master *** -CREATE TABLE t16 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Create Index and Data Insert *** -CREATE INDEX part_of_c6 ON t16 (c6); -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t16 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t16 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -***************** -*** BUG 30434 *** -***************** - -include/wait_for_slave_sql_error.inc [errno=1072] -Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Default database: 'test'. Query: 'CREATE INDEX part_of_c6 ON t16 (c6)'' -STOP SLAVE; -RESET SLAVE; - -*** Drop t16 *** -DROP TABLE t16; -DROP TABLE t16; -RESET MASTER; -START SLAVE; - -***************************************************** -* - Delete rows using column on Master not on slave * -* Expect: Rows Deleted * -***************************************************** - -*** Create t17 on slave *** -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t17 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t17 on Master *** -CREATE TABLE t17 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t17 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** Delete from master ** -DELETE FROM t17 WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -DROP TABLE t17; - - -***************************************************** -* - Update row using column on Master not on slave * -* Expect: Rows updated * -***************************************************** - -** Bug30674 ** - -*** Create t18 on slave *** - -STOP SLAVE; -RESET SLAVE; -CREATE TABLE t18 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) -) ENGINE='MyISAM'; - -*** Create t18 on Master *** -CREATE TABLE t18 (c1 INT KEY, c4 BLOB, c5 CHAR(5), -c6 INT DEFAULT '1', -c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP -)ENGINE='MyISAM'; -RESET MASTER; - -*** Start Slave *** -START SLAVE; - -*** Master Data Insert *** -set @b1 = 'b1b1b1b1'; -set @b1 = concat(@b1,@b1); -INSERT INTO t18 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT), -(2,@b1,'JOE',2,DEFAULT), -(3,@b1,'QA',3,DEFAULT); -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP - -** Select * from Slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA - -** update from master ** -UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; -SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; -c1 hex(c4) c5 c6 c7 -1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP -2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP - -** Check slave ** -SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; -c1 hex(c4) c5 -1 62316231623162316231623162316231 Kyle -2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 TEST -DROP TABLE t18; - - ***************************************************** * - Insert UUID column on Master not on slave * * Expect: Rows inserted * diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test b/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test index 11211e51286..201392346be 100644 --- a/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test +++ b/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test @@ -1,17 +1,11 @@ ############################################################# # Purpose: To test having extra columns on the master WL#3915 ############################################################# --- source include/master-slave.inc +-- source include/have_binlog_format_row.inc -- source include/have_innodb.inc +-- source include/master-slave.inc let $engine_type = 'InnoDB'; +--source extra/rpl_tests/rpl_extra_col_master.test -set binlog_format=row; --- source extra/rpl_tests/rpl_extra_col_master.test - -set binlog_format=statement; --- source extra/rpl_tests/rpl_extra_col_master.test - -set binlog_format=mixed; --- source extra/rpl_tests/rpl_extra_col_master.test --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test b/mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test index 2343d430784..4f344cfaca9 100644 --- a/mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test +++ b/mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test @@ -1,16 +1,10 @@ ############################################################# # Purpose: To test having extra columns on the master WL#3915 ############################################################# +-- source include/have_binlog_format_row.inc -- source include/master-slave.inc let $engine_type = 'MyISAM'; +--source extra/rpl_tests/rpl_extra_col_master.test -set binlog_format=row; --- source extra/rpl_tests/rpl_extra_col_master.test - -set binlog_format=statement; --- source extra/rpl_tests/rpl_extra_col_master.test - -set binlog_format=mixed; --- source extra/rpl_tests/rpl_extra_col_master.test --source include/rpl_end.inc -- cgit v1.2.1 From 97e83eae2d359466801ada81c99d617d82a0cd20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Jan 2012 14:22:03 +0200 Subject: Bug#13496818 ASSERTION: REC_PAGE_NO > 4 IN IBUF CONTRACTION Relax a bogus debug assertion. Approved by Jimmy Yang on IM. --- storage/innobase/ibuf/ibuf0ibuf.c | 10 +++++++++- storage/innodb_plugin/ChangeLog | 15 ++++++++++----- storage/innodb_plugin/ibuf/ibuf0ibuf.c | 12 ++++++++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 1406b2de4e9..476d78e79ba 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -2009,7 +2009,15 @@ ibuf_get_merge_page_nos( } else { rec_page_no = ibuf_rec_get_page_no(rec); rec_space_id = ibuf_rec_get_space(rec); - ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO); + /* In the system tablespace, the smallest + possible secondary index leaf page number is + bigger than IBUF_TREE_ROOT_PAGE_NO (4). In + other tablespaces, the clustered index tree is + created at page 3, which makes page 4 the + smallest possible secondary index leaf page + (and that only after DROP INDEX). */ + ut_ad(rec_page_no + > IBUF_TREE_ROOT_PAGE_NO - (rec_space_id != 0)); } #ifdef UNIV_IBUF_DEBUG diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 61de897bed4..97647b679e2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,7 +1,12 @@ +2012-01-16 The InnoDB Team + + * ibuf/ibuf0ibuf.c: + Fix Bug#13496818 ASSERTION: REC_PAGE_NO > 4 IN IBUF CONTRACTION + 2012-01-16 The InnoDB Team * handler/ha_innodb.cc: - Fix Bug#11765438: 58406: ISSUES WITH COPYING PARTITIONED INNODB + Fix Bug#11765438: 58406: ISSUES WITH COPYING PARTITIONED INNODB TABLES FROM LINUX TO WINDOWS 2012-01-04 The InnoDB Team @@ -17,8 +22,8 @@ 2011-12-13 The InnoDB Team * handler/ha_innodb.cc, innodb.test, innodb.result: - Fix Bug#13117023: InnoDB was incrementing the handler_read_key, - also the SSV::ha_read_key_count, at the wrong place. + Fix Bug#13117023: InnoDB was incrementing the handler_read_key, + also the SSV::ha_read_key_count, at the wrong place. 2011-12-10 The InnoDB Team @@ -279,7 +284,7 @@ 2011-01-06 The InnoDB Team * dict/dict0dict.c, handler/ha_innodb.cc, handler/i_s.cc, - include/univ.i: + include/univ.i: Fix Bug#58643 InnoDB: too long table name 2011-01-06 The InnoDB Team @@ -545,7 +550,7 @@ * handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c: Fix Bug#53592: crash replacing duplicates into table after fast - alter table added unique key + alter table added unique key 2010-05-24 The InnoDB Team diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c index a22de3b0e70..9a243d83bd5 100644 --- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c +++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2090,7 +2090,15 @@ ibuf_get_merge_page_nos( } else { rec_page_no = ibuf_rec_get_page_no(rec); rec_space_id = ibuf_rec_get_space(rec); - ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO); + /* In the system tablespace, the smallest + possible secondary index leaf page number is + bigger than IBUF_TREE_ROOT_PAGE_NO (4). In + other tablespaces, the clustered index tree is + created at page 3, which makes page 4 the + smallest possible secondary index leaf page + (and that only after DROP INDEX). */ + ut_ad(rec_page_no + > IBUF_TREE_ROOT_PAGE_NO - (rec_space_id != 0)); } #ifdef UNIV_IBUF_DEBUG -- cgit v1.2.1 From 2bffb8b1de54e74fee8d0cc72d58b08129d6c442 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Tue, 17 Jan 2012 09:10:58 +0530 Subject: Bug #11760384 52792: MYSQLDUMP IN XML MODE DOES NOT DUMP ROUTINES Minor post-fix to avoid build failure when built with Werror. --- client/mysqldump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 27a593ff592..eff74e93152 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1877,7 +1877,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, { uint i; my_bool body_found= 0; - char *create_stmt_ptr; + char *create_stmt_ptr= NULL; ulong create_stmt_len= 0; MYSQL_FIELD *field; ulong *lengths= mysql_fetch_lengths(tableRes); -- cgit v1.2.1 From 316a60af6db522a71879960f4f5fbdd215a8d262 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Thu, 19 Jan 2012 17:05:47 +0100 Subject: Compile fix needed for AIX, to work around the lack of a bzero() prototype. include/m_string.h: AIX does have bzero() in its system libraries, and the configure phase detects it, including the prototype (sets both HAVE_BZERO and HAVE_DECL_BZERO), but the declaration is missing when the source is compiled. Several attempts all failed. This patch takes the brute force approach to always map "bzero()" to "memset()" on AIX, like is done on platforms where "bzero()" is not found at all. --- include/m_string.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/m_string.h b/include/m_string.h index e1cf7651519..dc916792f60 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -60,7 +60,9 @@ # define bfill(A,B,C) memset((A),(C),(B)) #endif -#if !defined(bzero) && (!defined(HAVE_BZERO) || !defined(HAVE_DECL_BZERO)) +#if !defined(bzero) && (!defined(HAVE_BZERO) || !HAVE_DECL_BZERO || defined(_AIX)) +/* See autoconf doku: "HAVE_DECL_symbol" will be defined after configure, to 0 or 1 */ +/* AIX has bzero() as a function, but the declaration prototype is strangely hidden */ # define bzero(A,B) memset((A),0,(B)) #endif -- cgit v1.2.1 From e449cf48afc34705b601113fd73bce84338c2e37 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 23 Jan 2012 13:07:10 +0400 Subject: Bug#11752408 - 43593: DUMP/BACKUP/RESTORE/UPGRADE TOOLS FAILS BECAUSE OF UTF8_GENERAL_CI Introducing new collations: utf8_general_mysql500_ci and ucs2_general_mysql500_ci, to reproduce behaviour of utf8_general_ci and ucs2_general_ci from mysql-5.1.23 (and earlier). The collations are added to simplify upgrade from mysql-5.1.23 and earlier. Note: The patch does not make new server start over old data automatically. Some manual upgrade procedures are assumed. Paul: please get in touch with me to discuss upgrade procedures when documenting this bug. modified: include/m_ctype.h mysql-test/r/ctype_utf8.result mysql-test/t/ctype_utf8.test mysys/charset-def.c strings/ctype-ucs2.c strings/ctype-utf8.c --- include/m_ctype.h | 4 + mysql-test/r/ctype_utf8.result | 24 +++++ mysql-test/t/ctype_utf8.test | 8 ++ mysys/charset-def.c | 2 + strings/ctype-ucs2.c | 34 +++++++ strings/ctype-utf8.c | 210 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 282 insertions(+) diff --git a/include/m_ctype.h b/include/m_ctype.h index 3b836dfbaf3..f8d654f387e 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -50,6 +50,8 @@ typedef struct unicase_info_st extern MY_UNICASE_INFO *my_unicase_default[256]; extern MY_UNICASE_INFO *my_unicase_turkish[256]; +extern MY_UNICASE_INFO *my_unicase_mysql500[256]; + typedef struct uni_ctype_st { @@ -311,11 +313,13 @@ extern CHARSET_INFO my_charset_tis620_bin; extern CHARSET_INFO my_charset_ucs2_general_ci; extern CHARSET_INFO my_charset_ucs2_bin; extern CHARSET_INFO my_charset_ucs2_unicode_ci; +extern CHARSET_INFO my_charset_ucs2_general_mysql500_ci; extern CHARSET_INFO my_charset_ujis_japanese_ci; extern CHARSET_INFO my_charset_ujis_bin; extern CHARSET_INFO my_charset_utf8_general_ci; extern CHARSET_INFO my_charset_utf8_unicode_ci; extern CHARSET_INFO my_charset_utf8_bin; +extern CHARSET_INFO my_charset_utf8_general_mysql500_ci; extern CHARSET_INFO my_charset_cp1250_czech_ci; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index b491ce504bf..c540c750f9d 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1928,4 +1928,28 @@ D120 SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)) D120D18E +# +# Bug#11752408 - 43593: DUMP/BACKUP/RESTORE/UPGRADE TOOLS FAILS BECAUSE OF UTF8_GENERAL_CI +# +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci); +INSERT INTO t1 VALUES ('a'),('r'),('s'),(_latin1 0xDF),(_latin1 0xF7),('t'),('z'); +SELECT * FROM t1 ORDER BY a; +a +a +r +s +t +z +ß +÷ +SELECT a, COUNT(*) FROM t1 GROUP BY a; +a COUNT(*) +a 1 +r 1 +s 1 +t 1 +z 1 +ß 1 +÷ 1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 8e9f09d1e56..545afbbcf6c 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1484,5 +1484,13 @@ SELECT HEX(LPAD(_utf8 0xD18F, 3, 0x20)); SELECT HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)); SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); +--echo # +--echo # Bug#11752408 - 43593: DUMP/BACKUP/RESTORE/UPGRADE TOOLS FAILS BECAUSE OF UTF8_GENERAL_CI +--echo # +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci); +INSERT INTO t1 VALUES ('a'),('r'),('s'),(_latin1 0xDF),(_latin1 0xF7),('t'),('z'); +SELECT * FROM t1 ORDER BY a; +SELECT a, COUNT(*) FROM t1 GROUP BY a; +DROP TABLE t1; --echo End of 5.1 tests diff --git a/mysys/charset-def.c b/mysys/charset-def.c index 63bbceef29b..8adef3eb72e 100644 --- a/mysys/charset-def.c +++ b/mysys/charset-def.c @@ -132,6 +132,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) #ifdef HAVE_CHARSET_ucs2 add_compiled_collation(&my_charset_ucs2_general_ci); add_compiled_collation(&my_charset_ucs2_bin); + add_compiled_collation(&my_charset_ucs2_general_mysql500_ci); #ifdef HAVE_UCA_COLLATIONS add_compiled_collation(&my_charset_ucs2_unicode_ci); add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci); @@ -163,6 +164,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) #ifdef HAVE_CHARSET_utf8 add_compiled_collation(&my_charset_utf8_general_ci); add_compiled_collation(&my_charset_utf8_bin); + add_compiled_collation(&my_charset_utf8_general_mysql500_ci); #ifdef HAVE_UTF8_GENERAL_CS add_compiled_collation(&my_charset_utf8_general_cs); #endif diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 4fceb1a8c71..4b6fc7ccc10 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1732,6 +1732,40 @@ CHARSET_INFO my_charset_ucs2_general_ci= &my_collation_ucs2_general_ci_handler }; + +CHARSET_INFO my_charset_ucs2_general_mysql500_ci= +{ + 159, 0, 0, /* number */ + MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */ + "ucs2", /* cs name */ + "ucs2_general_mysql500_ci", /* name */ + "", /* comment */ + NULL, /* tailoring */ + ctype_ucs2, /* ctype */ + to_lower_ucs2, /* to_lower */ + to_upper_ucs2, /* to_upper */ + to_upper_ucs2, /* sort_order */ + NULL, /* contractions */ + NULL, /* sort_order_big */ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + my_unicase_mysql500, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 2, /* mbminlen */ + 2, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFFFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + &my_charset_ucs2_handler, + &my_collation_ucs2_general_ci_handler +}; + + CHARSET_INFO my_charset_ucs2_bin= { 90,0,0, /* number */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 264b79dca63..1af08ded62b 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -177,6 +177,141 @@ static MY_UNICASE_INFO plane00[]={ }; +/* + Almost similar to plane00, but maps sorting order + for U+00DF to 0x00DF instead of 0x0053. +*/ +static MY_UNICASE_INFO plane00_mysql500[]={ + {0x0000,0x0000,0x0000}, {0x0001,0x0001,0x0001}, + {0x0002,0x0002,0x0002}, {0x0003,0x0003,0x0003}, + {0x0004,0x0004,0x0004}, {0x0005,0x0005,0x0005}, + {0x0006,0x0006,0x0006}, {0x0007,0x0007,0x0007}, + {0x0008,0x0008,0x0008}, {0x0009,0x0009,0x0009}, + {0x000A,0x000A,0x000A}, {0x000B,0x000B,0x000B}, + {0x000C,0x000C,0x000C}, {0x000D,0x000D,0x000D}, + {0x000E,0x000E,0x000E}, {0x000F,0x000F,0x000F}, + {0x0010,0x0010,0x0010}, {0x0011,0x0011,0x0011}, + {0x0012,0x0012,0x0012}, {0x0013,0x0013,0x0013}, + {0x0014,0x0014,0x0014}, {0x0015,0x0015,0x0015}, + {0x0016,0x0016,0x0016}, {0x0017,0x0017,0x0017}, + {0x0018,0x0018,0x0018}, {0x0019,0x0019,0x0019}, + {0x001A,0x001A,0x001A}, {0x001B,0x001B,0x001B}, + {0x001C,0x001C,0x001C}, {0x001D,0x001D,0x001D}, + {0x001E,0x001E,0x001E}, {0x001F,0x001F,0x001F}, + {0x0020,0x0020,0x0020}, {0x0021,0x0021,0x0021}, + {0x0022,0x0022,0x0022}, {0x0023,0x0023,0x0023}, + {0x0024,0x0024,0x0024}, {0x0025,0x0025,0x0025}, + {0x0026,0x0026,0x0026}, {0x0027,0x0027,0x0027}, + {0x0028,0x0028,0x0028}, {0x0029,0x0029,0x0029}, + {0x002A,0x002A,0x002A}, {0x002B,0x002B,0x002B}, + {0x002C,0x002C,0x002C}, {0x002D,0x002D,0x002D}, + {0x002E,0x002E,0x002E}, {0x002F,0x002F,0x002F}, + {0x0030,0x0030,0x0030}, {0x0031,0x0031,0x0031}, + {0x0032,0x0032,0x0032}, {0x0033,0x0033,0x0033}, + {0x0034,0x0034,0x0034}, {0x0035,0x0035,0x0035}, + {0x0036,0x0036,0x0036}, {0x0037,0x0037,0x0037}, + {0x0038,0x0038,0x0038}, {0x0039,0x0039,0x0039}, + {0x003A,0x003A,0x003A}, {0x003B,0x003B,0x003B}, + {0x003C,0x003C,0x003C}, {0x003D,0x003D,0x003D}, + {0x003E,0x003E,0x003E}, {0x003F,0x003F,0x003F}, + {0x0040,0x0040,0x0040}, {0x0041,0x0061,0x0041}, + {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, + {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, + {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, + {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049}, + {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, + {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, + {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, + {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, + {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, + {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, + {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, + {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, + {0x005A,0x007A,0x005A}, {0x005B,0x005B,0x005B}, + {0x005C,0x005C,0x005C}, {0x005D,0x005D,0x005D}, + {0x005E,0x005E,0x005E}, {0x005F,0x005F,0x005F}, + {0x0060,0x0060,0x0060}, {0x0041,0x0061,0x0041}, + {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, + {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, + {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, + {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049}, + {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, + {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, + {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, + {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, + {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, + {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, + {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, + {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, + {0x005A,0x007A,0x005A}, {0x007B,0x007B,0x007B}, + {0x007C,0x007C,0x007C}, {0x007D,0x007D,0x007D}, + {0x007E,0x007E,0x007E}, {0x007F,0x007F,0x007F}, + {0x0080,0x0080,0x0080}, {0x0081,0x0081,0x0081}, + {0x0082,0x0082,0x0082}, {0x0083,0x0083,0x0083}, + {0x0084,0x0084,0x0084}, {0x0085,0x0085,0x0085}, + {0x0086,0x0086,0x0086}, {0x0087,0x0087,0x0087}, + {0x0088,0x0088,0x0088}, {0x0089,0x0089,0x0089}, + {0x008A,0x008A,0x008A}, {0x008B,0x008B,0x008B}, + {0x008C,0x008C,0x008C}, {0x008D,0x008D,0x008D}, + {0x008E,0x008E,0x008E}, {0x008F,0x008F,0x008F}, + {0x0090,0x0090,0x0090}, {0x0091,0x0091,0x0091}, + {0x0092,0x0092,0x0092}, {0x0093,0x0093,0x0093}, + {0x0094,0x0094,0x0094}, {0x0095,0x0095,0x0095}, + {0x0096,0x0096,0x0096}, {0x0097,0x0097,0x0097}, + {0x0098,0x0098,0x0098}, {0x0099,0x0099,0x0099}, + {0x009A,0x009A,0x009A}, {0x009B,0x009B,0x009B}, + {0x009C,0x009C,0x009C}, {0x009D,0x009D,0x009D}, + {0x009E,0x009E,0x009E}, {0x009F,0x009F,0x009F}, + {0x00A0,0x00A0,0x00A0}, {0x00A1,0x00A1,0x00A1}, + {0x00A2,0x00A2,0x00A2}, {0x00A3,0x00A3,0x00A3}, + {0x00A4,0x00A4,0x00A4}, {0x00A5,0x00A5,0x00A5}, + {0x00A6,0x00A6,0x00A6}, {0x00A7,0x00A7,0x00A7}, + {0x00A8,0x00A8,0x00A8}, {0x00A9,0x00A9,0x00A9}, + {0x00AA,0x00AA,0x00AA}, {0x00AB,0x00AB,0x00AB}, + {0x00AC,0x00AC,0x00AC}, {0x00AD,0x00AD,0x00AD}, + {0x00AE,0x00AE,0x00AE}, {0x00AF,0x00AF,0x00AF}, + {0x00B0,0x00B0,0x00B0}, {0x00B1,0x00B1,0x00B1}, + {0x00B2,0x00B2,0x00B2}, {0x00B3,0x00B3,0x00B3}, + {0x00B4,0x00B4,0x00B4}, {0x039C,0x00B5,0x039C}, + {0x00B6,0x00B6,0x00B6}, {0x00B7,0x00B7,0x00B7}, + {0x00B8,0x00B8,0x00B8}, {0x00B9,0x00B9,0x00B9}, + {0x00BA,0x00BA,0x00BA}, {0x00BB,0x00BB,0x00BB}, + {0x00BC,0x00BC,0x00BC}, {0x00BD,0x00BD,0x00BD}, + {0x00BE,0x00BE,0x00BE}, {0x00BF,0x00BF,0x00BF}, + {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, + {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, + {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, + {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, + {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, + {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, + {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, + {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, + {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, + {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, + {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, + {0x00D6,0x00F6,0x004F}, {0x00D7,0x00D7,0x00D7}, + {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, + {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, + {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, + {0x00DE,0x00FE,0x00DE}, {0x00DF,0x00DF,0x00DF}, + {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, + {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, + {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, + {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, + {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, + {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, + {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, + {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, + {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, + {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, + {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, + {0x00D6,0x00F6,0x004F}, {0x00F7,0x00F7,0x00F7}, + {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, + {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, + {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, + {0x00DE,0x00FE,0x00DE}, {0x0178,0x00FF,0x0059} +}; + static MY_UNICASE_INFO plane01[]={ {0x0100,0x0101,0x0041}, {0x0100,0x0101,0x0041}, @@ -1525,6 +1660,47 @@ MY_UNICASE_INFO *my_unicase_default[256]={ }; +/* + Reproduce old utf8_general_ci behaviour before we fixed Bug#27877. +*/ +MY_UNICASE_INFO *my_unicase_mysql500[256]={ + plane00_mysql500, + plane01, plane02, plane03, plane04, plane05, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, plane1E, plane1F, + NULL, plane21, NULL, NULL, plane24, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, planeFF + +}; + + /* Turkish lower/upper mapping: 1. LOWER(0x0049 LATIN CAPITAL LETTER I) -> @@ -2720,6 +2896,39 @@ CHARSET_INFO my_charset_utf8_general_ci= }; +CHARSET_INFO my_charset_utf8_general_mysql500_ci= +{ + 223,0,0, /* number */ + MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */ + "utf8", /* cs name */ + "utf8_general_mysql500_ci", /* name */ + "", /* comment */ + NULL, /* tailoring */ + ctype_utf8, /* ctype */ + to_lower_utf8, /* to_lower */ + to_upper_utf8, /* to_upper */ + to_upper_utf8, /* sort_order */ + NULL, /* contractions */ + NULL, /* sort_order_big */ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + my_unicase_mysql500, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 1, /* mbminlen */ + 3, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFFFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + &my_charset_utf8_handler, + &my_collation_ci_handler +}; + + CHARSET_INFO my_charset_utf8_bin= { 83,0,0, /* number */ @@ -4231,6 +4440,7 @@ CHARSET_INFO my_charset_filename= &my_collation_filename_handler }; + #ifdef MY_TEST_UTF8 #include -- cgit v1.2.1 From f8e924b467d099b5d99248c160a2aba59a6ea3ce Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 24 Jan 2012 13:00:13 +0400 Subject: BUG#13458237 - INCONSISTENT HANDLING OF INVALIDE DATES WITH ZERO DAY. SIMILAR TO '2009-10-00' - Reverting the patch for Bug # 12584302 The patch will be reverted in 5.1 and 5.5. The patch will not be reverted in 5.6, the change will be properly documented in 5.6. - Backporting DBUG_ASSERT not to crash on '0000-01-00' (already fixed in mysql-trunk (5.6)) --- mysql-test/r/func_time.result | 184 +++++++++++++++++++++++++++++++++++++++++- mysql-test/t/func_time.test | 61 ++++++++++++++ sql-common/my_time.c | 2 +- sql/item_timefunc.cc | 2 +- 4 files changed, 246 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 68c1e667440..ceb9dd4f7ea 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1430,6 +1430,188 @@ NULL # Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0, # DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); +# +# BUG#13458237 INCONSISTENT HANDLING OF INVALIDE DATES WITH ZERO DAY +# SIMILAR TO '2009-10-00' +# +SELECT +DATE('20091000'), +STR_TO_DATE('200910','%Y%m'), +LAST_DAY('2009-10-00'), +LAST_DAY(DATE('2009-10-00')), +LAST_DAY(DATE'2009-10-00'), +LAST_DAY(STR_TO_DATE('200910','%Y%m')), +WEEK('2009-10-00'), +WEEK(DATE('2009-10-00')), +WEEK(DATE'2009-10-00'), +WEEK(STR_TO_DATE('200910','%Y%m')), +WEEKOFYEAR('2009-10-00'), +WEEKOFYEAR(DATE('2009-10-00')), +WEEKOFYEAR(DATE'2009-10-00'), +WEEKOFYEAR(STR_TO_DATE('200910','%Y%m')), +DAYOFYEAR('2009-10-00'), +DAYOFYEAR(DATE('2009-10-00')), +DAYOFYEAR(DATE'2009-10-00'), +DAYOFYEAR(STR_TO_DATE('200910','%Y%m')), +WEEKDAY('2009-10-00'), +WEEKDAY(DATE('2009-10-00')), +WEEKDAY(DATE'2009-10-00'), +WEEKDAY(STR_TO_DATE('200910','%Y%m')), +TO_DAYs('2009-10-00'), +TO_DAYs(DATE('2009-10-00')), +TO_DAYs(DATE'2009-10-00'), +TO_DAYs(STR_TO_DATE('200910','%Y%m')); +DATE('20091000') 2009-10-00 +STR_TO_DATE('200910','%Y%m') 2009-10-00 +LAST_DAY('2009-10-00') NULL +LAST_DAY(DATE('2009-10-00')) 2009-10-31 +LAST_DAY(DATE'2009-10-00') NULL +LAST_DAY(STR_TO_DATE('200910','%Y%m')) 2009-10-31 +WEEK('2009-10-00') NULL +WEEK(DATE('2009-10-00')) 39 +WEEK(DATE'2009-10-00') NULL +WEEK(STR_TO_DATE('200910','%Y%m')) NULL +WEEKOFYEAR('2009-10-00') NULL +WEEKOFYEAR(DATE('2009-10-00')) 40 +WEEKOFYEAR(DATE'2009-10-00') NULL +WEEKOFYEAR(STR_TO_DATE('200910','%Y%m')) NULL +DAYOFYEAR('2009-10-00') NULL +DAYOFYEAR(DATE('2009-10-00')) 273 +DAYOFYEAR(DATE'2009-10-00') NULL +DAYOFYEAR(STR_TO_DATE('200910','%Y%m')) NULL +WEEKDAY('2009-10-00') NULL +WEEKDAY(DATE('2009-10-00')) 2 +WEEKDAY(DATE'2009-10-00') NULL +WEEKDAY(STR_TO_DATE('200910','%Y%m')) NULL +TO_DAYs('2009-10-00') NULL +TO_DAYs(DATE('2009-10-00')) 734045 +TO_DAYs(DATE'2009-10-00') NULL +TO_DAYs(STR_TO_DATE('200910','%Y%m')) NULL +Warnings: +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +SELECT +DATE('00000100'), +STR_TO_DATE('000001','%Y%m'), +LAST_DAY('0000-01-00'), +LAST_DAY(DATE('0000-01-00')), +LAST_DAY(DATE'0000-01-00'), +LAST_DAY(STR_TO_DATE('000001','%Y%m')), +WEEK('0000-01-00'), +WEEK(DATE('0000-01-00')), +WEEK(DATE'0000-01-00'), +WEEK(STR_TO_DATE('000001','%Y%m')), +WEEKOFYEAR('0000-01-00'), +WEEKOFYEAR(DATE('0000-01-00')), +WEEKOFYEAR(DATE'0000-01-00'), +WEEKOFYEAR(STR_TO_DATE('000001','%Y%m')), +DAYOFYEAR('0000-01-00'), +DAYOFYEAR(DATE('0000-01-00')), +DAYOFYEAR(DATE'0000-01-00'), +DAYOFYEAR(STR_TO_DATE('000001','%Y%m')), +WEEKDAY('0000-01-00'), +WEEKDAY(DATE('0000-01-00')), +WEEKDAY(DATE'0000-01-00'), +WEEKDAY(STR_TO_DATE('000001','%Y%m')), +TO_DAYs('0000-01-00'), +TO_DAYs(DATE('0000-01-00')), +TO_DAYs(DATE'0000-01-00'), +TO_DAYs(STR_TO_DATE('000001','%Y%m')); +DATE('00000100') 0000-01-00 +STR_TO_DATE('000001','%Y%m') 0000-01-00 +LAST_DAY('0000-01-00') NULL +LAST_DAY(DATE('0000-01-00')) 0000-01-31 +LAST_DAY(DATE'0000-01-00') NULL +LAST_DAY(STR_TO_DATE('000001','%Y%m')) 0000-01-31 +WEEK('0000-01-00') NULL +WEEK(DATE('0000-01-00')) 52 +WEEK(DATE'0000-01-00') NULL +WEEK(STR_TO_DATE('000001','%Y%m')) NULL +WEEKOFYEAR('0000-01-00') NULL +WEEKOFYEAR(DATE('0000-01-00')) 52 +WEEKOFYEAR(DATE'0000-01-00') NULL +WEEKOFYEAR(STR_TO_DATE('000001','%Y%m')) NULL +DAYOFYEAR('0000-01-00') NULL +DAYOFYEAR(DATE('0000-01-00')) 0 +DAYOFYEAR(DATE'0000-01-00') NULL +DAYOFYEAR(STR_TO_DATE('000001','%Y%m')) NULL +WEEKDAY('0000-01-00') NULL +WEEKDAY(DATE('0000-01-00')) 5 +WEEKDAY(DATE'0000-01-00') NULL +WEEKDAY(STR_TO_DATE('000001','%Y%m')) NULL +TO_DAYs('0000-01-00') NULL +TO_DAYs(DATE('0000-01-00')) 0 +TO_DAYs(DATE'0000-01-00') NULL +TO_DAYs(STR_TO_DATE('000001','%Y%m')) NULL Warnings: -Warning 1292 Incorrect datetime value: '0' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' End of 5.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 2dcac0d5796..3ea79a7fc94 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -934,4 +934,65 @@ SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); +--echo # +--echo # BUG#13458237 INCONSISTENT HANDLING OF INVALIDE DATES WITH ZERO DAY +--echo # SIMILAR TO '2009-10-00' +--echo # + +query_vertical SELECT + DATE('20091000'), + STR_TO_DATE('200910','%Y%m'), + LAST_DAY('2009-10-00'), + LAST_DAY(DATE('2009-10-00')), + LAST_DAY(DATE'2009-10-00'), + LAST_DAY(STR_TO_DATE('200910','%Y%m')), + WEEK('2009-10-00'), + WEEK(DATE('2009-10-00')), + WEEK(DATE'2009-10-00'), + WEEK(STR_TO_DATE('200910','%Y%m')), + WEEKOFYEAR('2009-10-00'), + WEEKOFYEAR(DATE('2009-10-00')), + WEEKOFYEAR(DATE'2009-10-00'), + WEEKOFYEAR(STR_TO_DATE('200910','%Y%m')), + DAYOFYEAR('2009-10-00'), + DAYOFYEAR(DATE('2009-10-00')), + DAYOFYEAR(DATE'2009-10-00'), + DAYOFYEAR(STR_TO_DATE('200910','%Y%m')), + WEEKDAY('2009-10-00'), + WEEKDAY(DATE('2009-10-00')), + WEEKDAY(DATE'2009-10-00'), + WEEKDAY(STR_TO_DATE('200910','%Y%m')), + TO_DAYs('2009-10-00'), + TO_DAYs(DATE('2009-10-00')), + TO_DAYs(DATE'2009-10-00'), + TO_DAYs(STR_TO_DATE('200910','%Y%m')); + +query_vertical SELECT + DATE('00000100'), + STR_TO_DATE('000001','%Y%m'), + LAST_DAY('0000-01-00'), + LAST_DAY(DATE('0000-01-00')), + LAST_DAY(DATE'0000-01-00'), + LAST_DAY(STR_TO_DATE('000001','%Y%m')), + WEEK('0000-01-00'), + WEEK(DATE('0000-01-00')), + WEEK(DATE'0000-01-00'), + WEEK(STR_TO_DATE('000001','%Y%m')), + WEEKOFYEAR('0000-01-00'), + WEEKOFYEAR(DATE('0000-01-00')), + WEEKOFYEAR(DATE'0000-01-00'), + WEEKOFYEAR(STR_TO_DATE('000001','%Y%m')), + DAYOFYEAR('0000-01-00'), + DAYOFYEAR(DATE('0000-01-00')), + DAYOFYEAR(DATE'0000-01-00'), + DAYOFYEAR(STR_TO_DATE('000001','%Y%m')), + WEEKDAY('0000-01-00'), + WEEKDAY(DATE('0000-01-00')), + WEEKDAY(DATE'0000-01-00'), + WEEKDAY(STR_TO_DATE('000001','%Y%m')), + TO_DAYs('0000-01-00'), + TO_DAYs(DATE('0000-01-00')), + TO_DAYs(DATE'0000-01-00'), + TO_DAYs(STR_TO_DATE('000001','%Y%m')); + --echo End of 5.1 tests diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 0c90f14ae79..13ba691a090 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -785,7 +785,7 @@ long calc_daynr(uint year,uint month,uint day) temp=(int) ((y/100+1)*3)/4; DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", y+(month <= 2),month,day,delsum+y/4-temp)); - DBUG_ASSERT(delsum+(int) y/4-temp > 0); + DBUG_ASSERT(delsum+(int) y/4-temp >= 0); DBUG_RETURN(delsum+(int) y/4-temp); } /* calc_daynr */ diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 31474f1d6ca..83b0b7cdebc 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2646,7 +2646,7 @@ String *Item_time_typecast::val_str(String *str) bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date) { - bool res= get_arg0_date(ltime, fuzzy_date); + bool res= get_arg0_date(ltime, TIME_FUZZY_DATE); ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; ltime->time_type= MYSQL_TIMESTAMP_DATE; return res; -- cgit v1.2.1 From a5d2554db0dbde65dcd3097d9094ac00235d32b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 25 Jan 2012 10:15:27 +0200 Subject: btr_cur_search_to_nth_level(): Add a debug assertion and some Valgrind instrumentation. --- storage/innobase/btr/btr0cur.c | 5 +++++ storage/innodb_plugin/btr/btr0cur.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 3c12e28feb6..c09d6408fa0 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -321,7 +321,12 @@ btr_cur_search_to_nth_level( ut_ad(dict_index_check_search_tuple(index, tuple)); ut_ad(!(index->type & DICT_IBUF) || ibuf_inside()); ut_ad(dtuple_check_typed(tuple)); + ut_ad(index->page != FIL_NULL); + UNIV_MEM_INVALID(&cursor->up_match, sizeof cursor->up_match); + UNIV_MEM_INVALID(&cursor->up_bytes, sizeof cursor->up_bytes); + UNIV_MEM_INVALID(&cursor->low_match, sizeof cursor->low_match); + UNIV_MEM_INVALID(&cursor->low_bytes, sizeof cursor->low_bytes); #ifdef UNIV_DEBUG cursor->up_match = ULINT_UNDEFINED; cursor->low_match = ULINT_UNDEFINED; diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 9f4be053a43..46e850bb218 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -393,7 +393,12 @@ btr_cur_search_to_nth_level( ut_ad(dict_index_check_search_tuple(index, tuple)); ut_ad(!dict_index_is_ibuf(index) || ibuf_inside()); ut_ad(dtuple_check_typed(tuple)); + ut_ad(index->page != FIL_NULL); + UNIV_MEM_INVALID(&cursor->up_match, sizeof cursor->up_match); + UNIV_MEM_INVALID(&cursor->up_bytes, sizeof cursor->up_bytes); + UNIV_MEM_INVALID(&cursor->low_match, sizeof cursor->low_match); + UNIV_MEM_INVALID(&cursor->low_bytes, sizeof cursor->low_bytes); #ifdef UNIV_DEBUG cursor->up_match = ULINT_UNDEFINED; cursor->low_match = ULINT_UNDEFINED; -- cgit v1.2.1 From 9e0b69c0b7122d2973aa61a4efd9e8d80ad4a970 Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Thu, 26 Jan 2012 10:25:23 +0100 Subject: Fixes for: BUG#13519696 - 62940: SELECT RESULTS VARY WITH VERSION AND WITH/WITHOUT INDEX RANGE SCAN BUG#13453382 - REGRESSION SINCE 5.1.39, RANGE OPTIMIZER WRONG RESULTS WITH DECIMAL CONVERSION BUG#13463488 - 63437: CHAR & BETWEEN WITH INDEX RETURNS WRONG RESULT AFTER MYSQL 5.1. Those are all cases where the range optimizer got it wrong with > and >=. mysql-test/r/range.result: Without the code fix for DECIMAL, "select count(val) from t2 where val > 0.1155" (which uses a range scan) returned 127 instead of 128); Moreover, both select * from t1 force index (primary) where a=1 and c>= 2.9; and select * from t1 force index (primary) where a=1 and c> 2.9; would miss "1 1 3". Without the code fix for strings, both SELECT * FROM t1 WHERE F1 >= 'A '; and SELECT * FROM t1 WHERE F1 BETWEEN 'A ' AND 'AAAAA'; would miss "A A A". sql/item.cc: Preamble to the explanations below: opt_range.cc:get_mm_leaf() does this (this is not changed by the patch): changes column > value to column OP V where: * V is what is in "column" after we stored "value" in it (such store operation may have done rounding...) * OP is > or >=, depending on what's correct. For example, if c is an INT column, c > 2.9 is changed to c OP 3 where OP is >= ('>' would not be correct). The bugs below are cases where we chose OP wrongly. Note that such transformations are visible in the optimizer trace. 1) Fix for STRING. In the scenario with CHAR(5) in range.test, this happens, in get_mm_tree(), for the condition F1>='A ': * value->save_in_field_no_warnings(field, 1) wants to store the right argument (named 'item') into the CHAR(5) field; this stores 'A ' (the item's value) padded with spaces (which changes nothing: still 'A ') * we come to case Item_func::GE_FUNC: /* Don't use open ranges for partial key_segments */ if ((!(key_part->flag & HA_PART_KEY_SEG)) && (stored_field_cmp_to_item(param->thd, field, value) < 0)) tree->min_flag= NEAR_MIN; tree->max_flag=NO_MAX_RANGE; What this wants to do is: if the field's value is strictly smaller than the item's, then ">=" can be changed to ">" (this is an optimization, it can help pruning one useless partition). * stored_field_cmp_to_item() is called; it compares the field's and item's values: the item's value (Item_string::val_str()) is 'A ') and the field's value (Field_string::val_str()) is 'A' (yes val_str() removes end spaces unless sql_mode='PAD_CHAR_TO_FULL_LENGTH'); and the comparison is done with stringcmp() which considers end spaces as relevant; as end spaces differ, function returns a negative number, and ">='A '" becomes ">'A'" (i.e. the NEAR_MIN flag is turned on). During execution the index range scan code will search for "A", find a match, but exclude it (because of ">"), wrongly. The badness is the string comparison done by stored_field_cmp_to_item(): we use the reply of this function to determine where the index search should start, so it should do comparison like index search does comparisons; index search comparisons are ha_key_cmp() which uses a collation-aware comparison (in our case, my_strnncollsp_simple(), which ignores end spaces); so stored_field_cmp_to_item() needs to do the same. When this is fixed, condition becomes ">='A '". 2) Fix for DECIMAL: just like in other comparisons in stored_field_cmp_to_item(), we must first pass the field and then the item; otherwise expectations on what <0 and >0 mean (inferiority, superiority) get violated. In the test in range.test about c>2.9: c is an INT column, so 2.9 gets stored as 3, then stored_field_cmp_to_item() compares 3 and 2.9; because of the wrong order of arguments passed to my_decimal_cmp(), range optimizer thinks that 3 is < 2.9 and thus changes "c> 2.9" to "c> 3". After fixing the order, it changes to the correct "c>= 3". In the test in range.inc for val > 0.1155, it was changed to val > 0.116, now it is changed to val >= 0.116. --- mysql-test/r/range.result | 117 ++++++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/range.test | 76 ++++++++++++++++++++++++++++++ sql/item.cc | 4 +- 3 files changed, 195 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index ae63edf87b9..5a964baf2c2 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1767,4 +1767,121 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 DROP TABLE t1; +# +# BUG#13519696 - 62940: SELECT RESULTS VARY WITH VERSION AND +# WITH/WITHOUT INDEX RANGE SCAN +# +create table t1 (id int unsigned not null auto_increment primary key); +insert into t1 values (null); +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +create table t2 ( +id int unsigned not null auto_increment, +val decimal(5,3) not null, +primary key (id,val), +unique key (val,id), +unique key (id)); +insert into t2 select null,id*0.0009 from t1; +select count(val) from t2 ignore index (val) where val > 0.1155; +count(val) +128 +select count(val) from t2 force index (val) where val > 0.1155; +count(val) +128 +drop table t2, t1; +# +# BUG#13453382 - REGRESSION SINCE 5.1.39, RANGE OPTIMIZER WRONG +# RESULTS WITH DECIMAL CONVERSION +# +create table t1 (a int,b int,c int,primary key (a,c)); +insert into t1 values (1,1,2),(1,1,3),(1,1,4); +select convert(3, signed integer) > 2.9; +convert(3, signed integer) > 2.9 +1 +select * from t1 force index (primary) where a=1 and c>= 2.9; +a b c +1 1 3 +1 1 4 +select * from t1 ignore index (primary) where a=1 and c>= 2.9; +a b c +1 1 3 +1 1 4 +select * from t1 force index (primary) where a=1 and c> 2.9; +a b c +1 1 3 +1 1 4 +select * from t1 ignore index (primary) where a=1 and c> 2.9; +a b c +1 1 3 +1 1 4 +drop table t1; +# +# BUG#13463488 - 63437: CHAR & BETWEEN WITH INDEX RETURNS WRONG +# RESULT AFTER MYSQL 5.1. +# +CREATE TABLE t1( +F1 CHAR(5) NOT NULL, +F2 CHAR(5) NOT NULL, +F3 CHAR(5) NOT NULL, +PRIMARY KEY(F1), +INDEX IDX_F2(F2) +); +INSERT INTO t1 VALUES +('A','A','A'),('AA','AA','AA'),('AAA','AAA','AAA'), +('AAAA','AAAA','AAAA'),('AAAAA','AAAAA','AAAAA'); +SELECT * FROM t1 WHERE F1 = 'A '; +F1 F2 F3 +A A A +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 = 'A '; +F1 F2 F3 +A A A +SELECT * FROM t1 WHERE F1 >= 'A '; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F1 > 'A '; +F1 F2 F3 +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F1 BETWEEN 'A ' AND 'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F2 BETWEEN 'A ' AND 'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F3 BETWEEN 'A ' AND 'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 BETWEEN 'A ' AND +'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 6c9320b708a..30d15798336 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1392,4 +1392,80 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; DROP TABLE t1; +--echo # +--echo # BUG#13519696 - 62940: SELECT RESULTS VARY WITH VERSION AND +--echo # WITH/WITHOUT INDEX RANGE SCAN +--echo # + +create table t1 (id int unsigned not null auto_increment primary key); +insert into t1 values (null); +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +create table t2 ( + id int unsigned not null auto_increment, + val decimal(5,3) not null, + primary key (id,val), + unique key (val,id), + unique key (id)); +--disable_warnings +insert into t2 select null,id*0.0009 from t1; +--enable_warnings + +select count(val) from t2 ignore index (val) where val > 0.1155; +select count(val) from t2 force index (val) where val > 0.1155; + +drop table t2, t1; + +--echo # +--echo # BUG#13453382 - REGRESSION SINCE 5.1.39, RANGE OPTIMIZER WRONG +--echo # RESULTS WITH DECIMAL CONVERSION +--echo # + +create table t1 (a int,b int,c int,primary key (a,c)); +insert into t1 values (1,1,2),(1,1,3),(1,1,4); +# show that the integer 3 is bigger than the decimal 2.9, +# which should also apply to comparing "c" with 2.9 +# when c is 3. +select convert(3, signed integer) > 2.9; +select * from t1 force index (primary) where a=1 and c>= 2.9; +select * from t1 ignore index (primary) where a=1 and c>= 2.9; +select * from t1 force index (primary) where a=1 and c> 2.9; +select * from t1 ignore index (primary) where a=1 and c> 2.9; +drop table t1; + +--echo # +--echo # BUG#13463488 - 63437: CHAR & BETWEEN WITH INDEX RETURNS WRONG +--echo # RESULT AFTER MYSQL 5.1. +--echo # + +CREATE TABLE t1( + F1 CHAR(5) NOT NULL, + F2 CHAR(5) NOT NULL, + F3 CHAR(5) NOT NULL, + PRIMARY KEY(F1), + INDEX IDX_F2(F2) +); + +INSERT INTO t1 VALUES +('A','A','A'),('AA','AA','AA'),('AAA','AAA','AAA'), +('AAAA','AAAA','AAAA'),('AAAAA','AAAAA','AAAAA'); + +SELECT * FROM t1 WHERE F1 = 'A '; +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 = 'A '; +SELECT * FROM t1 WHERE F1 >= 'A '; +SELECT * FROM t1 WHERE F1 > 'A '; +SELECT * FROM t1 WHERE F1 BETWEEN 'A ' AND 'AAAAA'; +SELECT * FROM t1 WHERE F2 BETWEEN 'A ' AND 'AAAAA'; +SELECT * FROM t1 WHERE F3 BETWEEN 'A ' AND 'AAAAA'; +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 BETWEEN 'A ' AND +'AAAAA'; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/item.cc b/sql/item.cc index 930c5d7426e..f4eb418b700 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7006,7 +7006,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) return my_time_compare(&field_time, &item_time); } - return stringcmp(field_result, item_result); + return sortcmp(field_result, item_result, field->charset()); } if (res_type == INT_RESULT) return 0; // Both are of type int @@ -7018,7 +7018,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) if (item->null_value) return 0; field_val= field->val_decimal(&field_buf); - return my_decimal_cmp(item_val, field_val); + return my_decimal_cmp(field_val, item_val); } double result= item->val_real(); if (item->null_value) -- cgit v1.2.1 From 26c52659c9fb2ddbdabb661f0a089705d16a46c1 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Fri, 27 Jan 2012 11:13:13 +0100 Subject: Bug#13580775 ASSERTION FAILED: RECORD_LENGTH == M_RECORD_LENGTH Bug#13011410 CRASH IN FILESORT CODE WITH GROUP BY/ROLLUP The assert in 13580775 is visible in 5.6 only, but shows that all versions are vulnerable. 13011410 crashes in all versions. filesort tries to re-use the sort buffer between invocations in order to save malloc/free overhead. The fix for Bug 11748783 - 37359: FILESORT CAN BE MORE EFFICIENT. added an assert that buffer properties (num_records, record_length) are consistent between invocations. Indeed, they are not necessarily consistent. Fix: re-allocate the sort buffer if properties change. mysql-test/r/partition.result: New tests. mysql-test/t/partition.test: New tests. sql/filesort.cc: If we already have allocated a sort buffer in a previous execution, then verify that it is big enough for the current one. sql/table.h: Add sort_keys_size; Number of bytes allocated for the sort_keys buffer. --- mysql-test/r/partition.result | 40 ++++++++++++++++++++++++++++++++++++ mysql-test/t/partition.test | 45 ++++++++++++++++++++++++++++++++++++++++ sql/filesort.cc | 48 ++++++++++++++++++++++++++++++++----------- sql/table.h | 1 + 4 files changed, 122 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 379f7499e11..49fe208d9bd 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -2206,4 +2206,44 @@ TRUNCATE TABLE t1; INSERT INTO t1 VALUES(0); DROP TABLE t1; SET GLOBAL myisam_use_mmap=default; +# +# Bug#13580775 ASSERTION FAILED: RECORD_LENGTH == M_RECORD_LENGTH, +# FILE FILESORT_UTILS.CC +# +CREATE TABLE t1 ( +a INT PRIMARY KEY, +b INT, +c CHAR(1), +d INT, +KEY (c,d) +) PARTITION BY KEY () PARTITIONS 1; +INSERT INTO t1 VALUES (1,1,'a',1), (2,2,'a',1); +SELECT 1 FROM t1 WHERE 1 IN +(SELECT group_concat(b) +FROM t1 +WHERE c > geomfromtext('point(1 1)') +GROUP BY b +); +1 +1 +1 +DROP TABLE t1; +# +# Bug#13011410 CRASH IN FILESORT CODE WITH GROUP BY/ROLLUP +# +CREATE TABLE t1 ( +a INT, +b MEDIUMINT, +c VARCHAR(300) CHARACTER SET hp8 COLLATE hp8_bin, +PRIMARY KEY (a,c(299))) +ENGINE=myisam +PARTITION BY LINEAR KEY () PARTITIONS 2; +INSERT INTO t1 VALUES (1,2,'test'), (2,3,'hi'), (4,5,'bye'); +SELECT 1 FROM t1 WHERE b < SOME +( SELECT 1 FROM t1 WHERE a >= 1 +GROUP BY b WITH ROLLUP +HAVING b > geomfromtext("") +); +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 341e8780b2b..134bbd0527d 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -2218,4 +2218,49 @@ INSERT INTO t1 VALUES(0); DROP TABLE t1; SET GLOBAL myisam_use_mmap=default; +--echo # +--echo # Bug#13580775 ASSERTION FAILED: RECORD_LENGTH == M_RECORD_LENGTH, +--echo # FILE FILESORT_UTILS.CC +--echo # + +CREATE TABLE t1 ( + a INT PRIMARY KEY, + b INT, + c CHAR(1), + d INT, + KEY (c,d) +) PARTITION BY KEY () PARTITIONS 1; + +INSERT INTO t1 VALUES (1,1,'a',1), (2,2,'a',1); + +SELECT 1 FROM t1 WHERE 1 IN +(SELECT group_concat(b) + FROM t1 + WHERE c > geomfromtext('point(1 1)') + GROUP BY b +); + +DROP TABLE t1; + +--echo # +--echo # Bug#13011410 CRASH IN FILESORT CODE WITH GROUP BY/ROLLUP +--echo # + +CREATE TABLE t1 ( + a INT, + b MEDIUMINT, + c VARCHAR(300) CHARACTER SET hp8 COLLATE hp8_bin, + PRIMARY KEY (a,c(299))) +ENGINE=myisam +PARTITION BY LINEAR KEY () PARTITIONS 2; + +INSERT INTO t1 VALUES (1,2,'test'), (2,3,'hi'), (4,5,'bye'); +SELECT 1 FROM t1 WHERE b < SOME +( SELECT 1 FROM t1 WHERE a >= 1 + GROUP BY b WITH ROLLUP + HAVING b > geomfromtext("") +); + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/filesort.cc b/sql/filesort.cc index 715528bcd52..ed198549890 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -41,8 +41,9 @@ if (my_b_write((file),(uchar*) (from),param->ref_length)) \ /* functions defined in this file */ -static char **make_char_array(char **old_pos, register uint fields, - uint length, myf my_flag); +static size_t char_array_size(uint fields, uint length); +static uchar **make_char_array(uchar **old_pos, uint fields, + uint length, myf my_flag); static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count, uchar *buf); static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select, @@ -221,10 +222,22 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, ulong old_memavl; ulong keys= memavl/(param.rec_length+sizeof(char*)); param.keys=(uint) min(records+1, keys); + + if (table_sort.sort_keys && + table_sort.sort_keys_size != char_array_size(param.keys, + param.rec_length)) + { + x_free((uchar*) table_sort.sort_keys); + table_sort.sort_keys= NULL; + table_sort.sort_keys_size= 0; + } if ((table_sort.sort_keys= - (uchar **) make_char_array((char **) table_sort.sort_keys, - param.keys, param.rec_length, MYF(0)))) + make_char_array(table_sort.sort_keys, + param.keys, param.rec_length, MYF(0)))) + { + table_sort.sort_keys_size= char_array_size(param.keys, param.rec_length); break; + } old_memavl=memavl; if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory) memavl= min_sort_memory; @@ -306,6 +319,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, { x_free((uchar*) sort_keys); table_sort.sort_keys= 0; + table_sort.sort_keys_size= 0; x_free((uchar*) buffpek); table_sort.buffpek= 0; table_sort.buffpek_len= 0; @@ -353,6 +367,7 @@ void filesort_free_buffers(TABLE *table, bool full) { x_free((uchar*) table->sort.sort_keys); table->sort.sort_keys= 0; + table->sort.sort_keys_size= 0; } if (table->sort.buffpek) { @@ -372,19 +387,28 @@ void filesort_free_buffers(TABLE *table, bool full) /** Make a array of string pointers. */ -static char **make_char_array(char **old_pos, register uint fields, - uint length, myf my_flag) +static size_t char_array_size(uint fields, uint length) { - register char **pos; - char *char_pos; + return fields * (length + sizeof(uchar*)); +} + + +static uchar **make_char_array(uchar **old_pos, uint fields, + uint length, myf my_flag) +{ + register uchar **pos; + uchar *char_pos; DBUG_ENTER("make_char_array"); if (old_pos || - (old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)), - my_flag))) + (old_pos= (uchar**) my_malloc(char_array_size(fields, length), my_flag))) { - pos=old_pos; char_pos=((char*) (pos+fields)) -length; - while (fields--) *(pos++) = (char_pos+= length); + pos=old_pos; + char_pos= ((uchar*)(pos+fields)) -length; + while (fields--) + { + *(pos++) = (char_pos+= length); + } } DBUG_RETURN(old_pos); diff --git a/sql/table.h b/sql/table.h index 20f11f4e7e1..690abdff714 100644 --- a/sql/table.h +++ b/sql/table.h @@ -157,6 +157,7 @@ typedef struct st_filesort_info { IO_CACHE *io_cache; /* If sorted through filesort */ uchar **sort_keys; /* Buffer for sorting keys */ + size_t sort_keys_size; /* Number of bytes allocated */ uchar *buffpek; /* Buffer for buffpek structures */ uint buffpek_len; /* Max number of buffpeks in the buffer */ uchar *addon_buf; /* Pointer to a buffer if sorted with fields */ -- cgit v1.2.1 From 7f0f18cd6ecd5a40f45393bfcc678350855f1513 Mon Sep 17 00:00:00 2001 From: Gopal Shankar Date: Mon, 30 Jan 2012 11:57:33 +0530 Subject: Bug#13105873 :Valgrind Warning: CRASH IN FOREIGN KEY HANDLING ON SUBSEQUENT CREATE TABLE IF NOT EXISTS PROBLEM: -------- Consider a SP routine which does CREATE TABLE with REFERENCES clause. The first call to this routine invokes parser and the parsed items are cached, so as to avoid parsing for the second execution of the routine. It is obsevered that valgrind reports a warning upon read of thd->lex->alter_info->key_list->Foreign_key object, which seem to be pointing to a invalid memory address during second time execution of the routine. Accessing this object theoretically could cause a crash. ANALYSIS: --------- The problem stems from the fact that for some reason elements of ref_columns list in thd->lex->alter_info-> key_list->Foreign_key object are changed to point to objects allocated on runtime memory root. During the first execution of routine we create a copy of thd->lex->alter_info object. As part of this process we create a clones of objects in Alter_info::key_list and of Foreign_key object in particular. Then Foreign_key object is cloned for some reason we perform shallow copies of both Foreign_key::ref_columns and Foreign_key::columns list. So new instance of Foreign_key object starts to SHARE contents of ref_columns and columns list with the original instance. After that as part of cloning process we call list_copy_and_replace_each_value() for elements of ref_columns list. As result ref_columns lists in both original and cloned Foreign_key object start to contain pointers to Key_part_spec objects allocated on runtime memory root because of shallow copy. So when we start copying of thd->lex->alter_info object during the second execution of stored routine we indeed encounter pointer to the Key_part_spec object allocated on runtime mem-root which was cleared during at the end of previous execution. This is done in sp_head::execute(), by a call to free_root(&execute_mem_root,MYF(0)); As result we get valgrind warnings about accessing unreferenced memory. FIX: ---- The safest solution to this problem is to fix Foreign_key(Foreign_key, MEM_ROOT) constructor to do a deep copy of columns lists, similar to Key(Key, MEM_ROOT) constructor. --- mysql-test/r/sp-bugs.result | 19 +++++++++++++++++++ mysql-test/t/sp-bugs.test | 24 ++++++++++++++++++++++++ sql/sql_class.cc | 4 ++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp-bugs.result b/mysql-test/r/sp-bugs.result index 507c73c2683..59588768d14 100644 --- a/mysql-test/r/sp-bugs.result +++ b/mysql-test/r/sp-bugs.result @@ -109,4 +109,23 @@ DROP FUNCTION db1.f1; DROP TABLE db1.t1; DROP DATABASE db1; DROP DATABASE db2; +# +# Bug#13105873:valgrind warning:possible crash in foreign +# key handling on subsequent create table if not exists +# +DROP DATABASE IF EXISTS testdb; +CREATE DATABASE testdb; +USE testdb; +CREATE TABLE t1 (id1 INT PRIMARY KEY); +CREATE PROCEDURE `p1`() +BEGIN +CREATE TABLE IF NOT EXISTS t2(id INT PRIMARY KEY, +CONSTRAINT FK FOREIGN KEY (id) REFERENCES t1( id1 )); +END$ +CALL p1(); +# below stmt should not return valgrind warnings +CALL p1(); +Warnings: +Note 1050 Table 't2' already exists +DROP DATABASE testdb; End of 5.1 tests diff --git a/mysql-test/t/sp-bugs.test b/mysql-test/t/sp-bugs.test index fe52632c784..a23ccea8189 100644 --- a/mysql-test/t/sp-bugs.test +++ b/mysql-test/t/sp-bugs.test @@ -138,4 +138,28 @@ DROP FUNCTION db1.f1; DROP TABLE db1.t1; DROP DATABASE db1; DROP DATABASE db2; + +--echo # +--echo # Bug#13105873:valgrind warning:possible crash in foreign +--echo # key handling on subsequent create table if not exists +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS testdb; +--enable_warnings +CREATE DATABASE testdb; +USE testdb; +CREATE TABLE t1 (id1 INT PRIMARY KEY); +DELIMITER $; +CREATE PROCEDURE `p1`() +BEGIN + CREATE TABLE IF NOT EXISTS t2(id INT PRIMARY KEY, + CONSTRAINT FK FOREIGN KEY (id) REFERENCES t1( id1 )); +END$ +DELIMITER ;$ +CALL p1(); +--echo # below stmt should not return valgrind warnings +CALL p1(); +DROP DATABASE testdb; + --echo End of 5.1 tests diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7fb1d2ade5f..32e2e90acd7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -122,9 +122,9 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root) */ Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root) - :Key(rhs), + :Key(rhs,mem_root), ref_table(rhs.ref_table), - ref_columns(rhs.ref_columns), + ref_columns(rhs.ref_columns,mem_root), delete_opt(rhs.delete_opt), update_opt(rhs.update_opt), match_opt(rhs.match_opt) -- cgit v1.2.1 From 882ef63e704002a9b0be76efff0259e7b61871d8 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Mon, 30 Jan 2012 22:52:33 +0400 Subject: Fix for BUG#13596377: MYSQL CRASHES ON STARTUP ON FREEBSD IN PB2 Fix for #36428/#38364 backported into 5.0. --- mysys/my_init.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mysys/my_init.c b/mysys/my_init.c index 4095f4b865e..87ec253f983 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -77,16 +77,18 @@ my_bool my_init(void) mysys_usage_id++; my_umask= 0660; /* Default umask for new files */ my_umask_dir= 0700; /* Default umask for new directories */ -#if defined(THREAD) && defined(SAFE_MUTEX) +#if defined(THREAD) + if (my_thread_global_init()) + return 1; +#if defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ -#endif +#endif /* SAFE_MUTEX */ +#endif /* THREAD */ netware_init(); #ifdef THREAD #if defined(HAVE_PTHREAD_INIT) pthread_init(); /* Must be called before DBUG_ENTER */ #endif - if (my_thread_global_init()) - return 1; #if !defined( __WIN__) && !defined(OS2) && !defined(__NETWARE__) sigfillset(&my_signals); /* signals blocked by mf_brkhant */ #endif -- cgit v1.2.1 From 2e4ae477f87f283b8f8b998081c3f28ef8b5f0ce Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Jan 2012 17:09:32 +0530 Subject: Bug #64127: MTR --warnings option misses some of InnoDB errors and warnings --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4e4333767da..5931e64ca4e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3932,7 +3932,7 @@ sub extract_warning_lines ($$) { qr/^Warning:|mysqld: Warning|\[Warning\]/, qr/^Error:|\[ERROR\]/, qr/^==\d+==\s+\S/, # valgrind errors - qr/InnoDB: Warning|InnoDB: Error/, + qr/InnoDB: (Warning|WARNING)|InnoDB: (Error|ERROR)/, qr/^safe_mutex:|allocated at line/, qr/missing DBUG_RETURN/, qr/Attempting backtrace/, -- cgit v1.2.1 From 9ac635321b80ccadcc73d6db98378f4828fc6928 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Jan 2012 17:39:40 +0530 Subject: --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5931e64ca4e..4e4333767da 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3932,7 +3932,7 @@ sub extract_warning_lines ($$) { qr/^Warning:|mysqld: Warning|\[Warning\]/, qr/^Error:|\[ERROR\]/, qr/^==\d+==\s+\S/, # valgrind errors - qr/InnoDB: (Warning|WARNING)|InnoDB: (Error|ERROR)/, + qr/InnoDB: Warning|InnoDB: Error/, qr/^safe_mutex:|allocated at line/, qr/missing DBUG_RETURN/, qr/Attempting backtrace/, -- cgit v1.2.1 From 63769afc52adaba998771a8780388781cf7defd4 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 31 Jan 2012 09:31:31 -0500 Subject: Bug#13636122 THE ORIGINAL TABLE MISSING WHILE EXECUTE THE DDL 'ALTER TABLE ADD COLUMN rb://914 approved by: Marko Makela Poll in fil_rename_tablespace() after setting ::stop_ios flag can result in a hang because the other thread actually dispatching the IO won't wake IO helper threads or flush the tablespace before starting wait in fil_mutex_enter_and_prepare_for_io(). --- storage/innobase/fil/fil0fil.c | 24 ++++++++++++++++++------ storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/fil/fil0fil.c | 31 +++++++++++++++++++++++++------ 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 6ca8381ebdf..1d3cdc6e227 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -772,11 +772,6 @@ retry: return; } - if (system->n_open < system->max_n_open) { - - return; - } - HASH_SEARCH(hash, system->spaces, space_id, space, space->id == space_id); if (space != NULL && space->stop_ios) { @@ -793,6 +788,18 @@ retry: mutex_exit(&(system->mutex)); +#ifndef UNIV_HOTBACKUP + /* Wake the i/o-handler threads to make sure pending + i/o's are performed */ + os_aio_simulated_wake_handler_threads(); + + os_thread_sleep(20000); +#endif /* UNIV_HOTBACKUP */ + + /* Flush tablespaces so that we can close modified + files in the LRU list */ + fil_flush_file_spaces(FIL_TABLESPACE); + os_thread_sleep(20000); count2++; @@ -800,6 +807,11 @@ retry: goto retry; } + if (system->n_open < system->max_n_open) { + + return; + } + /* If the file is already open, no need to do anything; if the space does not exist, we handle the situation in the function which called this function */ @@ -2290,7 +2302,7 @@ fil_rename_tablespace( retry: count++; - if (count > 1000) { + if (!(count % 1000)) { ut_print_timestamp(stderr); fputs(" InnoDB: Warning: problems renaming ", stderr); ut_print_filename(stderr, old_name); diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 97647b679e2..45b4d05de68 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2012-01-30 The InnoDB Team + + * fil/fil0fil.c: + Fix Bug#13636122 THE ORIGINAL TABLE MISSING WHILE EXECUTE THE + DDL 'ALTER TABLE ADD COLUMN' + 2012-01-16 The InnoDB Team * ibuf/ibuf0ibuf.c: diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index 0f774dcaaa1..01057c26d94 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -918,11 +918,6 @@ retry: return; } - if (fil_system->n_open < fil_system->max_n_open) { - - return; - } - space = fil_space_get_by_id(space_id); if (space != NULL && space->stop_ios) { @@ -939,6 +934,25 @@ retry: mutex_exit(&fil_system->mutex); +#ifndef UNIV_HOTBACKUP + + /* Wake the i/o-handler threads to make sure pending + i/o's are performed */ + os_aio_simulated_wake_handler_threads(); + + /* The sleep here is just to give IO helper threads a + bit of time to do some work. It is not required that + all IO related to the tablespace being renamed must + be flushed here as we do fil_flush() in + fil_rename_tablespace() as well. */ + os_thread_sleep(20000); + +#endif /* UNIV_HOTBACKUP */ + + /* Flush tablespaces so that we can close modified + files in the LRU list */ + fil_flush_file_spaces(FIL_TABLESPACE); + os_thread_sleep(20000); count2++; @@ -946,6 +960,11 @@ retry: goto retry; } + if (fil_system->n_open < fil_system->max_n_open) { + + return; + } + /* If the file is already open, no need to do anything; if the space does not exist, we handle the situation in the function which called this function */ @@ -2496,7 +2515,7 @@ fil_rename_tablespace( retry: count++; - if (count > 1000) { + if (!(count % 1000)) { ut_print_timestamp(stderr); fputs(" InnoDB: Warning: problems renaming ", stderr); ut_print_filename(stderr, old_name); -- cgit v1.2.1 From 52357198d0296e4c98551932ccf52ecb29adb85c Mon Sep 17 00:00:00 2001 From: Ashish Agarwal Date: Wed, 1 Feb 2012 11:19:53 +0530 Subject: BUG#11756869 - 48848: MYISAMCHK DOING SORT RECOVER IN CERTAIN CASES RESETS DATA POINTER TO SMAL ISSUE: Myisamchk doing sort recover on a table reduces data_file_length. Maximum size of data file decreases, lesser number of rows are stored. SOLUTION: Size of data_file_length is fixed to the original length. --- mysql-test/r/myisam.result | 13 +++++++++++++ mysql-test/t/myisam.test | 16 ++++++++++++++++ storage/myisam/mi_check.c | 16 ++++++++-------- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 433fc7c16a7..4ce6c445fb6 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2412,4 +2412,17 @@ CARDINALITY DROP TABLE t1; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; SET myisam_repair_threads=@@global.myisam_repair_threads; +# +# BUG 11756869 - 48848: MYISAMCHK DOING SORT RECOVER IN CERTAIN +# CASES RESETS DATA POINTER TO SMAL +# +CREATE TABLE t1(a INT, KEY(a)); +ALTER TABLE t1 DISABLE KEYS; +SET @before:= (SELECT MAX_DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'); +FLUSH TABLES; +SET @after:= (SELECT MAX_DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'); +SELECT @before=@after; +@before=@after +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 4abd7dd2b1b..9c79669c999 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1645,4 +1645,20 @@ DROP TABLE t1; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; SET myisam_repair_threads=@@global.myisam_repair_threads; +--echo # +--echo # BUG 11756869 - 48848: MYISAMCHK DOING SORT RECOVER IN CERTAIN +--echo # CASES RESETS DATA POINTER TO SMAL +--echo # + +CREATE TABLE t1(a INT, KEY(a)); +ALTER TABLE t1 DISABLE KEYS; +let $MYSQLD_DATADIR= `select @@datadir`; +SET @before:= (SELECT MAX_DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'); +FLUSH TABLES; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--exec $MYISAMCHK -sn $MYSQLD_DATADIR/test/t1 +SET @after:= (SELECT MAX_DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'); +SELECT @before=@after; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 4a0c2da5559..e71c583a9d3 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -4314,13 +4314,6 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) u_ptr->seg=keyseg; keyseg+=u_ptr->keysegs+1; } - if (share.options & HA_OPTION_COMPRESS_RECORD) - share.base.records=max_records=info.state->records; - else if (share.base.min_pack_length) - max_records=(ha_rows) (my_seek(info.dfile,0L,MY_SEEK_END,MYF(0)) / - (ulong) share.base.min_pack_length); - else - max_records=0; unpack= (share.options & HA_OPTION_COMPRESS_RECORD) && (param->testflag & T_UNPACK); share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD; @@ -4330,10 +4323,17 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) set_if_bigger(file_length,param->max_data_file_length); set_if_bigger(file_length,tmp_length); set_if_bigger(file_length,(ulonglong) share.base.max_data_file_length); + + if (share.options & HA_OPTION_COMPRESS_RECORD) + share.base.records=max_records=info.state->records; + else if (!(share.options & HA_OPTION_PACK_RECORD)) + max_records= (ha_rows) (file_length / share.base.pack_reclength); + else + max_records= 0; VOID(mi_close(*org_info)); bzero((char*) &create_info,sizeof(create_info)); - create_info.max_rows=max(max_records,share.base.records); + create_info.max_rows= max_records; create_info.reloc_rows=share.base.reloc; create_info.old_options=(share.options | (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0)); -- cgit v1.2.1 From ed822984e1397745310e11ca6c71092ef587e24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 2 Feb 2012 12:07:06 +0200 Subject: Suppress messages about long semaphore waits in innodb_bug34300.test. --- mysql-test/suite/innodb/t/innodb_bug34300.test | 1 + mysql-test/suite/innodb_plugin/t/innodb_bug34300.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/suite/innodb/t/innodb_bug34300.test b/mysql-test/suite/innodb/t/innodb_bug34300.test index 432ddd03547..6c516ccb73e 100644 --- a/mysql-test/suite/innodb/t/innodb_bug34300.test +++ b/mysql-test/suite/innodb/t/innodb_bug34300.test @@ -7,6 +7,7 @@ -- disable_query_log -- disable_result_log +call mtr.add_suppression("InnoDB: Warning: a long semaphore wait:"); # set packet size and reconnect SET @@global.max_allowed_packet=16777216; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug34300.test b/mysql-test/suite/innodb_plugin/t/innodb_bug34300.test index d91ce205042..8be53f0db30 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug34300.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug34300.test @@ -7,6 +7,7 @@ -- disable_query_log -- disable_result_log +call mtr.add_suppression("InnoDB: Warning: a long semaphore wait:"); # set packet size and reconnect let $max_packet=`select @@global.max_allowed_packet`; -- cgit v1.2.1 From e726580b6668956ca05c93cd2bd4ec5938314354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 2 Feb 2012 13:38:32 +0200 Subject: Bug#13654923 BOGUS DEBUG ASSERTION IN INDEX CREATION FOR ZERO-LENGTH RECORD row_merge_buf_write(): Relax the bogus assertion. --- mysql-test/suite/innodb_plugin/r/innodb-index.result | 4 ++++ mysql-test/suite/innodb_plugin/t/innodb-index.test | 5 +++++ storage/innodb_plugin/row/row0merge.c | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb-index.result b/mysql-test/suite/innodb_plugin/r/innodb-index.result index 9600d0a79b4..37bd81e5ec6 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-index.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-index.result @@ -114,6 +114,10 @@ t12963823 CREATE TABLE `t12963823` ( KEY `ndx_o` (`o`(500)), KEY `ndx_p` (`p`(500)) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +create table t1(a varchar(2) primary key) engine=innodb; +insert into t1 values(''); +create index t1a1 on t1(a(1)); +drop table t1; set global innodb_file_per_table=0; set global innodb_file_format=Antelope; create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-index.test b/mysql-test/suite/innodb_plugin/t/innodb-index.test index 0d891939d6e..d4310093bfd 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-index.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-index.test @@ -119,6 +119,11 @@ show create table t12963823; # this file complete before dropping the table. By then, the purge thread # will have delt with the updates above. +# Bug#13654923 BOGUS DEBUG ASSERTION IN INDEX CREATION FOR ZERO-LENGTH RECORD +create table t1(a varchar(2) primary key) engine=innodb; +insert into t1 values(''); +create index t1a1 on t1(a(1)); +drop table t1; eval set global innodb_file_per_table=$per_table; eval set global innodb_file_format=$format; diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 647d0031635..8c18cfa078b 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -576,7 +576,7 @@ row_merge_buf_write( REC_STATUS_ORDINARY, entry, n_fields, &extra_size); - ut_ad(size > extra_size); + ut_ad(size >= extra_size); ut_ad(extra_size >= REC_N_NEW_EXTRA_BYTES); extra_size -= REC_N_NEW_EXTRA_BYTES; size -= REC_N_NEW_EXTRA_BYTES; -- cgit v1.2.1 From bbcc86f5d41aba2562936e90ea1ea2c3034f8f6b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 2 Feb 2012 16:22:13 +0400 Subject: Postfix for Bug#11752408. Recording correct test results. modified: mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result --- mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result | 2 ++ mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result index 4e940a5a183..8f79469d8de 100644 --- a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result +++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result @@ -76,6 +76,7 @@ utf8_roman_ci utf8 207 # # utf8_persian_ci utf8 208 # # utf8_esperanto_ci utf8 209 # # utf8_hungarian_ci utf8 210 # # +utf8_general_mysql500_ci utf8 223 # # ucs2_general_ci ucs2 35 Yes # # ucs2_bin ucs2 90 # # ucs2_unicode_ci ucs2 128 # # @@ -97,6 +98,7 @@ ucs2_roman_ci ucs2 143 # # ucs2_persian_ci ucs2 144 # # ucs2_esperanto_ci ucs2 145 # # ucs2_hungarian_ci ucs2 146 # # +ucs2_general_mysql500_ci ucs2 159 # # cp866_general_ci cp866 36 Yes # # cp866_bin cp866 68 # # keybcs2_general_ci keybcs2 37 Yes # # diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result index 586fb20a58b..9fb36bd0927 100644 --- a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result +++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result @@ -76,6 +76,7 @@ utf8_roman_ci utf8 207 # # utf8_persian_ci utf8 208 # # utf8_esperanto_ci utf8 209 # # utf8_hungarian_ci utf8 210 # # +utf8_general_mysql500_ci utf8 223 # # ucs2_general_ci ucs2 35 Yes # # ucs2_bin ucs2 90 # # ucs2_unicode_ci ucs2 128 # # @@ -97,6 +98,7 @@ ucs2_roman_ci ucs2 143 # # ucs2_persian_ci ucs2 144 # # ucs2_esperanto_ci ucs2 145 # # ucs2_hungarian_ci ucs2 146 # # +ucs2_general_mysql500_ci ucs2 159 # # cp866_general_ci cp866 36 Yes # # cp866_bin cp866 68 # # keybcs2_general_ci keybcs2 37 Yes # # -- cgit v1.2.1 From cfcb5daba80df535527890b5bd37607057623e8f Mon Sep 17 00:00:00 2001 From: Ashish Agarwal Date: Fri, 3 Feb 2012 19:37:00 +0530 Subject: BUG#11748748 - 37280: CHECK AND REPAIR TABLE REPORT TABLE CORRUPTED WHEN RUN CONCURRENTLY WITH ISSUE: Table corruption due to concurrent queries. Different threads running check, repair query along with insert. Locks not properly acquired in repair query. Rows are inserted inbetween repair query. SOLUTION: Mutex lock is acquired before the repair call. Concurrent queries wont effect the call to repair. --- storage/archive/ha_archive.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 79053f284b3..dc88f1d652f 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1310,6 +1310,7 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) azio_stream writer; char writer_filename[FN_REFLEN]; + pthread_mutex_lock(&share->mutex); init_archive_reader(); // now we close both our writer and our reader for the rename @@ -1324,7 +1325,10 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) MY_REPLACE_EXT | MY_UNPACK_FILENAME); if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY))) + { + pthread_mutex_unlock(&share->mutex); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + } /* An extended rebuild is a lot more effort. We open up each row and re-record it. @@ -1403,10 +1407,12 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) rc = my_rename(writer_filename,share->data_file_name,MYF(0)); + pthread_mutex_unlock(&share->mutex); DBUG_RETURN(rc); error: DBUG_PRINT("ha_archive", ("Failed to recover, error was %d", rc)); azclose(&writer); + pthread_mutex_unlock(&share->mutex); DBUG_RETURN(rc); } -- cgit v1.2.1 From 1c4fd3bb546a501fc95ca52def2c728681d62b28 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 6 Feb 2012 12:44:59 +0200 Subject: Fix Bug#11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON GRACEFUL SHUTDOWN During startup mysql picks up .frm files from the tmpdir directory and tries to drop those tables in the storage engine. The problem is that when tmpdir ends in / then ha_innobase::delete_table() is passed a string like "/var/tmp//#sql123", then it wrongly normalizes it to "/#sql123" and calls row_drop_table_for_mysql() which of course fails to delete the table entry from the InnoDB dictionary cache. ha_innobase::delete_table() returns an error but nevertheless mysql wipes away the .frm file and the entry in the InnoDB dictionary cache remains orphaned with no easy way to remove it. The "no easy" way to remove it is to create a similar temporary table again, copy its .frm file to tmpdir under "#sql123.frm" and restart mysqld with tmpdir=/var/tmp (no trailing slash) - this way mysql will pick the .frm file after restart and will try to issue drop table for "/var/tmp/#sql123" (notice do double slash), ha_innobase::delete_table() will normalize it to "tmp/#sql123" and row_drop_table_for_mysql() will successfully remove the table entry from the dictionary cache. The solution is to fix normalize_table_name_low() to normalize things like "/var/tmp//table" correctly to "tmp/table". This patch also adds a test function which invokes normalize_table_name_low() with various inputs to make sure it works correctly and a mtr test that calls this test function. Reviewed by: Marko (http://bur03.no.oracle.com/rb/r/929/) --- .../suite/innodb/r/innodb_bug11754376.result | 4 + mysql-test/suite/innodb/t/innodb_bug11754376.test | 16 ++++ .../innodb_plugin/r/innodb_bug11754376.result | 4 + .../suite/innodb_plugin/t/innodb_bug11754376.test | 16 ++++ storage/innobase/handler/ha_innodb.cc | 92 ++++++++++++++++++++-- storage/innodb_plugin/ChangeLog | 6 ++ storage/innodb_plugin/handler/ha_innodb.cc | 92 ++++++++++++++++++++-- 7 files changed, 220 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug11754376.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug11754376.test create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug11754376.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug11754376.test diff --git a/mysql-test/suite/innodb/r/innodb_bug11754376.result b/mysql-test/suite/innodb/r/innodb_bug11754376.result new file mode 100644 index 00000000000..26e92b9d3ea --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug11754376.result @@ -0,0 +1,4 @@ +CREATE TABLE bug11754376 (c INT) ENGINE=INNODB; +SET SESSION DEBUG='+d,test_normalize_table_name_low'; +DROP TABLE bug11754376; +SET SESSION DEBUG='-d,test_normalize_table_name_low'; diff --git a/mysql-test/suite/innodb/t/innodb_bug11754376.test b/mysql-test/suite/innodb/t/innodb_bug11754376.test new file mode 100644 index 00000000000..4ab695fe9c2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug11754376.test @@ -0,0 +1,16 @@ +# +# Bug#11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON GRACEFUL SHUTDOWN +# + +-- source include/have_debug.inc +-- source include/have_innodb.inc + +CREATE TABLE bug11754376 (c INT) ENGINE=INNODB; + +# This will invoke test_normalize_table_name_low() in debug builds + +SET SESSION DEBUG='+d,test_normalize_table_name_low'; + +DROP TABLE bug11754376; + +SET SESSION DEBUG='-d,test_normalize_table_name_low'; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug11754376.result b/mysql-test/suite/innodb_plugin/r/innodb_bug11754376.result new file mode 100644 index 00000000000..26e92b9d3ea --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug11754376.result @@ -0,0 +1,4 @@ +CREATE TABLE bug11754376 (c INT) ENGINE=INNODB; +SET SESSION DEBUG='+d,test_normalize_table_name_low'; +DROP TABLE bug11754376; +SET SESSION DEBUG='-d,test_normalize_table_name_low'; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug11754376.test b/mysql-test/suite/innodb_plugin/t/innodb_bug11754376.test new file mode 100644 index 00000000000..d4f221f187e --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug11754376.test @@ -0,0 +1,16 @@ +# +# Bug#11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON GRACEFUL SHUTDOWN +# + +-- source include/have_debug.inc +-- source include/have_innodb_plugin.inc + +CREATE TABLE bug11754376 (c INT) ENGINE=INNODB; + +# This will invoke test_normalize_table_name_low() in debug builds + +SET SESSION DEBUG='+d,test_normalize_table_name_low'; + +DROP TABLE bug11754376; + +SET SESSION DEBUG='-d,test_normalize_table_name_low'; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b229354ce88..20ab9c7a101 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2618,37 +2618,114 @@ normalize_table_name_low( { char* name_ptr; char* db_ptr; + ulint db_len; char* ptr; /* Scan name from the end */ - ptr = strend(name)-1; + ptr = strend(name) - 1; + /* seek to the last path separator */ while (ptr >= name && *ptr != '\\' && *ptr != '/') { ptr--; } name_ptr = ptr + 1; - DBUG_ASSERT(ptr > name); + /* skip any number of path separators */ + while (ptr >= name && (*ptr == '\\' || *ptr == '/')) { + ptr--; + } - ptr--; + DBUG_ASSERT(ptr >= name); + /* seek to the last but one path separator or one char before + the beginning of name */ + db_len = 0; while (ptr >= name && *ptr != '\\' && *ptr != '/') { ptr--; + db_len++; } db_ptr = ptr + 1; - memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name)); + memcpy(norm_name, db_ptr, db_len); - norm_name[name_ptr - db_ptr - 1] = '/'; + norm_name[db_len] = '/'; + + memcpy(norm_name + db_len + 1, name_ptr, strlen(name_ptr) + 1); if (set_lower_case) { innobase_casedn_str(norm_name); } } +#if !defined(DBUG_OFF) +/********************************************************************* +Test normalize_table_name_low(). */ +static +void +test_normalize_table_name_low() +/*===========================*/ +{ + char norm_name[128]; + const char* test_data[][2] = { + /* input, expected result */ + {"./mysqltest/t1", "mysqltest/t1"}, + {"./test/#sql-842b_2", "test/#sql-842b_2"}, + {"./test/#sql-85a3_10", "test/#sql-85a3_10"}, + {"./test/#sql2-842b-2", "test/#sql2-842b-2"}, + {"./test/bug29807", "test/bug29807"}, + {"./test/foo", "test/foo"}, + {"./test/innodb_bug52663", "test/innodb_bug52663"}, + {"./test/t", "test/t"}, + {"./test/t1", "test/t1"}, + {"./test/t10", "test/t10"}, + {"/a/b/db/table", "db/table"}, + {"/a/b/db///////table", "db/table"}, + {"/a/b////db///////table", "db/table"}, + {"/var/tmp/mysqld.1/#sql842b_2_10", "mysqld.1/#sql842b_2_10"}, + {"db/table", "db/table"}, + {"ddd/t", "ddd/t"}, + {"d/ttt", "d/ttt"}, + {"d/t", "d/t"}, + {".\\mysqltest\\t1", "mysqltest/t1"}, + {".\\test\\#sql-842b_2", "test/#sql-842b_2"}, + {".\\test\\#sql-85a3_10", "test/#sql-85a3_10"}, + {".\\test\\#sql2-842b-2", "test/#sql2-842b-2"}, + {".\\test\\bug29807", "test/bug29807"}, + {".\\test\\foo", "test/foo"}, + {".\\test\\innodb_bug52663", "test/innodb_bug52663"}, + {".\\test\\t", "test/t"}, + {".\\test\\t1", "test/t1"}, + {".\\test\\t10", "test/t10"}, + {"C:\\a\\b\\db\\table", "db/table"}, + {"C:\\a\\b\\db\\\\\\\\\\\\\\table", "db/table"}, + {"C:\\a\\b\\\\\\\\db\\\\\\\\\\\\\\table", "db/table"}, + {"C:\\var\\tmp\\mysqld.1\\#sql842b_2_10", "mysqld.1/#sql842b_2_10"}, + {"db\\table", "db/table"}, + {"ddd\\t", "ddd/t"}, + {"d\\ttt", "d/ttt"}, + {"d\\t", "d/t"}, + }; + + for (size_t i = 0; i < UT_ARR_SIZE(test_data); i++) { + printf("test_normalize_table_name_low(): " + "testing \"%s\", expected \"%s\"... ", + test_data[i][0], test_data[i][1]); + + normalize_table_name_low(norm_name, test_data[i][0], FALSE); + + if (strcmp(norm_name, test_data[i][1]) == 0) { + printf("ok\n"); + } else { + printf("got \"%s\"\n", norm_name); + ut_error; + } + } +} +#endif /* !DBUG_OFF */ + /************************************************************************ Get the upper limit of the MySQL integral and floating-point type. */ static @@ -5990,6 +6067,11 @@ ha_innobase::delete_table( DBUG_ENTER("ha_innobase::delete_table"); + DBUG_EXECUTE_IF( + "test_normalize_table_name_low", + test_normalize_table_name_low(); + ); + /* Strangely, MySQL passes the table name without the '.frm' extension, in contrast to ::create */ normalize_table_name(norm_name, name); diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 45b4d05de68..1fad9d8420e 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2012-02-06 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug #11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON + GRACEFUL SHUTDOWN + 2012-01-30 The InnoDB Team * fil/fil0fil.c: diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index abb7180b0d0..f23642d6af8 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -3048,37 +3048,114 @@ normalize_table_name_low( { char* name_ptr; char* db_ptr; + ulint db_len; char* ptr; /* Scan name from the end */ - ptr = strend(name)-1; + ptr = strend(name) - 1; + /* seek to the last path separator */ while (ptr >= name && *ptr != '\\' && *ptr != '/') { ptr--; } name_ptr = ptr + 1; - DBUG_ASSERT(ptr > name); + /* skip any number of path separators */ + while (ptr >= name && (*ptr == '\\' || *ptr == '/')) { + ptr--; + } - ptr--; + DBUG_ASSERT(ptr >= name); + /* seek to the last but one path separator or one char before + the beginning of name */ + db_len = 0; while (ptr >= name && *ptr != '\\' && *ptr != '/') { ptr--; + db_len++; } db_ptr = ptr + 1; - memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name)); + memcpy(norm_name, db_ptr, db_len); + + norm_name[db_len] = '/'; - norm_name[name_ptr - db_ptr - 1] = '/'; + memcpy(norm_name + db_len + 1, name_ptr, strlen(name_ptr) + 1); if (set_lower_case) { innobase_casedn_str(norm_name); } } +#if !defined(DBUG_OFF) +/********************************************************************* +Test normalize_table_name_low(). */ +static +void +test_normalize_table_name_low() +/*===========================*/ +{ + char norm_name[128]; + const char* test_data[][2] = { + /* input, expected result */ + {"./mysqltest/t1", "mysqltest/t1"}, + {"./test/#sql-842b_2", "test/#sql-842b_2"}, + {"./test/#sql-85a3_10", "test/#sql-85a3_10"}, + {"./test/#sql2-842b-2", "test/#sql2-842b-2"}, + {"./test/bug29807", "test/bug29807"}, + {"./test/foo", "test/foo"}, + {"./test/innodb_bug52663", "test/innodb_bug52663"}, + {"./test/t", "test/t"}, + {"./test/t1", "test/t1"}, + {"./test/t10", "test/t10"}, + {"/a/b/db/table", "db/table"}, + {"/a/b/db///////table", "db/table"}, + {"/a/b////db///////table", "db/table"}, + {"/var/tmp/mysqld.1/#sql842b_2_10", "mysqld.1/#sql842b_2_10"}, + {"db/table", "db/table"}, + {"ddd/t", "ddd/t"}, + {"d/ttt", "d/ttt"}, + {"d/t", "d/t"}, + {".\\mysqltest\\t1", "mysqltest/t1"}, + {".\\test\\#sql-842b_2", "test/#sql-842b_2"}, + {".\\test\\#sql-85a3_10", "test/#sql-85a3_10"}, + {".\\test\\#sql2-842b-2", "test/#sql2-842b-2"}, + {".\\test\\bug29807", "test/bug29807"}, + {".\\test\\foo", "test/foo"}, + {".\\test\\innodb_bug52663", "test/innodb_bug52663"}, + {".\\test\\t", "test/t"}, + {".\\test\\t1", "test/t1"}, + {".\\test\\t10", "test/t10"}, + {"C:\\a\\b\\db\\table", "db/table"}, + {"C:\\a\\b\\db\\\\\\\\\\\\\\table", "db/table"}, + {"C:\\a\\b\\\\\\\\db\\\\\\\\\\\\\\table", "db/table"}, + {"C:\\var\\tmp\\mysqld.1\\#sql842b_2_10", "mysqld.1/#sql842b_2_10"}, + {"db\\table", "db/table"}, + {"ddd\\t", "ddd/t"}, + {"d\\ttt", "d/ttt"}, + {"d\\t", "d/t"}, + }; + + for (size_t i = 0; i < UT_ARR_SIZE(test_data); i++) { + printf("test_normalize_table_name_low(): " + "testing \"%s\", expected \"%s\"... ", + test_data[i][0], test_data[i][1]); + + normalize_table_name_low(norm_name, test_data[i][0], FALSE); + + if (strcmp(norm_name, test_data[i][1]) == 0) { + printf("ok\n"); + } else { + printf("got \"%s\"\n", norm_name); + ut_error; + } + } +} +#endif /* !DBUG_OFF */ + /********************************************************************//** Get the upper limit of the MySQL integral and floating-point type. @return maximum allowed value for the field */ @@ -7047,6 +7124,11 @@ ha_innobase::delete_table( DBUG_ENTER("ha_innobase::delete_table"); + DBUG_EXECUTE_IF( + "test_normalize_table_name_low", + test_normalize_table_name_low(); + ); + /* Strangely, MySQL passes the table name without the '.frm' extension, in contrast to ::create */ normalize_table_name(norm_name, name); -- cgit v1.2.1 From 9ada2f8ec5d29c036bcd185a411f64eea17d8132 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Tue, 7 Feb 2012 14:16:09 +0100 Subject: Bug #11765810 58813: SERVER THREAD HANGS WHEN JOIN + WHERE + GROUP BY IS EXECUTED TWICE FROM P This bug is a duplicate of bug 12567331, which was pushed to the optimizer backporting tree on 2011-06-11. This is just a back-port of the fix. Both test cases are included as they differ somewhat. --- mysql-test/r/join_outer.result | 58 ++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/join_outer.test | 58 ++++++++++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 12 +-------- 3 files changed, 117 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index d9c4ac5478e..d8a734a7158 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1427,4 +1427,62 @@ WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; f1 f1 f2 DROP TABLE t1,t2; + +# BUG#12567331 - INFINITE LOOP WHEN RESOLVING AN ALIASED COLUMN +# USED IN GROUP BY + +CREATE TABLE t1 ( +col_varchar_1024_latin1_key varchar(1024), +col_varchar_10_latin1 varchar(10), +col_int int(11), +pk int(11) +); +CREATE TABLE t2 ( +col_int_key int(11), +col_int int(11), +pk int(11) +); +PREPARE prep_stmt_9846 FROM ' +SELECT alias1.pk AS field1 FROM +t1 AS alias1 +LEFT JOIN +( + t2 AS alias2 + RIGHT JOIN + ( + t2 AS alias3 + JOIN t1 AS alias4 + ON 1 + ) + ON 1 +) +ON 1 +GROUP BY field1'; +execute prep_stmt_9846; +field1 +execute prep_stmt_9846; +field1 +drop table t1,t2; +# +# Bug #11765810 58813: SERVER THREAD HANGS WHEN JOIN + WHERE + GROUP BY +# IS EXECUTED TWICE FROM P +# +CREATE TABLE t1 ( a INT ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1); +PREPARE prep_stmt FROM ' + SELECT 1 AS f FROM t1 + LEFT JOIN t1 t2 + RIGHT JOIN t1 t3 + JOIN t1 t4 + ON 1 + ON 1 + ON 1 + GROUP BY f'; +EXECUTE prep_stmt; +f +1 +EXECUTE prep_stmt; +f +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 3251ff292b6..1ba29fdd4cf 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1010,4 +1010,62 @@ GROUP BY t2.f1, t2.f2; DROP TABLE t1,t2; + +--echo +--echo # BUG#12567331 - INFINITE LOOP WHEN RESOLVING AN ALIASED COLUMN +--echo # USED IN GROUP BY +--echo +CREATE TABLE t1 ( + col_varchar_1024_latin1_key varchar(1024), + col_varchar_10_latin1 varchar(10), + col_int int(11), + pk int(11) +); +CREATE TABLE t2 ( + col_int_key int(11), + col_int int(11), + pk int(11) +); + +PREPARE prep_stmt_9846 FROM ' +SELECT alias1.pk AS field1 FROM +t1 AS alias1 +LEFT JOIN +( + t2 AS alias2 + RIGHT JOIN + ( + t2 AS alias3 + JOIN t1 AS alias4 + ON 1 + ) + ON 1 +) +ON 1 +GROUP BY field1'; +execute prep_stmt_9846; +execute prep_stmt_9846; +drop table t1,t2; + +--echo # +--echo # Bug #11765810 58813: SERVER THREAD HANGS WHEN JOIN + WHERE + GROUP BY +--echo # IS EXECUTED TWICE FROM P +--echo # +CREATE TABLE t1 ( a INT ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1); +PREPARE prep_stmt FROM ' + SELECT 1 AS f FROM t1 + LEFT JOIN t1 t2 + RIGHT JOIN t1 t3 + JOIN t1 t4 + ON 1 + ON 1 + ON 1 + GROUP BY f'; +EXECUTE prep_stmt; +EXECUTE prep_stmt; + +DROP TABLE t1; + + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 72c826ff32d..5f1efabfc97 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8947,11 +8947,9 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) } /* Flatten nested joins that can be flattened. */ - TABLE_LIST *right_neighbor= NULL; li.rewind(); while ((table= li++)) { - bool fix_name_res= FALSE; nested_join= table->nested_join; if (nested_join && !table->on_expr) { @@ -8963,15 +8961,7 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) tbl->join_list= table->join_list; } li.replace(nested_join->join_list); - /* Need to update the name resolution table chain when flattening joins */ - fix_name_res= TRUE; - table= *li.ref(); - } - if (fix_name_res) - table->next_name_resolution_table= right_neighbor ? - right_neighbor->first_leaf_for_name_resolution() : - NULL; - right_neighbor= table; + } } DBUG_RETURN(conds); } -- cgit v1.2.1 From b566d9a512a9671a423e1ff944d1e4ede2df7f7e Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Fri, 10 Feb 2012 14:09:12 +1100 Subject: BUG#12739098 - 62401: ASSERTION TRX->ERROR_STATE == DB_SUCCESS, QUE0QUE.C LINE 1264 ON TRUNCATE During FIC error handling the trx->error_state was not being set to DB_SUCCESS after failure, before attempting the next DDL SQL operation. This reset to DB_SUCCESS is somewhat of a requirement though not explicitly stated anywhere. The fix is to reset it to DB_SUCCESS in row0merge.cc if row_merge_rename_indexes or row_merge_drop_index functions fail, also reset to DB_SUCCESS at trx commit. rb://935 Approved by Jimmy Yang. --- storage/innodb_plugin/row/row0merge.c | 31 +++++++++++++++++++++++++------ storage/innodb_plugin/trx/trx0trx.c | 2 ++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 8c18cfa078b..7f59d7cf9e9 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -2012,7 +2012,7 @@ row_merge_drop_index( tables in Innobase. Deleting a row from SYS_INDEXES table also frees the file segments of the B-tree associated with the index. */ - static const char str1[] = + static const char sql[] = "PROCEDURE DROP_INDEX_PROC () IS\n" "BEGIN\n" /* Rename the index, so that it will be dropped by @@ -2036,9 +2036,19 @@ row_merge_drop_index( ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); - err = que_eval_sql(info, str1, FALSE, trx); + err = que_eval_sql(info, sql, FALSE, trx); - ut_a(err == DB_SUCCESS); + + if (err != DB_SUCCESS) { + /* Even though we ensure that DDL transactions are WAIT + and DEADLOCK free, we could encounter other errors e.g., + DB_TOO_MANY_TRANSACTIONS. */ + trx->error_state = DB_SUCCESS; + + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Error: row_merge_drop_index failed " + "with error code: %lu.\n", (ulint) err); + } /* Replace this index with another equivalent index for all foreign key constraints on this table where this index is used */ @@ -2290,7 +2300,7 @@ row_merge_rename_indexes( /* We use the private SQL parser of Innobase to generate the query graphs needed in renaming indexes. */ - static const char rename_indexes[] = + static const char sql[] = "PROCEDURE RENAME_INDEXES_PROC () IS\n" "BEGIN\n" "UPDATE SYS_INDEXES SET NAME=SUBSTR(NAME,1,LENGTH(NAME)-1)\n" @@ -2306,7 +2316,7 @@ row_merge_rename_indexes( pars_info_add_dulint_literal(info, "tableid", table->id); - err = que_eval_sql(info, rename_indexes, FALSE, trx); + err = que_eval_sql(info, sql, FALSE, trx); if (err == DB_SUCCESS) { dict_index_t* index = dict_table_get_first_index(table); @@ -2316,6 +2326,15 @@ row_merge_rename_indexes( } index = dict_table_get_next_index(index); } while (index); + } else { + /* Even though we ensure that DDL transactions are WAIT + and DEADLOCK free, we could encounter other errors e.g., + DB_TOO_MANY_TRANSACTIONS. */ + trx->error_state = DB_SUCCESS; + + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Error: row_merge_rename_indexes " + "failed with error code: %lu.\n", (ulint) err); } trx->op_info = ""; @@ -2354,7 +2373,7 @@ row_merge_rename_tables( memcpy(old_name, old_table->name, strlen(old_table->name) + 1); } else { ut_print_timestamp(stderr); - fprintf(stderr, "InnoDB: too long table name: '%s', " + fprintf(stderr, " InnoDB: too long table name: '%s', " "max length is %d\n", old_table->name, MAX_FULL_NAME_LEN); ut_error; diff --git a/storage/innodb_plugin/trx/trx0trx.c b/storage/innodb_plugin/trx/trx0trx.c index 7f3a3fcb4bf..80f079423fe 100644 --- a/storage/innodb_plugin/trx/trx0trx.c +++ b/storage/innodb_plugin/trx/trx0trx.c @@ -1008,6 +1008,8 @@ trx_commit_off_kernel( ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0); UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx); + + trx->error_state = DB_SUCCESS; } /****************************************************************//** -- cgit v1.2.1 From d3de138311dd7fcabf2ade7b2c024c3edcab5094 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 10 Feb 2012 11:10:07 +0200 Subject: Bug#13706621 : UNIFY THE YASSL VERSIONS THAT WE USE BY BACKPORTING 5.1 AND 5.5 YASSL FIXES. Took the 5.5 yassl code and applied it to the 5.0 codebase, keeping the compilation files. --- extra/yassl/include/cert_wrapper.hpp | 6 +- extra/yassl/include/openssl/prefix_ssl.h | 4 +- extra/yassl/include/openssl/ssl.h | 12 +- extra/yassl/include/yassl_error.hpp | 5 +- extra/yassl/include/yassl_imp.hpp | 7 +- extra/yassl/include/yassl_int.hpp | 15 ++- extra/yassl/include/yassl_types.hpp | 13 ++- extra/yassl/src/cert_wrapper.cpp | 40 +++++-- extra/yassl/src/crypto_wrapper.cpp | 7 +- extra/yassl/src/socket_wrapper.cpp | 4 +- extra/yassl/src/ssl.cpp | 31 ++++-- extra/yassl/src/yassl_error.cpp | 11 +- extra/yassl/src/yassl_imp.cpp | 179 ++++++++++++++++++------------ extra/yassl/src/yassl_int.cpp | 101 ++++++++++++++--- extra/yassl/taocrypt/include/blowfish.hpp | 8 +- extra/yassl/taocrypt/include/misc.hpp | 4 +- extra/yassl/taocrypt/include/runtime.hpp | 18 +-- extra/yassl/taocrypt/src/aes.cpp | 5 +- extra/yassl/taocrypt/src/algebra.cpp | 9 +- extra/yassl/taocrypt/src/blowfish.cpp | 5 +- extra/yassl/taocrypt/src/coding.cpp | 4 +- extra/yassl/taocrypt/src/integer.cpp | 34 +++--- extra/yassl/taocrypt/src/misc.cpp | 25 +++-- extra/yassl/taocrypt/src/random.cpp | 64 +---------- extra/yassl/taocrypt/src/twofish.cpp | 5 +- extra/yassl/testsuite/test.hpp | 16 +-- 26 files changed, 372 insertions(+), 260 deletions(-) diff --git a/extra/yassl/include/cert_wrapper.hpp b/extra/yassl/include/cert_wrapper.hpp index ce8003aa4cf..d07e5b627b0 100644 --- a/extra/yassl/include/cert_wrapper.hpp +++ b/extra/yassl/include/cert_wrapper.hpp @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005-2007 MySQL AB, 2008 Sun Microsystems, Inc. + Use is subject to license terms. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,6 +35,7 @@ #include "yassl_types.hpp" // SignatureAlgorithm #include "buffer.hpp" // input_buffer #include "asn.hpp" // SignerList +#include "openssl/ssl.h" // internal and external use #include STL_LIST_FILE #include STL_ALGORITHM_FILE @@ -87,6 +89,7 @@ class CertManager { bool verifyNone_; // no error if verify fails bool failNoCert_; bool sendVerify_; + VerifyCallback verifyCallback_; // user verify callback public: CertManager(); ~CertManager(); @@ -118,6 +121,7 @@ public: void setFailNoCert(); void setSendVerify(); void setPeerX509(X509*); + void setVerifyCallback(VerifyCallback); private: CertManager(const CertManager&); // hide copy CertManager& operator=(const CertManager&); // and assign diff --git a/extra/yassl/include/openssl/prefix_ssl.h b/extra/yassl/include/openssl/prefix_ssl.h index 5906ecbbbce..024cb0a9aff 100644 --- a/extra/yassl/include/openssl/prefix_ssl.h +++ b/extra/yassl/include/openssl/prefix_ssl.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2006, 2007 MySQL AB + Copyright (c) 2006, 2007 MySQL AB, 2008 Sun Microsystems, Inc. + Use is subject to license terms. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -70,6 +71,7 @@ #define SSL_load_error_strings yaSSL_load_error_strings #define SSL_set_session yaSSL_set_session #define SSL_get_session yaSSL_get_session +#define SSL_flush_sessions yaSSL_flush_sessions #define SSL_SESSION_set_timeout yaSSL_SESSION_set_timeout #define SSL_CTX_set_session_cache_mode yaSSL_CTX_set_session_cache_mode #define SSL_get_peer_certificate yaSSL_get_peer_certificate diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index c0b87f804ad..ba5fa51f34c 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005-2007 MySQL AB, 2008 Sun Microsystems, Inc. + Use is subject to license terms. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -170,8 +171,9 @@ enum { /* X509 Constants */ X509_V_ERR_CRL_SIGNATURE_FAILURE = 10, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 11, X509_V_ERR_CRL_HAS_EXPIRED = 12, - X509_V_ERR_CERT_REVOKED = 13 - + X509_V_ERR_CERT_REVOKED = 13, + X509_V_FLAG_CRL_CHECK = 14, + X509_V_FLAG_CRL_CHECK_ALL = 15 }; @@ -202,7 +204,8 @@ SSL_CTX* SSL_CTX_new(SSL_METHOD*); SSL* SSL_new(SSL_CTX*); int SSL_set_fd (SSL*, YASSL_SOCKET_T); YASSL_SOCKET_T SSL_get_fd(const SSL*); -int SSL_connect(SSL*); +int SSL_connect(SSL*); /* if you get an error from connect + see note at top of REAMDE */ int SSL_write(SSL*, const void*, int); int SSL_read(SSL*, void*, int); int SSL_accept(SSL*); @@ -227,6 +230,7 @@ void SSL_load_error_strings(void); int SSL_set_session(SSL *ssl, SSL_SESSION *session); SSL_SESSION* SSL_get_session(SSL* ssl); +void SSL_flush_sessions(SSL_CTX *ctx, long tm); long SSL_SESSION_set_timeout(SSL_SESSION*, long); long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode); X509* SSL_get_peer_certificate(SSL*); diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index 63fa9a761ba..87bb4c55e96 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005-2007 MySQL AB, 2010 Sun Microsystems, Inc. + Use is subject to license terms. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -64,7 +65,7 @@ enum YasslError { enum Library { yaSSL_Lib = 0, CryptoLib, SocketLib }; enum { MAX_ERROR_SZ = 80 }; -void SetErrorString(YasslError, char*); +void SetErrorString(unsigned long, char*); /* remove for now, if go back to exceptions use this wrapper // Base class for all yaSSL exceptions diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp index f6434443cb0..04e85c16a04 100644 --- a/extra/yassl/include/yassl_imp.hpp +++ b/extra/yassl/include/yassl_imp.hpp @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005-2007 MySQL AB, 2008 Sun Microsystems, Inc. + Use is subject to license terms. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -667,10 +668,12 @@ struct Parameters { Cipher suites_[MAX_SUITE_SZ]; char cipher_name_[MAX_SUITE_NAME]; char cipher_list_[MAX_CIPHERS][MAX_SUITE_NAME]; + bool removeDH_; // for server's later use Parameters(ConnectionEnd, const Ciphers&, ProtocolVersion, bool haveDH); - void SetSuites(ProtocolVersion pv, bool removeDH = false); + void SetSuites(ProtocolVersion pv, bool removeDH = false, + bool removeRSA = false, bool removeDSA = false); void SetCipherNames(); private: Parameters(const Parameters&); // hide copy diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index b207f0bffbd..433649c545b 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,9 +34,8 @@ #include "openssl/ssl.h" // ASN1_STRING and DH // Check if _POSIX_THREADS should be forced -#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux)) +#if !defined(_POSIX_THREADS) && defined(__hpux) // HPUX does not define _POSIX_THREADS as it's not _fully_ implemented -// Netware supports pthreads but does not announce it #define _POSIX_THREADS #endif @@ -268,12 +267,14 @@ class Sessions { STL::list list_; RandomPool random_; // for session cleaning Mutex mutex_; // no-op for single threaded + int count_; // flush counter - Sessions() {} // only GetSessions can create + Sessions() : count_(0) {} // only GetSessions can create public: SSL_SESSION* lookup(const opaque*, SSL_SESSION* copy = 0); void add(const SSL&); void remove(const opaque*); + void Flush(); ~Sessions(); @@ -425,8 +426,10 @@ private: pem_password_cb passwordCb_; void* userData_; bool sessionCacheOff_; + bool sessionCacheFlushOff_; Stats stats_; Mutex mutex_; // for Stats + VerifyCallback verifyCallback_; public: explicit SSL_CTX(SSL_METHOD* meth); ~SSL_CTX(); @@ -437,18 +440,22 @@ public: const Ciphers& GetCiphers() const; const DH_Parms& GetDH_Parms() const; const Stats& GetStats() const; + VerifyCallback getVerifyCallback() const; pem_password_cb GetPasswordCb() const; void* GetUserData() const; bool GetSessionCacheOff() const; + bool GetSessionCacheFlushOff() const; void setVerifyPeer(); void setVerifyNone(); void setFailNoCert(); + void setVerifyCallback(VerifyCallback); bool SetCipherList(const char*); bool SetDH(const DH&); void SetPasswordCb(pem_password_cb cb); void SetUserData(void*); void SetSessionCacheOff(); + void SetSessionCacheFlushOff(); void IncrementStats(StatsField); void AddCA(x509* ca); diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp index e4b81f98fff..c73a54a7c15 100644 --- a/extra/yassl/include/yassl_types.hpp +++ b/extra/yassl/include/yassl_types.hpp @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005-2007 MySQL AB, 2008 Sun Microsystems, Inc. + Use is subject to license terms. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,6 +30,13 @@ #include "type_traits.hpp" +#ifdef _MSC_VER + // disable conversion warning + // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy + #pragma warning(disable:4244 4996) +#endif + + namespace yaSSL { #define YASSL_LIB @@ -163,7 +171,7 @@ const int RMD_LEN = 20; // RIPEMD-160 digest length const int PREFIX = 3; // up to 3 prefix letters for secret rounds const int KEY_PREFIX = 7; // up to 7 prefix letters for key rounds const int FORTEZZA_MAX = 128; // Maximum Fortezza Key length -const int MAX_SUITE_SZ = 64; // 32 max suites * sizeof(suite) +const int MAX_SUITE_SZ = 128; // 64 max suites * sizeof(suite) const int MAX_SUITE_NAME = 48; // max length of suite name const int MAX_CIPHERS = 32; // max supported ciphers for cipher list const int SIZEOF_ENUM = 1; // SSL considers an enum 1 byte, not 4 @@ -205,6 +213,7 @@ const int SEED_LEN = RAN_LEN * 2; // TLS seed, client + server random const int DEFAULT_TIMEOUT = 500; // Default Session timeout in seconds const int MAX_RECORD_SIZE = 16384; // 2^14, max size by standard const int COMPRESS_EXTRA = 1024; // extra compression possible addition +const int SESSION_FLUSH_COUNT = 256; // when to flush session cache typedef uint8 Cipher; // first byte is always 0x00 for SSLv3 & TLS diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index 12da19962ef..d8660533f2e 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc. + Copyright (c) 2005-2007 MySQL AB, 2008, 2009 Sun Microsystems, Inc. Use is subject to license terms. This program is free software; you can redistribute it and/or modify @@ -25,6 +25,7 @@ #include "runtime.hpp" #include "cert_wrapper.hpp" #include "yassl_int.hpp" +#include "error.hpp" #if defined(USE_CML_LIB) #include "cmapi_cpp.h" @@ -91,7 +92,7 @@ opaque* x509::use_buffer() //CertManager CertManager::CertManager() : peerX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false), - sendVerify_(false) + sendVerify_(false), verifyCallback_(0) {} @@ -155,6 +156,12 @@ void CertManager::setSendVerify() } +void CertManager::setVerifyCallback(VerifyCallback vc) +{ + verifyCallback_ = vc; +} + + void CertManager::AddPeerCert(x509* x) { peerList_.push_back(x); // take ownership @@ -237,7 +244,7 @@ uint CertManager::get_privateKeyLength() const int CertManager::Validate() { CertList::reverse_iterator last = peerList_.rbegin(); - size_t count= peerList_.size(); + size_t count = peerList_.size(); while ( count > 1 ) { TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); @@ -258,7 +265,8 @@ int CertManager::Validate() TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); - if (int err = cert.GetError().What()) + int err = cert.GetError().What(); + if ( err ) return err; uint sz = cert.GetPublicKey().size(); @@ -270,13 +278,25 @@ int CertManager::Validate() else peerKeyType_ = dsa_sa_algo; - size_t iSz= strlen(cert.GetIssuer()) + 1; - size_t sSz= strlen(cert.GetCommonName()) + 1; - size_t bSz= strlen(cert.GetBeforeDate()) + 1; - size_t aSz= strlen(cert.GetAfterDate()) + 1; + size_t iSz = strlen(cert.GetIssuer()) + 1; + size_t sSz = strlen(cert.GetCommonName()) + 1; + int bSz = (int)strlen(cert.GetBeforeDate()) + 1; + int aSz = (int)strlen(cert.GetAfterDate()) + 1; peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(), - sSz, cert.GetBeforeDate(), (int) bSz, - cert.GetAfterDate(), (int) aSz); + sSz, cert.GetBeforeDate(), bSz, + cert.GetAfterDate(), aSz); + + if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) { + X509_STORE_CTX store; + store.error = err; + store.error_depth = static_cast(count) - 1; + store.current_cert = peerX509_; + + int ok = verifyCallback_(0, &store); + if (ok) return 0; + } + + if (err == TaoCrypt::SIG_OTHER_E) return err; } return 0; } diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index 28d7f1b5693..e6168d4d69c 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -953,8 +953,9 @@ x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info) info->set = true; } } - fgets(line,sizeof(line), file); // get blank line - begin = ftell(file); + // get blank line + if (fgets(line, sizeof(line), file)) + begin = ftell(file); } } diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index eee5d47377f..3cf6c14c4b3 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,7 +37,7 @@ #include #endif // _WIN32 -#if defined(__sun) || defined(__SCO_VERSION__) || defined(__NETWARE__) +#if defined(__sun) || defined(__SCO_VERSION__) #include #endif diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index b5fe774fa1a..67d2d428e51 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc. + Copyright (c) 2005-2007 MySQL AB, 2008-2010 Sun Microsystems, Inc. Use is subject to license terms. This program is free software; you can redistribute it and/or modify @@ -246,6 +246,7 @@ YASSL_SOCKET_T SSL_get_fd(const SSL* ssl) } +// if you get an error from connect see note at top of README int SSL_connect(SSL* ssl) { if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ)) @@ -448,6 +449,9 @@ long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode) if (mode == SSL_SESS_CACHE_OFF) ctx->SetSessionCacheOff(); + if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR) + ctx->SetSessionCacheFlushOff(); + return SSL_SUCCESS; } @@ -494,6 +498,15 @@ long SSL_get_default_timeout(SSL* /*ssl*/) } +void SSL_flush_sessions(SSL_CTX *ctx, long /* tm */) +{ + if (ctx->GetSessionCacheOff()) + return; + + GetSessions().Flush(); +} + + const char* SSL_get_cipher_name(SSL* ssl) { return SSL_get_cipher(ssl); @@ -561,7 +574,7 @@ int SSL_get_error(SSL* ssl, int /*previous*/) only need to turn on for client, becuase server on by default if built in but calling for server will tell you whether it's available or not */ -int SSL_set_compression(SSL* ssl) +int SSL_set_compression(SSL* ssl) /* Chad didn't rename to ya~ because it is prob. bug. */ { return ssl->SetCompression(); } @@ -605,13 +618,13 @@ char* X509_NAME_oneline(X509_NAME* name, char* buffer, int sz) { if (!name->GetName()) return buffer; - size_t len= strlen(name->GetName()) + 1; - int copySz = min((int) len, sz); + int len = (int)strlen(name->GetName()) + 1; + int copySz = min(len, sz); if (!buffer) { buffer = (char*)malloc(len); if (!buffer) return buffer; - copySz = (int) len; + copySz = len; } if (copySz == 0) @@ -694,7 +707,7 @@ int SSL_CTX_use_PrivateKey_file(SSL_CTX* ctx, const char* file, int format) } -void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback /*vc*/) +void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc) { if (mode & SSL_VERIFY_PEER) ctx->setVerifyPeer(); @@ -704,6 +717,8 @@ void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback /*vc*/) if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) ctx->setFailNoCert(); + + ctx->setVerifyCallback(vc); } @@ -977,7 +992,7 @@ char* ERR_error_string(unsigned long errNumber, char* buffer) static char* msg = (char*)"Please supply a buffer for error string"; if (buffer) { - SetErrorString(YasslError(errNumber), buffer); + SetErrorString(errNumber, buffer); return buffer; } @@ -1451,6 +1466,8 @@ unsigned long err_helper(bool peek = false) default : return 0; } + + return 0; // shut up compiler } diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index dc120028e13..e167075b984 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,11 @@ #include "openssl/ssl.h" // SSL_ERROR_WANT_READ #include // strncpy +#ifdef _MSC_VER + // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy + #pragma warning(disable: 4996) +#endif + namespace yaSSL { @@ -50,7 +55,7 @@ Library Error::get_lib() const */ -void SetErrorString(YasslError error, char* buffer) +void SetErrorString(unsigned long error, char* buffer) { using namespace TaoCrypt; const int max = MAX_ERROR_SZ; // shorthand @@ -123,7 +128,7 @@ void SetErrorString(YasslError error, char* buffer) break; case badVersion_error : - strncpy(buffer, "protocl version mismatch", max); + strncpy(buffer, "protocol version mismatch", max); break; case compress_error : diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index 2030163d35a..d981605d35a 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -1,6 +1,5 @@ /* - Copyright (c) 2005-2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -137,9 +136,19 @@ void DH_Server::build(SSL& ssl) const CertManager& cert = ssl.getCrypto().get_certManager(); if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) + { + if (cert.get_keyType() != rsa_sa_algo) { + ssl.SetError(privateKey_error); + return; + } auth.reset(NEW_YS RSA(cert.get_privateKey(), cert.get_privateKeyLength(), false)); + } else { + if (cert.get_keyType() != dsa_sa_algo) { + ssl.SetError(privateKey_error); + return; + } auth.reset(NEW_YS DSS(cert.get_privateKey(), cert.get_privateKeyLength(), false)); sigSz += DSS_ENCODED_EXTRA; @@ -437,18 +446,21 @@ Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers, pending_ = true; // suite not set yet strncpy(cipher_name_, "NONE", 5); + removeDH_ = !haveDH; // only use on server side for set suites + if (ciphers.setSuites_) { // use user set list suites_size_ = ciphers.suiteSz_; memcpy(suites_, ciphers.suites_, ciphers.suiteSz_); SetCipherNames(); } else - SetSuites(pv, ce == server_end && !haveDH); // defaults + SetSuites(pv, ce == server_end && removeDH_); // defaults } -void Parameters::SetSuites(ProtocolVersion pv, bool removeDH) +void Parameters::SetSuites(ProtocolVersion pv, bool removeDH, bool removeRSA, + bool removeDSA) { int i = 0; // available suites, best first @@ -457,67 +469,87 @@ void Parameters::SetSuites(ProtocolVersion pv, bool removeDH) if (isTLS(pv)) { if (!removeDH) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA; + if (!removeRSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; + } + if (!removeDSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA; + } + } + if (!removeRSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_RSA_WITH_AES_256_CBC_SHA; } - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_256_CBC_SHA; - if (!removeDH) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA; + if (!removeRSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA; + } + if (!removeDSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA; + } + } + if (!removeRSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_RSA_WITH_AES_128_CBC_SHA; + suites_[i++] = 0x00; + suites_[i++] = TLS_RSA_WITH_AES_256_CBC_RMD160; + suites_[i++] = 0x00; + suites_[i++] = TLS_RSA_WITH_AES_128_CBC_RMD160; + suites_[i++] = 0x00; + suites_[i++] = TLS_RSA_WITH_3DES_EDE_CBC_RMD160; } - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_128_CBC_SHA; - - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_256_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_128_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_3DES_EDE_CBC_RMD160; - if (!removeDH) { + if (!removeRSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_RMD160; + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_RMD160; + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160; + } + if (!removeDSA) { + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_RMD160; + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_RMD160; + suites_[i++] = 0x00; + suites_[i++] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160; + } + } + } + + if (!removeRSA) { suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_RMD160; + suites_[i++] = SSL_RSA_WITH_RC4_128_SHA; suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160; + suites_[i++] = SSL_RSA_WITH_RC4_128_MD5; suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_RMD160; + suites_[i++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA; suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160; - } + suites_[i++] = SSL_RSA_WITH_DES_CBC_SHA; } - - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_RC4_128_SHA; - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_RC4_128_MD5; - - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA; - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_DES_CBC_SHA; - if (!removeDH) { - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA; - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; - - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_RSA_WITH_DES_CBC_SHA; - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_DSS_WITH_DES_CBC_SHA; + if (!removeRSA) { + suites_[i++] = 0x00; + suites_[i++] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA; + } + if (!removeDSA) { + suites_[i++] = 0x00; + suites_[i++] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; + } + if (!removeRSA) { + suites_[i++] = 0x00; + suites_[i++] = SSL_DHE_RSA_WITH_DES_CBC_SHA; + } + if (!removeDSA) { + suites_[i++] = 0x00; + suites_[i++] = SSL_DHE_DSS_WITH_DES_CBC_SHA; + } } suites_size_ = i; @@ -852,21 +884,19 @@ void Alert::Process(input_buffer& input, SSL& ssl) else hmac(ssl, verify, data, aSz, alert, true); - // read mac and fill + // read mac and skip fill int digestSz = ssl.getCrypto().get_digest().get_digestSize(); opaque mac[SHA_LEN]; input.read(mac, digestSz); if (ssl.getSecurity().get_parms().cipher_type_ == block) { int ivExtra = 0; - opaque fill; if (ssl.isTLSv1_1()) ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - aSz - digestSz; - for (int i = 0; i < padSz; i++) - fill = input[AUTO]; + input.set_current(input.get_current() + padSz); } // verify @@ -949,17 +979,17 @@ output_buffer& operator<<(output_buffer& output, const Data& data) void Data::Process(input_buffer& input, SSL& ssl) { int msgSz = ssl.getSecurity().get_parms().encrypt_size_; - int pad = 0, padByte = 0; + int pad = 0, padSz = 0; int ivExtra = 0; if (ssl.getSecurity().get_parms().cipher_type_ == block) { if (ssl.isTLSv1_1()) // IV ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); pad = *(input.get_buffer() + input.get_current() + msgSz -ivExtra - 1); - padByte = 1; + padSz = 1; } int digestSz = ssl.getCrypto().get_digest().get_digestSize(); - int dataSz = msgSz - ivExtra - digestSz - pad - padByte; + int dataSz = msgSz - ivExtra - digestSz - pad - padSz; opaque verify[SHA_LEN]; const byte* rawData = input.get_buffer() + input.get_current(); @@ -988,14 +1018,10 @@ void Data::Process(input_buffer& input, SSL& ssl) hmac(ssl, verify, rawData, dataSz, application_data, true); } - // read mac and fill + // read mac and skip fill opaque mac[SHA_LEN]; - opaque fill; input.read(mac, digestSz); - for (int i = 0; i < pad; i++) - fill = input[AUTO]; - if (padByte) - fill = input[AUTO]; + input.set_current(input.get_current() + pad + padSz); // verify if (dataSz) { @@ -1472,7 +1498,19 @@ void ClientHello::Process(input_buffer&, SSL& ssl) // downgrade to SSLv3 ssl.useSecurity().use_connection().TurnOffTLS(); ProtocolVersion pv = ssl.getSecurity().get_connection().version_; - ssl.useSecurity().use_parms().SetSuites(pv); // reset w/ SSL suites + bool removeDH = ssl.getSecurity().get_parms().removeDH_; + bool removeRSA = false; + bool removeDSA = false; + + const CertManager& cm = ssl.getCrypto().get_certManager(); + if (cm.get_keyType() == rsa_sa_algo) + removeDSA = true; + else + removeRSA = true; + + // reset w/ SSL suites + ssl.useSecurity().use_parms().SetSuites(pv, removeDH, removeRSA, + removeDSA); } else if (ssl.isTLSv1_1() && client_version_.minor_ == 1) // downgrade to TLSv1, but use same suites @@ -1518,6 +1556,7 @@ void ClientHello::Process(input_buffer&, SSL& ssl) return; } ssl.matchSuite(cipher_suites_, suite_len_); + if (ssl.GetError()) return; ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]); if (compression_methods_ == zlib) @@ -2028,11 +2067,9 @@ void Finished::Process(input_buffer& input, SSL& ssl) if (ssl.isTLSv1_1()) ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); - opaque fill; int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - HANDSHAKE_HEADER - finishedSz - digestSz; - for (int i = 0; i < padSz; i++) - fill = input[AUTO]; + input.set_current(input.get_current() + padSz); // verify mac if (memcmp(mac, verifyMAC, digestSz)) { diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 18acf752e98..66a854e6922 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -1,6 +1,5 @@ /* - Copyright (c) 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,28 +40,28 @@ void* operator new(size_t sz, yaSSL::new_t) { - void* ptr = malloc(sz ? sz : 1); - if (!ptr) abort(); + void* ptr = malloc(sz ? sz : 1); + if (!ptr) abort(); - return ptr; + return ptr; } void operator delete(void* ptr, yaSSL::new_t) { - if (ptr) free(ptr); + if (ptr) free(ptr); } void* operator new[](size_t sz, yaSSL::new_t nt) { - return ::operator new(sz, nt); + return ::operator new(sz, nt); } void operator delete[](void* ptr, yaSSL::new_t nt) { - ::operator delete(ptr, nt); + ::operator delete(ptr, nt); } namespace yaSSL { @@ -309,6 +308,20 @@ SSL::SSL(SSL_CTX* ctx) SetError(YasslError(err)); return; } + else if (serverSide && !(ctx->GetCiphers().setSuites_)) { + // remove RSA or DSA suites depending on cert key type + ProtocolVersion pv = secure_.get_connection().version_; + + bool removeDH = secure_.use_parms().removeDH_; + bool removeRSA = false; + bool removeDSA = false; + + if (cm.get_keyType() == rsa_sa_algo) + removeDSA = true; + else + removeRSA = true; + secure_.use_parms().SetSuites(pv, removeDH, removeRSA, removeDSA); + } } else if (serverSide) { SetError(no_key_file); @@ -321,6 +334,7 @@ SSL::SSL(SSL_CTX* ctx) cm.setVerifyNone(); if (ctx->getMethod()->failNoCert()) cm.setFailNoCert(); + cm.setVerifyCallback(ctx->getVerifyCallback()); if (serverSide) crypto_.SetDH(ctx->GetDH_Parms()); @@ -1040,7 +1054,7 @@ void SSL::fillData(Data& data) data.set_length(0); // output, actual data filled dataSz = min(dataSz, bufferedData()); - for (uint i = 0; i < elements; i++) { + for (size_t i = 0; i < elements; i++) { input_buffer* front = buffers_.getData().front(); uint frontSz = front->get_remaining(); uint readSz = min(dataSz - data.get_length(), frontSz); @@ -1064,7 +1078,7 @@ void SSL::fillData(Data& data) void SSL::PeekData(Data& data) { if (GetError()) return; - uint dataSz = data.get_length(); // input, data size to fill + uint dataSz = data.get_length(); // input, data size to fill size_t elements = buffers_.getData().size(); data.set_length(0); // output, actual data filled @@ -1101,7 +1115,7 @@ void SSL::flushBuffer() output_buffer out(sz); size_t elements = buffers_.getHandShake().size(); - for (uint i = 0; i < elements; i++) { + for (size_t i = 0; i < elements; i++) { output_buffer* front = buffers_.getHandShake().front(); out.write(front->get_buffer(), front->get_size()); @@ -1277,6 +1291,7 @@ void SSL::matchSuite(const opaque* peer, uint length) if (secure_.use_parms().suites_[i] == peer[j]) { secure_.use_parms().suite_[0] = 0x00; secure_.use_parms().suite_[1] = peer[j]; + return; } @@ -1285,7 +1300,7 @@ void SSL::matchSuite(const opaque* peer, uint length) void SSL::set_session(SSL_SESSION* s) -{ +{ if (getSecurity().GetContext()->GetSessionCacheOff()) return; @@ -1566,13 +1581,19 @@ Errors& GetErrors() typedef Mutex::Lock Lock; + void Sessions::add(const SSL& ssl) { if (ssl.getSecurity().get_connection().sessionID_Set_) { - Lock guard(mutex_); - list_.push_back(NEW_YS SSL_SESSION(ssl, random_)); + Lock guard(mutex_); + list_.push_back(NEW_YS SSL_SESSION(ssl, random_)); + count_++; } + + if (count_ > SESSION_FLUSH_COUNT) + if (!ssl.getSecurity().GetContext()->GetSessionCacheFlushOff()) + Flush(); } @@ -1661,6 +1682,25 @@ void Sessions::remove(const opaque* id) } +// flush expired sessions from cache +void Sessions::Flush() +{ + Lock guard(mutex_); + sess_iterator next = list_.begin(); + uint current = lowResTimer(); + + while (next != list_.end()) { + sess_iterator si = next; + ++next; + if ( ((*si)->GetBornOn() + (*si)->GetTimeOut()) < current) { + del_ptr_zero()(*si); + list_.erase(si); + } + } + count_ = 0; // reset flush counter +} + + // remove a self thread error void Errors::Remove() { @@ -1765,7 +1805,8 @@ bool SSL_METHOD::multipleProtocol() const SSL_CTX::SSL_CTX(SSL_METHOD* meth) : method_(meth), certificate_(0), privateKey_(0), passwordCb_(0), - userData_(0), sessionCacheOff_(false) + userData_(0), sessionCacheOff_(false), sessionCacheFlushOff_(false), + verifyCallback_(0) {} @@ -1792,6 +1833,12 @@ SSL_CTX::GetCA_List() const } +VerifyCallback SSL_CTX::getVerifyCallback() const +{ + return verifyCallback_; +} + + const x509* SSL_CTX::getCert() const { return certificate_; @@ -1852,6 +1899,12 @@ bool SSL_CTX::GetSessionCacheOff() const } +bool SSL_CTX::GetSessionCacheFlushOff() const +{ + return sessionCacheFlushOff_; +} + + void SSL_CTX::SetUserData(void* data) { userData_ = data; @@ -1864,6 +1917,12 @@ void SSL_CTX::SetSessionCacheOff() } +void SSL_CTX::SetSessionCacheFlushOff() +{ + sessionCacheFlushOff_ = true; +} + + void SSL_CTX::setVerifyPeer() { method_->setVerifyPeer(); @@ -1882,6 +1941,12 @@ void SSL_CTX::setFailNoCert() } +void SSL_CTX::setVerifyCallback(VerifyCallback vc) +{ + verifyCallback_ = vc; +} + + bool SSL_CTX::SetDH(const DH& dh) { dhParms_.p_ = dh.p->int_; @@ -2317,7 +2382,7 @@ X509::X509(const char* i, size_t iSz, const char* s, size_t sSz, : issuer_(i, iSz), subject_(s, sSz), beforeDate_(b, bSz), afterDate_(a, aSz) {} - + X509_NAME* X509::GetIssuer() { @@ -2355,10 +2420,10 @@ ASN1_STRING* X509_NAME::GetEntry(int i) memcpy(entry_.data, &name_[i], sz_ - i); if (entry_.data[sz_ -i - 1]) { entry_.data[sz_ - i] = 0; - entry_.length = (int) (sz_ - i); + entry_.length = int(sz_) - i; } else - entry_.length = (int) (sz_ - i - 1); + entry_.length = int(sz_) - i - 1; entry_.type = 0; return &entry_; diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp index 90d2c014b4c..99d932353df 100644 --- a/extra/yassl/taocrypt/include/blowfish.hpp +++ b/extra/yassl/taocrypt/include/blowfish.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,7 +51,7 @@ public: enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 }; Blowfish(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE), sbox_(pbox_ + ROUNDS + 2) {} #ifdef DO_BLOWFISH_ASM void Process(byte*, const byte*, word32); @@ -62,8 +62,8 @@ private: static const word32 p_init_[ROUNDS + 2]; static const word32 s_init_[4 * 256]; - word32 pbox_[ROUNDS + 2]; - word32 sbox_[4 * 256]; + word32 pbox_[ROUNDS + 2 + 4 * 256]; + word32* sbox_; void crypt_block(const word32 in[2], word32 out[2]) const; void AsmProcess(const byte* in, byte* out) const; diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 96648a39aa1..a375b17eb1e 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -125,7 +125,7 @@ void CleanUp(); // no gas on these systems ?, disable for now -#if defined(__sun__) || defined (__QNX__) || defined (__APPLE__) +#if defined(__sun__) || defined (__APPLE__) #define TAOCRYPT_DISABLE_X86ASM #endif diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp index 99bbe3ac8a3..ad66a5bf9d0 100644 --- a/extra/yassl/taocrypt/include/runtime.hpp +++ b/extra/yassl/taocrypt/include/runtime.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,10 +35,7 @@ // Handler for pure virtual functions namespace __Crun { - static void pure_error(void) - { - assert("Pure virtual method called." == "Aborted"); - } + void pure_error(void); } // namespace __Crun #endif // __sun @@ -54,16 +51,7 @@ extern "C" { #else #include "kernelc.hpp" #endif - -/* Disallow inline __cxa_pure_virtual() */ -static int __cxa_pure_virtual() __attribute__((noinline, used)); -static int __cxa_pure_virtual() -{ - // oops, pure virtual called! - assert("Pure virtual method called." == "Aborted"); - return 0; -} - + int __cxa_pure_virtual () __attribute__ ((weak)); } // extern "C" #endif // __GNUC__ > 2 diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp index b2b42d3dcf0..21b21dc4856 100644 --- a/extra/yassl/taocrypt/src/aes.cpp +++ b/extra/yassl/taocrypt/src/aes.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,7 +51,7 @@ void AES::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -78,6 +78,7 @@ void AES::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_AES_ASM diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index 33a1c5c3945..20a152d1a9d 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -1,6 +1,5 @@ /* - Copyright (c) 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -187,10 +186,10 @@ Integer AbstractGroup::CascadeScalarMultiply(const Element &x, struct WindowSlider { - WindowSlider(const Integer &exp, bool fastNegate, + WindowSlider(const Integer &expIn, bool fastNegateIn, unsigned int windowSizeIn=0) - : exp(exp), windowModulus(Integer::One()), windowSize(windowSizeIn), - windowBegin(0), fastNegate(fastNegate), firstTime(true), + : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), + windowBegin(0), fastNegate(fastNegateIn), firstTime(true), finished(false) { if (windowSize == 0) diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp index 66ff4d829d7..8ee2f3fe569 100644 --- a/extra/yassl/taocrypt/src/blowfish.cpp +++ b/extra/yassl/taocrypt/src/blowfish.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -53,7 +53,7 @@ void Blowfish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -78,6 +78,7 @@ void Blowfish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_BLOWFISH_ASM diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp index 7a9d50aaac9..7c6a6a8bd8b 100644 --- a/extra/yassl/taocrypt/src/coding.cpp +++ b/extra/yassl/taocrypt/src/coding.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -185,7 +185,7 @@ void Base64Decoder::Decode() { word32 bytes = coded_.size(); word32 plainSz = bytes - ((bytes + (pemLineSz - 1)) / pemLineSz); - plainSz = (plainSz * 3 + 3) / 4; + plainSz = ((plainSz * 3) / 4) + 3; decoded_.New(plainSz); word32 i = 0; diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 85733b88aa9..c00815df8cf 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -283,21 +283,23 @@ DWord() {} word GetHighHalfAsBorrow() const {return 0-halfs_.high;} private: + struct dword_struct + { + #ifdef LITTLE_ENDIAN_ORDER + word low; + word high; + #else + word high; + word low; + #endif + }; + union { #ifdef TAOCRYPT_NATIVE_DWORD_AVAILABLE dword whole_; #endif - struct - { - #ifdef LITTLE_ENDIAN_ORDER - word low; - word high; - #else - word high; - word low; - #endif - } halfs_; + struct dword_struct halfs_; }; }; @@ -1214,20 +1216,24 @@ public: #define AS1(x) #x ";" #define AS2(x, y) #x ", " #y ";" #define AddPrologue \ + word res; \ __asm__ __volatile__ \ ( \ "push %%ebx;" /* save this manually, in case of -fPIC */ \ - "mov %2, %%ebx;" \ + "mov %3, %%ebx;" \ ".intel_syntax noprefix;" \ "push ebp;" #define AddEpilogue \ "pop ebp;" \ ".att_syntax prefix;" \ "pop %%ebx;" \ - : \ + "mov %%eax, %0;" \ + : "=g" (res) \ : "c" (C), "d" (A), "m" (B), "S" (N) \ : "%edi", "memory", "cc" \ - ); + ); \ + return res; + #define MulPrologue \ __asm__ __volatile__ \ ( \ diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index 402645c93fd..6045ea3e42b 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -84,12 +84,23 @@ namespace STL = STL_NAMESPACE; } -#if defined(__ICC) || defined(__INTEL_COMPILER) +#ifdef __sun + +// Handler for pure virtual functions +namespace __Crun { + void pure_error() { + assert(!"Aborted: pure virtual method called."); + } +} + +#endif + +#if defined(__ICC) || defined(__INTEL_COMPILER) || (__GNUC__ > 2) extern "C" { int __cxa_pure_virtual() { - assert("Pure virtual method called." == "Aborted"); + assert(!"Aborted: pure virtual method called."); return 0; } @@ -166,14 +177,6 @@ word Crop(word value, unsigned int size) #ifdef TAOCRYPT_X86ASM_AVAILABLE -#ifndef _MSC_VER - static jmp_buf s_env; - static void SigIllHandler(int) - { - longjmp(s_env, 1); - } -#endif - bool HaveCpuId() { diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp index 89fd5f7c7bc..1be0fed612f 100644 --- a/extra/yassl/taocrypt/src/random.cpp +++ b/extra/yassl/taocrypt/src/random.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,7 +27,6 @@ #include #if defined(_WIN32) - #define _WIN32_WINNT 0x0400 #include #include #else @@ -93,67 +92,6 @@ void OS_Seed::GenerateSeed(byte* output, word32 sz) } -#elif defined(__NETWARE__) - -/* The OS_Seed implementation for Netware */ - -#include -#include - -// Loop on high resulution Read Time Stamp Counter -static void NetwareSeed(byte* output, word32 sz) -{ - word32 tscResult; - - for (word32 i = 0; i < sz; i += sizeof(tscResult)) { - #if defined(__GNUC__) - asm volatile("rdtsc" : "=A" (tscResult)); - #else - #ifdef __MWERKS__ - asm { - #else - __asm { - #endif - rdtsc - mov tscResult, eax - } - #endif - - memcpy(output, &tscResult, sizeof(tscResult)); - output += sizeof(tscResult); - - NXThreadYield(); // induce more variance - } -} - - -OS_Seed::OS_Seed() -{ -} - - -OS_Seed::~OS_Seed() -{ -} - - -void OS_Seed::GenerateSeed(byte* output, word32 sz) -{ - /* - Try to use NXSeedRandom as it will generate a strong - seed using the onboard 82802 chip - - As it's not always supported, fallback to default - implementation if an error is returned - */ - - if (NXSeedRandom(sz, output) != 0) - { - NetwareSeed(output, sz); - } -} - - #else /* The default OS_Seed implementation */ diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp index 84dd35f9191..272a0def169 100644 --- a/extra/yassl/taocrypt/src/twofish.cpp +++ b/extra/yassl/taocrypt/src/twofish.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,7 +54,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -82,6 +82,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_TWOFISH_ASM diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index 4555080f84c..e14cdc54ae0 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2006, 2007 MySQL AB + Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -50,8 +50,7 @@ #endif /* _WIN32 */ -#if !defined(_SOCKLEN_T) && \ - (defined(_WIN32) || defined(__NETWARE__) || defined(__APPLE__)) +#if !defined(_SOCKLEN_T) && (defined(_WIN32) || defined(__APPLE__)) typedef int socklen_t; #endif @@ -60,18 +59,14 @@ #if defined(__hpux) // HPUX uses int* for third parameter to accept typedef int* ACCEPT_THIRD_T; -#elif defined(__NETWARE__) -// NetWare uses size_t* for third parameter to accept - typedef size_t* ACCEPT_THIRD_T; #else typedef socklen_t* ACCEPT_THIRD_T; #endif // Check if _POSIX_THREADS should be forced -#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux)) +#if !defined(_POSIX_THREADS) && defined(__hpux) // HPUX does not define _POSIX_THREADS as it's not _fully_ implemented -// Netware supports pthreads but does not announce it #define _POSIX_THREADS #endif @@ -178,6 +173,11 @@ inline void err_sys(const char* msg) } +extern "C" { + static int PasswordCallBack(char*, int, int, void*); +} + + static int PasswordCallBack(char* passwd, int sz, int rw, void* userdata) { strncpy(passwd, "12345678", sz); -- cgit v1.2.1 From c77656dcb357b2e2fea8433ef8063d32699b3033 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 10 Feb 2012 11:35:36 +0200 Subject: Bug#13706621 : UNIFY THE YASSL VERSIONS THAT WE USE BY BACKPORTING 5.1 AND 5.5 YASSL FIXES. Took the 5.5 yassl directory and moved it to the 5.1 tree, while preserving the makefiles. --- extra/yassl/include/cert_wrapper.hpp | 5 ++- extra/yassl/include/openssl/ssl.h | 5 ++- extra/yassl/include/yassl_error.hpp | 5 ++- extra/yassl/include/yassl_imp.hpp | 5 ++- extra/yassl/include/yassl_int.hpp | 11 +++-- extra/yassl/include/yassl_types.hpp | 5 ++- extra/yassl/src/buffer.cpp | 5 ++- extra/yassl/src/cert_wrapper.cpp | 5 ++- extra/yassl/src/crypto_wrapper.cpp | 5 ++- extra/yassl/src/handshake.cpp | 5 ++- extra/yassl/src/socket_wrapper.cpp | 4 +- extra/yassl/src/ssl.cpp | 5 ++- extra/yassl/src/yassl_error.cpp | 5 ++- extra/yassl/src/yassl_imp.cpp | 5 ++- extra/yassl/src/yassl_int.cpp | 5 ++- extra/yassl/taocrypt/include/asn.hpp | 5 ++- extra/yassl/taocrypt/include/block.hpp | 5 ++- extra/yassl/taocrypt/include/blowfish.hpp | 5 ++- extra/yassl/taocrypt/include/misc.hpp | 4 +- extra/yassl/taocrypt/include/modes.hpp | 5 ++- extra/yassl/taocrypt/include/runtime.hpp | 5 ++- extra/yassl/taocrypt/src/aes.cpp | 5 ++- extra/yassl/taocrypt/src/algebra.cpp | 5 ++- extra/yassl/taocrypt/src/asn.cpp | 5 ++- extra/yassl/taocrypt/src/blowfish.cpp | 5 ++- extra/yassl/taocrypt/src/coding.cpp | 5 ++- extra/yassl/taocrypt/src/integer.cpp | 5 ++- extra/yassl/taocrypt/src/misc.cpp | 5 ++- extra/yassl/taocrypt/src/random.cpp | 69 ++----------------------------- extra/yassl/taocrypt/src/twofish.cpp | 5 ++- extra/yassl/testsuite/test.hpp | 9 +--- 31 files changed, 93 insertions(+), 134 deletions(-) diff --git a/extra/yassl/include/cert_wrapper.hpp b/extra/yassl/include/cert_wrapper.hpp index 755a3925c8e..d07e5b627b0 100644 --- a/extra/yassl/include/cert_wrapper.hpp +++ b/extra/yassl/include/cert_wrapper.hpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 9ffd4c0328e..ba5fa51f34c 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* ssl.h defines openssl compatibility layer diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index d9bbbc2dc69..87bb4c55e96 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp index ee29d89332a..04e85c16a04 100644 --- a/extra/yassl/include/yassl_imp.hpp +++ b/extra/yassl/include/yassl_imp.hpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* yaSSL implementation header defines all strucutres from the SSL.v3 diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index adb9f5ea67a..433649c545b 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -1,6 +1,5 @@ /* - Copyright (c) 2005-2007 MySQL AB, 2008, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ @@ -34,9 +34,8 @@ #include "openssl/ssl.h" // ASN1_STRING and DH // Check if _POSIX_THREADS should be forced -#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux)) +#if !defined(_POSIX_THREADS) && defined(__hpux) // HPUX does not define _POSIX_THREADS as it's not _fully_ implemented -// Netware supports pthreads but does not announce it #define _POSIX_THREADS #endif diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp index e898befda3a..c73a54a7c15 100644 --- a/extra/yassl/include/yassl_types.hpp +++ b/extra/yassl/include/yassl_types.hpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* yaSSL types header defines all constants, enums, and typedefs diff --git a/extra/yassl/src/buffer.cpp b/extra/yassl/src/buffer.cpp index a774cf4a26a..86c1bcf3388 100644 --- a/extra/yassl/src/buffer.cpp +++ b/extra/yassl/src/buffer.cpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index 308ca70c748..d8660533f2e 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index 8d596b84200..e6168d4d69c 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* The crypto wrapper source implements the policies for the cipher diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 1059df1d63e..08fae4ac17d 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index eee5d47377f..3cf6c14c4b3 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,7 +37,7 @@ #include #endif // _WIN32 -#if defined(__sun) || defined(__SCO_VERSION__) || defined(__NETWARE__) +#if defined(__sun) || defined(__SCO_VERSION__) #include #endif diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 9d1cc9407ea..67d2d428e51 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* SSL source implements all openssl compatibility API functions diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index f4862fe0a7c..e167075b984 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index a152ebb2e19..d981605d35a 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* yaSSL source implements all SSL.v3 secification structures. diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 7fea438622d..66a854e6922 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp index 986686c93d2..ece7140741a 100644 --- a/extra/yassl/taocrypt/include/asn.hpp +++ b/extra/yassl/taocrypt/include/asn.hpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* asn.hpp provides ASN1 BER, PublicKey, and x509v3 decoding diff --git a/extra/yassl/taocrypt/include/block.hpp b/extra/yassl/taocrypt/include/block.hpp index 6263cfeb80d..ad3dcf2db59 100644 --- a/extra/yassl/taocrypt/include/block.hpp +++ b/extra/yassl/taocrypt/include/block.hpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp index 1ca7588cc44..99d932353df 100644 --- a/extra/yassl/taocrypt/include/blowfish.hpp +++ b/extra/yassl/taocrypt/include/blowfish.hpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* blowfish.hpp defines Blowfish diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 96648a39aa1..a375b17eb1e 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -125,7 +125,7 @@ void CleanUp(); // no gas on these systems ?, disable for now -#if defined(__sun__) || defined (__QNX__) || defined (__APPLE__) +#if defined(__sun__) || defined (__APPLE__) #define TAOCRYPT_DISABLE_X86ASM #endif diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp index 6c04c4e4457..2285bd0e845 100644 --- a/extra/yassl/taocrypt/include/modes.hpp +++ b/extra/yassl/taocrypt/include/modes.hpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* modes.hpp provides ECB and CBC modes for block cipher encryption/decryption diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp index 3b62ead22fd..ad66a5bf9d0 100644 --- a/extra/yassl/taocrypt/include/runtime.hpp +++ b/extra/yassl/taocrypt/include/runtime.hpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* runtime.hpp provides C++ runtime support functions when building a pure C diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp index ea4a68fc19a..21b21dc4856 100644 --- a/extra/yassl/taocrypt/src/aes.cpp +++ b/extra/yassl/taocrypt/src/aes.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* C++ based on Wei Dai's aes.cpp from CryptoPP */ diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index 31f09d9d683..20a152d1a9d 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* based on Wei Dai's algebra.cpp from CryptoPP */ diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index c7afb682c75..1b81db4f0a4 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -12,8 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* asn.cpp implements ASN1 BER, PublicKey, and x509v3 decoding diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp index 85af10beac5..8ee2f3fe569 100644 --- a/extra/yassl/taocrypt/src/blowfish.cpp +++ b/extra/yassl/taocrypt/src/blowfish.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* C++ code based on Wei Dai's blowfish.cpp from CryptoPP */ diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp index 9481497dc4d..7c6a6a8bd8b 100644 --- a/extra/yassl/taocrypt/src/coding.cpp +++ b/extra/yassl/taocrypt/src/coding.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* coding.cpp implements hex and base64 encoding/decoing diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index f59b768c9ff..c00815df8cf 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index 6e9b101bf0f..6045ea3e42b 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* based on Wei Dai's misc.cpp from CryptoPP */ diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp index 2a2ac83ca34..1be0fed612f 100644 --- a/extra/yassl/taocrypt/src/random.cpp +++ b/extra/yassl/taocrypt/src/random.cpp @@ -1,6 +1,5 @@ /* - Copyright (c) 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ @@ -92,67 +92,6 @@ void OS_Seed::GenerateSeed(byte* output, word32 sz) } -#elif defined(__NETWARE__) - -/* The OS_Seed implementation for Netware */ - -#include -#include - -// Loop on high resulution Read Time Stamp Counter -static void NetwareSeed(byte* output, word32 sz) -{ - word32 tscResult; - - for (word32 i = 0; i < sz; i += sizeof(tscResult)) { - #if defined(__GNUC__) - asm volatile("rdtsc" : "=A" (tscResult)); - #else - #ifdef __MWERKS__ - asm { - #else - __asm { - #endif - rdtsc - mov tscResult, eax - } - #endif - - memcpy(output, &tscResult, sizeof(tscResult)); - output += sizeof(tscResult); - - NXThreadYield(); // induce more variance - } -} - - -OS_Seed::OS_Seed() -{ -} - - -OS_Seed::~OS_Seed() -{ -} - - -void OS_Seed::GenerateSeed(byte* output, word32 sz) -{ - /* - Try to use NXSeedRandom as it will generate a strong - seed using the onboard 82802 chip - - As it's not always supported, fallback to default - implementation if an error is returned - */ - - if (NXSeedRandom(sz, output) != 0) - { - NetwareSeed(output, sz); - } -} - - #else /* The default OS_Seed implementation */ diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp index e33abd41ea5..272a0def169 100644 --- a/extra/yassl/taocrypt/src/twofish.cpp +++ b/extra/yassl/taocrypt/src/twofish.cpp @@ -11,8 +11,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. */ /* C++ based on Wei Dai's twofish.cpp from CryptoPP */ diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index 8107090842b..e14cdc54ae0 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -50,8 +50,7 @@ #endif /* _WIN32 */ -#if !defined(_SOCKLEN_T) && \ - (defined(_WIN32) || defined(__NETWARE__) || defined(__APPLE__)) +#if !defined(_SOCKLEN_T) && (defined(_WIN32) || defined(__APPLE__)) typedef int socklen_t; #endif @@ -60,18 +59,14 @@ #if defined(__hpux) // HPUX uses int* for third parameter to accept typedef int* ACCEPT_THIRD_T; -#elif defined(__NETWARE__) -// NetWare uses size_t* for third parameter to accept - typedef size_t* ACCEPT_THIRD_T; #else typedef socklen_t* ACCEPT_THIRD_T; #endif // Check if _POSIX_THREADS should be forced -#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux)) +#if !defined(_POSIX_THREADS) && defined(__hpux) // HPUX does not define _POSIX_THREADS as it's not _fully_ implemented -// Netware supports pthreads but does not announce it #define _POSIX_THREADS #endif -- cgit v1.2.1 From 937302d6a887523c56331a7c05e68b71cf9abb7b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 10 Feb 2012 16:33:27 +0200 Subject: Bug #13706828: UPGRADE YASSL FROM 1.7.2 TO 2.1.4 $SUBJ$ 1. Took a diff between the previous base version and the mysql sources. 2. Added the new 2.1.4 base version. 3. Reviewed and re-applied the diff from step #1. --- extra/yassl/CMakeLists.txt | 0 extra/yassl/INSTALL | 103 ++++---- extra/yassl/README | 122 +++++++++- extra/yassl/certs/ca-cert.pem | 71 +++--- extra/yassl/certs/ca-key.pem | 9 + extra/yassl/certs/client-cert.der | Bin 699 -> 782 bytes extra/yassl/certs/client-cert.pem | 69 +++--- extra/yassl/certs/client-key.der | Bin 318 -> 319 bytes extra/yassl/certs/client-key.pem | 14 +- extra/yassl/certs/client-keyEnc.pem | 12 + extra/yassl/certs/client-keyEnc3.pem | 12 + extra/yassl/certs/dsa-cert.pem | 58 ++--- extra/yassl/certs/dsa512.der | Bin 250 -> 249 bytes extra/yassl/certs/server-cert.pem | 49 ++-- extra/yassl/certs/server-key.pem | 14 +- extra/yassl/certs/server-keyEnc.pem | 12 + extra/yassl/certs/taoCert.txt | 12 + extra/yassl/examples/client/client.cpp | 22 +- extra/yassl/examples/echoclient/echoclient.cpp | 6 +- extra/yassl/examples/echoserver/echoserver.cpp | 12 +- extra/yassl/examples/server/server.cpp | 17 +- extra/yassl/include/buffer.hpp | 10 +- extra/yassl/include/openssl/ssl.h | 49 ++-- extra/yassl/include/socket_wrapper.hpp | 4 +- extra/yassl/include/yassl_int.hpp | 62 ++--- extra/yassl/include/yassl_types.hpp | 30 ++- extra/yassl/src/buffer.cpp | 12 - extra/yassl/src/cert_wrapper.cpp | 6 +- extra/yassl/src/crypto_wrapper.cpp | 2 +- extra/yassl/src/handshake.cpp | 47 ++-- extra/yassl/src/make.bat | 0 extra/yassl/src/socket_wrapper.cpp | 23 +- extra/yassl/src/ssl.cpp | 123 ++++++---- extra/yassl/src/yassl.cpp | 6 +- extra/yassl/src/yassl_error.cpp | 16 +- extra/yassl/src/yassl_imp.cpp | 41 ++-- extra/yassl/src/yassl_int.cpp | 51 +++- extra/yassl/taocrypt/README | 2 +- extra/yassl/taocrypt/benchmark/benchmark.cpp | 18 +- extra/yassl/taocrypt/benchmark/benchmark.dsp | 10 +- extra/yassl/taocrypt/benchmark/dh1024.der | Bin 140 -> 138 bytes extra/yassl/taocrypt/benchmark/dsa1024.der | Bin 448 -> 445 bytes extra/yassl/taocrypt/benchmark/make.bat | 0 extra/yassl/taocrypt/benchmark/rsa1024.der | Bin 610 -> 606 bytes extra/yassl/taocrypt/certs/client-cert.der | Bin 0 -> 782 bytes extra/yassl/taocrypt/certs/client-key.der | Bin 0 -> 319 bytes extra/yassl/taocrypt/certs/dh1024.dat | 1 + extra/yassl/taocrypt/certs/dsa512.der | Bin 0 -> 249 bytes extra/yassl/taocrypt/include/asn.hpp | 1 + extra/yassl/taocrypt/include/block.hpp | 12 +- extra/yassl/taocrypt/include/blowfish.hpp | 8 +- extra/yassl/taocrypt/include/des.hpp | 2 +- extra/yassl/taocrypt/include/hash.hpp | 4 +- extra/yassl/taocrypt/include/hc128.hpp | 63 +++++ extra/yassl/taocrypt/include/integer.hpp | 7 - extra/yassl/taocrypt/include/kernelc.hpp | 12 - extra/yassl/taocrypt/include/misc.hpp | 45 ++-- extra/yassl/taocrypt/include/modes.hpp | 7 +- extra/yassl/taocrypt/include/pwdbased.hpp | 5 +- extra/yassl/taocrypt/include/rabbit.hpp | 65 +++++ extra/yassl/taocrypt/include/rsa.hpp | 4 +- extra/yassl/taocrypt/include/runtime.hpp | 5 +- extra/yassl/taocrypt/include/types.hpp | 2 +- extra/yassl/taocrypt/mySTL/stdexcept.hpp | 3 +- extra/yassl/taocrypt/mySTL/vector.hpp | 7 +- extra/yassl/taocrypt/src/Makefile.am | 2 +- extra/yassl/taocrypt/src/aes.cpp | 39 +-- extra/yassl/taocrypt/src/aestables.cpp | 2 - extra/yassl/taocrypt/src/algebra.cpp | 3 +- extra/yassl/taocrypt/src/arc4.cpp | 2 +- extra/yassl/taocrypt/src/asn.cpp | 196 +++++++++------ extra/yassl/taocrypt/src/blowfish.cpp | 36 ++- extra/yassl/taocrypt/src/coding.cpp | 16 +- extra/yassl/taocrypt/src/dsa.cpp | 3 +- extra/yassl/taocrypt/src/hash.cpp | 17 +- extra/yassl/taocrypt/src/hc128.cpp | 317 +++++++++++++++++++++++++ extra/yassl/taocrypt/src/integer.cpp | 95 ++------ extra/yassl/taocrypt/src/make.bat | 0 extra/yassl/taocrypt/src/md4.cpp | 2 +- extra/yassl/taocrypt/src/md5.cpp | 18 +- extra/yassl/taocrypt/src/misc.cpp | 22 +- extra/yassl/taocrypt/src/rabbit.cpp | 250 +++++++++++++++++++ extra/yassl/taocrypt/src/random.cpp | 6 +- extra/yassl/taocrypt/src/ripemd.cpp | 16 +- extra/yassl/taocrypt/src/rsa.cpp | 7 +- extra/yassl/taocrypt/src/sha.cpp | 16 +- extra/yassl/taocrypt/src/template_instnt.cpp | 1 - extra/yassl/taocrypt/src/twofish.cpp | 2 - extra/yassl/taocrypt/taocrypt.dsp | 16 ++ extra/yassl/taocrypt/test/make.bat | 0 extra/yassl/taocrypt/test/memory.cpp | 29 +++ extra/yassl/taocrypt/test/test.cpp | 158 ++++++++++-- extra/yassl/testsuite/make.bat | 0 extra/yassl/testsuite/test.hpp | 95 ++++++-- extra/yassl/testsuite/testsuite.cpp | 8 +- 95 files changed, 1956 insertions(+), 797 deletions(-) mode change 100755 => 100644 extra/yassl/CMakeLists.txt create mode 100644 extra/yassl/certs/ca-key.pem create mode 100644 extra/yassl/certs/client-keyEnc.pem create mode 100644 extra/yassl/certs/client-keyEnc3.pem create mode 100644 extra/yassl/certs/server-keyEnc.pem mode change 100644 => 100755 extra/yassl/src/make.bat mode change 100644 => 100755 extra/yassl/taocrypt/benchmark/make.bat create mode 100644 extra/yassl/taocrypt/certs/client-cert.der create mode 100644 extra/yassl/taocrypt/certs/client-key.der create mode 100644 extra/yassl/taocrypt/certs/dh1024.dat create mode 100644 extra/yassl/taocrypt/certs/dsa512.der create mode 100644 extra/yassl/taocrypt/include/hc128.hpp create mode 100644 extra/yassl/taocrypt/include/rabbit.hpp create mode 100644 extra/yassl/taocrypt/src/hc128.cpp mode change 100644 => 100755 extra/yassl/taocrypt/src/make.bat create mode 100644 extra/yassl/taocrypt/src/rabbit.cpp mode change 100644 => 100755 extra/yassl/taocrypt/test/make.bat mode change 100644 => 100755 extra/yassl/testsuite/make.bat diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/extra/yassl/INSTALL b/extra/yassl/INSTALL index 54caf7c190f..5458714e1e2 100644 --- a/extra/yassl/INSTALL +++ b/extra/yassl/INSTALL @@ -1,13 +1,19 @@ -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software -Foundation, Inc. +Installation Instructions +************************* - This file is free documentation; the Free Software Foundation gives +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006 Free Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== - These are generic installation instructions. +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -20,9 +26,9 @@ debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is +the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale -cache files.) +cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail @@ -32,20 +38,17 @@ some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. + `./configure' to configure the package for your system. - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. 2. Type `make' to compile the package. @@ -67,51 +70,49 @@ The simplest way to compile this package is: Compilers and Options ===================== - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== - You can compile the package for more than one kind of computer at the +You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the +own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. Installation Names ================== - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular +options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. @@ -122,7 +123,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= - Some packages pay attention to `--enable-FEATURE' options to +Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The @@ -137,11 +138,11 @@ you can use the `configure' options `--x-includes=DIR' and Specifying the System Type ========================== - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: @@ -156,7 +157,7 @@ where SYSTEM can have one of these forms: need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will +use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a @@ -167,9 +168,9 @@ eventually be run) with `--host=TYPE'. Sharing Defaults ================ - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. @@ -178,7 +179,7 @@ A warning: not all `configure' scripts look for a site script. Defining Variables ================== - Variables not defined in a site shell script can be set in the +Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set @@ -186,14 +187,18 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -will cause the specified gcc to be used as the C compiler (unless it is +causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + `configure' Invocation ====================== - `configure' recognizes the following options to control how it -operates. +`configure' recognizes the following options to control how it operates. `--help' `-h' diff --git a/extra/yassl/README b/extra/yassl/README index 6c4d101efc0..0ca656bb932 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -1,3 +1,121 @@ +*** Note, Please read *** + +yaSSL takes a different approach to certificate verification than OpenSSL does. +The default policy for the client is to verify the server, this means that if +you don't load CAs to verify the server you'll get a connect error, unable to +verify. It you want to mimic OpenSSL behavior of not verifying the server and +reducing security you can do this by calling: + +SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); + +before calling SSL_new(); + +*** end Note *** + +yaSSL Release notes, version 2.1.2 (9/2/2011) + + This release of yaSSL contains bug fixes, better non-blocking support with + SSL_write, and OpenSSL RSA public key format support. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.9.9 (1/26/2010) +yaSSL Release notes, version 2.0.0 (7/6/2010) + + This release of yaSSL contains bug fixes, new testing certs, + and a security patch for a potential heap overflow on forged application + data processing. Vulnerability discovered by Matthieu Bonetti from VUPEN + Security http://www.vupen.com. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.9.9 (1/26/2010) + + This release of yaSSL contains bug fixes, the removal of assert() s and + a security patch for a buffer overflow possibility in certificate name + processing. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.9.8 (10/14/09) + + This release of yaSSL contains bug fixes and adds new stream ciphers + Rabbit and HC-128 + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.9.6 (11/13/08) + + This release of yaSSL contains bug fixes, adds autconf shared library + support and has better server suite detection based on certficate and + private key. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.9.2 (9/24/08) + + This release of yaSSL contains bug fixes and improved certificate verify + callback support. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.8.8 (5/7/08) + + This release of yaSSL contains bug fixes, and better socket handling. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.8.6 (1/31/08) + + This release of yaSSL contains bug fixes, and fixes security problems + associated with using SSL 2.0 client hellos and improper input handling. + Please upgrade to this version if you are using a previous one. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.7.5 (10/15/07) + + This release of yaSSL contains bug fixes, adds MSVC 2005 project support, + GCC 4.2 support, IPV6 support and test, and new test certificates. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.7.2 (8/20/07) + + This release of yaSSL contains bug fixes and adds initial OpenVPN support. + Just configure at this point and beginning of build. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 1.6.8 (4/16/07) + + This release of yaSSL contains bug fixes and adds SHA-256, SHA-512, SHA-224, + and SHA-384. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + *****************yaSSL Release notes, version 1.6.0 (2/22/07) This release of yaSSL contains bug fixes, portability enhancements, and @@ -13,7 +131,7 @@ See libcurl build instructions below under 1.3.0 and note in 1.5.8. - Since yaSSL now supports zlib, as does libcur, the libcurl build test can + Since yaSSL now supports zlib, as does libcurl, the libcurl build test can fail if yaSSL is built with zlib support since the zlib library isn't passed. You can do two things to fix this: @@ -518,7 +636,7 @@ in the source and include files. ********************* Contact: please send comments or questions to Todd A Ouska at todd@yassl.com -and/or Larry Stefonic at larry@yassl.com or 425-741-6858. +and/or Larry Stefonic at larry@yassl.com. diff --git a/extra/yassl/certs/ca-cert.pem b/extra/yassl/certs/ca-cert.pem index e353d118712..6a0cf898e53 100644 --- a/extra/yassl/certs/ca-cert.pem +++ b/extra/yassl/certs/ca-cert.pem @@ -1,53 +1,56 @@ Certificate: Data: Version: 3 (0x2) - Serial Number: 0 (0x0) + Serial Number: + 8a:37:22:65:73:f5:aa:e8 Signature Algorithm: md5WithRSAEncryption - Issuer: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + Issuer: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com Validity - Not Before: Mar 7 03:10:11 2005 GMT - Not After : Apr 1 03:10:11 2046 GMT - Subject: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + Not Before: Jun 30 18:47:10 2010 GMT + Not After : Mar 26 18:47:10 2013 GMT + Subject: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): - 00:ef:c1:e3:9a:3c:6e:6e:cb:26:6f:05:be:e0:cb: - 57:a0:4b:68:e6:1b:f9:95:db:01:92:aa:6e:a6:b5: - 2d:b1:2b:50:fd:db:13:f2:c5:d8:b8:4f:75:28:53: - 72:e8:e5:11:9d:bb:c3:4f:4f:09:fd:4c:e7:46:d5: - 1d:bb:35:02:af + 00:97:30:b9:1a:92:ef:25:4f:ca:4c:11:31:95:1a: + e1:c0:10:19:0a:20:b9:37:80:1a:57:38:02:4e:1b: + c5:0f:28:4f:da:e3:c9:16:aa:50:bd:4a:fb:b7:71: + c7:35:cc:63:81:c1:dd:9d:33:f9:38:16:88:32:a0: + aa:56:23:03:a3 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - 1D:EF:A1:B8:81:78:12:47:E8:57:06:08:74:18:F7:D3:AA:D8:F7:BD + 3B:66:FD:A0:40:C6:F4:E2:70:CF:21:1A:0C:4F:67:FE:B7:4B:42:09 X509v3 Authority Key Identifier: - keyid:1D:EF:A1:B8:81:78:12:47:E8:57:06:08:74:18:F7:D3:AA:D8:F7:BD - DirName:/C=US/ST=Oregon/L=Portland/O=sawtooth/CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com - serial:00 + keyid:3B:66:FD:A0:40:C6:F4:E2:70:CF:21:1A:0C:4F:67:FE:B7:4B:42:09 + DirName:/C=US/ST=Montana/L=Bozeman/O=sawtooth/OU=consulting/CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + serial:8A:37:22:65:73:F5:AA:E8 X509v3 Basic Constraints: CA:TRUE Signature Algorithm: md5WithRSAEncryption - d9:77:e3:07:d9:2e:ec:2f:9b:8e:9e:ca:b4:00:0b:ef:c7:74: - cb:f4:f6:44:2f:02:75:17:a5:74:3e:26:b2:26:fd:1f:ab:3a: - df:d5:e3:05:14:08:d0:8c:1d:c9:3e:e1:59:6f:b3:38:5d:af: - 78:60:e3:c5:6a:69:96:80:7d:00 + 32:65:a2:b1:dc:6d:e0:8d:8b:c8:58:29:8e:b8:18:4b:62:88: + 13:67:f8:6c:75:46:75:8f:8a:19:a6:a3:d5:3c:fc:57:4e:7a: + 68:a9:fc:93:dc:ae:29:7d:bb:4e:ec:ea:55:fa:a4:e3:00:61: + f4:b0:34:6d:d1:d5:a4:64:24:f8 -----BEGIN CERTIFICATE----- -MIIC7zCCApmgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBiTELMAkGA1UEBhMCVVMx -DzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxhbmQxETAPBgNVBAoTCHNh -d3Rvb3RoMSQwIgYDVQQDExt3d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAb -BgkqhkiG9w0BCQEWDmluZm9AeWFzc2wuY29tMB4XDTA1MDMwNzAzMTAxMVoXDTQ2 -MDQwMTAzMTAxMVowgYkxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIEwZPcmVnb24xETAP -BgNVBAcTCFBvcnRsYW5kMREwDwYDVQQKEwhzYXd0b290aDEkMCIGA1UEAxMbd3d3 -LnNhd3Rvb3RoLWNvbnN1bHRpbmcuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlh -c3NsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDvweOaPG5uyyZvBb7gy1eg -S2jmG/mV2wGSqm6mtS2xK1D92xPyxdi4T3UoU3Lo5RGdu8NPTwn9TOdG1R27NQKv -AgMBAAGjgekwgeYwHQYDVR0OBBYEFB3vobiBeBJH6FcGCHQY99Oq2Pe9MIG2BgNV -HSMEga4wgauAFB3vobiBeBJH6FcGCHQY99Oq2Pe9oYGPpIGMMIGJMQswCQYDVQQG -EwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDERMA8GA1UE -ChMIc2F3dG9vdGgxJDAiBgNVBAMTG3d3dy5zYXd0b290aC1jb25zdWx0aW5nLmNv -bTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb22CAQAwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQQFAANBANl34wfZLuwvm46eyrQAC+/HdMv09kQvAnUXpXQ+ -JrIm/R+rOt/V4wUUCNCMHck+4Vlvszhdr3hg48VqaZaAfQA= +MIIDQDCCAuqgAwIBAgIJAIo3ImVz9aroMA0GCSqGSIb3DQEBBAUAMIGeMQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHTW9udGFuYTEQMA4GA1UEBxMHQm96ZW1hbjERMA8G +A1UEChMIc2F3dG9vdGgxEzARBgNVBAsTCmNvbnN1bHRpbmcxJDAiBgNVBAMTG3d3 +dy5zYXd0b290aC1jb25zdWx0aW5nLmNvbTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5 +YXNzbC5jb20wHhcNMTAwNjMwMTg0NzEwWhcNMTMwMzI2MTg0NzEwWjCBnjELMAkG +A1UEBhMCVVMxEDAOBgNVBAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAP +BgNVBAoTCHNhd3Rvb3RoMRMwEQYDVQQLEwpjb25zdWx0aW5nMSQwIgYDVQQDExt3 +d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A +eWFzc2wuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJcwuRqS7yVPykwRMZUa +4cAQGQoguTeAGlc4Ak4bxQ8oT9rjyRaqUL1K+7dxxzXMY4HB3Z0z+TgWiDKgqlYj +A6MCAwEAAaOCAQcwggEDMB0GA1UdDgQWBBQ7Zv2gQMb04nDPIRoMT2f+t0tCCTCB +0wYDVR0jBIHLMIHIgBQ7Zv2gQMb04nDPIRoMT2f+t0tCCaGBpKSBoTCBnjELMAkG +A1UEBhMCVVMxEDAOBgNVBAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAP +BgNVBAoTCHNhd3Rvb3RoMRMwEQYDVQQLEwpjb25zdWx0aW5nMSQwIgYDVQQDExt3 +d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A +eWFzc2wuY29tggkAijciZXP1qugwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQF +AANBADJlorHcbeCNi8hYKY64GEtiiBNn+Gx1RnWPihmmo9U8/FdOemip/JPcril9 +u07s6lX6pOMAYfSwNG3R1aRkJPg= -----END CERTIFICATE----- diff --git a/extra/yassl/certs/ca-key.pem b/extra/yassl/certs/ca-key.pem new file mode 100644 index 00000000000..45d7b149857 --- /dev/null +++ b/extra/yassl/certs/ca-key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOQIBAAJBAJcwuRqS7yVPykwRMZUa4cAQGQoguTeAGlc4Ak4bxQ8oT9rjyRaq +UL1K+7dxxzXMY4HB3Z0z+TgWiDKgqlYjA6MCAwEAAQJAEQ9TY7c+uuQU/J5YDO4a +mRR37tegbq3Kyxqrz+p8QuhqLDtVh13GaF7rVU70vyNHm+cgihUyzho/PViAkPBo +qQIhAMU8/RDhDLgL5BxID4sxKIVBtg+imFSbyKVyg7oQLUcXAiEAxDu94O45Cf4a +np9R0thumY/QqWpCkycWAB7fFEuaf1UCIEH+bg4/vqm2ENUFp23DPPOZUPlaRe3J +UhFJh5mx3/RxAiBq++8vfHFYg1Lb/BxOCXVy/zdRxf753ytdcXdJx1Y56QIgVgpN +FNfYJofQfWaP96sjlc0usrT28uceHx0QmHqolVc= +-----END RSA PRIVATE KEY----- diff --git a/extra/yassl/certs/client-cert.der b/extra/yassl/certs/client-cert.der index c2a75119e54..9c2ef138bf6 100644 Binary files a/extra/yassl/certs/client-cert.der and b/extra/yassl/certs/client-cert.der differ diff --git a/extra/yassl/certs/client-cert.pem b/extra/yassl/certs/client-cert.pem index 4d2bbff7ca5..7acc9a850d5 100644 --- a/extra/yassl/certs/client-cert.pem +++ b/extra/yassl/certs/client-cert.pem @@ -1,52 +1,55 @@ Certificate: Data: Version: 3 (0x2) - Serial Number: 0 (0x0) + Serial Number: + c5:d7:6c:11:36:f0:35:e1 Signature Algorithm: md5WithRSAEncryption - Issuer: C=US, ST=Oregon, L=Portland, O=yaSSL, CN=www.yassl.com/emailAddress=info@yassl.com + Issuer: C=US, ST=Oregon, L=Portland, O=yaSSL, OU=programming, CN=www.yassl.com/emailAddress=info@yassl.com Validity - Not Before: Mar 7 03:00:31 2005 GMT - Not After : Apr 1 03:00:31 2046 GMT - Subject: C=US, ST=Oregon, L=Portland, O=yaSSL, CN=www.yassl.com/emailAddress=info@yassl.com + Not Before: Jun 30 18:39:39 2010 GMT + Not After : Mar 26 18:39:40 2013 GMT + Subject: C=US, ST=Oregon, L=Portland, O=yaSSL, OU=programming, CN=www.yassl.com/emailAddress=info@yassl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): - 00:cd:1f:78:47:f8:b8:d6:08:bf:bd:7c:23:61:86: - 36:28:ac:ee:3c:a8:9a:94:e6:d5:26:e8:71:50:b2: - 26:8b:1c:1e:3f:75:b2:d3:b3:67:95:0c:fd:76:28: - 65:d5:ce:12:82:9e:06:00:a2:09:dd:ce:3a:26:dd: - 46:2a:a0:45:71 + 00:bd:51:4a:14:fd:6a:19:84:0c:33:38:fc:27:32: + 9c:97:0b:fc:a4:18:60:69:4e:d9:d8:78:50:0b:e9: + 20:5d:d6:1d:70:1c:0c:24:9f:23:82:cc:3a:01:d5: + 97:17:b2:73:6c:86:cf:b5:f1:e5:ce:68:0c:d9:a2: + 12:39:7c:f2:53 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - AE:25:5E:FA:4D:A3:5B:2B:87:DE:F1:2A:F5:42:C0:FF:CE:B5:B4:AD + 5C:F7:29:21:69:7A:09:78:9E:7B:CD:53:42:02:EC:CE:29:0D:11:DF X509v3 Authority Key Identifier: - keyid:AE:25:5E:FA:4D:A3:5B:2B:87:DE:F1:2A:F5:42:C0:FF:CE:B5:B4:AD - DirName:/C=US/ST=Oregon/L=Portland/O=yaSSL/CN=www.yassl.com/emailAddress=info@yassl.com - serial:00 + keyid:5C:F7:29:21:69:7A:09:78:9E:7B:CD:53:42:02:EC:CE:29:0D:11:DF + DirName:/C=US/ST=Oregon/L=Portland/O=yaSSL/OU=programming/CN=www.yassl.com/emailAddress=info@yassl.com + serial:C5:D7:6C:11:36:F0:35:E1 X509v3 Basic Constraints: CA:TRUE Signature Algorithm: md5WithRSAEncryption - 59:19:ae:1b:4e:65:9e:ca:f1:b8:3d:ff:c7:5e:15:86:10:97: - 8c:3e:22:32:ab:4e:75:a7:70:83:f2:fb:2f:af:fe:26:28:e9: - 4f:d4:c9:49:7c:6f:51:7e:2a:ff:a0:5b:25:45:2e:66:d9:0d: - 92:94:e5:b8:60:c6:67:1a:f3:03 + b4:a5:f1:71:26:4d:b9:ff:54:f3:09:1f:ac:e1:19:59:e5:ec: + 57:e3:f1:0b:b2:8f:f3:29:eb:6b:c6:fa:27:33:3e:91:d0:77: + 43:c9:ce:1e:0f:71:07:a9:f7:26:e0:7e:ff:30:7d:52:0a:e1: + 80:48:46:bb:99:e9:d9:77:ce:75 -----BEGIN CERTIFICATE----- -MIICtzCCAmGgAwIBAgIBADANBgkqhkiG9w0BAQQFADB4MQswCQYDVQQGEwJVUzEP -MA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDEOMAwGA1UEChMFeWFT -U0wxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A -eWFzc2wuY29tMB4XDTA1MDMwNzAzMDAzMVoXDTQ2MDQwMTAzMDAzMVoweDELMAkG -A1UEBhMCVVMxDzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxhbmQxDjAM -BgNVBAoTBXlhU1NMMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0wGwYJKoZIhvcN -AQkBFg5pbmZvQHlhc3NsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDNH3hH -+LjWCL+9fCNhhjYorO48qJqU5tUm6HFQsiaLHB4/dbLTs2eVDP12KGXVzhKCngYA -ogndzjom3UYqoEVxAgMBAAGjgdUwgdIwHQYDVR0OBBYEFK4lXvpNo1srh97xKvVC -wP/OtbStMIGiBgNVHSMEgZowgZeAFK4lXvpNo1srh97xKvVCwP/OtbStoXykejB4 -MQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFu -ZDEOMAwGA1UEChMFeWFTU0wxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkq -hkiG9w0BCQEWDmluZm9AeWFzc2wuY29tggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEEBQADQQBZGa4bTmWeyvG4Pf/HXhWGEJeMPiIyq051p3CD8vsvr/4mKOlP -1MlJfG9Rfir/oFslRS5m2Q2SlOW4YMZnGvMD +MIIDDjCCArigAwIBAgIJAMXXbBE28DXhMA0GCSqGSIb3DQEBBAUAMIGOMQswCQYD +VQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDEOMAwG +A1UEChMFeWFTU0wxFDASBgNVBAsTC3Byb2dyYW1taW5nMRYwFAYDVQQDEw13d3cu +eWFzc2wuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbTAeFw0xMDA2 +MzAxODM5MzlaFw0xMzAzMjYxODM5NDBaMIGOMQswCQYDVQQGEwJVUzEPMA0GA1UE +CBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDEOMAwGA1UEChMFeWFTU0wxFDAS +BgNVBAsTC3Byb2dyYW1taW5nMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0wGwYJ +KoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC +QQC9UUoU/WoZhAwzOPwnMpyXC/ykGGBpTtnYeFAL6SBd1h1wHAwknyOCzDoB1ZcX +snNshs+18eXOaAzZohI5fPJTAgMBAAGjgfYwgfMwHQYDVR0OBBYEFFz3KSFpegl4 +nnvNU0IC7M4pDRHfMIHDBgNVHSMEgbswgbiAFFz3KSFpegl4nnvNU0IC7M4pDRHf +oYGUpIGRMIGOMQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQH +EwhQb3J0bGFuZDEOMAwGA1UEChMFeWFTU0wxFDASBgNVBAsTC3Byb2dyYW1taW5n +MRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlh +c3NsLmNvbYIJAMXXbBE28DXhMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQAD +QQC0pfFxJk25/1TzCR+s4RlZ5exX4/ELso/zKetrxvonMz6R0HdDyc4eD3EHqfcm +4H7/MH1SCuGASEa7menZd851 -----END CERTIFICATE----- diff --git a/extra/yassl/certs/client-key.der b/extra/yassl/certs/client-key.der index 6e8b432a07c..649406c4417 100644 Binary files a/extra/yassl/certs/client-key.der and b/extra/yassl/certs/client-key.der differ diff --git a/extra/yassl/certs/client-key.pem b/extra/yassl/certs/client-key.pem index 6898b2796fa..92c052fef84 100644 --- a/extra/yassl/certs/client-key.pem +++ b/extra/yassl/certs/client-key.pem @@ -1,9 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOgIBAAJBAM0feEf4uNYIv718I2GGNiis7jyompTm1SbocVCyJoscHj91stOz -Z5UM/XYoZdXOEoKeBgCiCd3OOibdRiqgRXECAwEAAQJAXwa6OVVvg7Bv63+MAI0l -n/hlMfLGEj9R9gFvJXwywPSEQhijOZmedpHALufFPNHtwba9dmbqMkBAw9JDaAgg -QQIhAO+mBaSmoG5AYVKYQZiASe/2wMZjaQSN+zFLyF97OX8ZAiEA2x5iRmXUkbOT -8Td/vx8R9mq9W5CJu+cN+SWGwTYhPBkCIGZFM6NQeKaUUvQshdHO7b66Twpa4jZP -YSNoc9pLe/4BAiB+jIvBkKo2A/rbg2waG32qTXdTXKTPiuA9Fnk/OV30cQIhANuA -uMdo+T+rYcNGJ1hCYKDe9JWBpNfSQ+H/A7sWuW8L +MIIBPAIBAAJBAL1RShT9ahmEDDM4/CcynJcL/KQYYGlO2dh4UAvpIF3WHXAcDCSf +I4LMOgHVlxeyc2yGz7Xx5c5oDNmiEjl88lMCAwEAAQJAVGHWLlLhpqvXsEEXCvWh +HCYono+K8YVGzhiaPSTU212fCoQryIxsXQKGBjhFdZm96DZWp+Vd/t/u+B4ZeaqY ++QIhAOBEfbFtdZqk5OmbbRsRVPI7+YYmubgY1TVIPqmxHQ4NAiEA2BrTQkjOb3ul +A/SZO04fJUZsm7Ng92FWHDJsRancSd8CIQCmGbQqZBK1TamJZ6dAY+7RViAx/p6Q +vjuzMeXPUrFdRQIhAMkfBhg9bCqjFyt8PBPOm/vz8+ZgZlE0/JAXeV7IPCVfAiEA +gZwCFm1ghGxmaoB424YC4DHeDeN/g9xwJHT7EuM9Mvc= -----END RSA PRIVATE KEY----- diff --git a/extra/yassl/certs/client-keyEnc.pem b/extra/yassl/certs/client-keyEnc.pem new file mode 100644 index 00000000000..f6b857fc48c --- /dev/null +++ b/extra/yassl/certs/client-keyEnc.pem @@ -0,0 +1,12 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-CBC,B9D8FB94E38635AB + +e7bVyzL1RF6p7hl8GDaOrRTcgB4ip+pWWUcnNf6y2tsuAQx/c/Bd5c9ZDc3L5AXC +oOAzWYB+ay1vWkmAQB4ivFS5QzGDf8870d4FbOejwmgPhiHdZNw5xNwscAN6ps0v +dFaUrR9nzWmbycsQCjXZGIZtGFCtXkA8Gdl5OMO4o+rzM0muNPS5fb++x7oNl1YG +gjReu2sQ85dPfMlnoHhr8Pz9LBcxVyOmcqtmT0SOSuPcoj6aDtcZ+EY9MQf6SR9E +ysmrJKMtp+ABgXglAj5hbT0dMpoJ2KpJYk62JAh/A6DDyv5YYUI0W57xY5+QzaV+ +YXnIvqwLjJ3cXEV4YH7ozLHAESgnAAUoQsin42rrRKt7GxjSdBoFhWjH69V2nl65 +LYRNjE1O5BBEX+rz0S+fe2ZZgT17kUr7eLZCq15J+L5xWQ7R4ERc0w== +-----END RSA PRIVATE KEY----- diff --git a/extra/yassl/certs/client-keyEnc3.pem b/extra/yassl/certs/client-keyEnc3.pem new file mode 100644 index 00000000000..0097c0760a5 --- /dev/null +++ b/extra/yassl/certs/client-keyEnc3.pem @@ -0,0 +1,12 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,BDE979D13CCC0ABD + +N7yz2JV13EmQ7MZPL5wamid5+G1V1gp8FKqMemAC5JDxonS/W9oViMLUcxbfPTDx +FznKdYSVTIQ7vv3ofmDG4MEyV/2C568N2kdtAw+jTfrZFN+IU9CI+W+In/nacirF +02sAcvDMofustnooKNOO7/iyb5+3vRvEt5vSSRQn5WuSQ9sUKjuzoLs/lbf7fyAt +4NeqfI3rYBZXxiUOLITOGXzGNRuFoY+o2uDCfelLAJ8uhiVG6ME3LeJEo1dT5lZ8 +CSJOLPasKg0iG4V7olM4j9FvAfZr48RRsSfUen756Jo2HpI4bad8LKhFYIdNs2Au +WwKLmjpo6QB9hBmRshR04rEXPdrgTqLBExCE08PyaGYnWU8ggWritCeBzDQFj/n4 +sI+NO0Mymuvg98e5RpO52lg3Xnqv9RIK3guLFOmI6aEHC0PS4WwOEQ== +-----END RSA PRIVATE KEY----- diff --git a/extra/yassl/certs/dsa-cert.pem b/extra/yassl/certs/dsa-cert.pem index 788d263bb9f..ed1138dad01 100644 --- a/extra/yassl/certs/dsa-cert.pem +++ b/extra/yassl/certs/dsa-cert.pem @@ -1,13 +1,14 @@ Certificate: Data: Version: 3 (0x2) - Serial Number: 0 (0x0) + Serial Number: + ce:df:23:31:64:b4:13:da Signature Algorithm: dsaWithSHA1 - Issuer: C=US, ST=Oregon, L=Portland, O=yaSSL DSA, CN=yaSSL DSA/emailAddress=info@yassl.com + Issuer: C=US, ST=Oregon, L=Portland, O=yaSSL, OU=testing, CN=www.yassl.com/emailAddress=info@yassl.com Validity - Not Before: Mar 7 03:22:00 2005 GMT - Not After : Apr 1 03:22:00 2046 GMT - Subject: C=US, ST=Oregon, L=Portland, O=yaSSL DSA, CN=yaSSL DSA/emailAddress=info@yassl.com + Not Before: Jun 30 18:56:38 2010 GMT + Not After : Mar 26 18:56:39 2013 GMT + Subject: C=US, ST=Oregon, L=Portland, O=yaSSL, OU=testing, CN=www.yassl.com/emailAddress=info@yassl.com Subject Public Key Info: Public Key Algorithm: dsaEncryption DSA Public Key: @@ -37,32 +38,33 @@ Certificate: BE:F9:8C:5D:D6:1C:B4:EE:81:DD:36:56:0A:21:E4:61:44:73:E9:E2 X509v3 Authority Key Identifier: keyid:BE:F9:8C:5D:D6:1C:B4:EE:81:DD:36:56:0A:21:E4:61:44:73:E9:E2 - DirName:/C=US/ST=Oregon/L=Portland/O=yaSSL DSA/CN=yaSSL DSA/emailAddress=info@yassl.com - serial:00 + DirName:/C=US/ST=Oregon/L=Portland/O=yaSSL/OU=testing/CN=www.yassl.com/emailAddress=info@yassl.com + serial:CE:DF:23:31:64:B4:13:DA X509v3 Basic Constraints: CA:TRUE Signature Algorithm: dsaWithSHA1 - 30:2c:02:14:7e:5e:94:fc:7f:ca:81:ab:b3:32:f7:21:83:48: - 48:5f:0a:f1:13:ca:02:14:73:54:32:14:51:22:bf:0b:ec:d7: - 6a:6a:fa:a7:1d:46:b4:c2:a3:b5 + 30:2d:02:14:00:a3:21:20:34:6a:2c:f9:fb:76:d7:20:c9:c0: + 35:1b:64:9a:c2:83:02:15:00:a4:59:ac:6d:da:85:48:ff:f5: + 0d:49:72:c8:cd:91:fc:ec:2f:5c:63 -----BEGIN CERTIFICATE----- -MIIDMjCCAvKgAwIBAgIBADAJBgcqhkjOOAQDMHgxCzAJBgNVBAYTAlVTMQ8wDQYD -VQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRsYW5kMRIwEAYDVQQKEwl5YVNTTCBE -U0ExEjAQBgNVBAMTCXlhU1NMIERTQTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNz -bC5jb20wHhcNMDUwMzA3MDMyMjAwWhcNNDYwNDAxMDMyMjAwWjB4MQswCQYDVQQG -EwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDESMBAGA1UE -ChMJeWFTU0wgRFNBMRIwEAYDVQQDEwl5YVNTTCBEU0ExHTAbBgkqhkiG9w0BCQEW -DmluZm9AeWFzc2wuY29tMIHwMIGoBgcqhkjOOAQBMIGcAkEAmSlpgMk8mGhFqYL+ -Z+uViMW0DNYmRZUZLKAgW37faencww/zYQolm/IhAWrNqow358pm21b0D3160Ri5 -Qv0bEQIVAK0lKasKnwkcwa0DIHZ/prfdTQMJAkASiJna59ALk5vm7jwhf5yztI2l -jOI3gD8X0YFPvfBxtjIIVN2/AeKzdwZkdYoE1nk5sQIDA8YGdOWQBQoQRhkxA0MA -AkAEhKAmMXIM6E9dUxdisYDKwBZfwx7qxdmYOPm+VlNHaM4IIlccuw13kc9bNu3z -JIKQis2QfNt3+Rctc3Pvu7mCo4HVMIHSMB0GA1UdDgQWBBS++Yxd1hy07oHdNlYK -IeRhRHPp4jCBogYDVR0jBIGaMIGXgBS++Yxd1hy07oHdNlYKIeRhRHPp4qF8pHow -eDELMAkGA1UEBhMCVVMxDzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxh -bmQxEjAQBgNVBAoTCXlhU1NMIERTQTESMBAGA1UEAxMJeWFTU0wgRFNBMR0wGwYJ -KoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbYIBADAMBgNVHRMEBTADAQH/MAkGByqG -SM44BAMDLwAwLAIUfl6U/H/KgauzMvchg0hIXwrxE8oCFHNUMhRRIr8L7Ndqavqn -HUa0wqO1 +MIIDfjCCAz2gAwIBAgIJAM7fIzFktBPaMAkGByqGSM44BAMwgYoxCzAJBgNVBAYT +AlVTMQ8wDQYDVQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRsYW5kMQ4wDAYDVQQK +EwV5YVNTTDEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNv +bTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb20wHhcNMTAwNjMwMTg1NjM4 +WhcNMTMwMzI2MTg1NjM5WjCBijELMAkGA1UEBhMCVVMxDzANBgNVBAgTBk9yZWdv +bjERMA8GA1UEBxMIUG9ydGxhbmQxDjAMBgNVBAoTBXlhU1NMMRAwDgYDVQQLEwd0 +ZXN0aW5nMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0wGwYJKoZIhvcNAQkBFg5p +bmZvQHlhc3NsLmNvbTCB8DCBqAYHKoZIzjgEATCBnAJBAJkpaYDJPJhoRamC/mfr +lYjFtAzWJkWVGSygIFt+32np3MMP82EKJZvyIQFqzaqMN+fKZttW9A99etEYuUL9 +GxECFQCtJSmrCp8JHMGtAyB2f6a33U0DCQJAEoiZ2ufQC5Ob5u48IX+cs7SNpYzi +N4A/F9GBT73wcbYyCFTdvwHis3cGZHWKBNZ5ObECAwPGBnTlkAUKEEYZMQNDAAJA +BISgJjFyDOhPXVMXYrGAysAWX8Me6sXZmDj5vlZTR2jOCCJXHLsNd5HPWzbt8ySC +kIrNkHzbd/kXLXNz77u5gqOB8jCB7zAdBgNVHQ4EFgQUvvmMXdYctO6B3TZWCiHk +YURz6eIwgb8GA1UdIwSBtzCBtIAUvvmMXdYctO6B3TZWCiHkYURz6eKhgZCkgY0w +gYoxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRs +YW5kMQ4wDAYDVQQKEwV5YVNTTDEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMN +d3d3Lnlhc3NsLmNvbTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb22CCQDO +3yMxZLQT2jAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDMAAwLQIUAKMhIDRqLPn7 +dtcgycA1G2SawoMCFQCkWaxt2oVI//UNSXLIzZH87C9cYw== -----END CERTIFICATE----- diff --git a/extra/yassl/certs/dsa512.der b/extra/yassl/certs/dsa512.der index fe79ccb612b..027bedeffb1 100644 Binary files a/extra/yassl/certs/dsa512.der and b/extra/yassl/certs/dsa512.der differ diff --git a/extra/yassl/certs/server-cert.pem b/extra/yassl/certs/server-cert.pem index 30608f5f65b..1ec53c02628 100644 --- a/extra/yassl/certs/server-cert.pem +++ b/extra/yassl/certs/server-cert.pem @@ -3,36 +3,37 @@ Certificate: Version: 1 (0x0) Serial Number: 1 (0x1) Signature Algorithm: md5WithRSAEncryption - Issuer: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + Issuer: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com Validity - Not Before: Mar 8 03:00:47 2005 GMT - Not After : Apr 2 03:00:47 2046 GMT - Subject: C=US, ST=Oregon, L=Portland, O=taoSoftDev, CN=www.taosoftdev.com/emailAddress=info@yassl.com + Not Before: Jun 30 18:52:17 2010 GMT + Not After : Mar 26 18:52:17 2013 GMT + Subject: C=US, ST=Montana, L=Bozeman, O=yaSSL, OU=support, CN=www.yassl.com/emailAddress=info@yassl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): - 00:a4:68:bb:bc:b7:27:5f:3c:f5:78:c6:1a:af:b9: - 95:fc:7e:61:1f:a8:81:0a:ca:43:88:9a:03:e0:d0: - a6:79:70:16:34:b9:7c:75:54:ca:70:19:66:38:be: - 6e:28:7e:a5:ff:6b:3c:83:2f:39:42:c3:15:f3:bd: - f2:25:93:22:e7 + 00:c6:7b:c0:68:81:2f:de:82:3f:f9:ac:c3:86:4a: + 66:b7:ec:d4:f1:f6:64:21:ff:f5:a2:34:42:d0:38: + 9f:c6:dd:3b:6e:26:65:6a:54:96:dd:d2:7b:eb:36: + a2:ae:7e:2a:9e:7e:56:a5:b6:87:9f:15:c7:18:66: + 7e:16:77:e2:a7 Exponent: 65537 (0x10001) Signature Algorithm: md5WithRSAEncryption - 36:72:12:3b:ac:e4:58:83:09:86:4f:71:2a:3a:0d:8a:05:27: - 75:f3:3e:62:4f:ab:b8:70:20:cd:ad:70:ab:91:11:68:f8:82: - 33:e2:78:85:a8:16:f5:66:bd:68:2c:5a:26:15:12:1e:6e:83: - c7:6d:62:b9:c3:ff:e1:86:e4:e6 + 58:a9:98:e7:16:52:4c:40:e7:e1:47:92:19:1b:3a:8f:97:6c: + 7b:b7:b0:cb:20:6d:ad:b5:d3:47:58:d8:e4:f2:3e:32:e9:ef: + 87:77:e5:54:36:f4:8d:50:8d:07:b4:77:45:ea:9d:a4:33:36: + 9b:0b:e0:74:58:11:c5:01:7b:4d -----BEGIN CERTIFICATE----- -MIIB9zCCAaECAQEwDQYJKoZIhvcNAQEEBQAwgYkxCzAJBgNVBAYTAlVTMQ8wDQYD -VQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRsYW5kMREwDwYDVQQKEwhzYXd0b290 -aDEkMCIGA1UEAxMbd3d3LnNhd3Rvb3RoLWNvbnN1bHRpbmcuY29tMR0wGwYJKoZI -hvcNAQkBFg5pbmZvQHlhc3NsLmNvbTAeFw0wNTAzMDgwMzAwNDdaFw00NjA0MDIw -MzAwNDdaMIGCMQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQH -EwhQb3J0bGFuZDETMBEGA1UEChMKdGFvU29mdERldjEbMBkGA1UEAxMSd3d3LnRh -b3NvZnRkZXYuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbTBcMA0G -CSqGSIb3DQEBAQUAA0sAMEgCQQCkaLu8tydfPPV4xhqvuZX8fmEfqIEKykOImgPg -0KZ5cBY0uXx1VMpwGWY4vm4ofqX/azyDLzlCwxXzvfIlkyLnAgMBAAEwDQYJKoZI -hvcNAQEEBQADQQA2chI7rORYgwmGT3EqOg2KBSd18z5iT6u4cCDNrXCrkRFo+IIz -4niFqBb1Zr1oLFomFRIeboPHbWK5w//hhuTm +MIICFDCCAb4CAQEwDQYJKoZIhvcNAQEEBQAwgZ4xCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdNb250YW5hMRAwDgYDVQQHEwdCb3plbWFuMREwDwYDVQQKEwhzYXd0b290 +aDETMBEGA1UECxMKY29uc3VsdGluZzEkMCIGA1UEAxMbd3d3LnNhd3Rvb3RoLWNv +bnN1bHRpbmcuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbTAeFw0x +MDA2MzAxODUyMTdaFw0xMzAzMjYxODUyMTdaMIGKMQswCQYDVQQGEwJVUzEQMA4G +A1UECBMHTW9udGFuYTEQMA4GA1UEBxMHQm96ZW1hbjEOMAwGA1UEChMFeWFTU0wx +EDAOBgNVBAsTB3N1cHBvcnQxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkq +hkiG9w0BCQEWDmluZm9AeWFzc2wuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB +AMZ7wGiBL96CP/msw4ZKZrfs1PH2ZCH/9aI0QtA4n8bdO24mZWpUlt3Se+s2oq5+ +Kp5+VqW2h58VxxhmfhZ34qcCAwEAATANBgkqhkiG9w0BAQQFAANBAFipmOcWUkxA +5+FHkhkbOo+XbHu3sMsgba2100dY2OTyPjLp74d35VQ29I1QjQe0d0XqnaQzNpsL +4HRYEcUBe00= -----END CERTIFICATE----- diff --git a/extra/yassl/certs/server-key.pem b/extra/yassl/certs/server-key.pem index d6055c4cfd8..154d661b1df 100644 --- a/extra/yassl/certs/server-key.pem +++ b/extra/yassl/certs/server-key.pem @@ -1,9 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOQIBAAJBAKRou7y3J1889XjGGq+5lfx+YR+ogQrKQ4iaA+DQpnlwFjS5fHVU -ynAZZji+bih+pf9rPIMvOULDFfO98iWTIucCAwEAAQJABLVvMw931DV1vljGKORC -1HF2LKbx0zJJzt7CX6z6J54vcE79K3NYXdU6o7/j1WTtfD47tFG+4ljGvSYPmrCI -2QIhANfiY6is6JUJGGgeMxyWeQRPXfaE9Yrk6OhxHhpYf5CTAiEAwvWraeLPy/NE -B+0w80mh8tCv2tpuKaYMOG53XpYX3N0CIDy/Bj3rUZLGOWjqvoUXzjupPY5lgVYw -7Vyin87YAiUjAiAgM8X5em5KSMc+6+2+8bWfTtsNMjEqDfRMyepLpE0SvQIgTSYL -WWfcZoRUPDM9GEuQ40nifVNjobzvjTW4aYyHCEI= +MIIBOwIBAAJBAMZ7wGiBL96CP/msw4ZKZrfs1PH2ZCH/9aI0QtA4n8bdO24mZWpU +lt3Se+s2oq5+Kp5+VqW2h58VxxhmfhZ34qcCAwEAAQJBAJSbGxgjgV+rTZL2Ev58 +viN/IoB25cm/Bn4Heu7DNn2A2kpdGX2cCaf7rEQoIKCiHxvopvxOcd/7nLS/gNli +dCECIQD/cX/9fvB1Uajw0fmvwNON9+3P9uJSqpig90zL32pwjQIhAMbqee9TBMN4 +TxXbgWqA92PrCXe8WDZ3PwoJqdR6MRUDAiEAny+TDF1z6hiWiGTCDgXDkKBlwgjf +p5aKgR077XzwLu0CICVpWEGg1ZaF/CnaPP7w/pZ2UDOK4vRrfRnAM4bY7H5NAiBS +1eXJ/MCZ2uPfpl7XK2BU9P69KdKUk5WHxdRchVvcDg== -----END RSA PRIVATE KEY----- diff --git a/extra/yassl/certs/server-keyEnc.pem b/extra/yassl/certs/server-keyEnc.pem new file mode 100644 index 00000000000..d3500a1b647 --- /dev/null +++ b/extra/yassl/certs/server-keyEnc.pem @@ -0,0 +1,12 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-CBC,08132C1FFF5BC8CC + +gsvuAsGmB8AkR23M25w4E6wuywfBey1Jqh3g71gJcnsUYwynex9dvfAU0lTowOXh +sb7ld1KNjEMzrht9AC1IC0iE1rLqvRQZOdJ7h3n7aHZQ4a/HjcwAhqJq0ZW45m6Q +mpoO5fRISjx2VbKFRUz6Xj2x0/do3IjQhpuUDVrTFFe1sEySM6APZ6CVpcnTOyPR +ADyLDKzOi2E+sj1UXs58pct56FaqTIZPUEflICU3k6q9FPU6gsYANRLfzegclkv4 +JAx6mKVSJuYnjCCppx8WBwGJa1J1GcYRJ3qFfdbUzL4bcXTvoFkJEnDkHsXgDUS6 +xmT0XGT3IMaW8cwQ8KD8m5YYI/L26Mas/w3eA2ekyMR8pYICjXp/YZtcKxxkQSVE +Uv/+D+20KbNAHIW5Mrxf61cX/CggGEbVP8ZhDY1flh8= +-----END RSA PRIVATE KEY----- diff --git a/extra/yassl/certs/taoCert.txt b/extra/yassl/certs/taoCert.txt index 585293e4f2b..f1132c0b5b8 100644 --- a/extra/yassl/certs/taoCert.txt +++ b/extra/yassl/certs/taoCert.txt @@ -47,4 +47,16 @@ to convert rsa private PEM to DER : b) openssl rsa -in key.pem -outform DER -out key.der +**** To encrypt rsa key already in pem ********** + +a) openssl rsa server-keyEnc.pem + +note location of des, pass = yassl123 + + +*** To make a public key from a private key ****** + + +openssl rsa -in 1024rsa.priv -pubout -out 1024rsa.pub + diff --git a/extra/yassl/examples/client/client.cpp b/extra/yassl/examples/client/client.cpp index a80a8c2f1a2..d05c31d4d63 100644 --- a/extra/yassl/examples/client/client.cpp +++ b/extra/yassl/examples/client/client.cpp @@ -36,15 +36,20 @@ void ClientError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg) void NonBlockingSSL_Connect(SSL* ssl, SSL_CTX* ctx, SOCKET_T& sockfd) { int ret = SSL_connect(ssl); - while (ret =! SSL_SUCCESS && SSL_get_error(ssl, 0) == - SSL_ERROR_WANT_READ) { - printf("... client would block\n"); + int err = SSL_get_error(ssl, 0); + while (ret != SSL_SUCCESS && (err == SSL_ERROR_WANT_READ || + err == SSL_ERROR_WANT_WRITE)) { + if (err == SSL_ERROR_WANT_READ) + printf("... client would read block\n"); + else + printf("... client would write block\n"); #ifdef _WIN32 Sleep(1000); #else sleep(1); #endif ret = SSL_connect(ssl); + err = SSL_get_error(ssl, 0); } if (ret != SSL_SUCCESS) ClientError(ctx, ssl, sockfd, "SSL_connect failed"); @@ -81,7 +86,8 @@ void client_test(void* args) #ifdef NON_BLOCKING NonBlockingSSL_Connect(ssl, ctx, sockfd); #else - if (SSL_connect(ssl) != SSL_SUCCESS) + // if you get an error here see note at top of README + if (SSL_connect(ssl) != SSL_SUCCESS) ClientError(ctx, ssl, sockfd, "SSL_connect failed"); #endif showPeer(ssl); @@ -105,7 +111,7 @@ void client_test(void* args) int input = SSL_read(ssl, reply, sizeof(reply)); if (input > 0) { reply[input] = 0; - printf("Server response: %s\n", reply); + printf("Server response: %s\n", reply); } #ifdef TEST_RESUME @@ -121,18 +127,18 @@ void client_test(void* args) tcp_connect(sockfd); SSL_set_fd(sslResume, sockfd); SSL_set_session(sslResume, session); - + if (SSL_connect(sslResume) != SSL_SUCCESS) ClientError(ctx, sslResume, sockfd, "SSL_resume failed"); showPeer(sslResume); - + if (SSL_write(sslResume, msg, sizeof(msg)) != sizeof(msg)) ClientError(ctx, sslResume, sockfd, "SSL_write failed"); input = SSL_read(sslResume, reply, sizeof(reply)); if (input > 0) { reply[input] = 0; - printf("Server response: %s\n", reply); + printf("Server response: %s\n", reply); } SSL_shutdown(sslResume); diff --git a/extra/yassl/examples/echoclient/echoclient.cpp b/extra/yassl/examples/echoclient/echoclient.cpp index 787e554f8bf..c2b8ff66ac9 100644 --- a/extra/yassl/examples/echoclient/echoclient.cpp +++ b/extra/yassl/examples/echoclient/echoclient.cpp @@ -74,10 +74,10 @@ void echoclient_test(void* args) char send[1024]; char reply[1024]; - + while (fgets(send, sizeof(send), fin)) { - int sendSz = strlen(send) + 1; + int sendSz = (int)strlen(send) + 1; if (SSL_write(ssl, send, sendSz) != sendSz) EchoClientError(ctx, ssl, sockfd, "SSL_write failed"); @@ -86,7 +86,7 @@ void echoclient_test(void* args) break; } - if (SSL_read(ssl, reply, sizeof(reply)) > 0) + if (SSL_read(ssl, reply, sizeof(reply)) > 0) fputs(reply, fout); } diff --git a/extra/yassl/examples/echoserver/echoserver.cpp b/extra/yassl/examples/echoserver/echoserver.cpp index a3ba8c12c60..bd044e70e8b 100644 --- a/extra/yassl/examples/echoserver/echoserver.cpp +++ b/extra/yassl/examples/echoserver/echoserver.cpp @@ -93,11 +93,11 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) #endif while (!shutdown) { - sockaddr_in client; + SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); SOCKET_T clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); - if (clientfd == -1) { + if (clientfd == (SOCKET_T) -1) { SSL_CTX_free(ctx); tcp_close(sockfd); err_sys("tcp accept failed"); @@ -111,11 +111,11 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) tcp_close(clientfd); continue; } - + char command[1024]; int echoSz(0); while ( (echoSz = SSL_read(ssl, command, sizeof(command))) > 0) { - + if ( strncmp(command, "quit", 4) == 0) { printf("client sent quit command: shutting down!\n"); shutdown = true; @@ -127,7 +127,7 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) char header[] = "\n
\n";
                 char body[]   = "greetings from yaSSL\n";
                 char footer[] = "\r\n\r\n";
-            
+
                 strncpy(command, type, sizeof(type));
                 echoSz = sizeof(type) - 1;
 
@@ -140,7 +140,7 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
 
                 if (SSL_write(ssl, command, echoSz) != echoSz)
                     EchoError(ctx, ssl, sockfd, clientfd, "SSL_write failed");
-
+               
                 break;
             }
             command[echoSz] = 0;
diff --git a/extra/yassl/examples/server/server.cpp b/extra/yassl/examples/server/server.cpp
index 8b8066eace5..3fac40e88c4 100644
--- a/extra/yassl/examples/server/server.cpp
+++ b/extra/yassl/examples/server/server.cpp
@@ -35,15 +35,20 @@ void ServerError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg)
     void NonBlockingSSL_Accept(SSL* ssl, SSL_CTX* ctx, SOCKET_T& clientfd)
     {
         int ret = SSL_accept(ssl);
-        while (ret != SSL_SUCCESS && SSL_get_error(ssl, 0) ==
-                                     SSL_ERROR_WANT_READ) {
-            printf("... server would block\n");
+        int err = SSL_get_error(ssl, 0);
+        while (ret != SSL_SUCCESS && (err == SSL_ERROR_WANT_READ ||
+                                      err == SSL_ERROR_WANT_WRITE)) {
+            if (err == SSL_ERROR_WANT_READ)
+                printf("... server would read block\n");
+            else
+                printf("... server would write block\n");
             #ifdef _WIN32
                 Sleep(1000);
             #else
                 sleep(1);
             #endif
             ret = SSL_accept(ssl);
+            err = SSL_get_error(ssl, 0);
         }
         if (ret != SSL_SUCCESS)
             ServerError(ctx, ssl, clientfd, "SSL_accept failed");
@@ -78,14 +83,14 @@ THREAD_RETURN YASSL_API server_test(void* args)
 
     SSL* ssl = SSL_new(ctx);
     SSL_set_fd(ssl, clientfd);
-   
+
 #ifdef NON_BLOCKING
     NonBlockingSSL_Accept(ssl, ctx, clientfd);
 #else
     if (SSL_accept(ssl) != SSL_SUCCESS)
         ServerError(ctx, ssl, clientfd, "SSL_accept failed");
 #endif
-
+     
     showPeer(ssl);
     printf("Using Cipher Suite: %s\n", SSL_get_cipher(ssl));
 
@@ -93,7 +98,7 @@ THREAD_RETURN YASSL_API server_test(void* args)
     int input = SSL_read(ssl, command, sizeof(command));
     if (input > 0) {
         command[input] = 0;
-    printf("First client command: %s\n", command);
+        printf("First client command: %s\n", command);
     }
 
     char msg[] = "I hear you, fa shizzle!";
diff --git a/extra/yassl/include/buffer.hpp b/extra/yassl/include/buffer.hpp
index a51bca9a630..2d7817a7ca2 100644
--- a/extra/yassl/include/buffer.hpp
+++ b/extra/yassl/include/buffer.hpp
@@ -46,12 +46,6 @@ typedef unsigned int  uint;
 const uint AUTO = 0xFEEDBEEF;
 
 
-// Checking Policy should implement a check function that tests whether the
-// index is within the size limit of the array
-struct Check {
-    void check(uint i, uint limit);
-};
-
 
 struct NoCheck {
     void check(uint, uint);
@@ -66,7 +60,7 @@ struct NoCheck {
  * write to the buffer bulk wise and have the correct size
  */
 
-class input_buffer : public Check {
+class input_buffer : public NoCheck {
     uint   size_;                // number of elements in buffer
     uint   current_;             // current offset position in buffer
     byte*  buffer_;              // storage for buffer
@@ -132,7 +126,7 @@ private:
  * Not using vector because need checked []access and the ability to
  * write to the buffer bulk wise and retain correct size
  */
-class output_buffer : public Check {
+class output_buffer : public NoCheck {
     uint    current_;                // current offset and elements in buffer
     byte*   buffer_;                 // storage for buffer
     byte*   end_;                    // end of storage marker
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index ba5fa51f34c..0ae54f070bd 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -30,12 +30,12 @@
 #include "prefix_ssl.h"
 #endif
 
-#include    /* ERR_print fp */
+#include     /* ERR_print fp */
 #include "opensslv.h" /* for version number */
 #include "rsa.h"
 
 
-#define YASSL_VERSION "1.7.2"
+#define YASSL_VERSION "2.1.4"
 
 
 #if defined(__cplusplus)
@@ -43,9 +43,9 @@ extern "C" {
 #endif
 
  void yaSSL_CleanUp();   /* call once at end of application use to
-                                      free static singleton memory holders,
-                                      not a leak per se, but helpful when 
-                                      looking for them                      */
+                            free static singleton memory holders,
+                            not a leak per se, but helpful when
+                            looking for them                      */
 
 #if defined(__cplusplus)
 } // extern
@@ -70,11 +70,11 @@ extern "C" {
     class X509;
     class X509_NAME;
 #else
-    typedef struct SSL         SSL;          
+    typedef struct SSL          SSL;          
     typedef struct SSL_SESSION  SSL_SESSION;
-    typedef struct SSL_METHOD  SSL_METHOD;
-    typedef struct SSL_CTX     SSL_CTX;
-    typedef struct SSL_CIPHER  SSL_CIPHER;
+    typedef struct SSL_METHOD   SSL_METHOD;
+    typedef struct SSL_CTX      SSL_CTX;
+    typedef struct SSL_CIPHER   SSL_CIPHER;
 
     typedef struct RSA RSA;
 
@@ -107,6 +107,15 @@ RSA* RSA_generate_key(int, unsigned long, void(*)(int, int, void*), void*);
 
 /* X509 stuff, different file? */
 
+/* because mySQL dereferences to use error and current_cert, even after calling
+ * get functions for local references */
+typedef struct X509_STORE_CTX {
+    int   error;
+    int   error_depth;
+    X509* current_cert;
+} X509_STORE_CTX;
+
+
 typedef struct X509_STORE         X509_STORE;
 typedef struct X509_LOOKUP        X509_LOOKUP;
 typedef struct X509_OBJECT { char c; } X509_OBJECT;
@@ -125,16 +134,6 @@ typedef struct BIO BIO;
 
 
 
-/* because mySQL dereferences to use error and current_cert, even after calling
- * get functions for local references */
-typedef struct X509_STORE_CTX {
-    int   error;
-    int   error_depth;
-    X509* current_cert;
-} X509_STORE_CTX;
-
-
-
 X509* X509_STORE_CTX_get_current_cert(X509_STORE_CTX*);
 int   X509_STORE_CTX_get_error(X509_STORE_CTX*);
 int   X509_STORE_CTX_get_error_depth(X509_STORE_CTX*);
@@ -205,7 +204,7 @@ SSL* SSL_new(SSL_CTX*);
 int  SSL_set_fd (SSL*, YASSL_SOCKET_T);
 YASSL_SOCKET_T SSL_get_fd(const SSL*);
 int  SSL_connect(SSL*);                    /* if you get an error from connect
-                                              see note at top of REAMDE */
+                                              see note at top of README       */
 int  SSL_write(SSL*, const void*, int);
 int  SSL_read(SSL*, void*, int);
 int  SSL_accept(SSL*);
@@ -351,11 +350,11 @@ enum { /* ssl Constants */
     SSL_ERROR_ZERO_RETURN      = 84,
     SSL_ERROR_SSL              = 85,
 
-    SSL_SENT_SHUTDOWN     = 90,
-    SSL_RECEIVED_SHUTDOWN = 91,
+    SSL_ST_CONNECT        = 90,
+    SSL_ST_ACCEPT         = 91,
     SSL_CB_LOOP           = 92,
-    SSL_ST_CONNECT        = 93,
-    SSL_ST_ACCEPT         = 94,
+    SSL_SENT_SHUTDOWN     = 93,
+    SSL_RECEIVED_SHUTDOWN = 94,
     SSL_CB_ALERT          = 95,
     SSL_CB_READ           = 96,
     SSL_CB_HANDSHAKE_DONE = 97
@@ -366,7 +365,7 @@ enum { /* ssl Constants */
 SSL_METHOD *SSLv3_method(void);
 SSL_METHOD *SSLv3_server_method(void);
 SSL_METHOD *SSLv3_client_method(void);
-SSL_METHOD *TLSv1_server_method(void);  
+SSL_METHOD *TLSv1_server_method(void);
 SSL_METHOD *TLSv1_client_method(void);
 SSL_METHOD *TLSv1_1_server_method(void);
 SSL_METHOD *TLSv1_1_client_method(void);
diff --git a/extra/yassl/include/socket_wrapper.hpp b/extra/yassl/include/socket_wrapper.hpp
index 308704c2af0..2372e64e56c 100644
--- a/extra/yassl/include/socket_wrapper.hpp
+++ b/extra/yassl/include/socket_wrapper.hpp
@@ -26,7 +26,6 @@
 #ifndef yaSSL_SOCKET_WRAPPER_HPP
 #define yaSSL_SOCKET_WRAPPER_HPP
 
-#include 
 
 #ifdef _WIN32
     #include 
@@ -73,7 +72,8 @@ public:
     uint     get_ready() const;
     socket_t get_fd()    const;
 
-    uint send(const byte* buf, unsigned int len, int flags = 0) const;
+    uint send(const byte* buf, unsigned int len, unsigned int& sent,
+              int flags = 0);
     uint receive(byte* buf, unsigned int len, int flags = 0);
 
     bool wait();
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index 433649c545b..686e958d7e1 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -168,7 +168,7 @@ private:
 
 // openSSL X509 names
 class X509_NAME {
-    char* name_;
+    char*       name_;
     size_t      sz_;
     ASN1_STRING entry_;
 public:
@@ -246,11 +246,11 @@ public:
     SSL_SESSION(const SSL&, RandomPool&);
     ~SSL_SESSION();
 
-    const opaque* GetID()      const;
-    const opaque* GetSecret()  const;
-    const Cipher* GetSuite()   const;
-          uint    GetBornOn()  const;
-          uint    GetTimeOut() const;
+    const opaque* GetID()       const;
+    const opaque* GetSecret()   const;
+    const Cipher* GetSuite()    const;
+          uint    GetBornOn()   const;
+          uint    GetTimeOut()  const;
           X509*   GetPeerX509() const;
           void    SetTimeOut(uint);
 
@@ -417,33 +417,33 @@ class SSL_CTX {
 public:
     typedef STL::list CertList;
 private:
-    SSL_METHOD* method_;
-    x509*       certificate_;
-    x509*       privateKey_;
-    CertList    caList_;
-    Ciphers     ciphers_;
-    DH_Parms    dhParms_;
+    SSL_METHOD*     method_;
+    x509*           certificate_;
+    x509*           privateKey_;
+    CertList        caList_;
+    Ciphers         ciphers_;
+    DH_Parms        dhParms_;
     pem_password_cb passwordCb_;
     void*           userData_;
     bool            sessionCacheOff_;
     bool            sessionCacheFlushOff_;
-    Stats       stats_;
-    Mutex       mutex_;         // for Stats
+    Stats           stats_;
+    Mutex           mutex_;         // for Stats
     VerifyCallback  verifyCallback_;
 public:
     explicit SSL_CTX(SSL_METHOD* meth);
     ~SSL_CTX();
 
-    const x509*       getCert()     const;
-    const x509*       getKey()      const;
-    const SSL_METHOD* getMethod()   const;
-    const Ciphers&    GetCiphers()  const;
-    const DH_Parms&   GetDH_Parms() const;
-    const Stats&      GetStats()    const;
-    VerifyCallback    getVerifyCallback() const;
+    const x509*       getCert()       const;
+    const x509*       getKey()        const;
+    const SSL_METHOD* getMethod()     const;
+    const Ciphers&    GetCiphers()    const;
+    const DH_Parms&   GetDH_Parms()   const;
+    const Stats&      GetStats()      const;
+    const VerifyCallback getVerifyCallback() const;
     pem_password_cb   GetPasswordCb() const;
           void*       GetUserData()   const;
-          bool        GetSessionCacheOff() const;
+          bool        GetSessionCacheOff()      const;
           bool        GetSessionCacheFlushOff() const;
 
     void setVerifyPeer();
@@ -532,10 +532,13 @@ class Buffers {
 public: 
     typedef STL::list  inputList;
     typedef STL::list outputList;
+    int prevSent;     // previous plain text bytes sent when got WANT_WRITE
+    int plainSz;      // plain text bytes in buffer to send when got WANT_WRITE 
 private:
-    inputList  dataList_;                // list of users app data / handshake
-    outputList handShakeList_;           // buffered handshake msgs
-    input_buffer* rawInput_;             // buffered raw input yet to process
+    inputList      dataList_;             // list of users app data / handshake
+    outputList     handShakeList_;        // buffered handshake msgs
+    input_buffer*  rawInput_;             // buffered raw input yet to process
+    output_buffer* output_;               // WANT_WRITE buffered output 
 public:
     Buffers();
     ~Buffers();
@@ -546,11 +549,13 @@ public:
     inputList&  useData();
     outputList& useHandShake();
 
-    void          SetRawInput(input_buffer*);  // takes ownership
-    input_buffer* TakeRawInput();              // takes ownership 
+    void           SetRawInput(input_buffer*);  // takes ownership
+    input_buffer*  TakeRawInput();              // takes ownership 
+    void           SetOutput(output_buffer*);   // takes ownership
+    output_buffer* TakeOutput();                // takes ownership 
 private:
     Buffers(const Buffers&);             // hide copy
-    Buffers& operator=(const Buffers&); // and assign   
+    Buffers& operator=(const Buffers&);  // and assign   
 };
 
 
@@ -652,6 +657,7 @@ public:
     void deriveKeys();
     void deriveTLSKeys();
     void Send(const byte*, uint);
+    void SendWriteBuffered();
 
     uint bufferedData();
     uint get_SEQIncrement(bool);
diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp
index c73a54a7c15..a9e22833eb1 100644
--- a/extra/yassl/include/yassl_types.hpp
+++ b/extra/yassl/include/yassl_types.hpp
@@ -26,7 +26,6 @@
 #define yaSSL_TYPES_HPP
 
 #include 
-#include 
 #include "type_traits.hpp"
 
 
@@ -37,6 +36,13 @@
 #endif
 
 
+#ifdef _MSC_VER
+    // disable conversion warning
+    // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy
+    #pragma warning(disable:4244 4996)
+#endif
+
+
 namespace yaSSL {
 
 #define YASSL_LIB
@@ -63,29 +69,29 @@ namespace yaSSL {
     template
     void ysDelete(T* ptr)
     {
-    if (ptr) ptr->~T();
-    ::operator delete(ptr, yaSSL::ys);
+        if (ptr) ptr->~T();
+        ::operator delete(ptr, yaSSL::ys);
     }
 
     template
     void ysArrayDelete(T* ptr)
     {
-    // can't do array placement destruction since not tracking size in
-    // allocation, only allow builtins to use array placement since they
-    // don't need destructors called
-    typedef char builtin[TaoCrypt::IsFundamentalType::Yes ? 1 : -1];
-    (void)sizeof(builtin);
+        // can't do array placement destruction since not tracking size in
+        // allocation, only allow builtins to use array placement since they
+        // don't need destructors called
+        typedef char builtin[TaoCrypt::IsFundamentalType::Yes ? 1 : -1];
+        (void)sizeof(builtin);
 
-    ::operator delete[](ptr, yaSSL::ys);
+        ::operator delete[](ptr, yaSSL::ys);
     }
 
     #define NEW_YS new (yaSSL::ys)
 
     // to resolve compiler generated operator delete on base classes with
-    // virtual destructors (when on stack), make sure doesn't get called
+    // virtual destructors (when on stack)
     class virtual_base {
     public:
-    static void operator delete(void*) { assert(0); }
+        static void operator delete(void*) { }
     };
 
 
@@ -124,7 +130,7 @@ typedef opaque byte;
 
 typedef unsigned int uint;
 
- 
+
 #ifdef USE_SYS_STL
     // use system STL
     #define STL_VECTOR_FILE    
diff --git a/extra/yassl/src/buffer.cpp b/extra/yassl/src/buffer.cpp
index 86c1bcf3388..f8174098249 100644
--- a/extra/yassl/src/buffer.cpp
+++ b/extra/yassl/src/buffer.cpp
@@ -32,14 +32,6 @@ namespace yaSSL {
 
 
 
-// Checking Policy should implement a check function that tests whether the
-// index is within the size limit of the array
-
-void Check::check(uint i, uint limit) 
-{ 
-    assert(i < limit);
-}
-
 
 void NoCheck::check(uint, uint) 
 {
@@ -83,7 +75,6 @@ input_buffer::~input_buffer()
 // users can pass defualt zero length buffer and then allocate
 void input_buffer::allocate(uint s) 
 { 
-    assert(!buffer_);       // find realloc error
     buffer_ = NEW_YS byte[s];
     end_ = buffer_ + s; 
 }
@@ -141,7 +132,6 @@ void input_buffer::set_current(uint i)
 // user passes in AUTO index for ease of use
 const byte& input_buffer::operator[](uint i) 
 {
-    assert (i == AUTO);
     check(current_, size_);
     return buffer_[current_++];
 }
@@ -238,7 +228,6 @@ void output_buffer::set_current(uint c)
 // users can pass defualt zero length buffer and then allocate
 void output_buffer::allocate(uint s) 
 { 
-    assert(!buffer_);   // find realloc error
     buffer_ = NEW_YS byte[s]; end_ = buffer_ + s; 
 }
 
@@ -254,7 +243,6 @@ const byte* output_buffer::get_buffer() const
 // user passes in AUTO as index for ease of use
 byte& output_buffer::operator[](uint i) 
 {
-    assert(i == AUTO);
     check(current_, get_capacity());
     return buffer_[current_++];
 }
diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp
index d8660533f2e..7e73464001a 100644
--- a/extra/yassl/src/cert_wrapper.cpp
+++ b/extra/yassl/src/cert_wrapper.cpp
@@ -250,7 +250,8 @@ int CertManager::Validate()
         TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
         TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);
 
-        if (int err = cert.GetError().What())
+        int err = cert.GetError().What();
+        if ( err )
             return err;
 
         const TaoCrypt::PublicKey& key = cert.GetPublicKey();
@@ -266,7 +267,7 @@ int CertManager::Validate()
         TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);
 
         int err = cert.GetError().What();
-        if ( err )
+        if ( err && err != TaoCrypt::SIG_OTHER_E)
             return err;
 
         uint sz = cert.GetPublicKey().size();
@@ -327,7 +328,6 @@ int CertManager::SetPrivateKey(const x509& key)
 // Store OpenSSL type peer's cert
 void CertManager::setPeerX509(X509* x)
 {
-    assert(peerX509_ == 0);
     if (x == 0) return;
 
     X509_NAME* issuer   = x->GetIssuer();
diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp
index e6168d4d69c..ccd43c442c9 100644
--- a/extra/yassl/src/crypto_wrapper.cpp
+++ b/extra/yassl/src/crypto_wrapper.cpp
@@ -955,7 +955,7 @@ x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info)
             }
             // get blank line
             if (fgets(line, sizeof(line), file))
-              begin = ftell(file);
+            begin = ftell(file);
         }
           
     }
diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
index 08fae4ac17d..c1ee61d043e 100644
--- a/extra/yassl/src/handshake.cpp
+++ b/extra/yassl/src/handshake.cpp
@@ -50,7 +50,7 @@ void buildClientHello(SSL& ssl, ClientHello& hello)
     hello.suite_len_ = ssl.getSecurity().get_parms().suites_size_;
     memcpy(hello.cipher_suites_, ssl.getSecurity().get_parms().suites_,
            hello.suite_len_);
-    hello.comp_len_ = 1;                   
+    hello.comp_len_ = 1;
 
     hello.set_length(sizeof(ProtocolVersion) +
                      RAN_LEN +
@@ -528,8 +528,9 @@ void ProcessOldClientHello(input_buffer& input, SSL& ssl)
     input.read(len, sizeof(len));
     uint16 randomLen;
     ato16(len, randomLen);
+
     if (ch.suite_len_ > MAX_SUITE_SZ || sessionLen > ID_LEN ||
-        randomLen > RAN_LEN) {
+                                        randomLen > RAN_LEN) {
         ssl.SetError(bad_input);
         return;
     }
@@ -707,7 +708,7 @@ int DoProcessReply(SSL& ssl)
 {
     // wait for input if blocking
     if (!ssl.useSocket().wait()) {
-      ssl.SetError(receive_error);
+        ssl.SetError(receive_error);
         return 0;
     }
     uint ready = ssl.getSocket().get_ready();
@@ -750,8 +751,8 @@ int DoProcessReply(SSL& ssl)
         if (static_cast(RECORD_HEADER) > buffer.get_remaining())
             needHdr = true;
         else {
-        buffer >> hdr;
-        ssl.verifyState(hdr);
+            buffer >> hdr;
+            ssl.verifyState(hdr);
         }
 
         // make sure we have enough input in buffer to process this record
@@ -789,9 +790,8 @@ int DoProcessReply(SSL& ssl)
 void processReply(SSL& ssl)
 {
     if (ssl.GetError()) return;
-
-    if (DoProcessReply(ssl))
-    {
+  
+    if (DoProcessReply(ssl)) {
         // didn't complete process
         if (!ssl.getSocket().IsNonBlocking()) {
             // keep trying now, blocking ok
@@ -857,6 +857,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer)
     if (ssl.GetError()) return;
     ServerKeyExchange sk(ssl);
     sk.build(ssl);
+    if (ssl.GetError()) return;
 
     RecordLayerHeader rlHeader;
     HandShakeHeader   hsHeader;
@@ -875,8 +876,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer)
 // send change cipher
 void sendChangeCipher(SSL& ssl, BufferOutput buffer)
 {
-    if (ssl.getSecurity().get_parms().entity_ == server_end)
-    {
+    if (ssl.getSecurity().get_parms().entity_ == server_end) {
         if (ssl.getSecurity().get_resuming())
             ssl.verifyState(clientKeyExchangeComplete);
         else
@@ -913,7 +913,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer)
     }
     else {
         if (!ssl.getSecurity().GetContext()->GetSessionCacheOff())
-        GetSessions().add(ssl);  // store session
+            GetSessions().add(ssl);  // store session
         if (side == client_end)
             buildFinished(ssl, ssl.useHashes().use_verify(), server); // server
     }   
@@ -929,12 +929,22 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer)
 // send data
 int sendData(SSL& ssl, const void* buffer, int sz)
 {
+    int sent = 0;
+
     if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ))
         ssl.SetError(no_error);
 
+    if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) {
+        ssl.SetError(no_error);
+        ssl.SendWriteBuffered();
+        if (!ssl.GetError()) {
+            // advance sent to prvevious sent + plain size just sent
+            sent = ssl.useBuffers().prevSent + ssl.useBuffers().plainSz;
+        }
+    }
+
     ssl.verfiyHandShakeComplete();
     if (ssl.GetError()) return -1;
-    int sent = 0;
 
     for (;;) {
         int len = min(sz - sent, MAX_RECORD_SIZE);
@@ -943,6 +953,8 @@ int sendData(SSL& ssl, const void* buffer, int sz)
 
         Data data;
 
+        if (sent == sz) break;
+
         if (ssl.CompressionOn()) {
             if (Compress(static_cast(buffer) + sent, len,
                          tmp) == -1) {
@@ -957,9 +969,14 @@ int sendData(SSL& ssl, const void* buffer, int sz)
         buildMessage(ssl, out, data);
         ssl.Send(out.get_buffer(), out.get_size());
 
-        if (ssl.GetError()) return -1;
+        if (ssl.GetError()) {
+            if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) {
+                ssl.useBuffers().plainSz  = len;
+                ssl.useBuffers().prevSent = sent;
+            }
+            return -1;
+        }
         sent += len;
-        if (sent == sz) break;
     }
     ssl.useLog().ShowData(sent, true);
     return sent;
@@ -992,7 +1009,7 @@ int receiveData(SSL& ssl, Data& data, bool peek)
     if (peek)
         ssl.PeekData(data);
     else
-    ssl.fillData(data);
+        ssl.fillData(data);
 
     ssl.useLog().ShowData(data.get_length());
     if (ssl.GetError()) return -1;
diff --git a/extra/yassl/src/make.bat b/extra/yassl/src/make.bat
old mode 100644
new mode 100755
diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp
index 3cf6c14c4b3..d88df13c08e 100644
--- a/extra/yassl/src/socket_wrapper.cpp
+++ b/extra/yassl/src/socket_wrapper.cpp
@@ -109,19 +109,28 @@ uint Socket::get_ready() const
 }
 
 
-uint Socket::send(const byte* buf, unsigned int sz, int flags) const
+uint Socket::send(const byte* buf, unsigned int sz, unsigned int& written,
+                  int flags)
 {
     const byte* pos = buf;
     const byte* end = pos + sz;
 
+    wouldBlock_ = false;
+
     while (pos != end) {
         int sent = ::send(socket_, reinterpret_cast(pos),
                           static_cast(end - pos), flags);
-
-    if (sent == -1)
-        return 0;
-
+        if (sent == -1) {
+            if (get_lastError() == SOCKET_EWOULDBLOCK || 
+                get_lastError() == SOCKET_EAGAIN) {
+                wouldBlock_  = true; // would have blocked this time only
+                nonBlocking_ = true; // nonblocking, win32 only way to tell 
+                return 0;
+            }
+            return static_cast(-1);
+        }
         pos += sent;
+        written += sent;
     }
 
     return sz;
@@ -140,8 +149,8 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags)
             get_lastError() == SOCKET_EAGAIN) {
             wouldBlock_  = true; // would have blocked this time only
             nonBlocking_ = true; // socket nonblocking, win32 only way to tell
-        return 0;
-    }
+            return 0;
+        }
     }
     else if (recvd == 0)
         return static_cast(-1);
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 67d2d428e51..00a3b885f88 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -252,60 +252,73 @@ int SSL_connect(SSL* ssl)
     if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
         ssl->SetError(no_error);
 
+    if (ssl->GetError() == YasslError(SSL_ERROR_WANT_WRITE)) {
+    
+        ssl->SetError(no_error);
+        ssl->SendWriteBuffered();
+        if (!ssl->GetError())
+            ssl->useStates().UseConnect() =
+                             ConnectState(ssl->getStates().GetConnect() + 1);
+    }
+
     ClientState neededState;
 
     switch (ssl->getStates().GetConnect()) {
 
     case CONNECT_BEGIN :
-    sendClientHello(*ssl);
+        sendClientHello(*ssl);
         if (!ssl->GetError())
             ssl->useStates().UseConnect() = CLIENT_HELLO_SENT;
 
     case CLIENT_HELLO_SENT :
         neededState = ssl->getSecurity().get_resuming() ?
-        serverFinishedComplete : serverHelloDoneComplete;
-    while (ssl->getStates().getClient() < neededState) {
-        if (ssl->GetError()) break;
-    processReply(*ssl);
-    }
+                      serverFinishedComplete : serverHelloDoneComplete;
+        while (ssl->getStates().getClient() < neededState) {
+            if (ssl->GetError()) break;
+            processReply(*ssl);
+            // if resumption failed, reset needed state 
+            if (neededState == serverFinishedComplete)
+                if (!ssl->getSecurity().get_resuming())
+                    neededState = serverHelloDoneComplete;
+        }
         if (!ssl->GetError())
             ssl->useStates().UseConnect() = FIRST_REPLY_DONE;
 
     case FIRST_REPLY_DONE :
-    if(ssl->getCrypto().get_certManager().sendVerify())
-        sendCertificate(*ssl);
+        if(ssl->getCrypto().get_certManager().sendVerify())
+            sendCertificate(*ssl);
 
-    if (!ssl->getSecurity().get_resuming())
-        sendClientKeyExchange(*ssl);
+        if (!ssl->getSecurity().get_resuming())
+            sendClientKeyExchange(*ssl);
 
-    if(ssl->getCrypto().get_certManager().sendVerify())
-        sendCertificateVerify(*ssl);
+        if(ssl->getCrypto().get_certManager().sendVerify())
+            sendCertificateVerify(*ssl);
 
-    sendChangeCipher(*ssl);
-    sendFinished(*ssl, client_end);
-    ssl->flushBuffer();
+        sendChangeCipher(*ssl);
+        sendFinished(*ssl, client_end);
+        ssl->flushBuffer();
 
         if (!ssl->GetError())
             ssl->useStates().UseConnect() = FINISHED_DONE;
 
     case FINISHED_DONE :
-    if (!ssl->getSecurity().get_resuming())
-        while (ssl->getStates().getClient() < serverFinishedComplete) {
-            if (ssl->GetError()) break;
-        processReply(*ssl);
-        }
+        if (!ssl->getSecurity().get_resuming())
+            while (ssl->getStates().getClient() < serverFinishedComplete) {
+                if (ssl->GetError()) break;
+                processReply(*ssl);
+            }
         if (!ssl->GetError())
             ssl->useStates().UseConnect() = SECOND_REPLY_DONE;
 
     case SECOND_REPLY_DONE :
-    ssl->verifyState(serverFinishedComplete);
-    ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
+        ssl->verifyState(serverFinishedComplete);
+        ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
 
         if (ssl->GetError()) {
             GetErrors().Add(ssl->GetError());
-        return SSL_FATAL_ERROR;
+            return SSL_FATAL_ERROR;
         }   
-    return SSL_SUCCESS;
+        return SSL_SUCCESS;
 
     default :
         return SSL_FATAL_ERROR; // unkown state
@@ -331,27 +344,36 @@ int SSL_accept(SSL* ssl)
     if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
         ssl->SetError(no_error);
 
+    if (ssl->GetError() == YasslError(SSL_ERROR_WANT_WRITE)) {
+    
+        ssl->SetError(no_error);
+        ssl->SendWriteBuffered();
+        if (!ssl->GetError())
+            ssl->useStates().UseAccept() =
+                             AcceptState(ssl->getStates().GetAccept() + 1);
+    }
+
     switch (ssl->getStates().GetAccept()) {
 
     case ACCEPT_BEGIN :
-    processReply(*ssl);
+        processReply(*ssl);
         if (!ssl->GetError())
             ssl->useStates().UseAccept() = ACCEPT_FIRST_REPLY_DONE;
 
     case ACCEPT_FIRST_REPLY_DONE :
-    sendServerHello(*ssl);
+        sendServerHello(*ssl);
 
-    if (!ssl->getSecurity().get_resuming()) {
-        sendCertificate(*ssl);
+        if (!ssl->getSecurity().get_resuming()) {
+            sendCertificate(*ssl);
 
-        if (ssl->getSecurity().get_connection().send_server_key_)
-            sendServerKeyExchange(*ssl);
+            if (ssl->getSecurity().get_connection().send_server_key_)
+                sendServerKeyExchange(*ssl);
 
-        if(ssl->getCrypto().get_certManager().verifyPeer())
-            sendCertificateRequest(*ssl);
+            if(ssl->getCrypto().get_certManager().verifyPeer())
+                sendCertificateRequest(*ssl);
 
-        sendServerHelloDone(*ssl);
-        ssl->flushBuffer();
+            sendServerHelloDone(*ssl);
+            ssl->flushBuffer();
         }
       
         if (!ssl->GetError())
@@ -359,40 +381,40 @@ int SSL_accept(SSL* ssl)
 
     case SERVER_HELLO_DONE :
         if (!ssl->getSecurity().get_resuming()) {
-        while (ssl->getStates().getServer() < clientFinishedComplete) {
-            if (ssl->GetError()) break;
-            processReply(*ssl);
+            while (ssl->getStates().getServer() < clientFinishedComplete) {
+                if (ssl->GetError()) break;
+                processReply(*ssl);
+            }
         }
-    }
         if (!ssl->GetError())
             ssl->useStates().UseAccept() = ACCEPT_SECOND_REPLY_DONE;
 
     case ACCEPT_SECOND_REPLY_DONE :
-    sendChangeCipher(*ssl);
-    sendFinished(*ssl, server_end);
-    ssl->flushBuffer();
+        sendChangeCipher(*ssl);
+        sendFinished(*ssl, server_end);
+        ssl->flushBuffer();
 
         if (!ssl->GetError())
             ssl->useStates().UseAccept() = ACCEPT_FINISHED_DONE;
 
     case ACCEPT_FINISHED_DONE :
-    if (ssl->getSecurity().get_resuming()) {
-        while (ssl->getStates().getServer() < clientFinishedComplete) {
-          if (ssl->GetError()) break;
-          processReply(*ssl);
-      }
-    }
+        if (ssl->getSecurity().get_resuming()) {
+            while (ssl->getStates().getServer() < clientFinishedComplete) {
+                if (ssl->GetError()) break;
+                processReply(*ssl);
+            }
+        }
         if (!ssl->GetError())
             ssl->useStates().UseAccept() = ACCEPT_THIRD_REPLY_DONE;
 
     case ACCEPT_THIRD_REPLY_DONE :
-    ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
+        ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
 
         if (ssl->GetError()) {
             GetErrors().Add(ssl->GetError());
-        return SSL_FATAL_ERROR;
+            return SSL_FATAL_ERROR;
         }
-    return SSL_SUCCESS;
+        return SSL_SUCCESS;
 
     default:
         return SSL_FATAL_ERROR; // unknown state
@@ -1097,7 +1119,6 @@ int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md, const byte* salt,
             ivLeft    -= store;
         }
     }
-    assert(keyOutput == (keyLen + ivLen));
     return keyOutput;
 }
 
diff --git a/extra/yassl/src/yassl.cpp b/extra/yassl/src/yassl.cpp
index 815277ce6f3..99a1da5371b 100644
--- a/extra/yassl/src/yassl.cpp
+++ b/extra/yassl/src/yassl.cpp
@@ -69,13 +69,13 @@ void SetUpBase(Base& base, ConnectionEnd end, SOCKET_T s)
 
     if (base.ca_)
         if (SSL_CTX_load_verify_locations(base.ctx_,
-            base.ca_, 0) != SSL_SUCCESS) assert(0);
+            base.ca_, 0) != SSL_SUCCESS) throw(0);
     if (base.cert_)
         if (SSL_CTX_use_certificate_file(base.ctx_,
-            base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0);
+            base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0);
     if (base.key_)
         if (SSL_CTX_use_PrivateKey_file(base.ctx_, base.key_,
-            SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0);
+            SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0);
 
     if (end == server_end) SetDH(base);
 
diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp
index e167075b984..74735347841 100644
--- a/extra/yassl/src/yassl_error.cpp
+++ b/extra/yassl/src/yassl_error.cpp
@@ -31,6 +31,11 @@
     #pragma warning(disable: 4996)
 #endif
 
+#ifdef _MSC_VER
+    // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy
+    #pragma warning(disable: 4996)
+#endif
+
 namespace yaSSL {
 
 
@@ -59,8 +64,9 @@ void SetErrorString(unsigned long error, char* buffer)
 {
     using namespace TaoCrypt;
     const int max = MAX_ERROR_SZ;  // shorthand
+    int localError = error;        // errors from a few enums 
 
-    switch (error) {
+    switch (localError) {
 
         // yaSSL proper errors
     case range_error :
@@ -121,7 +127,7 @@ void SetErrorString(unsigned long error, char* buffer)
 
     case certificate_error :
         strncpy(buffer, "unable to proccess cerificate", max);
-        break; 
+        break;
 
     case privateKey_error :
         strncpy(buffer, "unable to proccess private key, bad format", max);
@@ -130,7 +136,7 @@ void SetErrorString(unsigned long error, char* buffer)
     case badVersion_error :
         strncpy(buffer, "protocol version mismatch", max);
         break;
-        
+
     case compress_error :
         strncpy(buffer, "compression error", max);
         break;
@@ -148,6 +154,10 @@ void SetErrorString(unsigned long error, char* buffer)
         strncpy(buffer, "the read operation would block", max);
         break;
 
+    case SSL_ERROR_WANT_WRITE :
+        strncpy(buffer, "the write operation would block", max);
+        break;
+
     case CERTFICATE_ERROR :
         strncpy(buffer, "Unable to verify certificate", max);
         break;
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index d981605d35a..6d2549749f2 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -117,7 +117,7 @@ void ClientDiffieHellmanPublic::build(SSL& ssl)
     if (*dhClient.get_agreedKey() == 0) 
         ssl.set_preMaster(dhClient.get_agreedKey() + 1, keyLength - 1);
     else
-    ssl.set_preMaster(dhClient.get_agreedKey(), keyLength);
+        ssl.set_preMaster(dhClient.get_agreedKey(), keyLength);
 }
 
 
@@ -135,8 +135,7 @@ void DH_Server::build(SSL& ssl)
     mySTL::auto_ptr auth;
     const CertManager& cert = ssl.getCrypto().get_certManager();
     
-    if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo)
-    {
+    if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) {
         if (cert.get_keyType() != rsa_sa_algo) {
             ssl.SetError(privateKey_error);
             return;
@@ -925,8 +924,6 @@ Data::Data(uint16 len, opaque* b)
 
 void Data::SetData(uint16 len, const opaque* buffer)
 {
-    assert(write_buffer_ == 0);
-
     length_ = len;
     write_buffer_ = buffer;
 }
@@ -992,6 +989,11 @@ void Data::Process(input_buffer& input, SSL& ssl)
     int dataSz = msgSz - ivExtra - digestSz - pad - padSz;
     opaque verify[SHA_LEN];
 
+    if (dataSz < 0) {
+        ssl.SetError(bad_input);
+        return;
+    }
+
     const byte* rawData = input.get_buffer() + input.get_current();
 
     // read data
@@ -1006,10 +1008,10 @@ void Data::Process(input_buffer& input, SSL& ssl)
                                             tmp.get_buffer(), tmp.get_size()));
         }
         else {
-        input_buffer* data;
-        ssl.addData(data = NEW_YS input_buffer(dataSz));
-        input.read(data->get_buffer(), dataSz);
-        data->add_size(dataSz);
+            input_buffer* data;
+            ssl.addData(data = NEW_YS input_buffer(dataSz));
+            input.read(data->get_buffer(), dataSz);
+            data->add_size(dataSz);
         }
 
         if (ssl.isTLS())
@@ -1294,12 +1296,11 @@ void ServerHello::Process(input_buffer&, SSL& ssl)
     ssl.set_pending(cipher_suite_[1]);
     ssl.set_random(random_, server_end);
     if (id_len_)
-    ssl.set_sessionID(session_id_);
+        ssl.set_sessionID(session_id_);
     else
         ssl.useSecurity().use_connection().sessionID_Set_ = false;
 
-    if (ssl.getSecurity().get_resuming())
-    {
+    if (ssl.getSecurity().get_resuming()) {
         if (memcmp(session_id_, ssl.getSecurity().get_resume().GetID(),
                    ID_LEN) == 0) {
             ssl.set_masterSecret(ssl.getSecurity().get_resume().GetSecret());
@@ -1423,7 +1424,7 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello)
     if (hello.id_len_) input.read(hello.session_id_, ID_LEN);
     
     // Suites
-    byte tmp[2];
+    byte   tmp[2];
     uint16 len;
     tmp[0] = input[AUTO];
     tmp[1] = input[AUTO];
@@ -1431,8 +1432,8 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello)
 
     hello.suite_len_ = min(len, static_cast(MAX_SUITE_SZ));
     input.read(hello.cipher_suites_, hello.suite_len_);
-    if (len > hello.suite_len_) // ignore extra suites
-        input.set_current(input.get_current() + len -  hello.suite_len_);
+    if (len > hello.suite_len_)  // ignore extra suites
+        input.set_current(input.get_current() + len - hello.suite_len_);
 
     // Compression
     hello.comp_len_ = input[AUTO];
@@ -1496,8 +1497,9 @@ void ClientHello::Process(input_buffer&, SSL& ssl)
     if (ssl.GetMultiProtocol()) {   // SSLv23 support
         if (ssl.isTLS() && client_version_.minor_ < 1) {
             // downgrade to SSLv3
-        ssl.useSecurity().use_connection().TurnOffTLS();
-        ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
+            ssl.useSecurity().use_connection().TurnOffTLS();
+            
+            ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
             bool removeDH  = ssl.getSecurity().get_parms().removeDH_;
             bool removeRSA = false;
             bool removeDSA = false;
@@ -1511,7 +1513,7 @@ void ClientHello::Process(input_buffer&, SSL& ssl)
             // reset w/ SSL suites
             ssl.useSecurity().use_parms().SetSuites(pv, removeDH, removeRSA,
                                                     removeDSA);
-    }
+        }
         else if (ssl.isTLSv1_1() && client_version_.minor_ == 1)
             // downgrade to TLSv1, but use same suites
             ssl.useSecurity().use_connection().TurnOffTLS1_1();
@@ -1542,6 +1544,7 @@ void ClientHello::Process(input_buffer&, SSL& ssl)
         ssl.set_session(session);
         ssl.useSecurity().set_resuming(true);
         ssl.matchSuite(session->GetSuite(), SUITE_LEN);
+        if (ssl.GetError()) return;
         ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]);
         ssl.set_masterSecret(session->GetSecret());
 
@@ -2038,7 +2041,7 @@ void Finished::Process(input_buffer& input, SSL& ssl)
     // verify hashes
     const  Finished& verify = ssl.getHashes().get_verify();
     uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ;
-
+    
     input.read(hashes_.md5_, finishedSz);
 
     if (memcmp(&hashes_, &verify.hashes_, finishedSz)) {
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 66a854e6922..15a85e36909 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -308,7 +308,7 @@ SSL::SSL(SSL_CTX* ctx)
             SetError(YasslError(err));
             return;
         }
-        else if (serverSide && !(ctx->GetCiphers().setSuites_)) {
+        else if (serverSide) {
             // remove RSA or DSA suites depending on cert key type
             ProtocolVersion pv = secure_.get_connection().version_;
             
@@ -1128,8 +1128,28 @@ void SSL::flushBuffer()
 
 void SSL::Send(const byte* buffer, uint sz)
 {
-    if (socket_.send(buffer, sz) != sz)
-        SetError(send_error);
+    unsigned int sent = 0;
+
+    if (socket_.send(buffer, sz, sent) != sz) {
+        if (socket_.WouldBlock()) {
+            buffers_.SetOutput(NEW_YS output_buffer(sz - sent, buffer + sent,
+                                                    sz - sent));
+            SetError(YasslError(SSL_ERROR_WANT_WRITE));
+        }
+        else
+            SetError(send_error);
+    }
+}
+
+
+void SSL::SendWriteBuffered()
+{
+    output_buffer* out = buffers_.TakeOutput();
+
+    if (out) {
+        mySTL::auto_ptr tmp(out);
+        Send(out->get_buffer(), out->get_size());
+    }
 }
 
 
@@ -1291,7 +1311,6 @@ void SSL::matchSuite(const opaque* peer, uint length)
             if (secure_.use_parms().suites_[i] == peer[j]) {
                 secure_.use_parms().suite_[0] = 0x00;
                 secure_.use_parms().suite_[1] = peer[j];
-
                 return;
             }
 
@@ -1435,7 +1454,6 @@ void SSL::addBuffer(output_buffer* b)
 
 void SSL_SESSION::CopyX509(X509* x)
 {
-    assert(peerX509_ == 0);
     if (x == 0) return;
 
     X509_NAME* issuer   = x->GetIssuer();
@@ -1833,7 +1851,7 @@ SSL_CTX::GetCA_List() const
 }
 
 
-VerifyCallback SSL_CTX::getVerifyCallback() const
+const VerifyCallback SSL_CTX::getVerifyCallback() const
 {
     return verifyCallback_;
 }
@@ -2232,7 +2250,7 @@ Hashes& sslHashes::use_certVerify()
 }
 
 
-Buffers::Buffers() : rawInput_(0)
+Buffers::Buffers() : prevSent(0), plainSz(0), rawInput_(0), output_(0)
 {}
 
 
@@ -2243,12 +2261,18 @@ Buffers::~Buffers()
     STL::for_each(dataList_.begin(), dataList_.end(),
                   del_ptr_zero()) ;
     ysDelete(rawInput_);
+    ysDelete(output_);
+}
+
+
+void Buffers::SetOutput(output_buffer* ob)
+{
+    output_ = ob;
 }
 
 
 void Buffers::SetRawInput(input_buffer* ib)
 {
-    assert(rawInput_ == 0);
     rawInput_ = ib;
 }
 
@@ -2262,6 +2286,15 @@ input_buffer* Buffers::TakeRawInput()
 }
 
 
+output_buffer* Buffers::TakeOutput()
+{
+    output_buffer* ret = output_;
+    output_ = 0;
+
+    return ret;
+}
+
+
 const Buffers::inputList& Buffers::getData() const
 {
     return dataList_;
@@ -2536,14 +2569,12 @@ ASN1_STRING* StringHolder::GetString()
     // these versions should never get called
     int Compress(const byte* in, int sz, input_buffer& buffer)
     {
-        assert(0);  
         return -1;
     } 
 
 
     int DeCompress(input_buffer& in, int sz, input_buffer& out)
     {
-        assert(0);  
         return -1;
     } 
 
diff --git a/extra/yassl/taocrypt/README b/extra/yassl/taocrypt/README
index 0a7ff301786..bd786b7ce54 100644
--- a/extra/yassl/taocrypt/README
+++ b/extra/yassl/taocrypt/README
@@ -21,7 +21,7 @@ Stream Ciphers: ARC4
 Public Key Crypto: RSA, DSA, Diffie-Hellman
 Password based key derivation: PBKDF2 from PKCS #5
 Pseudo Random Number Generators
-Lare Integer Support
+Large Integer Support
 Base 16/64 encoding/decoding
 DER encoding/decoding
 X.509 processing
diff --git a/extra/yassl/taocrypt/benchmark/benchmark.cpp b/extra/yassl/taocrypt/benchmark/benchmark.cpp
index 55e94275b20..225a1a0fa46 100644
--- a/extra/yassl/taocrypt/benchmark/benchmark.cpp
+++ b/extra/yassl/taocrypt/benchmark/benchmark.cpp
@@ -117,7 +117,7 @@ void bench_des()
 
     double persec = 1 / total * megs;
 
-    printf("3DES     %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+    printf("3DES     %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                              persec);
 }
 
@@ -137,7 +137,7 @@ void bench_aes(bool show)
     double persec = 1 / total * megs;
 
     if (show)
-        printf("AES      %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+        printf("AES      %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                                  persec);
 }
 
@@ -156,7 +156,7 @@ void bench_twofish()
 
     double persec = 1 / total * megs;
 
-    printf("Twofish  %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+    printf("Twofish  %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                             persec);
 
 }
@@ -176,7 +176,7 @@ void bench_blowfish()
 
     double persec = 1 / total * megs;
 
-    printf("Blowfish %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+    printf("Blowfish %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                              persec);
 }
 
@@ -195,7 +195,7 @@ void bench_arc4()
 
     double persec = 1 / total * megs;
 
-    printf("ARC4     %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+    printf("ARC4     %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                              persec);
 }
 
@@ -217,7 +217,7 @@ void bench_md5()
 
     double persec = 1 / total * megs;
 
-    printf("MD5      %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+    printf("MD5      %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                              persec);
 }
 
@@ -245,7 +245,7 @@ void bench_sha()
 
     double persec = 1 / total * megs;
 
-    printf("SHA      %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+    printf("SHA      %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                              persec);
 }
 
@@ -267,7 +267,7 @@ void bench_ripemd()
 
     double persec = 1 / total * megs;
 
-    printf("RIPEMD   %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+    printf("RIPEMD   %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
                                                              persec);
 }
 
@@ -290,7 +290,7 @@ void bench_rsa()
     byte      message[] = "Everyone gets Friday off.";
     byte      cipher[128];  // for 1024 bit
     byte      plain[128];   // for 1024 bit
-    const int len = strlen((char*)message);
+    const int len = (word32)strlen((char*)message);
     
     int i;    
     double start = current_time();
diff --git a/extra/yassl/taocrypt/benchmark/benchmark.dsp b/extra/yassl/taocrypt/benchmark/benchmark.dsp
index 878dc2b2783..449299a1c8d 100644
--- a/extra/yassl/taocrypt/benchmark/benchmark.dsp
+++ b/extra/yassl/taocrypt/benchmark/benchmark.dsp
@@ -49,8 +49,8 @@ BSC32=bscmake.exe
 # ADD BASE BSC32 /nologo
 # ADD BSC32 /nologo
 LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
 
 !ELSEIF  "$(CFG)" == "benchmark - Win32 Debug"
 
@@ -64,7 +64,7 @@ LINK32=link.exe
 # PROP Output_Dir "Debug"
 # PROP Intermediate_Dir "Debug"
 # PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
 # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\mySTL" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
@@ -72,8 +72,8 @@ BSC32=bscmake.exe
 # ADD BASE BSC32 /nologo
 # ADD BSC32 /nologo
 LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
 
 !ENDIF 
 
diff --git a/extra/yassl/taocrypt/benchmark/dh1024.der b/extra/yassl/taocrypt/benchmark/dh1024.der
index 1a85d90f3f7..09f81ee14c1 100644
Binary files a/extra/yassl/taocrypt/benchmark/dh1024.der and b/extra/yassl/taocrypt/benchmark/dh1024.der differ
diff --git a/extra/yassl/taocrypt/benchmark/dsa1024.der b/extra/yassl/taocrypt/benchmark/dsa1024.der
index 1fcb37fad6a..3a6dfca4b8f 100644
Binary files a/extra/yassl/taocrypt/benchmark/dsa1024.der and b/extra/yassl/taocrypt/benchmark/dsa1024.der differ
diff --git a/extra/yassl/taocrypt/benchmark/make.bat b/extra/yassl/taocrypt/benchmark/make.bat
old mode 100644
new mode 100755
diff --git a/extra/yassl/taocrypt/benchmark/rsa1024.der b/extra/yassl/taocrypt/benchmark/rsa1024.der
index 8fc91814472..5ba3fbe6c9c 100644
Binary files a/extra/yassl/taocrypt/benchmark/rsa1024.der and b/extra/yassl/taocrypt/benchmark/rsa1024.der differ
diff --git a/extra/yassl/taocrypt/certs/client-cert.der b/extra/yassl/taocrypt/certs/client-cert.der
new file mode 100644
index 00000000000..9c2ef138bf6
Binary files /dev/null and b/extra/yassl/taocrypt/certs/client-cert.der differ
diff --git a/extra/yassl/taocrypt/certs/client-key.der b/extra/yassl/taocrypt/certs/client-key.der
new file mode 100644
index 00000000000..649406c4417
Binary files /dev/null and b/extra/yassl/taocrypt/certs/client-key.der differ
diff --git a/extra/yassl/taocrypt/certs/dh1024.dat b/extra/yassl/taocrypt/certs/dh1024.dat
new file mode 100644
index 00000000000..86a95518278
--- /dev/null
+++ b/extra/yassl/taocrypt/certs/dh1024.dat
@@ -0,0 +1 @@
+30818702818100DA9A18547FF03B385CC16508C173A7EF4EB61CB40EF8FEF3B31F145051676166BCDC3FE6B799FC394D08C26385F9413F896E09117E46209D6923602683CEA100924A6EE695281775C619DAA94EA8CB3691B4275B0183F1D39639EBC92995FE645D6C1BC28D409E585549BBD2C5DCDD6C208B04EADD8B7A6D997F72CBAD88390F020102
\ No newline at end of file
diff --git a/extra/yassl/taocrypt/certs/dsa512.der b/extra/yassl/taocrypt/certs/dsa512.der
new file mode 100644
index 00000000000..027bedeffb1
Binary files /dev/null and b/extra/yassl/taocrypt/certs/dsa512.der differ
diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp
index ece7140741a..c20387d86c7 100644
--- a/extra/yassl/taocrypt/include/asn.hpp
+++ b/extra/yassl/taocrypt/include/asn.hpp
@@ -167,6 +167,7 @@ public:
     void Decode(RSA_PublicKey&);
 private:
     void ReadHeader();
+    void ReadHeaderOpenSSL();
 };
 
 
diff --git a/extra/yassl/taocrypt/include/block.hpp b/extra/yassl/taocrypt/include/block.hpp
index ad3dcf2db59..ae3df8a3009 100644
--- a/extra/yassl/taocrypt/include/block.hpp
+++ b/extra/yassl/taocrypt/include/block.hpp
@@ -61,10 +61,6 @@ public:
     void          destroy(pointer p) {p->~T();}
     size_type     max_size() const {return ~size_type(0)/sizeof(T);}
 protected:
-    static void CheckSize(size_t n)
-    {
-        assert(n <= ~size_t(0) / sizeof(T));
-    }
 };
 
 
@@ -101,7 +97,8 @@ public:
 
     pointer allocate(size_type n, const void* = 0)
     {
-        this->CheckSize(n);
+        if (n > this->max_size())
+            return 0;
         if (n == 0)
             return 0;
         return NEW_TC T[n];
@@ -144,9 +141,8 @@ public:
         return *this;
     }
 
-    T& operator[] (word32 i) { assert(i < sz_); return buffer_[i]; }
-    const T& operator[] (word32 i) const 
-        { assert(i < sz_); return buffer_[i]; }
+    T& operator[] (word32 i) { return buffer_[i]; }
+    const T& operator[] (word32 i) const { return buffer_[i]; }
 
     T* operator+ (word32 i) { return buffer_ + i; }
     const T* operator+ (word32 i) const { return buffer_ + i; }
diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp
index 99d932353df..3ad2aedc587 100644
--- a/extra/yassl/taocrypt/include/blowfish.hpp
+++ b/extra/yassl/taocrypt/include/blowfish.hpp
@@ -59,11 +59,11 @@ public:
     void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION);
     void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); }
 private:
-	static const word32 p_init_[ROUNDS + 2];
-	static const word32 s_init_[4 * 256];
+    static const word32 p_init_[ROUNDS + 2];
+    static const word32 s_init_[4 * 256];
 
-	word32 pbox_[ROUNDS + 2 + 4 * 256];
-	word32* sbox_;
+    word32 pbox_[ROUNDS + 2 + 4 * 256];
+    word32* sbox_;
 
     void crypt_block(const word32 in[2], word32 out[2]) const;
     void AsmProcess(const byte* in, byte* out) const;
diff --git a/extra/yassl/taocrypt/include/des.hpp b/extra/yassl/taocrypt/include/des.hpp
index f99a289392f..2bc41fc2628 100644
--- a/extra/yassl/taocrypt/include/des.hpp
+++ b/extra/yassl/taocrypt/include/des.hpp
@@ -84,7 +84,7 @@ private:
 // DES_EDE3
 class DES_EDE3 : public Mode_BASE {
 public:
-    DES_EDE3(CipherDir DIR, Mode MODE) 
+    DES_EDE3(CipherDir DIR, Mode MODE)
         : Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {}
 
     void SetKey(const byte*, word32, CipherDir dir);
diff --git a/extra/yassl/taocrypt/include/hash.hpp b/extra/yassl/taocrypt/include/hash.hpp
index fa5f6c04720..4ebc82e073d 100644
--- a/extra/yassl/taocrypt/include/hash.hpp
+++ b/extra/yassl/taocrypt/include/hash.hpp
@@ -63,8 +63,8 @@ protected:
     word32          buffLen_;   // in bytes
     HashLengthType  loLen_;     // length in bytes
     HashLengthType  hiLen_;     // length in bytes
-    word32  digest_[MaxDigestSz];
-    word32  buffer_[MaxBufferSz / sizeof(word32)];
+    word32          digest_[MaxDigestSz];
+    word32          buffer_[MaxBufferSz / sizeof(word32)];
 
     virtual void Transform() = 0;
 
diff --git a/extra/yassl/taocrypt/include/hc128.hpp b/extra/yassl/taocrypt/include/hc128.hpp
new file mode 100644
index 00000000000..d1cf5f075f2
--- /dev/null
+++ b/extra/yassl/taocrypt/include/hc128.hpp
@@ -0,0 +1,63 @@
+/*
+   Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+ 
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING. If not, write to the
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+   MA  02110-1301  USA.
+*/
+
+/* hc128.hpp defines HC128
+*/
+
+
+#ifndef TAO_CRYPT_HC128_HPP
+#define TAO_CRYPT_HC128_HPP
+
+#include "misc.hpp"
+
+namespace TaoCrypt {
+
+
+// HC128 encryption and decryption
+class HC128 {
+public:
+
+    typedef HC128 Encryption;
+    typedef HC128 Decryption;
+
+
+    HC128() {}
+
+    void Process(byte*, const byte*, word32);
+    void SetKey(const byte*, const byte*);
+private:
+    word32 T_[1024];             /* P[i] = T[i];  Q[i] = T[1024 + i ]; */
+    word32 X_[16];
+    word32 Y_[16];
+    word32 counter1024_;         /* counter1024 = i mod 1024 at the ith step */
+    word32 key_[8];
+    word32 iv_[8];
+
+    void SetIV(const byte*);
+    void GenerateKeystream(word32*);
+    void SetupUpdate();
+
+    HC128(const HC128&);                  // hide copy
+    const HC128 operator=(const HC128&);  // and assign
+};
+
+} // namespace
+
+
+#endif // TAO_CRYPT_HC128_HPP
+
diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp
index 186d62bb866..256573cf622 100644
--- a/extra/yassl/taocrypt/include/integer.hpp
+++ b/extra/yassl/taocrypt/include/integer.hpp
@@ -110,13 +110,6 @@ namespace TaoCrypt {
 #endif
 
 
-// general MIN
-template inline
-const T& min(const T& a, const T& b)
-{
-    return a < b ? a : b;
-}
-
 
 // general MAX
 template inline
diff --git a/extra/yassl/taocrypt/include/kernelc.hpp b/extra/yassl/taocrypt/include/kernelc.hpp
index daa3762d5dd..5bdf1cffa3f 100644
--- a/extra/yassl/taocrypt/include/kernelc.hpp
+++ b/extra/yassl/taocrypt/include/kernelc.hpp
@@ -30,17 +30,5 @@ extern "C" void* memcpy(void*, const void*, size_t);
 extern "C" void* memset(void*, int, size_t);
 extern "C" void  printk(char *fmt, ...);
 
-#define KERN_ERR "<3>"   /* error conditions */
-
-#if defined(NDEBUG)
-    #define assert(p)  	((void)0)
-#else
-    #define assert(expr)   \
-    if (!(expr))         { \
-         printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
-         #expr,__FILE__,__FUNCTION__,__LINE__); }
-#endif
-
-
 
 #endif // TAOCRYPT_KERNELC_HPP
diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp
index a375b17eb1e..b6925f916f8 100644
--- a/extra/yassl/taocrypt/include/misc.hpp
+++ b/extra/yassl/taocrypt/include/misc.hpp
@@ -24,7 +24,6 @@
 
 #if !defined(DO_TAOCRYPT_KERNEL_MODE)
     #include 
-    #include 
     #include 
 #else
     #include "kernelc.hpp"
@@ -62,30 +61,30 @@ void CleanUp();
     template
     void tcDelete(T* ptr)
     {
-    if (ptr) ptr->~T();
-    ::operator delete(ptr, TaoCrypt::tc);
+        if (ptr) ptr->~T();
+        ::operator delete(ptr, TaoCrypt::tc);
     }
 
     template
     void tcArrayDelete(T* ptr)
     {
-    // can't do array placement destruction since not tracking size in
-    // allocation, only allow builtins to use array placement since they
-    // don't need destructors called
-    typedef char builtin[IsFundamentalType::Yes ? 1 : -1];
-    (void)sizeof(builtin);
+        // can't do array placement destruction since not tracking size in
+        // allocation, only allow builtins to use array placement since they
+        // don't need destructors called
+        typedef char builtin[IsFundamentalType::Yes ? 1 : -1];
+        (void)sizeof(builtin);
 
-    ::operator delete[](ptr, TaoCrypt::tc);
+        ::operator delete[](ptr, TaoCrypt::tc);
     }
 
     #define NEW_TC new (TaoCrypt::tc)
 
 
     // to resolve compiler generated operator delete on base classes with
-    // virtual destructors (when on stack), make sure doesn't get called
+    // virtual destructors (when on stack)
     class virtual_base {
     public:
-    static void operator delete(void*) { assert(0); }
+        static void operator delete(void*) { }
     };
 
 #else // YASSL_PURE_C
@@ -366,7 +365,6 @@ inline bool IsPowerOf2(T n)
 template 
 inline T2 ModPowerOf2(T1 a, T2 b)
 {
-    assert(IsPowerOf2(b));
     return T2(a) & (b-1);
 }
 
@@ -409,14 +407,12 @@ inline bool IsAligned(const void* p, T* dummy = 0)	// VC60 workaround
 
 template  inline T rotlFixed(T x, unsigned int y)
 {
-    assert(y < sizeof(T)*8);
-        return (x<>(sizeof(T)*8-y));
+    return (x<>(sizeof(T)*8-y));
 }
 
 template  inline T rotrFixed(T x, unsigned int y)
 {
-    assert(y < sizeof(T)*8);
-        return (x>>y) | (x<<(sizeof(T)*8-y));
+    return (x>>y) | (x<<(sizeof(T)*8-y));
 }
 
 #ifdef INTEL_INTRINSICS
@@ -425,13 +421,11 @@ template  inline T rotrFixed(T x, unsigned int y)
 
 template<> inline word32 rotlFixed(word32 x, word32 y)
 {
-    assert(y < 32);
     return y ? _lrotl(x, y) : x;
 }
 
 template<> inline word32 rotrFixed(word32 x, word32 y)
 {
-    assert(y < 32);
     return y ? _lrotr(x, y) : x;
 }
 
@@ -441,7 +435,9 @@ template<> inline word32 rotrFixed(word32 x, word32 y)
 #undef min
 #endif 
 
-inline word32 min(word32 a, word32 b)
+
+template 
+inline const T& min(const T& a, const T& b)
 {
     return a < b ? a : b;
 }
@@ -486,7 +482,6 @@ inline word64 ByteReverse(word64 value)
 template 
 inline void ByteReverse(T* out, const T* in, word32 byteCount)
 {
-    assert(byteCount % sizeof(T) == 0);
     word32 count = byteCount/sizeof(T);
     for (word32 i=0; i
 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
 {
     if (assumeAligned)
-    {
-        assert(IsAligned(block));
         return ByteReverseIf(*reinterpret_cast(block), order);
-    }
     else
         return UnalignedGetWord(order, block);
 }
@@ -699,7 +691,6 @@ inline void PutWord(bool assumeAligned, ByteOrder order, byte* block, T value,
 {
     if (assumeAligned)
     {
-        assert(IsAligned(block));
         if (xorBlock)
             *reinterpret_cast(block) = ByteReverseIf(value, order) 
                 ^ *reinterpret_cast(xorBlock);
@@ -812,7 +803,6 @@ inline T SafeLeftShift(T value)
 inline
 word ShiftWordsLeftByBits(word* r, unsigned int n, unsigned int shiftBits)
 {
-    assert (shiftBits=0; i--)
diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp
index 2285bd0e845..5fd36b80d3e 100644
--- a/extra/yassl/taocrypt/include/modes.hpp
+++ b/extra/yassl/taocrypt/include/modes.hpp
@@ -61,9 +61,7 @@ public:
     explicit Mode_BASE(int sz, CipherDir dir, Mode mode) 
         : blockSz_(sz), reg_(reinterpret_cast(r_)),
           tmp_(reinterpret_cast(t_)), dir_(dir), mode_(mode)
-    { 
-        assert(sz <= MaxBlockSz);
-    }
+    {}
     virtual ~Mode_BASE() {}
 
     virtual void Process(byte*, const byte*, word32);
@@ -96,8 +94,7 @@ inline void Mode_BASE::Process(byte* out, const byte* in, word32 sz)
 {
     if (mode_ == ECB)
         ECB_Process(out, in, sz);
-    else if (mode_ == CBC)
-    {
+    else if (mode_ == CBC) {
         if (dir_ == ENCRYPTION)
             CBC_Encrypt(out, in, sz);
         else
diff --git a/extra/yassl/taocrypt/include/pwdbased.hpp b/extra/yassl/taocrypt/include/pwdbased.hpp
index 5ece1a8f43b..f40a336e2c3 100644
--- a/extra/yassl/taocrypt/include/pwdbased.hpp
+++ b/extra/yassl/taocrypt/include/pwdbased.hpp
@@ -48,8 +48,9 @@ word32 PBKDF2_HMAC::DeriveKey(byte* derived, word32 dLen, const byte* pwd,
                                  word32 pLen, const byte* salt, word32 sLen,
                                  word32 iterations) const
 {
-	assert(dLen <= MaxDerivedKeyLength());
-	assert(iterations > 0);
+	if (dLen > MaxDerivedKeyLength())
+        return 0;
+
 
     ByteBlock buffer(T::DIGEST_SIZE);
 	HMAC   hmac;
diff --git a/extra/yassl/taocrypt/include/rabbit.hpp b/extra/yassl/taocrypt/include/rabbit.hpp
new file mode 100644
index 00000000000..1e7276dd8ec
--- /dev/null
+++ b/extra/yassl/taocrypt/include/rabbit.hpp
@@ -0,0 +1,65 @@
+/*
+   Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+ 
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING. If not, write to the
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+   MA  02110-1301  USA.
+*/
+
+/* rabbit.hpp defines Rabbit
+*/
+
+
+#ifndef TAO_CRYPT_RABBIT_HPP
+#define TAO_CRYPT_RABBIT_HPP
+
+#include "misc.hpp"
+
+namespace TaoCrypt {
+
+
+// Rabbit encryption and decryption
+class Rabbit {
+public:
+
+    typedef Rabbit Encryption;
+    typedef Rabbit Decryption;
+
+    enum RabbitCtx { Master = 0, Work = 1 };
+
+    Rabbit() {}
+
+    void Process(byte*, const byte*, word32);
+    void SetKey(const byte*, const byte*);
+private:
+    struct Ctx {
+        word32 x[8];
+        word32 c[8];
+        word32 carry;
+    };
+
+    Ctx masterCtx_;
+    Ctx workCtx_;
+
+    void NextState(RabbitCtx);
+    void SetIV(const byte*);
+
+    Rabbit(const Rabbit&);                  // hide copy
+    const Rabbit operator=(const Rabbit&);  // and assign
+};
+
+} // namespace
+
+
+#endif // TAO_CRYPT_RABBIT_HPP
+
diff --git a/extra/yassl/taocrypt/include/rsa.hpp b/extra/yassl/taocrypt/include/rsa.hpp
index c895ab6fd34..11a4ccfd039 100644
--- a/extra/yassl/taocrypt/include/rsa.hpp
+++ b/extra/yassl/taocrypt/include/rsa.hpp
@@ -178,7 +178,8 @@ void RSA_Encryptor::Encrypt(const byte* plain, word32 sz, byte* cipher,
                                  RandomNumberGenerator& rng)
 {
     PK_Lengths lengths(key_.GetModulus());
-    assert(sz <= lengths.FixedMaxPlaintextLength());
+    if (sz > lengths.FixedMaxPlaintextLength())
+        return;
 
     ByteBlock paddedBlock(lengths.PaddedBlockByteLength());
     padding_.Pad(plain, sz, paddedBlock.get_buffer(),
@@ -195,7 +196,6 @@ word32 RSA_Decryptor::Decrypt(const byte* cipher, word32 sz, byte* plain,
                                    RandomNumberGenerator& rng)
 {
     PK_Lengths lengths(key_.GetModulus());
-    assert(sz == lengths.FixedCiphertextLength());
 
     if (sz != lengths.FixedCiphertextLength())
         return 0;
diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp
index ad66a5bf9d0..568c0b3afd8 100644
--- a/extra/yassl/taocrypt/include/runtime.hpp
+++ b/extra/yassl/taocrypt/include/runtime.hpp
@@ -31,7 +31,6 @@
 
 #ifdef __sun
  
-#include 
 
 // Handler for pure virtual functions
 namespace __Crun {
@@ -46,9 +45,7 @@ namespace __Crun {
 #if __GNUC__ > 2
 
 extern "C" {
-#if !defined(DO_TAOCRYPT_KERNEL_MODE)
-    #include 
-#else
+#if defined(DO_TAOCRYPT_KERNEL_MODE)
     #include "kernelc.hpp"
 #endif
     int __cxa_pure_virtual () __attribute__ ((weak));
diff --git a/extra/yassl/taocrypt/include/types.hpp b/extra/yassl/taocrypt/include/types.hpp
index 3efdcdfbccb..5d8bc9f0683 100644
--- a/extra/yassl/taocrypt/include/types.hpp
+++ b/extra/yassl/taocrypt/include/types.hpp
@@ -62,7 +62,7 @@ typedef unsigned int   word32;
 // compilers we've found 64-bit multiply insructions for
 #if defined(__GNUC__) || defined(_MSC_VER) || defined(__DECCXX)
     #if !(defined(__ICC) || defined(__INTEL_COMPILER))
-    #define HAVE_64_MULTIPLY
+        #define HAVE_64_MULTIPLY
     #endif
 #endif
 
diff --git a/extra/yassl/taocrypt/mySTL/stdexcept.hpp b/extra/yassl/taocrypt/mySTL/stdexcept.hpp
index 9696995248d..15533eebc02 100644
--- a/extra/yassl/taocrypt/mySTL/stdexcept.hpp
+++ b/extra/yassl/taocrypt/mySTL/stdexcept.hpp
@@ -26,7 +26,6 @@
 
 
 #include   // strncpy
-#include   // assert
 #include   // size_t
 
 
@@ -41,7 +40,7 @@ public:
     virtual const char* what() const { return ""; }
 
     // for compiler generated call, never used
-    static void operator delete(void*) { assert(0); }
+    static void operator delete(void*) { }
 private:
     // don't allow dynamic creation of exceptions
     static void* operator new(size_t);
diff --git a/extra/yassl/taocrypt/mySTL/vector.hpp b/extra/yassl/taocrypt/mySTL/vector.hpp
index 8ba8813ca70..35b92610942 100644
--- a/extra/yassl/taocrypt/mySTL/vector.hpp
+++ b/extra/yassl/taocrypt/mySTL/vector.hpp
@@ -26,7 +26,6 @@
 
 #include "helpers.hpp"    // construct, destory, fill, etc.
 #include "algorithm.hpp"  // swap
-#include        // assert
 
 
 namespace mySTL {
@@ -141,9 +140,9 @@ private:
     // for growing, n must be bigger than other size
     vector(size_t n, const vector& other) : vec_(n)
     {
-        assert(n > other.size());
-        vec_.finish_ = uninit_copy(other.vec_.start_, other.vec_.finish_,
-                                   vec_.start_);   
+        if (n > other.size())
+            vec_.finish_ = uninit_copy(other.vec_.start_, other.vec_.finish_,
+                                       vec_.start_);
     }
 };
 
diff --git a/extra/yassl/taocrypt/src/Makefile.am b/extra/yassl/taocrypt/src/Makefile.am
index 760205a625c..9fa0861babf 100644
--- a/extra/yassl/taocrypt/src/Makefile.am
+++ b/extra/yassl/taocrypt/src/Makefile.am
@@ -21,7 +21,7 @@ libtaocrypt_la_SOURCES  = aes.cpp aestables.cpp algebra.cpp arc4.cpp \
         asn.cpp bftables.cpp blowfish.cpp coding.cpp des.cpp dh.cpp \
         dsa.cpp file.cpp hash.cpp integer.cpp md2.cpp md4.cpp md5.cpp misc.cpp \
         random.cpp ripemd.cpp rsa.cpp sha.cpp template_instnt.cpp \
-        tftables.cpp twofish.cpp
+        tftables.cpp twofish.cpp crypto.cpp rabbit.cpp hc128.cpp
 
 libtaocrypt_la_CXXFLAGS = @yassl_taocrypt_extra_cxxflags@ -DYASSL_PURE_C \
 			  @yassl_thread_cxxflags@
diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp
index 21b21dc4856..811b483b0c9 100644
--- a/extra/yassl/taocrypt/src/aes.cpp
+++ b/extra/yassl/taocrypt/src/aes.cpp
@@ -78,7 +78,7 @@ void AES::Process(byte* out, const byte* in, word32 sz)
                 out += BLOCK_SIZE;
                 in  += BLOCK_SIZE;
             }
-    }
+   }
 }
 
 #endif // DO_AES_ASM
@@ -86,8 +86,13 @@ void AES::Process(byte* out, const byte* in, word32 sz)
 
 void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
 {
-    assert( (keylen == 16) || (keylen == 24) || (keylen == 32) );
-
+    if (keylen <= 16)
+        keylen = 16;
+    else if (keylen >= 32)
+        keylen = 32;
+    else if (keylen != 24)
+        keylen = 24;
+    
     rounds_ = keylen/4 + 6;
 
     word32 temp, *rk = key_;
@@ -245,34 +250,34 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
     for (;;) {
         t0 =
             Te0[GETBYTE(s0, 3)] ^
-            Te1[GETBYTE(s1, 2)] ^
-            Te2[GETBYTE(s2, 1)] ^
-            Te3[GETBYTE(s3, 0)] ^
+            Te1[GETBYTE(s1, 2)]  ^
+            Te2[GETBYTE(s2, 1)]  ^
+            Te3[GETBYTE(s3, 0)]  ^
             rk[4];
         t1 =
             Te0[GETBYTE(s1, 3)] ^
-            Te1[GETBYTE(s2, 2)] ^
-            Te2[GETBYTE(s3, 1)] ^
-            Te3[GETBYTE(s0, 0)] ^
+            Te1[GETBYTE(s2, 2)]  ^
+            Te2[GETBYTE(s3, 1)]  ^
+            Te3[GETBYTE(s0, 0)]  ^
             rk[5];
         t2 =
             Te0[GETBYTE(s2, 3)] ^
-            Te1[GETBYTE(s3, 2)] ^
-            Te2[GETBYTE(s0, 1)] ^
-            Te3[GETBYTE(s1, 0)] ^
+            Te1[GETBYTE(s3, 2)]  ^
+            Te2[GETBYTE(s0, 1)]  ^
+            Te3[GETBYTE(s1, 0)]  ^
             rk[6];
         t3 =
             Te0[GETBYTE(s3, 3)] ^
-            Te1[GETBYTE(s0, 2)] ^
-            Te2[GETBYTE(s1, 1)] ^
-            Te3[GETBYTE(s2, 0)] ^
+            Te1[GETBYTE(s0, 2)]  ^
+            Te2[GETBYTE(s1, 1)]  ^
+            Te3[GETBYTE(s2, 0)]  ^
             rk[7];
 
         rk += 8;
         if (--r == 0) {
             break;
         }
-
+        
         s0 =
             Te0[GETBYTE(t0, 3)] ^
             Te1[GETBYTE(t1, 2)] ^
@@ -421,7 +426,7 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
         (Td4[GETBYTE(t3, 2)] & 0x00ff0000) ^
         (Td4[GETBYTE(t2, 1)] & 0x0000ff00) ^
         (Td4[GETBYTE(t1, 0)] & 0x000000ff) ^
-    rk[0];
+        rk[0];
     s1 =
         (Td4[GETBYTE(t1, 3)] & 0xff000000) ^
         (Td4[GETBYTE(t0, 2)] & 0x00ff0000) ^
diff --git a/extra/yassl/taocrypt/src/aestables.cpp b/extra/yassl/taocrypt/src/aestables.cpp
index e9d6b7a80cb..05c2c3b8e62 100644
--- a/extra/yassl/taocrypt/src/aestables.cpp
+++ b/extra/yassl/taocrypt/src/aestables.cpp
@@ -33,6 +33,4 @@ const word32 AES::rcon_[] = {
 };
 
 
-
-
 } // namespace
diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp
index 20a152d1a9d..73423d47546 100644
--- a/extra/yassl/taocrypt/src/algebra.cpp
+++ b/extra/yassl/taocrypt/src/algebra.cpp
@@ -247,7 +247,6 @@ void AbstractGroup::SimultaneousMultiply(Integer *results, const Integer &base,
 
     for (i=0; iNotNegative());
         exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 0));
         exponents[i].FindNextWindow();
         buckets[i].resize(1<<(exponents[i].windowSize-1), Identity());
@@ -288,7 +287,7 @@ void AbstractGroup::SimultaneousMultiply(Integer *results, const Integer &base,
         r = buckets[i][buckets[i].size()-1];
         if (buckets[i].size() > 1)
         {
-            for (int j= (unsigned int) (buckets[i].size()) - 2; j >= 1; j--)
+            for (size_t j = buckets[i].size()-2; j >= 1; j--)
             {
                 Accumulate(buckets[i][j], buckets[i][j+1]);
                 Accumulate(r, buckets[i][j]);
diff --git a/extra/yassl/taocrypt/src/arc4.cpp b/extra/yassl/taocrypt/src/arc4.cpp
index 0944cc31837..4630adcb11a 100644
--- a/extra/yassl/taocrypt/src/arc4.cpp
+++ b/extra/yassl/taocrypt/src/arc4.cpp
@@ -104,7 +104,7 @@ void ARC4::Process(byte* out, const byte* in, word32 length)
 #ifdef DO_ARC4_ASM
 
 #ifdef _MSC_VER
-    __declspec(naked) 
+    __declspec(naked)
 #else
     __attribute__ ((noinline))
 #endif
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index 1b81db4f0a4..72cbd092f9d 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -111,7 +111,8 @@ bool ValidateDate(const byte* date, byte format, CertDecoder::DateType dt)
     GetTime(certTime.tm_min,  date, i); 
     GetTime(certTime.tm_sec,  date, i); 
 
-    assert(date[i] == 'Z');     // only Zulu supported for this profile
+    if (date[i] != 'Z')     // only Zulu supported for this profile
+        return false;
 
     time_t ltime = time(0);
     tm* localTime = gmtime(<ime);
@@ -214,9 +215,9 @@ void PublicKey::AddToEnd(const byte* data, word32 len)
 Signer::Signer(const byte* k, word32 kSz, const char* n, const byte* h)
     : key_(k, kSz)
 {
-        size_t sz = strlen(n);
-        memcpy(name_, n, sz);
-        name_[sz] = 0;
+    size_t sz = strlen(n);
+    memcpy(name_, n, sz);
+    name_[sz] = 0;
 
     memcpy(hash_, h, SHA::DIGEST_SIZE);
 }
@@ -364,12 +365,59 @@ void RSA_Public_Decoder::Decode(RSA_PublicKey& key)
     ReadHeader();
     if (source_.GetError().What()) return;
 
+    ReadHeaderOpenSSL();   // may or may not be
+    if (source_.GetError().What()) return;
+
     // public key
     key.SetModulus(GetInteger(Integer().Ref()));
     key.SetPublicExponent(GetInteger(Integer().Ref()));
 }
 
 
+// Read OpenSSL format public header
+void RSA_Public_Decoder::ReadHeaderOpenSSL()
+{
+    byte b = source_.next();  // peek
+    source_.prev();
+
+    if (b != INTEGER) { // have OpenSSL public format
+        GetSequence();
+        b = source_.next();
+        if (b != OBJECT_IDENTIFIER) {
+            source_.SetError(OBJECT_ID_E);
+            return;
+        }
+
+        word32 len = GetLength(source_);
+        source_.advance(len);
+
+        b = source_.next();
+        if (b == TAG_NULL) {   // could have NULL tag and 0 terminator, may not 
+            b = source_.next();
+            if (b != 0) {
+                source_.SetError(EXPECT_0_E);
+                return; 
+            }
+        }
+        else
+            source_.prev();   // put back
+
+        b = source_.next();
+        if (b != BIT_STRING) {   
+            source_.SetError(BIT_STR_E);
+            return; 
+        }
+
+        len = GetLength(source_); 
+        b = source_.next();
+        if (b != 0)           // could have 0
+            source_.prev();   // put back
+        
+        GetSequence();
+    }
+}
+
+
 void RSA_Public_Decoder::ReadHeader()
 {
     GetSequence();
@@ -420,12 +468,12 @@ CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers,
                          bool noVerify, CertType ct)
     : BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0),
       signature_(0), verify_(!noVerify)
-{ 
+{
     issuer_[0] = 0;
     subject_[0] = 0;
 
     if (decode)
-        Decode(signers, ct); 
+        Decode(signers, ct);
 
 }
 
@@ -470,9 +518,9 @@ void CertDecoder::Decode(SignerList* signers, CertType ct)
         source_.SetError(SIG_OID_E);
         return;
     }
-
+    
     if (ct != CA && verify_ && !ValidateSignature(signers))
-            source_.SetError(SIG_OTHER_E);
+        source_.SetError(SIG_OTHER_E);
 }
 
 
@@ -585,21 +633,19 @@ word32 CertDecoder::GetAlgoId()
     while(length--)
         oid += source_.next();        // just sum it up for now
 
-    if (oid != SHAwDSA && oid != DSAk) {
-        b = source_.next();               // should have NULL tag and 0
-
-        if (b != TAG_NULL) {
-            source_.SetError(TAG_NULL_E);
-            return 0;
-        }
-
+    // could have NULL tag and 0 terminator, but may not
+    b = source_.next();
+    if (b == TAG_NULL) {
         b = source_.next();
         if (b != 0) {
             source_.SetError(EXPECT_0_E);
             return 0;
         }
     }
- 
+    else
+        // go back, didn't have it
+        b = source_.prev();
+
     return oid;
 }
 
@@ -653,20 +699,22 @@ word32 CertDecoder::GetDigest()
 }
 
 
-char *CertDecoder::AddTag(char *ptr, const char *buf_end, 
-                          const char *tag_name, word32 tag_name_length,
-                          word32 tag_value_length)
+// memory length checked add tag to buffer
+char* CertDecoder::AddTag(char* ptr, const char* buf_end, const char* tag_name,
+                          word32 tag_name_length, word32 tag_value_length)
 {
-  if (ptr + tag_name_length + tag_value_length > buf_end)
-      return 0;
-    
-  memcpy(ptr, tag_name, tag_name_length);
-  ptr+= tag_name_length;
-  
-  memcpy(ptr, source_.get_current(), tag_value_length);
-  ptr+= tag_value_length;
-  
-  return ptr;
+    if (ptr + tag_name_length + tag_value_length > buf_end) {
+        source_.SetError(CONTENT_E);
+        return 0;
+    }
+
+    memcpy(ptr, tag_name, tag_name_length);
+    ptr += tag_name_length;
+
+    memcpy(ptr, source_.get_current(), tag_value_length);
+    ptr += tag_value_length;
+
+    return ptr;
 }
 
 
@@ -679,18 +727,19 @@ void CertDecoder::GetName(NameType nt)
     word32 length = GetSequence();  // length of all distinguished names
 
     if (length >= ASN_NAME_MAX)
-        goto err;
+        return;
     length += source_.get_index();
-
-    char *ptr, *buf_end;
+    
+    char* ptr;
+    char* buf_end;
 
     if (nt == ISSUER) {
-        ptr= issuer_;
-        buf_end= ptr + sizeof(issuer_) - 1;  // 1 byte for trailing 0
+        ptr = issuer_;
+        buf_end = ptr + sizeof(issuer_) - 1;   // 1 byte for trailing 0
     }
     else {
-        ptr= subject_;
-        buf_end= ptr + sizeof(subject_) - 1;  // 1 byte for trailing 0
+        ptr = subject_;
+        buf_end = ptr + sizeof(subject_) - 1;  // 1 byte for trailing 0
     }
 
     while (source_.get_index() < length) {
@@ -716,39 +765,39 @@ void CertDecoder::GetName(NameType nt)
 
             switch (id) {
             case COMMON_NAME:
-                if (!(ptr= AddTag(ptr, buf_end, "/CN=", 4, strLen)))
-                  goto err;
+                if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen)))
+                    return;
                 break;
             case SUR_NAME:
-                if (!(ptr= AddTag(ptr, buf_end, "/SN=", 4, strLen)))
-                  goto err;
+                if (!(ptr = AddTag(ptr, buf_end, "/SN=", 4, strLen)))
+                    return;
                 break;
             case COUNTRY_NAME:
-                if (!(ptr= AddTag(ptr, buf_end, "/C=", 3, strLen)))
-                  goto err;
+                if (!(ptr = AddTag(ptr, buf_end, "/C=", 3, strLen)))
+                    return;
                 break;
             case LOCALITY_NAME:
-                if (!(ptr= AddTag(ptr, buf_end, "/L=", 3, strLen)))
-                  goto err;
+                if (!(ptr = AddTag(ptr, buf_end, "/L=", 3, strLen)))
+                    return;
                 break;
             case STATE_NAME:
-                if (!(ptr= AddTag(ptr, buf_end, "/ST=", 4, strLen)))
-                  goto err;
+                if (!(ptr = AddTag(ptr, buf_end, "/ST=", 4, strLen)))
+                    return;
                 break;
             case ORG_NAME:
-                if (!(ptr= AddTag(ptr, buf_end, "/O=", 3, strLen)))
-                  goto err;
+                if (!(ptr = AddTag(ptr, buf_end, "/O=", 3, strLen)))
+                    return;
                 break;
             case ORGUNIT_NAME:
-                if (!(ptr= AddTag(ptr, buf_end, "/OU=", 4, strLen)))
-                  goto err;
+                if (!(ptr = AddTag(ptr, buf_end, "/OU=", 4, strLen)))
+                    return;
                 break;
             }
 
             sha.Update(source_.get_current(), strLen);
             source_.advance(strLen);
         }
-        else {
+        else { 
             bool email = false;
             if (joint[0] == 0x2a && joint[1] == 0x86)  // email id hdr
                 email = true;
@@ -756,20 +805,23 @@ void CertDecoder::GetName(NameType nt)
             source_.advance(oidSz + 1);
             word32 length = GetLength(source_);
 
-            if (email && !(ptr= AddTag(ptr, buf_end, "/emailAddress=", 14, length)))
-                goto err;
+            if (email) {
+                if (!(ptr = AddTag(ptr, buf_end, "/emailAddress=", 14, length))) {
+                    source_.SetError(CONTENT_E);
+                    return; 
+                }
+            }
 
             source_.advance(length);
         }
     }
-    *ptr= 0;
 
-    sha.Final(nt == ISSUER ? issuerHash_ : subjectHash_);
-        
-    return;
-    
-err:
-    source_.SetError(CONTENT_E);
+    *ptr = 0;
+
+    if (nt == ISSUER)
+        sha.Final(issuerHash_);
+    else
+        sha.Final(subjectHash_);
 }
 
 
@@ -794,8 +846,7 @@ void CertDecoder::GetDate(DateType dt)
     memcpy(date, source_.get_current(), length);
     source_.advance(length);
 
-    if (!ValidateDate(date, b, dt) && verify_)
-    {
+    if (!ValidateDate(date, b, dt) && verify_) {
         if (dt == BEFORE)
             source_.SetError(BEFORE_DATE_E);
         else
@@ -856,7 +907,8 @@ void CertDecoder::GetCompareHash(const byte* plain, word32 sz, byte* digest,
 // validate signature signed by someone else
 bool CertDecoder::ValidateSignature(SignerList* signers)
 {
-    assert(signers);
+    if (!signers)
+        return false;
 
     SignerList::iterator first = signers->begin();
     SignerList::iterator last  = signers->end();
@@ -1077,8 +1129,7 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
         return 0;
     }
     word32 rLen = GetLength(source);
-    if (rLen != 20)
-    {
+    if (rLen != 20) {
         if (rLen == 21) {       // zero at front, eat
             source.next();
             --rLen;
@@ -1101,8 +1152,7 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
         return 0;
     }
     word32 sLen = GetLength(source);
-    if (sLen != 20)
-    {
+    if (sLen != 20) {
         if (sLen == 21) {
             source.next();          // zero at front, eat
             --sLen;
@@ -1123,6 +1173,7 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
 }
 
 
+/*
 // Get Cert in PEM format from BEGIN to END
 int GetCert(Source& source)
 {
@@ -1174,12 +1225,10 @@ void PKCS12_Decoder::Decode()
 
 
     // Get MacData optional
-    /*
-    mac     digestInfo  like certdecoder::getdigest?
-    macsalt octet string
-    iter    integer
+    // mac     digestInfo  like certdecoder::getdigest?
+    // macsalt octet string
+    // iter    integer
     
-    */
 }
 
 
@@ -1199,6 +1248,7 @@ int GetPKCS_Cert(const char* password, Source& source)
 
     return 0;
 }
+*/
 
 
 
diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp
index 8ee2f3fe569..64e8f0a84aa 100644
--- a/extra/yassl/taocrypt/src/blowfish.cpp
+++ b/extra/yassl/taocrypt/src/blowfish.cpp
@@ -86,7 +86,10 @@ void Blowfish::Process(byte* out, const byte* in, word32 sz)
 
 void Blowfish::SetKey(const byte* key_string, word32 keylength, CipherDir dir)
 {
-	assert(keylength >= 4 && keylength <= 56);
+    if (keylength < 4)
+        keylength = 4;
+    else if (keylength > 56)
+        keylength = 56;
 
 	unsigned i, j=0, k;
 	word32 data, dspace[2] = {0, 0};
@@ -165,16 +168,21 @@ void Blowfish::crypt_block(const word32 in[2], word32 out[2]) const
 	word32 left  = in[0];
 	word32 right = in[1];
 
+	const word32  *const s = sbox_;
 	const word32* p = pbox_;
-    word32 tmp;
 
 	left ^= p[0];
 
-    BF_ROUNDS
+    // roll back up and use s and p index instead of just p
+    for (unsigned i = 0; i < ROUNDS / 2; i++) {
+        right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)])
+            ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)])
+            ^ p[2*i+1];
 
-#if ROUNDS == 20
-    BF_EXTRA_ROUNDS
-#endif
+        left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)])
+            ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)])
+            ^ p[2*i+2];
+    }
 
 	right ^= p[ROUNDS + 1];
 
@@ -188,17 +196,23 @@ typedef BlockGetAndPut gpBlock;
 void Blowfish::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out)
     const
 {
-    word32 tmp, left, right;
+    word32 left, right;
+	const word32  *const s = sbox_;
     const word32* p = pbox_;
     
     gpBlock::Get(in)(left)(right);
 	left ^= p[0];
 
-    BF_ROUNDS
+    // roll back up and use s and p index instead of just p
+    for (unsigned i = 0; i < ROUNDS / 2; i++) {
+        right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)])
+            ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)])
+            ^ p[2*i+1];
 
-#if ROUNDS == 20
-    BF_EXTRA_ROUNDS
-#endif
+        left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)])
+            ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)])
+            ^ p[2*i+2];
+    }
 
 	right ^= p[ROUNDS + 1];
 
diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp
index 7c6a6a8bd8b..8647ea13f20 100644
--- a/extra/yassl/taocrypt/src/coding.cpp
+++ b/extra/yassl/taocrypt/src/coding.cpp
@@ -95,7 +95,6 @@ void HexEncoder::Encode()
 void HexDecoder::Decode()
 {
     word32 bytes = coded_.size();
-    assert((bytes % 2) == 0);
     decoded_.New(bytes / 2);
 
     word32 i(0);
@@ -104,15 +103,9 @@ void HexDecoder::Decode()
         byte b  = coded_.next() - 0x30;  // 0 starts at 0x30
         byte b2 = coded_.next() - 0x30;
 
-        // sanity checks
-        assert( b  < sizeof(hexDecode)/sizeof(hexDecode[0]) );
-        assert( b2 < sizeof(hexDecode)/sizeof(hexDecode[0]) );
-
         b  = hexDecode[b];
         b2 = hexDecode[b2];
-        
-        assert( b != bad && b2 != bad );
-        
+
         decoded_[i++] = (b << 4) | b2;
         bytes -= 2;
     }
@@ -174,9 +167,9 @@ void Base64Encoder::Encode()
     } 
 
     encoded_[i++] = '\n';
-    assert(i == outSz);
-
-    plain_.reset(encoded_);
+    
+    if (i == outSz)
+        plain_.reset(encoded_);
 }
 
 
@@ -197,7 +190,6 @@ void Base64Decoder::Decode()
         byte e3 = coded_.next();
         byte e4 = coded_.next();
 
-        // do asserts first
         if (e1 == 0)            // end file 0's
             break;
 
diff --git a/extra/yassl/taocrypt/src/dsa.cpp b/extra/yassl/taocrypt/src/dsa.cpp
index 79ee91e76f9..a4e9c9503e7 100644
--- a/extra/yassl/taocrypt/src/dsa.cpp
+++ b/extra/yassl/taocrypt/src/dsa.cpp
@@ -183,7 +183,8 @@ word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
     Integer kInv = k.InverseMod(q);
     s_ = (kInv * (H + x*r_)) % q;
 
-    assert(!!r_ && !!s_);
+    if (!(!!r_ && !!s_))
+        return -1;
 
     int rSz = r_.ByteCount();
 
diff --git a/extra/yassl/taocrypt/src/hash.cpp b/extra/yassl/taocrypt/src/hash.cpp
index c51dc42a909..b36a486368c 100644
--- a/extra/yassl/taocrypt/src/hash.cpp
+++ b/extra/yassl/taocrypt/src/hash.cpp
@@ -21,7 +21,6 @@
 
 #include "runtime.hpp"
 #include 
-#include 
 
 #include "hash.hpp"
 
@@ -31,8 +30,6 @@ namespace TaoCrypt {
 
 HASHwithTransform::HASHwithTransform(word32 digSz, word32 buffSz)
 {
-    assert(digSz  <= MaxDigestSz);
-    assert(buffSz <= MaxBufferSz);
 }
 
 
@@ -73,15 +70,15 @@ void HASHwithTransform::Update(const byte* data, word32 len)
 // Final process, place digest in hash
 void HASHwithTransform::Final(byte* hash)
 {
-    word32    blockSz   = getBlockSize();
-    word32    digestSz  = getDigestSize();
-    word32    padSz     = getPadSize();
-    ByteOrder order     = getByteOrder();
+    word32    blockSz  = getBlockSize();
+    word32    digestSz = getDigestSize();
+    word32    padSz    = getPadSize();
+    ByteOrder order    = getByteOrder();
 
     AddLength(buffLen_);                        // before adding pads
     HashLengthType preLoLen = GetBitCountLo();
     HashLengthType preHiLen = GetBitCountHi();
-    byte*     local     = reinterpret_cast(buffer_);
+    byte*     local         = reinterpret_cast(buffer_);
 
     local[buffLen_++] = 0x80;  // add 1
 
@@ -95,7 +92,7 @@ void HASHwithTransform::Final(byte* hash)
         buffLen_ = 0;
     }
     memset(&local[buffLen_], 0, padSz - buffLen_);
-
+   
     ByteReverseIf(local, local, blockSz, order);
     
     memcpy(&local[padSz],   order ? &preHiLen : &preLoLen, sizeof(preLoLen));
@@ -113,8 +110,6 @@ void HASHwithTransform::Final(byte* hash)
 
 HASH64withTransform::HASH64withTransform(word32 digSz, word32 buffSz)
 {
-    assert(digSz  <= MaxDigestSz);
-    assert(buffSz <= MaxBufferSz);
 }
 
 
diff --git a/extra/yassl/taocrypt/src/hc128.cpp b/extra/yassl/taocrypt/src/hc128.cpp
new file mode 100644
index 00000000000..aac92f0abb4
--- /dev/null
+++ b/extra/yassl/taocrypt/src/hc128.cpp
@@ -0,0 +1,317 @@
+/*
+   Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+ 
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING. If not, write to the
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+   MA  02110-1301  USA.
+*/
+
+
+#include "runtime.hpp"
+#include "hc128.hpp"
+
+
+
+namespace TaoCrypt {
+
+
+
+
+#ifdef BIG_ENDIAN_ORDER
+    #define LITTLE32(x) ByteReverse((word32)x)
+#else
+    #define LITTLE32(x) (x)
+#endif
+
+
+/*h1 function*/
+#define h1(x, y) {                              \
+     byte a,c;                                  \
+     a = (byte) (x);                            \
+     c = (byte) ((x) >> 16);                    \
+     y = (T_[512+a])+(T_[512+256+c]);           \
+}
+
+/*h2 function*/
+#define h2(x, y) {                              \
+     byte a,c;                                  \
+     a = (byte) (x);                            \
+     c = (byte) ((x) >> 16);                    \
+     y = (T_[a])+(T_[256+c]);                   \
+}
+
+/*one step of HC-128, update P and generate 32 bits keystream*/
+#define step_P(u,v,a,b,c,d,n){                  \
+     word32 tem0,tem1,tem2,tem3;                \
+     h1((X_[(d)]),tem3);                        \
+     tem0 = rotrFixed((T_[(v)]),23);            \
+     tem1 = rotrFixed((X_[(c)]),10);            \
+     tem2 = rotrFixed((X_[(b)]),8);             \
+     (T_[(u)]) += tem2+(tem0 ^ tem1);           \
+     (X_[(a)]) = (T_[(u)]);                     \
+     (n) = tem3 ^ (T_[(u)]) ;                   \
+}       
+
+/*one step of HC-128, update Q and generate 32 bits keystream*/
+#define step_Q(u,v,a,b,c,d,n){                  \
+     word32 tem0,tem1,tem2,tem3;                \
+     h2((Y_[(d)]),tem3);                        \
+     tem0 = rotrFixed((T_[(v)]),(32-23));       \
+     tem1 = rotrFixed((Y_[(c)]),(32-10));       \
+     tem2 = rotrFixed((Y_[(b)]),(32-8));        \
+     (T_[(u)]) += tem2 + (tem0 ^ tem1);         \
+     (Y_[(a)]) = (T_[(u)]);                     \
+     (n) = tem3 ^ (T_[(u)]) ;                   \
+}   
+
+
+/*16 steps of HC-128, generate 512 bits keystream*/
+void HC128::GenerateKeystream(word32* keystream)  
+{
+   word32 cc,dd;
+   cc = counter1024_ & 0x1ff;
+   dd = (cc+16)&0x1ff;
+
+   if (counter1024_ < 512)	
+   {   		
+      counter1024_ = (counter1024_ + 16) & 0x3ff;
+      step_P(cc+0, cc+1, 0, 6, 13,4, keystream[0]);
+      step_P(cc+1, cc+2, 1, 7, 14,5, keystream[1]);
+      step_P(cc+2, cc+3, 2, 8, 15,6, keystream[2]);
+      step_P(cc+3, cc+4, 3, 9, 0, 7, keystream[3]);
+      step_P(cc+4, cc+5, 4, 10,1, 8, keystream[4]);
+      step_P(cc+5, cc+6, 5, 11,2, 9, keystream[5]);
+      step_P(cc+6, cc+7, 6, 12,3, 10,keystream[6]);
+      step_P(cc+7, cc+8, 7, 13,4, 11,keystream[7]);
+      step_P(cc+8, cc+9, 8, 14,5, 12,keystream[8]);
+      step_P(cc+9, cc+10,9, 15,6, 13,keystream[9]);
+      step_P(cc+10,cc+11,10,0, 7, 14,keystream[10]);
+      step_P(cc+11,cc+12,11,1, 8, 15,keystream[11]);
+      step_P(cc+12,cc+13,12,2, 9, 0, keystream[12]);
+      step_P(cc+13,cc+14,13,3, 10,1, keystream[13]);
+      step_P(cc+14,cc+15,14,4, 11,2, keystream[14]);
+      step_P(cc+15,dd+0, 15,5, 12,3, keystream[15]);
+   }
+   else				    
+   {
+	  counter1024_ = (counter1024_ + 16) & 0x3ff;
+      step_Q(512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]);
+      step_Q(512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]);
+      step_Q(512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]);
+      step_Q(512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]);
+      step_Q(512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]);
+      step_Q(512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]);
+      step_Q(512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]);
+      step_Q(512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]);
+      step_Q(512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]);
+      step_Q(512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]);
+      step_Q(512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]);
+      step_Q(512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]);
+      step_Q(512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]);
+      step_Q(512+cc+13,512+cc+14,13,3, 10,1, keystream[13]);
+      step_Q(512+cc+14,512+cc+15,14,4, 11,2, keystream[14]);
+      step_Q(512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]);
+   }
+}
+
+
+/* The following defines the initialization functions */
+#define f1(x)  (rotrFixed((x),7)  ^ rotrFixed((x),18) ^ ((x) >> 3))
+#define f2(x)  (rotrFixed((x),17) ^ rotrFixed((x),19) ^ ((x) >> 10))
+
+/*update table P*/
+#define update_P(u,v,a,b,c,d){                      \
+     word32 tem0,tem1,tem2,tem3;                    \
+     tem0 = rotrFixed((T_[(v)]),23);                \
+     tem1 = rotrFixed((X_[(c)]),10);                \
+     tem2 = rotrFixed((X_[(b)]),8);                 \
+     h1((X_[(d)]),tem3);                            \
+     (T_[(u)]) = ((T_[(u)]) + tem2+(tem0^tem1)) ^ tem3;     \
+     (X_[(a)]) = (T_[(u)]);                         \
+}  
+
+/*update table Q*/
+#define update_Q(u,v,a,b,c,d){                      \
+     word32 tem0,tem1,tem2,tem3;                    \
+     tem0 = rotrFixed((T_[(v)]),(32-23));           \
+     tem1 = rotrFixed((Y_[(c)]),(32-10));           \
+     tem2 = rotrFixed((Y_[(b)]),(32-8));            \
+     h2((Y_[(d)]),tem3);                            \
+     (T_[(u)]) = ((T_[(u)]) + tem2+(tem0^tem1)) ^ tem3;     \
+     (Y_[(a)]) = (T_[(u)]);                         \
+}     
+
+/*16 steps of HC-128, without generating keystream, */
+/*but use the outputs to update P and Q*/
+void HC128::SetupUpdate()  /*each time 16 steps*/
+{
+   word32 cc,dd;
+   cc = counter1024_ & 0x1ff;
+   dd = (cc+16)&0x1ff;
+
+   if (counter1024_ < 512)	
+   {   		
+      counter1024_ = (counter1024_ + 16) & 0x3ff;
+      update_P(cc+0, cc+1, 0, 6, 13, 4);
+      update_P(cc+1, cc+2, 1, 7, 14, 5);
+      update_P(cc+2, cc+3, 2, 8, 15, 6);
+      update_P(cc+3, cc+4, 3, 9, 0,  7);
+      update_P(cc+4, cc+5, 4, 10,1,  8);
+      update_P(cc+5, cc+6, 5, 11,2,  9);
+      update_P(cc+6, cc+7, 6, 12,3,  10);
+      update_P(cc+7, cc+8, 7, 13,4,  11);
+      update_P(cc+8, cc+9, 8, 14,5,  12);
+      update_P(cc+9, cc+10,9, 15,6,  13);
+      update_P(cc+10,cc+11,10,0, 7,  14);
+      update_P(cc+11,cc+12,11,1, 8,  15);
+      update_P(cc+12,cc+13,12,2, 9,  0);
+      update_P(cc+13,cc+14,13,3, 10, 1);
+      update_P(cc+14,cc+15,14,4, 11, 2);
+      update_P(cc+15,dd+0, 15,5, 12, 3);   
+   }
+   else				    
+   {
+      counter1024_ = (counter1024_ + 16) & 0x3ff;
+      update_Q(512+cc+0, 512+cc+1, 0, 6, 13, 4);
+      update_Q(512+cc+1, 512+cc+2, 1, 7, 14, 5);
+      update_Q(512+cc+2, 512+cc+3, 2, 8, 15, 6);
+      update_Q(512+cc+3, 512+cc+4, 3, 9, 0,  7);
+      update_Q(512+cc+4, 512+cc+5, 4, 10,1,  8);
+      update_Q(512+cc+5, 512+cc+6, 5, 11,2,  9);
+      update_Q(512+cc+6, 512+cc+7, 6, 12,3,  10);
+      update_Q(512+cc+7, 512+cc+8, 7, 13,4,  11);
+      update_Q(512+cc+8, 512+cc+9, 8, 14,5,  12);
+      update_Q(512+cc+9, 512+cc+10,9, 15,6,  13);
+      update_Q(512+cc+10,512+cc+11,10,0, 7,  14);
+      update_Q(512+cc+11,512+cc+12,11,1, 8,  15);
+      update_Q(512+cc+12,512+cc+13,12,2, 9,  0);
+      update_Q(512+cc+13,512+cc+14,13,3, 10, 1);
+      update_Q(512+cc+14,512+cc+15,14,4, 11, 2);
+      update_Q(512+cc+15,512+dd+0, 15,5, 12, 3); 
+   }       
+}
+
+
+/* for the 128-bit key:  key[0]...key[15]
+*  key[0] is the least significant byte of ctx->key[0] (K_0);
+*  key[3] is the most significant byte of ctx->key[0]  (K_0);
+*  ...
+*  key[12] is the least significant byte of ctx->key[3] (K_3)
+*  key[15] is the most significant byte of ctx->key[3]  (K_3)
+*
+*  for the 128-bit iv:  iv[0]...iv[15]
+*  iv[0] is the least significant byte of ctx->iv[0] (IV_0);
+*  iv[3] is the most significant byte of ctx->iv[0]  (IV_0);
+*  ...
+*  iv[12] is the least significant byte of ctx->iv[3] (IV_3)
+*  iv[15] is the most significant byte of ctx->iv[3]  (IV_3)
+*/
+
+
+
+void HC128::SetIV(const byte* iv)
+{ 
+    word32 i;
+	
+	for (i = 0; i < (128 >> 5); i++)
+        iv_[i] = LITTLE32(((word32*)iv)[i]);
+	
+    for (; i < 8; i++) iv_[i] = iv_[i-4];
+  
+    /* expand the key and IV into the table T */ 
+    /* (expand the key and IV into the table P and Q) */ 
+	
+	for (i = 0; i < 8;  i++)   T_[i] = key_[i];
+	for (i = 8; i < 16; i++)   T_[i] = iv_[i-8];
+
+    for (i = 16; i < (256+16); i++) 
+		T_[i] = f2(T_[i-2]) + T_[i-7] + f1(T_[i-15]) + T_[i-16]+i;
+    
+	for (i = 0; i < 16;  i++)  T_[i] = T_[256+i];
+
+	for (i = 16; i < 1024; i++) 
+		T_[i] = f2(T_[i-2]) + T_[i-7] + f1(T_[i-15]) + T_[i-16]+256+i;
+    
+    /* initialize counter1024, X and Y */
+	counter1024_ = 0;
+	for (i = 0; i < 16; i++) X_[i] = T_[512-16+i];
+    for (i = 0; i < 16; i++) Y_[i] = T_[512+512-16+i];
+    
+    /* run the cipher 1024 steps before generating the output */
+	for (i = 0; i < 64; i++)  SetupUpdate();  
+}
+
+
+void HC128::SetKey(const byte* key, const byte* iv)
+{ 
+  word32 i;  
+
+  /* Key size in bits 128 */ 
+  for (i = 0; i < (128 >> 5); i++)
+      key_[i] = LITTLE32(((word32*)key)[i]);
+ 
+  for ( ; i < 8 ; i++) key_[i] = key_[i-4];
+
+  SetIV(iv);
+}
+
+
+/* The following defines the encryption of data stream */
+void HC128::Process(byte* output, const byte* input, word32 msglen)
+{
+  word32 i, keystream[16];
+
+  for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64)
+  {
+	  GenerateKeystream(keystream);
+
+      /* unroll loop */
+	  ((word32*)output)[0]  = ((word32*)input)[0]  ^ LITTLE32(keystream[0]);
+	  ((word32*)output)[1]  = ((word32*)input)[1]  ^ LITTLE32(keystream[1]);
+	  ((word32*)output)[2]  = ((word32*)input)[2]  ^ LITTLE32(keystream[2]);
+	  ((word32*)output)[3]  = ((word32*)input)[3]  ^ LITTLE32(keystream[3]);
+	  ((word32*)output)[4]  = ((word32*)input)[4]  ^ LITTLE32(keystream[4]);
+	  ((word32*)output)[5]  = ((word32*)input)[5]  ^ LITTLE32(keystream[5]);
+	  ((word32*)output)[6]  = ((word32*)input)[6]  ^ LITTLE32(keystream[6]);
+	  ((word32*)output)[7]  = ((word32*)input)[7]  ^ LITTLE32(keystream[7]);
+	  ((word32*)output)[8]  = ((word32*)input)[8]  ^ LITTLE32(keystream[8]);
+	  ((word32*)output)[9]  = ((word32*)input)[9]  ^ LITTLE32(keystream[9]);
+	  ((word32*)output)[10] = ((word32*)input)[10] ^ LITTLE32(keystream[10]);
+	  ((word32*)output)[11] = ((word32*)input)[11] ^ LITTLE32(keystream[11]);
+	  ((word32*)output)[12] = ((word32*)input)[12] ^ LITTLE32(keystream[12]);
+	  ((word32*)output)[13] = ((word32*)input)[13] ^ LITTLE32(keystream[13]);
+	  ((word32*)output)[14] = ((word32*)input)[14] ^ LITTLE32(keystream[14]);
+	  ((word32*)output)[15] = ((word32*)input)[15] ^ LITTLE32(keystream[15]);
+  }
+
+  if (msglen > 0)
+  {
+      GenerateKeystream(keystream);
+
+#ifdef BIG_ENDIAN_ORDER
+      {
+          word32 wordsLeft = msglen / sizeof(word32);
+          if (msglen % sizeof(word32)) wordsLeft++;
+          
+          ByteReverse(keystream, keystream, wordsLeft * sizeof(word32));
+      }
+#endif
+
+      for (i = 0; i < msglen; i++)
+	      output[i] = input[i] ^ ((byte*)keystream)[i];
+  }
+
+}
+
+
+}  // namespace
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index c00815df8cf..2d55f48e91f 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -73,7 +73,8 @@ template 
 CPP_TYPENAME AlignedAllocator::pointer AlignedAllocator::allocate(
                                            size_type n, const void *)
 {
-    CheckSize(n);
+    if (n > max_size())
+        return 0;
     if (n == 0)
         return 0;
     if (n >= 4)
@@ -91,16 +92,13 @@ CPP_TYPENAME AlignedAllocator::pointer AlignedAllocator::allocate(
     #endif
 
     #ifdef TAOCRYPT_NO_ALIGNED_ALLOC
-        assert(m_pBlock == 0);
         m_pBlock = p;
         if (!IsAlignedOn(p, 16))
         {
-            assert(IsAlignedOn(p, 8));
             p = (byte *)p + 8;
         }
     #endif
 
-        assert(IsAlignedOn(p, 16));
         return (T*)p;
     }
     return NEW_TC T[n];
@@ -116,7 +114,6 @@ void AlignedAllocator::deallocate(void* p, size_type n)
         #ifdef TAOCRYPT_MM_MALLOC_AVAILABLE
             _mm_free(p);
         #elif defined(TAOCRYPT_NO_ALIGNED_ALLOC)
-            assert(m_pBlock == p || (byte*)m_pBlock+8 == p);
             free(m_pBlock);
             m_pBlock = 0;
         #else
@@ -284,14 +281,14 @@ DWord() {}
 
 private:
     struct dword_struct
-    {
-    #ifdef LITTLE_ENDIAN_ORDER
-        word low;
-        word high;
-    #else
-        word high;
-        word low;
-    #endif
+        {
+        #ifdef LITTLE_ENDIAN_ORDER
+            word low;
+            word high;
+        #else
+            word high;
+            word low;
+        #endif
     };
 
     union
@@ -365,9 +362,6 @@ private:
 template 
 S DivideThreeWordsByTwo(S* A, S B0, S B1, D* dummy_VC6_WorkAround = 0)
 {
-    // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S
-    assert(A[2] < B1 || (A[2]==B1 && A[1] < B0));
-
     // estimate the quotient: do a 2 S by 1 S divide
     S Q;
     if (S(B1+1) == 0)
@@ -393,7 +387,6 @@ S DivideThreeWordsByTwo(S* A, S B0, S B1, D* dummy_VC6_WorkAround = 0)
         A[1] = u.GetLowHalf();
         A[2] += u.GetHighHalf();
         Q++;
-        assert(Q);	// shouldn't overflow
     }
 
     return Q;
@@ -491,7 +484,6 @@ static int Compare(const word *A, const word *B, unsigned int N)
 
 static word Increment(word *A, unsigned int N, word B=1)
 {
-    assert(N);
     word t = A[0];
     A[0] = t+B;
     if (A[0] >= t)
@@ -504,7 +496,6 @@ static word Increment(word *A, unsigned int N, word B=1)
 
 static word Decrement(word *A, unsigned int N, word B=1)
 {
-    assert(N);
     word t = A[0];
     A[0] = t-B;
     if (A[0] <= t)
@@ -538,14 +529,11 @@ static word LinearMultiply(word *C, const word *A, word B, unsigned int N)
 
 static word AtomicInverseModPower2(word A)
 {
-    assert(A%2==1);
-
     word R=A%8;
 
     for (unsigned i=3; i=2 && N%2==0);
-
     if (LowLevel::MultiplyRecursionLimit() >= 8 && N==8)
         LowLevel::Multiply8(R, A, B);
     else if (LowLevel::MultiplyRecursionLimit() >= 4 && N==4)
@@ -2188,7 +2169,6 @@ void RecursiveMultiply(word *R, word *T, const word *A, const word *B,
         carry += LowLevel::Add(T0, T0, R2, N);
         carry += LowLevel::Add(R1, R1, T0, N);
 
-        assert (carry >= 0 && carry <= 2);
         Increment(R3, N2, carry);
     }
 }
@@ -2196,9 +2176,6 @@ void RecursiveMultiply(word *R, word *T, const word *A, const word *B,
 
 void RecursiveSquare(word *R, word *T, const word *A, unsigned int N)                     
 {
-    assert(N && N%2==0);
-    if (LowLevel::SquareRecursionLimit() >= 8 && N==8)
-        LowLevel::Square8(R, A);
     if (LowLevel::SquareRecursionLimit() >= 4 && N==4)
         LowLevel::Square4(R, A);
     else if (N==2)
@@ -2227,7 +2204,6 @@ void RecursiveSquare(word *R, word *T, const word *A, unsigned int N)
 void RecursiveMultiplyBottom(word *R, word *T, const word *A, const word *B,
                              unsigned int N)
 {
-    assert(N>=2 && N%2==0);
     if (LowLevel::MultiplyBottomRecursionLimit() >= 8 && N==8)
         LowLevel::Multiply8Bottom(R, A, B);
     else if (LowLevel::MultiplyBottomRecursionLimit() >= 4 && N==4)
@@ -2250,8 +2226,6 @@ void RecursiveMultiplyBottom(word *R, word *T, const word *A, const word *B,
 void RecursiveMultiplyTop(word *R, word *T, const word *L, const word *A,
                           const word *B, unsigned int N)
 {
-    assert(N>=2 && N%2==0);
-
     if (N==4)
     {
         LowLevel::Multiply4(T, A, B);
@@ -2315,7 +2289,6 @@ void RecursiveMultiplyTop(word *R, word *T, const word *L, const word *A,
         carry += Increment(R0, N2, c2+t);
         carry += LowLevel::Add(R0, R0, T1, N2);
         carry += LowLevel::Add(R0, R0, T3, N2);
-        assert (carry >= 0 && carry <= 2);
 
         CopyWords(R1, T3, N2);
         Increment(R1, N2, carry);
@@ -2364,9 +2337,6 @@ void AsymmetricMultiply(word *R, word *T, const word *A, unsigned int NA,
         STL::swap(NA, NB);
     }
 
-    assert(NB % NA == 0);
-    assert((NB/NA)%2 == 0); 	// NB is an even multiple of NA
-
     if (NA==2 && !A[1])
     {
         switch (A[0])
@@ -2433,8 +2403,6 @@ static inline unsigned int EvenWordCount(const word *X, unsigned int N)
 unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA,
                            const word *M, unsigned int N)
 {
-    assert(NA<=N && N && N%2==0);
-
     word *b = T;
     word *c = T+N;
     word *f = T+2*N;
@@ -2460,7 +2428,6 @@ unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA,
 
             ShiftWordsRightByWords(f, fgLen, 1);
             if (c[bcLen-1]) bcLen+=2;
-            assert(bcLen <= N);
             ShiftWordsLeftByWords(c, bcLen, 1);
             k+=WORD_BITS;
             t=f[0];
@@ -2489,7 +2456,6 @@ unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA,
         {
             c[bcLen] = t;
             bcLen+=2;
-            assert(bcLen <= N);
         }
 
         if (f[fgLen-2]==0 && g[fgLen-2]==0 && f[fgLen-1]==0 && g[fgLen-1]==0)
@@ -2508,7 +2474,6 @@ unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA,
         {
             b[bcLen] = 1;
             bcLen+=2;
-            assert(bcLen <= N);
         }
     }
 }
@@ -2741,8 +2706,6 @@ void Integer::Randomize(RandomNumberGenerator& rng, unsigned int nbits)
 void Integer::Randomize(RandomNumberGenerator& rng, const Integer& min,
                         const Integer& max)
 {
-    assert(min <= max);
-
     Integer range = max - min;
     const unsigned int nbits = range.BitCount();
 
@@ -2881,7 +2844,7 @@ Integer& Integer::operator++()
     else
     {
         word borrow = Decrement(reg_.get_buffer(), reg_.size());
-        assert(!borrow);
+        (void)borrow;           // shut up compiler
         if (WordCount()==0)
             *this = Zero();
     }
@@ -2998,7 +2961,6 @@ void PositiveSubtract(Integer &diff, const Integer &a, const Integer& b)
                                b.reg_.get_buffer(), bSize);
         CopyWords(diff.reg_+bSize, a.reg_+bSize, aSize-bSize);
         borrow = Decrement(diff.reg_+bSize, aSize-bSize, borrow);
-        assert(!borrow);
         diff.sign_ = Integer::POSITIVE;
     }
     else
@@ -3007,7 +2969,6 @@ void PositiveSubtract(Integer &diff, const Integer &a, const Integer& b)
                                a.reg_.get_buffer(), aSize);
         CopyWords(diff.reg_+aSize, b.reg_+aSize, bSize-aSize);
         borrow = Decrement(diff.reg_+aSize, bSize-aSize, borrow);
-        assert(!borrow);
         diff.sign_ = Integer::NEGATIVE;
     }
 }
@@ -3067,7 +3028,6 @@ bool Integer::GetBit(unsigned int n) const
 
 unsigned long Integer::GetBits(unsigned int i, unsigned int n) const
 {
-    assert(n <= sizeof(unsigned long)*8);
     unsigned long v = 0;
     for (unsigned int j=0; j(reg_[1]);
     return sign_ == POSITIVE ? value : -(signed long)value;
@@ -3227,11 +3185,9 @@ static inline void AtomicDivide(word *Q, const word *A, const word *B)
     {
         // multiply quotient and divisor and add remainder, make sure it 
         // equals dividend
-        assert(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0]= 0)
     {
         R[N] -= Subtract(R, R, B, N);
         Q[1] += (++Q[0]==0);
-        assert(Q[0] || Q[1]); // no overflow
     }
 }
 
@@ -3280,10 +3233,6 @@ static void CorrectQuotientEstimate(word *R, word *T, word *Q, const word *B,
 void Divide(word* R, word* Q, word* T, const word* A, unsigned int NA,
             const word* B, unsigned int NB)
 {
-    assert(NA && NB && NA%2==0 && NB%2==0);
-    assert(B[NB-1] || B[NB-2]);
-    assert(NB <= NA);
-
     // set up temporary work space
     word *const TA=T;
     word *const TB=T+NA+2;
@@ -3294,7 +3243,6 @@ void Divide(word* R, word* Q, word* T, const word* A, unsigned int NA,
     TB[0] = TB[NB-1] = 0;
     CopyWords(TB+shiftWords, B, NB-shiftWords);
     unsigned shiftBits = WORD_BITS - BitPrecision(TB[NB-1]);
-    assert(shiftBits < WORD_BITS);
     ShiftWordsLeftByBits(TB, NB, shiftBits);
 
     // copy A into TA and normalize it
@@ -3314,7 +3262,6 @@ void Divide(word* R, word* Q, word* T, const word* A, unsigned int NA,
     else
     {
         NA+=2;
-        assert(Compare(TA+NA-NB, TB, NB) < 0);
     }
 
     word BT[2];
@@ -3340,8 +3287,6 @@ void PositiveDivide(Integer& remainder, Integer& quotient,
     unsigned aSize = a.WordCount();
     unsigned bSize = b.WordCount();
 
-    assert(bSize);
-
     if (a.PositiveCompare(b) == -1)
     {
         remainder = a;
@@ -3429,8 +3374,6 @@ Integer Integer::Modulo(const Integer &b) const
 void Integer::Divide(word &remainder, Integer "ient,
                      const Integer ÷nd, word divisor)
 {
-    assert(divisor);
-
     if ((divisor & (divisor-1)) == 0)	// divisor is a power of 2
     {
         quotient = dividend >> (BitPrecision(divisor)-1);
@@ -3470,8 +3413,6 @@ Integer Integer::DividedBy(word b) const
 
 word Integer::Modulo(word divisor) const
 {
-    assert(divisor);
-
     word remainder;
 
     if ((divisor & (divisor-1)) == 0)	// divisor is a power of 2
@@ -3517,7 +3458,6 @@ Integer Integer::SquareRoot() const
 
     // overestimate square root
     Integer x, y = Power2((BitCount()+1)/2);
-    assert(y*y >= *this);
 
     do
     {
@@ -3562,8 +3502,6 @@ Integer Integer::Gcd(const Integer &a, const Integer &b)
 
 Integer Integer::InverseMod(const Integer &m) const
 {
-    assert(m.NotNegative());
-
     if (IsNegative() || *this>=m)
         return (*this%m).InverseMod(m);
 
@@ -3806,7 +3744,7 @@ void MontgomeryReduce(word *R, word *T, const word *X, const word *M,
     word borrow = Subtract(T, X+N, T, N);
     // defend against timing attack by doing this Add even when not needed
     word carry = Add(T+N, T, M, N);
-    assert(carry || !borrow);
+    (void)carry;            // shut up compiler
     CopyWords(R, T + (borrow ? N : 0), N);
 }
 
@@ -3862,7 +3800,6 @@ MontgomeryRepresentation::MontgomeryRepresentation(const Integer &m)
       u((word)0, modulus.reg_.size()),
       workspace(5*modulus.reg_.size())
 {
-    assert(modulus.IsOdd());
     RecursiveInverseModPower2(u.reg_.get_buffer(), workspace.get_buffer(),
                               modulus.reg_.get_buffer(), modulus.reg_.size());
 }
@@ -3873,7 +3810,6 @@ const Integer& MontgomeryRepresentation::Multiply(const Integer &a,
     word *const T = workspace.begin();
     word *const R = result.reg_.begin();
     const unsigned int N = modulus.reg_.size();
-    assert(a.reg_.size()<=N && b.reg_.size()<=N);
 
     AsymmetricMultiply(T, T+2*N, a.reg_.get_buffer(), a.reg_.size(),
                        b.reg_.get_buffer(), b.reg_.size());
@@ -3888,7 +3824,6 @@ const Integer& MontgomeryRepresentation::Square(const Integer &a) const
     word *const T = workspace.begin();
     word *const R = result.reg_.begin();
     const unsigned int N = modulus.reg_.size();
-    assert(a.reg_.size()<=N);
 
     TaoCrypt::Square(T, T+2*N, a.reg_.get_buffer(), a.reg_.size());
     SetWords(T+2*a.reg_.size(), 0, 2*N-2*a.reg_.size());
@@ -3902,7 +3837,6 @@ Integer MontgomeryRepresentation::ConvertOut(const Integer &a) const
     word *const T = workspace.begin();
     word *const R = result.reg_.begin();
     const unsigned int N = modulus.reg_.size();
-    assert(a.reg_.size()<=N);
 
     CopyWords(T, a.reg_.get_buffer(), a.reg_.size());
     SetWords(T+a.reg_.size(), 0, 2*N-a.reg_.size());
@@ -3919,7 +3853,6 @@ const Integer& MontgomeryRepresentation::MultiplicativeInverse(
     word *const T = workspace.begin();
     word *const R = result.reg_.begin();
     const unsigned int N = modulus.reg_.size();
-    assert(a.reg_.size()<=N);
 
     CopyWords(T, a.reg_.get_buffer(), a.reg_.size());
     SetWords(T+a.reg_.size(), 0, 2*N-a.reg_.size());
diff --git a/extra/yassl/taocrypt/src/make.bat b/extra/yassl/taocrypt/src/make.bat
old mode 100644
new mode 100755
diff --git a/extra/yassl/taocrypt/src/md4.cpp b/extra/yassl/taocrypt/src/md4.cpp
index cf17c218809..54820f4c944 100644
--- a/extra/yassl/taocrypt/src/md4.cpp
+++ b/extra/yassl/taocrypt/src/md4.cpp
@@ -27,7 +27,7 @@
     #include "algorithm.hpp"
 #endif
 
-   
+
 namespace STL = STL_NAMESPACE;
    
 
diff --git a/extra/yassl/taocrypt/src/md5.cpp b/extra/yassl/taocrypt/src/md5.cpp
index f18e0290c90..4d0a8bd03be 100644
--- a/extra/yassl/taocrypt/src/md5.cpp
+++ b/extra/yassl/taocrypt/src/md5.cpp
@@ -30,7 +30,7 @@
 
 namespace STL = STL_NAMESPACE;
 
-   
+
 
 namespace TaoCrypt {
 
@@ -108,14 +108,14 @@ void MD5::Update(const byte* data, word32 len)
 
     // at once for asm
     if (buffLen_ == 0) {
-            word32 times = len / BLOCK_SIZE;
-            if (times) {
-                AsmTransform(data, times);
-                const word32 add = BLOCK_SIZE * times;
-                AddLength(add);
-                len  -= add;
-                data += add;
-            }
+        word32 times = len / BLOCK_SIZE;
+        if (times) {
+            AsmTransform(data, times);
+            const word32 add = BLOCK_SIZE * times;
+            AddLength(add);
+            len  -= add;
+            data += add;
+        }
     }
 
     // cache any data left
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index 6045ea3e42b..5ffa2a2a07a 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -41,28 +41,28 @@ namespace STL = STL_NAMESPACE;
 
     void* operator new(size_t sz, TaoCrypt::new_t)
     {
-    void* ptr = malloc(sz ? sz : 1);
-    if (!ptr) abort();
+        void* ptr = malloc(sz ? sz : 1);
+        if (!ptr) abort();
 
-    return ptr;
+        return ptr;
     }
 
 
     void operator delete(void* ptr, TaoCrypt::new_t)
     {
-    if (ptr) free(ptr);
+        if (ptr) free(ptr);
     }
 
 
     void* operator new[](size_t sz, TaoCrypt::new_t nt)
     {
-    return ::operator new(sz, nt);
+        return ::operator new(sz, nt);
     }
 
 
     void operator delete[](void* ptr, TaoCrypt::new_t nt)
     {
-    ::operator delete(ptr, nt);
+        ::operator delete(ptr, nt);
     }
 
 
@@ -89,7 +89,6 @@ namespace STL = STL_NAMESPACE;
 // Handler for pure virtual functions
 namespace __Crun {
     void pure_error() {
-      assert(!"Aborted: pure virtual method called.");
     }
 }
 
@@ -100,7 +99,6 @@ namespace __Crun {
 extern "C" {
 
     int __cxa_pure_virtual() {
-      assert(!"Aborted: pure virtual method called.");
       return 0;
     }
 
@@ -196,8 +194,8 @@ bool HaveCpuId()
     return true;
 #else
     word32 eax, ebx;
-        __asm__ __volatile
-        (
+    __asm__ __volatile
+    (
         /* Put EFLAGS in eax and ebx */
         "pushf;"
         "pushf;"
@@ -214,9 +212,9 @@ bool HaveCpuId()
         "pop %0;"
         "popf"
         : "=r" (eax), "=r" (ebx)
-            :
+        :
         : "cc"
-        );
+    );
 
     if (eax == ebx)
         return false;
diff --git a/extra/yassl/taocrypt/src/rabbit.cpp b/extra/yassl/taocrypt/src/rabbit.cpp
new file mode 100644
index 00000000000..0ea4146618a
--- /dev/null
+++ b/extra/yassl/taocrypt/src/rabbit.cpp
@@ -0,0 +1,250 @@
+/*
+   Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+ 
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING. If not, write to the
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+   MA  02110-1301  USA.
+*/
+
+
+#include "runtime.hpp"
+#include "rabbit.hpp"
+
+
+
+namespace TaoCrypt {
+
+
+#define U32V(x)  (word32)(x)
+
+
+#ifdef BIG_ENDIAN_ORDER
+    #define LITTLE32(x) ByteReverse((word32)x)
+#else
+    #define LITTLE32(x) (x)
+#endif
+
+
+// local
+namespace {
+
+
+/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
+/* the upper 32 bits XOR the lower 32 bits */
+word32 RABBIT_g_func(word32 x)
+{
+    /* Temporary variables */
+    word32 a, b, h, l;
+
+    /* Construct high and low argument for squaring */
+    a = x&0xFFFF;
+    b = x>>16;
+
+    /* Calculate high and low result of squaring */
+    h = (((U32V(a*a)>>17) + U32V(a*b))>>15) + b*b;
+    l = x*x;
+
+    /* Return high XOR low */
+    return U32V(h^l);
+}
+
+
+} // namespace local
+
+
+/* Calculate the next internal state */
+void Rabbit::NextState(RabbitCtx which)
+{
+    /* Temporary variables */
+    word32 g[8], c_old[8], i;
+
+    Ctx* ctx;
+
+    if (which == Master)
+        ctx = &masterCtx_;
+    else
+        ctx = &workCtx_;
+
+    /* Save old counter values */
+    for (i=0; i<8; i++)
+        c_old[i] = ctx->c[i];
+
+    /* Calculate new counter values */
+    ctx->c[0] = U32V(ctx->c[0] + 0x4D34D34D + ctx->carry);
+    ctx->c[1] = U32V(ctx->c[1] + 0xD34D34D3 + (ctx->c[0] < c_old[0]));
+    ctx->c[2] = U32V(ctx->c[2] + 0x34D34D34 + (ctx->c[1] < c_old[1]));
+    ctx->c[3] = U32V(ctx->c[3] + 0x4D34D34D + (ctx->c[2] < c_old[2]));
+    ctx->c[4] = U32V(ctx->c[4] + 0xD34D34D3 + (ctx->c[3] < c_old[3]));
+    ctx->c[5] = U32V(ctx->c[5] + 0x34D34D34 + (ctx->c[4] < c_old[4]));
+    ctx->c[6] = U32V(ctx->c[6] + 0x4D34D34D + (ctx->c[5] < c_old[5]));
+    ctx->c[7] = U32V(ctx->c[7] + 0xD34D34D3 + (ctx->c[6] < c_old[6]));
+    ctx->carry = (ctx->c[7] < c_old[7]);
+   
+    /* Calculate the g-values */
+    for (i=0;i<8;i++)
+        g[i] = RABBIT_g_func(U32V(ctx->x[i] + ctx->c[i]));
+
+    /* Calculate new state values */
+    ctx->x[0] = U32V(g[0] + rotlFixed(g[7],16) + rotlFixed(g[6], 16));
+    ctx->x[1] = U32V(g[1] + rotlFixed(g[0], 8) + g[7]);
+    ctx->x[2] = U32V(g[2] + rotlFixed(g[1],16) + rotlFixed(g[0], 16));
+    ctx->x[3] = U32V(g[3] + rotlFixed(g[2], 8) + g[1]);
+    ctx->x[4] = U32V(g[4] + rotlFixed(g[3],16) + rotlFixed(g[2], 16));
+    ctx->x[5] = U32V(g[5] + rotlFixed(g[4], 8) + g[3]);
+    ctx->x[6] = U32V(g[6] + rotlFixed(g[5],16) + rotlFixed(g[4], 16));
+    ctx->x[7] = U32V(g[7] + rotlFixed(g[6], 8) + g[5]);
+}
+
+
+/* IV setup */
+void Rabbit::SetIV(const byte* iv)
+{
+    /* Temporary variables */
+    word32 i0, i1, i2, i3, i;
+      
+    /* Generate four subvectors */
+    i0 = LITTLE32(*(word32*)(iv+0));
+    i2 = LITTLE32(*(word32*)(iv+4));
+    i1 = (i0>>16) | (i2&0xFFFF0000);
+    i3 = (i2<<16) | (i0&0x0000FFFF);
+
+    /* Modify counter values */
+    workCtx_.c[0] = masterCtx_.c[0] ^ i0;
+    workCtx_.c[1] = masterCtx_.c[1] ^ i1;
+    workCtx_.c[2] = masterCtx_.c[2] ^ i2;
+    workCtx_.c[3] = masterCtx_.c[3] ^ i3;
+    workCtx_.c[4] = masterCtx_.c[4] ^ i0;
+    workCtx_.c[5] = masterCtx_.c[5] ^ i1;
+    workCtx_.c[6] = masterCtx_.c[6] ^ i2;
+    workCtx_.c[7] = masterCtx_.c[7] ^ i3;
+
+    /* Copy state variables */
+    for (i=0; i<8; i++)
+        workCtx_.x[i] = masterCtx_.x[i];
+    workCtx_.carry = masterCtx_.carry;
+
+    /* Iterate the system four times */
+    for (i=0; i<4; i++)
+        NextState(Work);
+}
+
+
+/* Key setup */
+void Rabbit::SetKey(const byte* key, const byte* iv)
+{
+    /* Temporary variables */
+    word32 k0, k1, k2, k3, i;
+
+    /* Generate four subkeys */
+    k0 = LITTLE32(*(word32*)(key+ 0));
+    k1 = LITTLE32(*(word32*)(key+ 4));
+    k2 = LITTLE32(*(word32*)(key+ 8));
+    k3 = LITTLE32(*(word32*)(key+12));
+
+    /* Generate initial state variables */
+    masterCtx_.x[0] = k0;
+    masterCtx_.x[2] = k1;
+    masterCtx_.x[4] = k2;
+    masterCtx_.x[6] = k3;
+    masterCtx_.x[1] = U32V(k3<<16) | (k2>>16);
+    masterCtx_.x[3] = U32V(k0<<16) | (k3>>16);
+    masterCtx_.x[5] = U32V(k1<<16) | (k0>>16);
+    masterCtx_.x[7] = U32V(k2<<16) | (k1>>16);
+
+    /* Generate initial counter values */
+    masterCtx_.c[0] = rotlFixed(k2, 16);
+    masterCtx_.c[2] = rotlFixed(k3, 16);
+    masterCtx_.c[4] = rotlFixed(k0, 16);
+    masterCtx_.c[6] = rotlFixed(k1, 16);
+    masterCtx_.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
+    masterCtx_.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
+    masterCtx_.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
+    masterCtx_.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
+
+    /* Clear carry bit */
+    masterCtx_.carry = 0;
+
+    /* Iterate the system four times */
+    for (i=0; i<4; i++)
+        NextState(Master);
+
+    /* Modify the counters */
+    for (i=0; i<8; i++)
+        masterCtx_.c[i] ^= masterCtx_.x[(i+4)&0x7];
+
+    /* Copy master instance to work instance */
+    for (i=0; i<8; i++) {
+        workCtx_.x[i] = masterCtx_.x[i];
+        workCtx_.c[i] = masterCtx_.c[i];
+    }
+    workCtx_.carry = masterCtx_.carry;
+
+    if (iv) SetIV(iv);    
+}
+
+
+/* Encrypt/decrypt a message of any size */
+void Rabbit::Process(byte* output, const byte* input, word32 msglen)
+{
+    /* Temporary variables */
+    word32 i;
+    byte buffer[16];
+
+    /* Encrypt/decrypt all full blocks */
+    while (msglen >= 16) {
+        /* Iterate the system */
+        NextState(Work);
+
+        /* Encrypt/decrypt 16 bytes of data */
+        *(word32*)(output+ 0) = *(word32*)(input+ 0) ^
+                   LITTLE32(workCtx_.x[0] ^ (workCtx_.x[5]>>16) ^
+                   U32V(workCtx_.x[3]<<16));
+        *(word32*)(output+ 4) = *(word32*)(input+ 4) ^
+                   LITTLE32(workCtx_.x[2] ^ (workCtx_.x[7]>>16) ^
+                   U32V(workCtx_.x[5]<<16));
+        *(word32*)(output+ 8) = *(word32*)(input+ 8) ^
+                   LITTLE32(workCtx_.x[4] ^ (workCtx_.x[1]>>16) ^
+                   U32V(workCtx_.x[7]<<16));
+        *(word32*)(output+12) = *(word32*)(input+12) ^
+                   LITTLE32(workCtx_.x[6] ^ (workCtx_.x[3]>>16) ^
+                   U32V(workCtx_.x[1]<<16));
+
+        /* Increment pointers and decrement length */
+        input  += 16;
+        output += 16;
+        msglen -= 16;
+    }
+
+    /* Encrypt/decrypt remaining data */
+    if (msglen) {
+        /* Iterate the system */
+        NextState(Work);
+
+        /* Generate 16 bytes of pseudo-random data */
+        *(word32*)(buffer+ 0) = LITTLE32(workCtx_.x[0] ^
+                  (workCtx_.x[5]>>16) ^ U32V(workCtx_.x[3]<<16));
+        *(word32*)(buffer+ 4) = LITTLE32(workCtx_.x[2] ^ 
+                  (workCtx_.x[7]>>16) ^ U32V(workCtx_.x[5]<<16));
+        *(word32*)(buffer+ 8) = LITTLE32(workCtx_.x[4] ^ 
+                  (workCtx_.x[1]>>16) ^ U32V(workCtx_.x[7]<<16));
+        *(word32*)(buffer+12) = LITTLE32(workCtx_.x[6] ^ 
+                  (workCtx_.x[3]>>16) ^ U32V(workCtx_.x[1]<<16));
+
+        /* Encrypt/decrypt the data */
+        for (i=0; i maxOutputLen) || invalid;
@@ -179,7 +179,8 @@ word32 RSA_BlockType1::UnPad(const byte* pkcsBlock, word32 pkcsBlockLen,
     unsigned i=1;
     while (i maxOutputLen) || invalid;
diff --git a/extra/yassl/taocrypt/src/sha.cpp b/extra/yassl/taocrypt/src/sha.cpp
index ef165a342ad..1ae42d94e4c 100644
--- a/extra/yassl/taocrypt/src/sha.cpp
+++ b/extra/yassl/taocrypt/src/sha.cpp
@@ -344,14 +344,14 @@ void SHA::Update(const byte* data, word32 len)
 
     // all at once for asm
     if (buffLen_ == 0) {
-            word32 times = len / BLOCK_SIZE;
-            if (times) {
-                AsmTransform(data, times);
-                const word32 add = BLOCK_SIZE * times;
-                AddLength(add);
-                 len  -= add;
-                data += add;
-            }
+        word32 times = len / BLOCK_SIZE;
+        if (times) {
+            AsmTransform(data, times);
+            const word32 add = BLOCK_SIZE * times;
+            AddLength(add);
+            len  -= add;
+            data += add;
+        }
     }
 
     // cache any data left
diff --git a/extra/yassl/taocrypt/src/template_instnt.cpp b/extra/yassl/taocrypt/src/template_instnt.cpp
index 390da58e191..b472d18236f 100644
--- a/extra/yassl/taocrypt/src/template_instnt.cpp
+++ b/extra/yassl/taocrypt/src/template_instnt.cpp
@@ -61,7 +61,6 @@ template class PBKDF2_HMAC;
 template class HMAC;
 template class HMAC;
 template class HMAC;
-
 }
 
 namespace mySTL {
diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp
index 272a0def169..4ff1304a4cd 100644
--- a/extra/yassl/taocrypt/src/twofish.cpp
+++ b/extra/yassl/taocrypt/src/twofish.cpp
@@ -140,8 +140,6 @@ inline word32 Twofish::h(word32 x, const word32* key, unsigned int kLen)
 
 void Twofish::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
 {
-	assert(keylen >= 16 && keylen <= 32);
-
 	unsigned int len = (keylen <= 16 ? 2 : (keylen <= 24 ? 3 : 4));
     word32 key[8];
 	GetUserKey(LittleEndianOrder, key, len*2, userKey, keylen);
diff --git a/extra/yassl/taocrypt/taocrypt.dsp b/extra/yassl/taocrypt/taocrypt.dsp
index 3f1b47990ad..9c8e74da8c8 100644
--- a/extra/yassl/taocrypt/taocrypt.dsp
+++ b/extra/yassl/taocrypt/taocrypt.dsp
@@ -138,6 +138,10 @@ SOURCE=.\src\hash.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\src\hc128.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\src\integer.cpp
 # End Source File
 # Begin Source File
@@ -158,6 +162,10 @@ SOURCE=.\src\misc.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\src\rabbit.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\src\random.cpp
 # End Source File
 # Begin Source File
@@ -238,6 +246,10 @@ SOURCE=.\include\hash.hpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\include\hc128.hpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\include\hmac.hpp
 # End Source File
 # Begin Source File
@@ -274,6 +286,10 @@ SOURCE=.\include\pwdbased.hpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\include\rabbit.hpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\include\random.hpp
 # End Source File
 # Begin Source File
diff --git a/extra/yassl/taocrypt/test/make.bat b/extra/yassl/taocrypt/test/make.bat
old mode 100644
new mode 100755
diff --git a/extra/yassl/taocrypt/test/memory.cpp b/extra/yassl/taocrypt/test/memory.cpp
index bac8f9c2e97..ec398a64c45 100644
--- a/extra/yassl/taocrypt/test/memory.cpp
+++ b/extra/yassl/taocrypt/test/memory.cpp
@@ -328,3 +328,32 @@ void operator delete[](void* ptr)
 {
     ::operator delete(ptr);
 }
+
+
+extern "C" {
+
+void* XMALLOC(size_t sz, void* head)
+{
+    return ::operator new(sz);
+}
+
+void* XREALLOC(void* ptr, size_t sz, void* heap)
+{
+    void* ret = ::operator new(sz);
+
+    if (ret && ptr)
+        memcpy(ret, ptr, sz);
+
+    if (ret)
+        ::operator delete(ptr);
+    return ret;
+}
+
+
+void XFREE(void* ptr, void* heap)
+{
+    ::operator delete(ptr);
+}
+
+}  // extern "C"
+
diff --git a/extra/yassl/taocrypt/test/test.cpp b/extra/yassl/taocrypt/test/test.cpp
index f8177b31e2f..4cd5dba8ac6 100644
--- a/extra/yassl/taocrypt/test/test.cpp
+++ b/extra/yassl/taocrypt/test/test.cpp
@@ -41,6 +41,8 @@
 #include "coding.hpp"
 #include "random.hpp"
 #include "pwdbased.hpp"
+#include "rabbit.hpp"
+#include "hc128.hpp"
 
 
 
@@ -100,16 +102,18 @@ using TaoCrypt::PBKDF2_HMAC;
 using TaoCrypt::tcArrayDelete;
 using TaoCrypt::GetCert;
 using TaoCrypt::GetPKCS_Cert;
-
+using TaoCrypt::Rabbit;
+using TaoCrypt::HC128;
 
 struct testVector {
     byte*  input_;
     byte*  output_; 
-    size_t inLen_;
-    size_t outLen_;
+    word32 inLen_;
+    word32 outLen_;
 
     testVector(const char* in, const char* out) : input_((byte*)in),
-               output_((byte*)out), inLen_(strlen(in)), outLen_(strlen(out)) {}
+               output_((byte*)out), inLen_((word32)strlen(in)),
+               outLen_((word32)strlen(out)) {}
 };
 
 int  sha_test();
@@ -134,13 +138,15 @@ int  dsa_test();
 int  dh_test();
 int  pwdbased_test();
 int  pkcs12_test();
+int  rabbit_test();
+int  hc128_test();
 
 TaoCrypt::RandomNumberGenerator rng;
 
 
 void err_sys(const char* msg, int es)
 {
-    printf("%s", msg);
+    printf("%s\n", msg);
     exit(es);    
 }
 
@@ -176,7 +182,7 @@ byte* cipher = 0;   // block output
 void taocrypt_test(void* args)
 {
     ((func_args*)args)->return_code = -1; // error state
-    
+
     msg    = NEW_TC byte[24];
     plain  = NEW_TC byte[24];
     cipher = NEW_TC byte[24];
@@ -243,6 +249,16 @@ void taocrypt_test(void* args)
     else
         printf( "ARC4     test passed!\n");
 
+    if ( (ret = rabbit_test()) )
+        err_sys("Rabbit   test failed!\n", ret);
+    else
+        printf( "Rabbit   test passed!\n");
+
+    if ( (ret = hc128_test()) )
+        err_sys("HC128    test failed!\n", ret);
+    else
+        printf( "HC128    test passed!\n");
+
     if ( (ret = des_test()) )
         err_sys("DES      test failed!\n", ret);
     else
@@ -320,16 +336,16 @@ void taocrypt_test(void* args)
 void file_test(const char* file, byte* check)
 {
     FILE* f;
-    int   i(0);
-    MD5   md5;
-    byte  buf[1024];
-    byte  md5sum[MD5::DIGEST_SIZE];
+    int i = 0;
+    MD5    md5;
+    byte   buf[1024];
+    byte   md5sum[MD5::DIGEST_SIZE];
     
     if( !( f = fopen( file, "rb" ) )) {
         printf("Can't open %s\n", file);
         return;
     }
-    while( ( i = fread(buf, 1, sizeof(buf), f )) > 0 )
+    while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 )
         md5.Update(buf, i);
     
     md5.Final(md5sum);
@@ -718,7 +734,7 @@ int hmac_test()
 
     int times( sizeof(test_hmacMD5) / sizeof(testVector) );
     for (int i = 0; i < times; ++i) {
-        hmacMD5.SetKey((byte*)keys[i], strlen(keys[i]));
+        hmacMD5.SetKey((byte*)keys[i], (word32)strlen(keys[i]));
         hmacMD5.Update(test_hmacMD5[i].input_, test_hmacMD5[i].inLen_);
         hmacMD5.Final(hash);
 
@@ -761,8 +777,8 @@ int arc4_test()
         ARC4::Encryption enc;
         ARC4::Decryption dec;
 
-        enc.SetKey((byte*)keys[i], strlen(keys[i]));
-        dec.SetKey((byte*)keys[i], strlen(keys[i]));
+        enc.SetKey((byte*)keys[i], (word32)strlen(keys[i]));
+        dec.SetKey((byte*)keys[i], (word32)strlen(keys[i]));
 
         enc.Process(cipher, test_arc4[i].input_, test_arc4[i].outLen_);
         dec.Process(plain,  cipher, test_arc4[i].outLen_);
@@ -778,6 +794,114 @@ int arc4_test()
 }
 
 
+int rabbit_test()
+{
+    byte cipher[16];
+    byte plain[16];
+
+    const char* keys[] = 
+    {           
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\xAC\xC3\x51\xDC\xF1\x62\xFC\x3B\xFE\x36\x3D\x2E\x29\x13\x28\x91"
+    };
+
+    const char* ivs[] =
+    {
+        "\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x59\x7E\x26\xC1\x75\xF5\x73\xC3",
+        0
+    };
+
+
+    testVector test_rabbit[] =
+    {
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\xED\xB7\x05\x67\x37\x5D\xCD\x7C"),
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\x6D\x7D\x01\x22\x92\xCC\xDC\xE0"),
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\x9C\x51\xE2\x87\x84\xC3\x7F\xE9")
+    };
+
+
+    int times( sizeof(test_rabbit) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        Rabbit::Encryption enc;
+        Rabbit::Decryption dec;
+
+        enc.SetKey((byte*)keys[i], (byte*)ivs[i]);
+        dec.SetKey((byte*)keys[i], (byte*)ivs[i]);
+
+        enc.Process(cipher, test_rabbit[i].input_, test_rabbit[i].outLen_);
+        dec.Process(plain,  cipher, test_rabbit[i].outLen_);
+
+        if (memcmp(plain, test_rabbit[i].input_, test_rabbit[i].outLen_))
+            return -230 - i;
+
+        if (memcmp(cipher, test_rabbit[i].output_, test_rabbit[i].outLen_))
+            return -240 - i;
+    }
+
+    return 0;
+}
+
+
+int hc128_test()
+{
+    byte cipher[16];
+    byte plain[16];
+
+    const char* keys[] = 
+    {           
+        "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD",
+        "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC"
+    };
+
+    const char* ivs[] =
+    {
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x0D\x74\xDB\x42\xA9\x10\x77\xDE\x45\xAC\x13\x7A\xE1\x48\xAF\x16",
+        "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9\x60\xC7\x2E\x95\xFC\x63\xCA\x31"
+    };
+
+    testVector test_hc128[] =
+    {
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\x37\x86\x02\xB9\x8F\x32\xA7\x48"),
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\x33\x7F\x86\x11\xC6\xED\x61\x5F"),
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\x2E\x1E\xD1\x2A\x85\x51\xC0\x5A"),
+      testVector("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+                 "\x1C\xD8\xAE\xDD\xFE\x52\xE2\x17\xE8\x35\xD0\xB7\xE8\x4E\x29")
+    };
+
+    int times( sizeof(test_hc128) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        HC128::Encryption enc;
+        HC128::Decryption dec;
+
+        enc.SetKey((byte*)keys[i], (byte*)ivs[i]);
+        dec.SetKey((byte*)keys[i], (byte*)ivs[i]);
+
+        enc.Process(cipher, test_hc128[i].input_, test_hc128[i].outLen_);
+        dec.Process(plain,  cipher, test_hc128[i].outLen_);
+
+        if (memcmp(plain, test_hc128[i].input_, test_hc128[i].outLen_))
+            return -330 - i;
+
+        if (memcmp(cipher, test_hc128[i].output_, test_hc128[i].outLen_))
+            return -340 - i;
+    }
+
+    return 0;
+}
+
+
 int des_test()
 {
     //ECB mode
@@ -1040,7 +1164,7 @@ int rsa_test()
 
     RSAES_Encryptor enc(priv);
     byte message[] = "Everyone gets Friday off.";
-    const int len(strlen((char*)message));
+    const word32 len = (word32)strlen((char*)message);
     byte cipher[64];
     enc.Encrypt(message, len, cipher, rng);
 
@@ -1068,6 +1192,8 @@ int rsa_test()
         }
     }
     CertDecoder cd(source2, true, 0, false, CertDecoder::CA);
+    if (cd.GetError().What())
+        err_sys("cert error", -80);
     Source source3(cd.GetPublicKey().GetKey(), cd.GetPublicKey().size());
     RSA_PublicKey pub(source3);
  
@@ -1188,6 +1314,7 @@ int pwdbased_test()
 }
 
 
+/*
 int pkcs12_test()
 {
     Source cert;
@@ -1220,4 +1347,5 @@ int pkcs12_test()
 
     return 0;
 }
+*/
 
diff --git a/extra/yassl/testsuite/make.bat b/extra/yassl/testsuite/make.bat
old mode 100644
new mode 100755
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index e14cdc54ae0..1f10095b945 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -23,6 +23,7 @@
 
 #include "runtime.hpp"
 #include "openssl/ssl.h"   /* openssl compatibility test */
+#include "error.hpp"
 #include 
 #include 
 #include 
@@ -32,6 +33,10 @@
 #ifdef _WIN32
     #include 
     #include 
+    #ifdef TEST_IPV6            // don't require newer SDK for IPV4
+	    #include 
+        #include 
+    #endif
     #define SOCKET_T unsigned int
 #else
     #include 
@@ -42,6 +47,9 @@
     #include 
     #include 
     #include 
+    #ifdef TEST_IPV6
+        #include 
+    #endif
     #include 
 #ifdef NON_BLOCKING
     #include 
@@ -50,6 +58,13 @@
 #endif /* _WIN32 */
 
 
+#ifdef _MSC_VER
+    // disable conversion warning
+    // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy
+    #pragma warning(disable:4244 4996)
+#endif
+
+
 #if !defined(_SOCKLEN_T) && (defined(_WIN32) || defined(__APPLE__))
     typedef int socklen_t;
 #endif
@@ -64,6 +79,15 @@
 #endif
 
 
+#ifdef TEST_IPV6
+    typedef sockaddr_in6 SOCKADDR_IN_T;
+    #define AF_INET_V    AF_INET6
+#else
+    typedef sockaddr_in  SOCKADDR_IN_T;
+    #define AF_INET_V    AF_INET
+#endif
+   
+
 // Check if _POSIX_THREADS should be forced
 #if !defined(_POSIX_THREADS) && defined(__hpux)
 // HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
@@ -73,7 +97,7 @@
 
 #ifndef _POSIX_THREADS
     typedef unsigned int  THREAD_RETURN;
-    typedef unsigned long THREAD_TYPE;
+    typedef HANDLE        THREAD_TYPE;
     #define YASSL_API __stdcall
 #else
     typedef void*         THREAD_RETURN;
@@ -120,8 +144,8 @@ void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
 void join_thread(THREAD_TYPE);
 
 // yaSSL
-const char* const    yasslIP   = "127.0.0.1";
-const unsigned short yasslPort = 11111;
+const char* const    yasslIP      = "127.0.0.1";
+const unsigned short yasslPort    =  11111;
 
 
 // client
@@ -180,7 +204,7 @@ extern "C" {
 
 static int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
 {
-    strncpy(passwd, "12345678", sz);
+    strncpy(passwd, "yassl123", sz);
     return 8;
 }
 
@@ -300,14 +324,35 @@ inline void tcp_set_nonblocking(SOCKET_T& sockfd)
 }
 
 
-inline void tcp_socket(SOCKET_T& sockfd, sockaddr_in& addr)
+inline void tcp_socket(SOCKET_T& sockfd, SOCKADDR_IN_T& addr)
 {
-    sockfd = socket(AF_INET, SOCK_STREAM, 0);
+    sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
     memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
 
+#ifdef TEST_IPV6
+    addr.sin6_family = AF_INET_V;
+    addr.sin6_port = htons(yasslPort);
+    addr.sin6_addr = in6addr_loopback;
+
+    /* // for external testing later 
+    addrinfo hints;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family   = AF_INET_V;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags    = AI_PASSIVE;
+
+    getaddrinfo(yasslIP6, yasslPortStr, &hints, info);
+    // then use info connect(sockfd, info->ai_addr, info->ai_addrlen)
+
+    if (*info == 0)
+        err_sys("getaddrinfo failed");
+        */   // end external testing later
+#else
+    addr.sin_family = AF_INET_V;
     addr.sin_port = htons(yasslPort);
     addr.sin_addr.s_addr = inet_addr(yasslIP);
+#endif
+
 }
 
 
@@ -318,13 +363,13 @@ inline void tcp_close(SOCKET_T& sockfd)
 #else
     close(sockfd);
 #endif
-    sockfd = -1;
+    sockfd = (SOCKET_T) -1;
 }
 
 
 inline void tcp_connect(SOCKET_T& sockfd)
 {
-    sockaddr_in addr;
+    SOCKADDR_IN_T addr;
     tcp_socket(sockfd, addr);
 
     if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) {
@@ -336,9 +381,15 @@ inline void tcp_connect(SOCKET_T& sockfd)
 
 inline void tcp_listen(SOCKET_T& sockfd)
 {
-    sockaddr_in addr;
+    SOCKADDR_IN_T addr;
     tcp_socket(sockfd, addr);
 
+#ifndef _WIN32
+    int       on  = 1;
+    socklen_t len = sizeof(on);
+    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
+#endif
+
     if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) {
         tcp_close(sockfd);
         err_sys("tcp bind failed");
@@ -355,7 +406,7 @@ inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args)
 {
     tcp_listen(sockfd);
 
-    sockaddr_in client;
+    SOCKADDR_IN_T client;
     socklen_t client_len = sizeof(client);
 
 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER)
@@ -369,7 +420,7 @@ inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args)
 
     clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len);
 
-    if (clientfd == -1) {
+    if (clientfd == (SOCKET_T) -1) {
         tcp_close(sockfd);
         err_sys("tcp accept failed");
     }
@@ -387,10 +438,8 @@ inline void showPeer(SSL* ssl)
         char* issuer  = X509_NAME_oneline(X509_get_issuer_name(peer), 0, 0);
         char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0);
 
-        printf("peer's cert info:\n");
-        printf("issuer : %s\n", issuer);
-        printf("subject: %s\n", subject);
-
+        printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
+                                                                  subject);
         free(subject);
         free(issuer);
     }
@@ -436,5 +485,19 @@ inline DH* set_tmpDH(SSL_CTX* ctx)
 }
 
 
+inline int verify_callback(int preverify_ok, X509_STORE_CTX* ctx)
+{
+    X509* err_cert = X509_STORE_CTX_get_current_cert(ctx);
+    int   err      = X509_STORE_CTX_get_error(ctx);
+    int   depth    = X509_STORE_CTX_get_error_depth(ctx);
+
+    // test allow self signed
+    if (err_cert && depth == 0 && err == TaoCrypt::SIG_OTHER_E)
+        return 1;
+
+    return 0;
+}
+
+
 #endif // yaSSL_TEST_HPP
 
diff --git a/extra/yassl/testsuite/testsuite.cpp b/extra/yassl/testsuite/testsuite.cpp
index 5ddb9bb4dab..fa8c997e7c2 100644
--- a/extra/yassl/testsuite/testsuite.cpp
+++ b/extra/yassl/testsuite/testsuite.cpp
@@ -119,7 +119,7 @@ int main(int argc, char** argv)
 void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread)
 {
 #ifndef _POSIX_THREADS
-    *thread = _beginthreadex(0, 0, fun, args, 0, 0);
+    *thread = (HANDLE)_beginthreadex(0, 0, fun, args, 0, 0);
 #else
     pthread_create(thread, 0, fun, args);
 #endif
@@ -129,9 +129,9 @@ void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread)
 void join_thread(THREAD_TYPE thread)
 {
 #ifndef _POSIX_THREADS
-    int res = WaitForSingleObject(reinterpret_cast(thread), INFINITE);
+    int res = WaitForSingleObject(thread, INFINITE);
     assert(res == WAIT_OBJECT_0);
-    res = CloseHandle(reinterpret_cast(thread));
+    res = CloseHandle(thread);
     assert(res);
 #else
     pthread_join(thread, 0);
@@ -158,7 +158,7 @@ int test_openSSL_des()
 {
     /* test des encrypt/decrypt */
     char data[] = "this is my data ";
-    int  dataSz = strlen(data);
+    int  dataSz = (int)strlen(data);
     DES_key_schedule key[3];
     byte iv[8];
     EVP_BytesToKey(EVP_des_ede3_cbc(), EVP_md5(), NULL, (byte*)data, dataSz, 1,
-- 
cgit v1.2.1


From c3ef620d393353d0882d0383b392bf70ce95a65b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= 
Date: Wed, 15 Feb 2012 15:53:29 +0200
Subject: store_create_info(): Fix a compiler warning about unused variable.

---
 sql/sql_show.cc | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index da77bf329b1..7645868180d 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1214,7 +1214,9 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
   handler *file= table->file;
   TABLE_SHARE *share= table->s;
   HA_CREATE_INFO create_info;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
   bool show_table_options= FALSE;
+#endif /* WITH_PARTITION_STORAGE_ENGINE */
   bool foreign_db_mode=  (thd->variables.sql_mode & (MODE_POSTGRESQL |
                                                      MODE_ORACLE |
                                                      MODE_MSSQL |
@@ -1429,7 +1431,9 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
   packet->append(STRING_WITH_LEN("\n)"));
   if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
   {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
     show_table_options= TRUE;
+#endif /* WITH_PARTITION_STORAGE_ENGINE */
     /*
       Get possible table space definitions and append them
       to the CREATE TABLE statement
-- 
cgit v1.2.1


From 2a6a6abb70202e94eb0b6eec62f7bdde25d8a68b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= 
Date: Wed, 15 Feb 2012 16:28:00 +0200
Subject: Remove a race condition in innodb_bug53756.test. Before killing the
 server, tell mysql-test-run that it is to be expected.

Discussed with Bjorn Munch on IM.
---
 mysql-test/suite/innodb/t/innodb_bug53756.test        | 6 +++---
 mysql-test/suite/innodb_plugin/t/innodb_bug53756.test | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/mysql-test/suite/innodb/t/innodb_bug53756.test b/mysql-test/suite/innodb/t/innodb_bug53756.test
index 7a48f130b2c..04856d448cb 100644
--- a/mysql-test/suite/innodb/t/innodb_bug53756.test
+++ b/mysql-test/suite/innodb/t/innodb_bug53756.test
@@ -139,6 +139,9 @@ INSERT INTO bug_53756 VALUES (666,666);
 # Request a crash on next execution of commit.
 SET SESSION debug="+d,crash_commit_before";
 #
+# Write file to make mysql-test-run.pl start up the server again
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+#
 # Execute the statement that causes the crash.
 --error 2013
 COMMIT;
@@ -154,9 +157,6 @@ COMMIT;
 --echo #
 --echo # Restart server.
 #
-# Write file to make mysql-test-run.pl start up the server again
---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-#
 # Turn on reconnect
 --enable_reconnect
 #
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test
index 37a79ea3021..ba035fe0a46 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test
@@ -139,6 +139,9 @@ INSERT INTO bug_53756 VALUES (666,666);
 # Request a crash on next execution of commit.
 SET SESSION debug="+d,crash_commit_before";
 #
+# Write file to make mysql-test-run.pl start up the server again
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+#
 # Execute the statement that causes the crash.
 --error 2013
 COMMIT;
@@ -154,9 +157,6 @@ COMMIT;
 --echo #
 --echo # Restart server.
 #
-# Write file to make mysql-test-run.pl start up the server again
---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-#
 # Turn on reconnect
 --enable_reconnect
 #
-- 
cgit v1.2.1


From 7177a2b9d79122babf85cfe26c8fe8f9dbd06f1c Mon Sep 17 00:00:00 2001
From: MySQL Build Team 
Date: Wed, 15 Feb 2012 17:13:47 +0100
Subject: Updated/added copyright headers

---
 client/sql_string.cc  | 3 +--
 include/heap.h        | 2 +-
 include/m_string.h    | 3 +--
 myisam/ft_stopwords.c | 2 +-
 myisam/mi_preload.c   | 3 +--
 mysys/my_compare.c    | 2 +-
 mysys/my_init.c       | 3 +--
 mysys/my_symlink.c    | 3 +--
 sql/item.cc           | 3 +--
 sql/item_strfunc.cc   | 3 +--
 sql/item_subselect.cc | 2 +-
 sql/item_sum.cc       | 2 +-
 sql/my_decimal.h      | 2 +-
 sql/sp_head.cc        | 3 +--
 sql/sql_class.cc      | 3 +--
 sql/sql_load.cc       | 3 +--
 sql/sql_select.cc     | 2 +-
 sql/sql_string.cc     | 3 +--
 sql/sql_table.cc      | 3 +--
 sql/sql_view.cc       | 3 +--
 sql/unireg.h          | 3 +--
 strings/decimal.c     | 3 +--
 22 files changed, 22 insertions(+), 37 deletions(-)

diff --git a/client/sql_string.cc b/client/sql_string.cc
index 0c89e1d0bca..246b5cd2c41 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -1,6 +1,5 @@
 /*
-   Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+   Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/include/heap.h b/include/heap.h
index 9d67c94e003..9a84b19f30b 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/include/m_string.h b/include/m_string.h
index 94de334a050..2d9033b7e95 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000, 2001, 2003-2007 MySQL AB, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/myisam/ft_stopwords.c b/myisam/ft_stopwords.c
index 72cbf6cc18a..03e96ce730c 100644
--- a/myisam/ft_stopwords.c
+++ b/myisam/ft_stopwords.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c
index f53fcd2e1ee..d11c1856b2e 100644
--- a/myisam/mi_preload.c
+++ b/myisam/mi_preload.c
@@ -1,5 +1,4 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_compare.c b/mysys/my_compare.c
index c7037befd93..f58c081b1cc 100644
--- a/mysys/my_compare.c
+++ b/mysys/my_compare.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 87ec253f983..a6b04276dd2 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2007 MySQL AB, 2008 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index fbf015512a3..8239f357d24 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -1,5 +1,4 @@
-/* Copyright (c) 2001-2003, 2005, 2006, 2008 MySQL AB, 2008 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/item.cc b/sql/item.cc
index ad73a5d6f5a..538d2ceff17 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index cd11cc3c34a..90291f4b8e6 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index db8d6b128a4..65ab147ca3c 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 56487e5fe7e..f902f0b6e90 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index ee023438f20..9100eab2ac2 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2006 MySQL AB
+/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f2061454e1e..bf53578d69b 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2002-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 9734629fd9c..bfa5cec940f 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2008 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index ad5334a906f..a6491e1bf49 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 86ff425d17b..42aa2f6c7fa 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 545643de49f..7049f50254f 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2bb758f8b86..c7fd637c5cf 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 3ae35e5cfe0..5fc357988da 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2004-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/sql/unireg.h b/sql/unireg.h
index dd79de0781a..ccc8a353b3d 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -1,5 +1,4 @@
-/* Copyright (c) 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/strings/decimal.c b/strings/decimal.c
index 87faff9b4cd..3a86d0b5324 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1,5 +1,4 @@
-/* Copyright (c) 2004-2008 MySQL AB, 2009 Sun Microsystems, Inc.
-   Use is subject to license terms.
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-- 
cgit v1.2.1


From 66b658720605482b5b98a827ed063a05a49318bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= 
Date: Thu, 16 Feb 2012 12:20:41 +0200
Subject: Correct a few copyright messages.

---
 storage/innodb_plugin/handler/ha_innodb.cc | 4 ++--
 storage/innodb_plugin/include/log0log.h    | 6 +++---
 storage/innodb_plugin/include/mtr0mtr.h    | 4 ++--
 storage/innodb_plugin/log/log0log.c        | 6 +++---
 storage/innodb_plugin/mtr/mtr0mtr.c        | 4 ++--
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index f23642d6af8..09094c0146e 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -26,8 +26,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
diff --git a/storage/innodb_plugin/include/log0log.h b/storage/innodb_plugin/include/log0log.h
index 8fce4ef96bc..8c61244a38d 100644
--- a/storage/innodb_plugin/include/log0log.h
+++ b/storage/innodb_plugin/include/log0log.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2010, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2009, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -18,8 +18,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
diff --git a/storage/innodb_plugin/include/mtr0mtr.h b/storage/innodb_plugin/include/mtr0mtr.h
index 8a9ec8ea7f0..46beb63ee80 100644
--- a/storage/innodb_plugin/include/mtr0mtr.h
+++ b/storage/innodb_plugin/include/mtr0mtr.h
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
diff --git a/storage/innodb_plugin/log/log0log.c b/storage/innodb_plugin/log/log0log.c
index 4bb9abdc1a4..28456e6b907 100644
--- a/storage/innodb_plugin/log/log0log.c
+++ b/storage/innodb_plugin/log/log0log.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2010, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2009, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -18,8 +18,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
diff --git a/storage/innodb_plugin/mtr/mtr0mtr.c b/storage/innodb_plugin/mtr/mtr0mtr.c
index 5fad61b2922..1988bbabbf3 100644
--- a/storage/innodb_plugin/mtr/mtr0mtr.c
+++ b/storage/innodb_plugin/mtr/mtr0mtr.c
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
-- 
cgit v1.2.1


From 4045c9976cf475b3f42f4133440c1d9a9060fb25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= 
Date: Thu, 16 Feb 2012 12:24:11 +0200
Subject: Add instrumentation for Bug#13721257 RACE CONDITION IN UPDATES OR
 INSERTS OF WIDE RECORDS

row_ins_index_entry_low(), row_upd_clust_rec(): Make a redo log
checkpoint if a DEBUG flag is set. Add DEBUG_SYNC around
btr_store_big_rec_extern_fields().

rb:946 approved by Jimmy Yang
---
 storage/innobase/row/row0ins.c      | 11 +++++++++++
 storage/innobase/row/row0upd.c      | 10 +++++++++-
 storage/innodb_plugin/row/row0ins.c | 11 +++++++++++
 storage/innodb_plugin/row/row0upd.c | 10 +++++++++-
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index db134ca7a41..bb5c95a572b 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -6,6 +6,9 @@ Insert into a table
 Created 4/20/1996 Heikki Tuuri
 *******************************************************/
 
+#include "my_global.h" /* HAVE_* */
+#include "m_string.h" /* for my_sys.h */
+#include "my_sys.h" /* DEBUG_SYNC_C */
 #include "row0ins.h"
 
 #ifdef UNIV_NONINL
@@ -2121,16 +2124,24 @@ function_exit:
 
 	if (big_rec) {
 		rec_t*		rec;
+
+		DBUG_EXECUTE_IF(
+			"row_ins_extern_checkpoint",
+			log_make_checkpoint_at(ut_dulint_max, TRUE););
+
 		mtr_start(&mtr);
 
+		DEBUG_SYNC_C("before_row_ins_extern_latch");
 		btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
 					    BTR_MODIFY_TREE, &cursor, 0, &mtr);
 		rec = btr_cur_get_rec(&cursor);
 		offsets = rec_get_offsets(rec, index, offsets,
 					  ULINT_UNDEFINED, &heap);
 
+		DEBUG_SYNC_C("before_row_ins_upd_extern");
 		err = btr_store_big_rec_extern_fields(index, rec,
 						      offsets, big_rec, &mtr);
+		DEBUG_SYNC_C("after_row_ins_upd_extern");
 
 		if (modify) {
 			dtuple_big_rec_free(big_rec);
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index 0790cfe02e2..d3ed71089a8 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -6,6 +6,9 @@ Update of a row
 Created 12/27/1996 Heikki Tuuri
 *******************************************************/
 
+#include "my_global.h" /* HAVE_* */
+#include "m_string.h" /* for my_sys.h */
+#include "my_sys.h" /* DEBUG_SYNC_C */
 #include "row0upd.h"
 
 #ifdef UNIV_NONINL
@@ -1591,15 +1594,20 @@ row_upd_clust_rec(
 		rec_t*		rec;
 		*offsets_ = (sizeof offsets_) / sizeof *offsets_;
 
-		mtr_start(mtr);
+		DBUG_EXECUTE_IF(
+			"row_upd_extern_checkpoint",
+			log_make_checkpoint_at(ut_dulint_max, TRUE););
 
+		mtr_start(mtr);
 		ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
 		rec = btr_cur_get_rec(btr_cur);
+		DEBUG_SYNC_C("before_row_upd_extern");
 		err = btr_store_big_rec_extern_fields(
 			index, rec,
 			rec_get_offsets(rec, index, offsets_,
 					ULINT_UNDEFINED, &heap),
 			 big_rec, mtr);
+		DEBUG_SYNC_C("after_row_upd_extern");
 		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c
index 2cbe1e13edc..939791aa19f 100644
--- a/storage/innodb_plugin/row/row0ins.c
+++ b/storage/innodb_plugin/row/row0ins.c
@@ -23,6 +23,9 @@ Insert into a table
 Created 4/20/1996 Heikki Tuuri
 *******************************************************/
 
+#include "my_global.h" /* HAVE_* */
+#include "m_string.h" /* for my_sys.h */
+#include "my_sys.h" /* DEBUG_SYNC_C */
 #include "row0ins.h"
 
 #ifdef UNIV_NONINL
@@ -2122,8 +2125,14 @@ function_exit:
 	if (UNIV_LIKELY_NULL(big_rec)) {
 		rec_t*	rec;
 		ulint*	offsets;
+
+		DBUG_EXECUTE_IF(
+			"row_ins_extern_checkpoint",
+			log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE););
+
 		mtr_start(&mtr);
 
+		DEBUG_SYNC_C("before_row_ins_extern_latch");
 		btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
 					    BTR_MODIFY_TREE, &cursor, 0,
 					    __FILE__, __LINE__, &mtr);
@@ -2131,9 +2140,11 @@ function_exit:
 		offsets = rec_get_offsets(rec, index, NULL,
 					  ULINT_UNDEFINED, &heap);
 
+		DEBUG_SYNC_C("before_row_ins_upd_extern");
 		err = btr_store_big_rec_extern_fields(
 			index, btr_cur_get_block(&cursor),
 			rec, offsets, &mtr, FALSE, big_rec);
+		DEBUG_SYNC_C("after_row_ins_upd_extern");
 
 		if (modify) {
 			dtuple_big_rec_free(big_rec);
diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c
index 072ca1d7b54..f03c120d6fb 100644
--- a/storage/innodb_plugin/row/row0upd.c
+++ b/storage/innodb_plugin/row/row0upd.c
@@ -23,6 +23,9 @@ Update of a row
 Created 12/27/1996 Heikki Tuuri
 *******************************************************/
 
+#include "my_global.h" /* HAVE_* */
+#include "m_string.h" /* for my_sys.h */
+#include "my_sys.h" /* DEBUG_SYNC_C */
 #include "row0upd.h"
 
 #ifdef UNIV_NONINL
@@ -1979,15 +1982,20 @@ row_upd_clust_rec(
 		rec_t*		rec;
 		rec_offs_init(offsets_);
 
-		mtr_start(mtr);
+		DBUG_EXECUTE_IF(
+			"row_upd_extern_checkpoint",
+			log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE););
 
+		mtr_start(mtr);
 		ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
 		rec = btr_cur_get_rec(btr_cur);
+		DEBUG_SYNC_C("before_row_upd_extern");
 		err = btr_store_big_rec_extern_fields(
 			index, btr_cur_get_block(btr_cur), rec,
 			rec_get_offsets(rec, index, offsets_,
 					ULINT_UNDEFINED, &heap),
 			mtr, TRUE, big_rec);
+		DEBUG_SYNC_C("after_row_upd_extern");
 		mtr_commit(mtr);
 	}
 
-- 
cgit v1.2.1


From 4fc7565ab7f1423c523d5868c7c37f14c9093c11 Mon Sep 17 00:00:00 2001
From: MySQL Build Team 
Date: Thu, 16 Feb 2012 11:35:30 +0100
Subject: Updated/added copyright headers

---
 sql/sql_show.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 7645868180d..2c85e29f985 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-- 
cgit v1.2.1


From e63d0c916bf36c1164143d05cc57a50b47827e2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= 
Date: Thu, 16 Feb 2012 15:54:16 +0200
Subject: Fix link error on Windows. error LNK2001: unresolved external symbol
 _debug_sync_C_callback_ptr

---
 storage/innodb_plugin/row/row0ins.c | 12 +++++++++---
 storage/innodb_plugin/row/row0upd.c | 12 +++++++++---
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c
index 939791aa19f..56d1c1a7b88 100644
--- a/storage/innodb_plugin/row/row0ins.c
+++ b/storage/innodb_plugin/row/row0ins.c
@@ -23,9 +23,15 @@ Insert into a table
 Created 4/20/1996 Heikki Tuuri
 *******************************************************/
 
-#include "my_global.h" /* HAVE_* */
-#include "m_string.h" /* for my_sys.h */
-#include "my_sys.h" /* DEBUG_SYNC_C */
+#ifdef __WIN__
+/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */
+# define DEBUG_SYNC_C(dummy) ((void) 0)
+#else
+# include "my_global.h" /* HAVE_* */
+# include "m_string.h" /* for my_sys.h */
+# include "my_sys.h" /* DEBUG_SYNC_C */
+#endif
+
 #include "row0ins.h"
 
 #ifdef UNIV_NONINL
diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c
index f03c120d6fb..acd72ead42f 100644
--- a/storage/innodb_plugin/row/row0upd.c
+++ b/storage/innodb_plugin/row/row0upd.c
@@ -23,9 +23,15 @@ Update of a row
 Created 12/27/1996 Heikki Tuuri
 *******************************************************/
 
-#include "my_global.h" /* HAVE_* */
-#include "m_string.h" /* for my_sys.h */
-#include "my_sys.h" /* DEBUG_SYNC_C */
+#ifdef __WIN__
+/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */
+# define DEBUG_SYNC_C(dummy) ((void) 0)
+#else
+# include "my_global.h" /* HAVE_* */
+# include "m_string.h" /* for my_sys.h */
+# include "my_sys.h" /* DEBUG_SYNC_C */
+#endif
+
 #include "row0upd.h"
 
 #ifdef UNIV_NONINL
-- 
cgit v1.2.1


From f77329ace9a8a415b05ad473970de6dc187327e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= 
Date: Fri, 17 Feb 2012 11:42:04 +0200
Subject: Bug#13721257 RACE CONDITION IN UPDATES OR INSERTS OF WIDE RECORDS

This bug was originally filed and fixed as Bug#12612184. The original
fix was buggy, and it was patched by Bug#12704861. Also that patch was
buggy (potentially breaking crash recovery), and both fixes were
reverted.

This fix was not ported to the built-in InnoDB of MySQL 5.1, because
the function signatures of many core functions are different from
InnoDB Plugin and later versions. The block allocation routines and
their callers would have to changed so that they handle block
descriptors instead of page frames.

When a record is updated so that its size grows, non-updated columns
can be selected for external (off-page) storage. The bug is that the
initially inserted updated record contains an all-zero BLOB pointer to
the field that was not updated. Only after the BLOB pages have been
allocated and written, the valid pointer can be written to the record.

Between the release of the page latch in mtr_commit(mtr) after
btr_cur_pessimistic_update() and the re-latching of the page in
btr_pcur_restore_position(), other threads can see the invalid BLOB
pointer consisting of 20 zero bytes. Moreover, if the system crashes
at this point, the situation could persist after crash recovery, and
the contents of the non-updated column would be permanently lost.

The problem is amplified by the ROW_FORMAT=DYNAMIC and
ROW_FORMAT=COMPRESSED that were introduced in
innodb_file_format=barracuda in InnoDB Plugin, but the bug does exist
in all InnoDB versions.

The fix is as follows. After a pessimistic B-tree operation that needs
to write out off-page columns, allocate the pages for these columns in
the mini-transaction that performed the B-tree operation (btr_mtr),
but write the pages in a separate mini-transaction (blob_mtr). Do
mtr_commit(blob_mtr) before mtr_commit(btr_mtr). A quirk: Do not reuse
pages that were previously freed in btr_mtr. Only write the off-page
columns to 'fresh' pages.

In this way, crash recovery will see redo log entries for blob_mtr
before any redo log entry for btr_mtr. It will apply the BLOB page
writes to pages that were marked free at that point. If crash recovery
fails to see all of the btr_mtr redo log, there will be some
unreachable BLOB data in free pages, but the B-tree will be in a
consistent state.

btr_page_alloc_low(): Renamed from btr_page_alloc(). Add the parameter
init_mtr. Return an allocated block, or NULL. If init_mtr!=mtr but
the page was already X-latched in mtr, do not initialize the page.

btr_page_alloc(): Wrapper for btr_page_alloc_for_ibuf() and
btr_page_alloc_low().

btr_page_free(): Add a debug assertion that the page was a B-tree page.

btr_lift_page_up(): Return the father block.

btr_compress(), btr_cur_compress_if_useful(): Add the parameter ibool
adjust, for adjusting the cursor position.

btr_cur_pessimistic_update(): Preserve the cursor position when
big_rec will be written and the new flag BTR_KEEP_POS_FLAG is defined.
Remove a duplicate rec_get_offsets() call. Keep the X-latch on
index->lock when big_rec is needed.

btr_store_big_rec_extern_fields(): Replace update_inplace with
an operation code, and local_mtr with btr_mtr. When not doing a
fresh insert and btr_mtr has freed pages, put aside any pages that
were previously X-latched in btr_mtr, and free the pages after
writing out all data. The data must be written to 'fresh' pages,
because btr_mtr will be committed and written to the redo log after
the BLOB writes have been written to the redo log.

btr_blob_op_is_update(): Check if an operation passed to
btr_store_big_rec_extern_fields() is an update or insert-by-update.

fseg_alloc_free_page_low(), fsp_alloc_free_page(),
fseg_alloc_free_extent(), fseg_alloc_free_page_general(): Add the
parameter init_mtr. Return an allocated block, or NULL. If
init_mtr!=mtr but the page was already X-latched in mtr, do not
initialize the page.

xdes_get_descriptor_with_space_hdr(): Assert that the file space
header is being X-latched.

fsp_alloc_from_free_frag(): Refactored from fsp_alloc_free_page().

fsp_page_create(): New function, for allocating, X-latching and
potentially initializing a page. If init_mtr!=mtr but the page was
already X-latched in mtr, do not initialize the page.

fsp_free_page(): Add ut_ad(0) to the error outcomes.

fsp_free_page(), fseg_free_page_low(): Increment mtr->n_freed_pages.

fsp_alloc_seg_inode_page(), fseg_create_general(): Assert that the
page was not previously X-latched in the mini-transaction. A file
segment or inode page should never be allocated in the middle of an
mini-transaction that frees pages, such as btr_cur_pessimistic_delete().

fseg_alloc_free_page_low(): If the hinted page was allocated, skip the
check if the tablespace should be extended. Return NULL instead of
FIL_NULL on failure. Remove the flag frag_page_allocated. Instead,
return directly, because the page would already have been initialized.

fseg_find_free_frag_page_slot() would return ULINT_UNDEFINED on error,
not FIL_NULL. Correct a bogus assertion.

fseg_alloc_free_page(): Redefine as a wrapper macro around
fseg_alloc_free_page_general().

buf_block_buf_fix_inc(): Move the definition from the buf0buf.ic to
buf0buf.h, so that it can be called from other modules.

mtr_t: Add n_freed_pages (number of pages that have been freed).

page_rec_get_nth_const(), page_rec_get_nth(): The inverse function of
page_rec_get_n_recs_before(), get the nth record of the record
list. This is faster than iterating the linked list. Refactored from
page_get_middle_rec().

trx_undo_rec_copy(): Add a debug assertion for the length.

trx_undo_add_page(): Return a block descriptor or NULL instead of a
page number or FIL_NULL.

trx_undo_report_row_operation(): Add debug assertions.

trx_sys_create_doublewrite_buf(): Assert that each page was not
previously X-latched.

page_cur_insert_rec_zip_reorg(): Make use of page_rec_get_nth().

row_ins_clust_index_entry_by_modify(): Pass BTR_KEEP_POS_FLAG, so that
the repositioning of the cursor can be avoided.

row_ins_index_entry_low(): Add DEBUG_SYNC points before and after
writing off-page columns. If inserting by updating a delete-marked
record, do not reposition the cursor or commit the mini-transaction
before writing the off-page columns.

row_build(): Tighten a debug assertion about null BLOB pointers.

row_upd_clust_rec(): Add DEBUG_SYNC points before and after writing
off-page columns. Do not reposition the cursor or commit the
mini-transaction before writing the off-page columns.

rb:939 approved by Jimmy Yang
---
 .../suite/innodb_plugin/r/innodb-blob.result       | 119 ++++++
 mysql-test/suite/innodb_plugin/t/innodb-blob.test  | 218 +++++++++++
 storage/innodb_plugin/ChangeLog                    |  14 +-
 storage/innodb_plugin/btr/btr0btr.c                | 153 +++++---
 storage/innodb_plugin/btr/btr0cur.c                | 253 +++++++++----
 storage/innodb_plugin/fsp/fsp0fsp.c                | 399 ++++++++++++---------
 storage/innodb_plugin/ibuf/ibuf0ibuf.c             |  50 ++-
 storage/innodb_plugin/include/btr0btr.h            |  31 +-
 storage/innodb_plugin/include/btr0cur.h            |  88 ++---
 storage/innodb_plugin/include/btr0cur.ic           |  29 +-
 storage/innodb_plugin/include/buf0buf.h            |  31 +-
 storage/innodb_plugin/include/buf0buf.ic           |  19 +-
 storage/innodb_plugin/include/fsp0fsp.h            |  43 ++-
 storage/innodb_plugin/include/mtr0mtr.h            |  13 +-
 storage/innodb_plugin/include/mtr0mtr.ic           |   7 +-
 storage/innodb_plugin/include/page0page.h          |  43 ++-
 storage/innodb_plugin/include/page0page.ic         |  36 +-
 storage/innodb_plugin/include/trx0rec.ic           |   7 +-
 storage/innodb_plugin/include/trx0undo.h           |  13 +-
 storage/innodb_plugin/page/page0cur.c              |  21 +-
 storage/innodb_plugin/page/page0page.c             |  56 +--
 storage/innodb_plugin/row/row0ins.c                |  81 ++++-
 storage/innodb_plugin/row/row0row.c                |  33 +-
 storage/innodb_plugin/row/row0upd.c                |  65 +++-
 storage/innodb_plugin/trx/trx0rec.c                |  38 +-
 storage/innodb_plugin/trx/trx0sys.c                |  24 +-
 storage/innodb_plugin/trx/trx0undo.c               |  43 ++-
 27 files changed, 1344 insertions(+), 583 deletions(-)
 create mode 100644 mysql-test/suite/innodb_plugin/r/innodb-blob.result
 create mode 100644 mysql-test/suite/innodb_plugin/t/innodb-blob.test

diff --git a/mysql-test/suite/innodb_plugin/r/innodb-blob.result b/mysql-test/suite/innodb_plugin/r/innodb-blob.result
new file mode 100644
index 00000000000..b0b6bb9e5e2
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/innodb-blob.result
@@ -0,0 +1,119 @@
+CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t3 (a INT PRIMARY KEY, b TEXT, c TEXT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,REPEAT('a',30000)),(2,REPEAT('b',40000));
+SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR go1';
+BEGIN;
+UPDATE t1 SET a=a+2;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET b=CONCAT(b,'foo');
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+SELECT a, RIGHT(b,20) FROM t1;
+SET DEBUG_SYNC='now SIGNAL go1';
+a	RIGHT(b,20)
+1	aaaaaaaaaaaaaaaaaaaa
+2	bbbbbbbbbbbbbbbbbbbb
+SET DEBUG='+d,row_ins_extern_checkpoint';
+SET DEBUG_SYNC='before_row_ins_extern_latch SIGNAL rec_not_blob WAIT_FOR crash';
+ROLLBACK;
+BEGIN;
+INSERT INTO t1 VALUES (3,REPEAT('c',50000));
+SET DEBUG_SYNC='now WAIT_FOR rec_not_blob';
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-UNCOMMITTED
+SELECT a, RIGHT(b,20) FROM t1;
+a	RIGHT(b,20)
+1	aaaaaaaaaaaaaaaaaaaa
+2	bbbbbbbbbbbbbbbbbbbb
+SELECT a FROM t1;
+a
+1
+2
+3
+SET DEBUG='+d,crash_commit_before';
+INSERT INTO t2 VALUES (42);
+ERROR HY000: Lost connection to MySQL server during query
+ERROR HY000: Lost connection to MySQL server during query
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+INSERT INTO t3 VALUES
+(1,REPEAT('d',7000),REPEAT('e',100)),
+(2,REPEAT('g',7000),REPEAT('h',100));
+SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR go';
+UPDATE t3 SET c=REPEAT('f',3000) WHERE a=1;
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-UNCOMMITTED
+SELECT a, RIGHT(b,20), RIGHT(c,20) FROM t3;
+SET DEBUG_SYNC='now SIGNAL go';
+a	RIGHT(b,20)	RIGHT(c,20)
+1	dddddddddddddddddddd	ffffffffffffffffffff
+2	gggggggggggggggggggg	hhhhhhhhhhhhhhhhhhhh
+CHECK TABLE t1,t2,t3;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+test.t2	check	status	OK
+test.t3	check	status	OK
+BEGIN;
+INSERT INTO t2 VALUES (347);
+SET DEBUG='+d,row_upd_extern_checkpoint';
+SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR crash';
+UPDATE t3 SET c=REPEAT('i',3000) WHERE a=2;
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+SELECT info FROM information_schema.processlist
+WHERE state = 'debug sync point: before_row_upd_extern';
+info
+UPDATE t3 SET c=REPEAT('i',3000) WHERE a=2
+SET DEBUG='+d,crash_commit_before';
+COMMIT;
+ERROR HY000: Lost connection to MySQL server during query
+ERROR HY000: Lost connection to MySQL server during query
+CHECK TABLE t1,t2,t3;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+test.t2	check	status	OK
+test.t3	check	status	OK
+SELECT a, RIGHT(b,20), RIGHT(c,20) FROM t3;
+a	RIGHT(b,20)	RIGHT(c,20)
+1	dddddddddddddddddddd	ffffffffffffffffffff
+2	gggggggggggggggggggg	hhhhhhhhhhhhhhhhhhhh
+SELECT a FROM t3;
+a
+1
+2
+BEGIN;
+INSERT INTO t2 VALUES (33101);
+SET DEBUG='+d,row_upd_extern_checkpoint';
+SET DEBUG_SYNC='after_row_upd_extern SIGNAL have_latch WAIT_FOR crash';
+UPDATE t3 SET c=REPEAT('j',3000) WHERE a=2;
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+SELECT info FROM information_schema.processlist
+WHERE state = 'debug sync point: after_row_upd_extern';
+info
+UPDATE t3 SET c=REPEAT('j',3000) WHERE a=2
+SET DEBUG='+d,crash_commit_before';
+COMMIT;
+ERROR HY000: Lost connection to MySQL server during query
+ERROR HY000: Lost connection to MySQL server during query
+CHECK TABLE t1,t2,t3;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+test.t2	check	status	OK
+test.t3	check	status	OK
+SELECT a, RIGHT(b,20), RIGHT(c,20) FROM t3;
+a	RIGHT(b,20)	RIGHT(c,20)
+1	dddddddddddddddddddd	ffffffffffffffffffff
+2	gggggggggggggggggggg	hhhhhhhhhhhhhhhhhhhh
+SELECT a FROM t3;
+a
+1
+2
+SELECT * FROM t2;
+a
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb-blob.test b/mysql-test/suite/innodb_plugin/t/innodb-blob.test
new file mode 100644
index 00000000000..7d2968c720d
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/innodb-blob.test
@@ -0,0 +1,218 @@
+# Bug#13721257 RACE CONDITION IN UPDATES OR INSERTS OF WIDE RECORDS
+# Test what happens when a record is inserted or updated so that some
+# columns are stored off-page.
+
+--source include/have_innodb_plugin.inc
+
+# DEBUG_SYNC must be compiled in.
+--source include/have_debug_sync.inc
+
+# Valgrind would complain about memory leaks when we crash on purpose.
+--source include/not_valgrind.inc
+# Embedded server does not support crashing
+--source include/not_embedded.inc
+# Avoid CrashReporter popup on Mac
+--source include/not_crashrep.inc
+# InnoDB Plugin cannot use DEBUG_SYNC on Windows
+--source include/not_windows.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t3 (a INT PRIMARY KEY, b TEXT, c TEXT) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (1,REPEAT('a',30000)),(2,REPEAT('b',40000));
+SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR go1';
+BEGIN;
+# This will not block, because it will not store new BLOBs.
+UPDATE t1 SET a=a+2;
+ROLLBACK;
+BEGIN;
+--send
+UPDATE t1 SET b=CONCAT(b,'foo');
+
+connect (con1,localhost,root,,);
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+
+# this one should block due to the clustered index tree and leaf page latches
+--send
+SELECT a, RIGHT(b,20) FROM t1;
+
+connect (con2,localhost,root,,);
+
+# Check that the above SELECT is blocked
+let $wait_condition=
+  select count(*) = 1 from information_schema.processlist
+  where state = 'Sending data' and
+        info = 'SELECT a, RIGHT(b,20) FROM t1';
+--source include/wait_condition.inc
+
+SET DEBUG_SYNC='now SIGNAL go1';
+
+connection con1;
+reap;
+connection default;
+reap;
+SET DEBUG='+d,row_ins_extern_checkpoint';
+SET DEBUG_SYNC='before_row_ins_extern_latch SIGNAL rec_not_blob WAIT_FOR crash';
+ROLLBACK;
+BEGIN;
+--send
+INSERT INTO t1 VALUES (3,REPEAT('c',50000));
+
+connection con1;
+SET DEBUG_SYNC='now WAIT_FOR rec_not_blob';
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT @@tx_isolation;
+
+# this one should see (3,NULL_BLOB)
+SELECT a, RIGHT(b,20) FROM t1;
+SELECT a FROM t1;
+
+# Request a crash, and restart the server.
+SET DEBUG='+d,crash_commit_before';
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--error 2013
+INSERT INTO t2 VALUES (42);
+
+disconnect con1;
+disconnect con2;
+connection default;
+# This connection should notice the crash as well.
+--error 2013
+reap;
+
+# Write file to make mysql-test-run.pl restart the server
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+CHECK TABLE t1;
+
+INSERT INTO t3 VALUES
+       (1,REPEAT('d',7000),REPEAT('e',100)),
+       (2,REPEAT('g',7000),REPEAT('h',100));
+SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR go';
+# This should move column b off-page.
+--send
+UPDATE t3 SET c=REPEAT('f',3000) WHERE a=1;
+
+connect (con1,localhost,root,,);
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT @@tx_isolation;
+
+# this one should block
+-- send
+SELECT a, RIGHT(b,20), RIGHT(c,20) FROM t3;
+
+connect (con2,localhost,root,,);
+
+# Check that the above SELECT is blocked
+let $wait_condition=
+  select count(*) = 1 from information_schema.processlist
+  where state = 'Sending data' and
+        info = 'SELECT a, RIGHT(b,20), RIGHT(c,20) FROM t3';
+--source include/wait_condition.inc
+
+SET DEBUG_SYNC='now SIGNAL go';
+
+connection con1;
+reap;
+disconnect con1;
+
+connection default;
+reap;
+
+CHECK TABLE t1,t2,t3;
+
+connection con2;
+BEGIN;
+INSERT INTO t2 VALUES (347);
+connection default;
+
+# The row_upd_extern_checkpoint was removed in Bug#13721257,
+# because the mini-transaction of the B-tree modification would
+# remain open while we are writing the off-page columns and are
+# stuck in the DEBUG_SYNC. A checkpoint involves a flush, which
+# would wait for the buffer-fix to cease.
+SET DEBUG='+d,row_upd_extern_checkpoint';
+SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR crash';
+# This should move column b off-page.
+--send
+UPDATE t3 SET c=REPEAT('i',3000) WHERE a=2;
+
+connection con2;
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+
+# Check that the above UPDATE is blocked
+SELECT info FROM information_schema.processlist
+WHERE state = 'debug sync point: before_row_upd_extern';
+
+# Request a crash, and restart the server.
+SET DEBUG='+d,crash_commit_before';
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--error 2013
+COMMIT;
+
+disconnect con2;
+connection default;
+# This connection should notice the crash as well.
+--error 2013
+reap;
+
+# Write file to make mysql-test-run.pl restart the server
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+CHECK TABLE t1,t2,t3;
+SELECT a, RIGHT(b,20), RIGHT(c,20) FROM t3;
+SELECT a FROM t3;
+
+connect (con2,localhost,root,,);
+BEGIN;
+INSERT INTO t2 VALUES (33101);
+connection default;
+
+# The row_upd_extern_checkpoint was removed in Bug#13721257,
+# because the mini-transaction of the B-tree modification would
+# remain open while we are writing the off-page columns and are
+# stuck in the DEBUG_SYNC. A checkpoint involves a flush, which
+# would wait for the buffer-fix to cease.
+SET DEBUG='+d,row_upd_extern_checkpoint';
+SET DEBUG_SYNC='after_row_upd_extern SIGNAL have_latch WAIT_FOR crash';
+# This should move column b off-page.
+--send
+UPDATE t3 SET c=REPEAT('j',3000) WHERE a=2;
+
+connection con2;
+SET DEBUG_SYNC='now WAIT_FOR have_latch';
+
+# Check that the above UPDATE is blocked
+SELECT info FROM information_schema.processlist
+WHERE state = 'debug sync point: after_row_upd_extern';
+
+# Request a crash, and restart the server.
+SET DEBUG='+d,crash_commit_before';
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--error 2013
+COMMIT;
+
+disconnect con2;
+connection default;
+# This connection should notice the crash as well.
+--error 2013
+reap;
+
+# Write file to make mysql-test-run.pl restart the server
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+CHECK TABLE t1,t2,t3;
+SELECT a, RIGHT(b,20), RIGHT(c,20) FROM t3;
+SELECT a FROM t3;
+
+SELECT * FROM t2;
+
+DROP TABLE t1,t2,t3;
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 1fad9d8420e..d6115a28148 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,7 +1,19 @@
+2012-02-15	The InnoDB Team
+
+	* btr/btr0btr.c, btr/btr0cur.c, fsp/fsp0fsp.c, ibuf/ibuf0ibuf.c,
+	include/btr0btr.h, include/btr0cur.h, include/btr0cur.ic,
+	include/buf0buf.h, include/buf0buf.ic, include/fsp0fsp.h,
+	include/mtr0mtr.h, include/mtr0mtr.ic, include/page0page.h,
+	include/page0page.ic, include/trx0rec.ic, include/trx0undo.h,
+	mtr/mtr0mtr.c, page/page0cur.c, page/page0page.c, row/row0ins.c,
+	row/row0row.c, row/row0upd.c, trx/trx0rec.c, trx/trx0sys.c,
+	trx/trx0undo.c:
+	Fix Bug#13721257 RACE CONDITION IN UPDATES OR INSERTS OF WIDE RECORDS
+
 2012-02-06	The InnoDB Team
 
 	* handler/ha_innodb.cc:
-	Fix Bug #11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON
+	Fix Bug#11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON
 	GRACEFUL SHUTDOWN
 
 2012-01-30	The InnoDB Team
diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c
index 23729c12c1a..20eb30588fa 100644
--- a/storage/innodb_plugin/btr/btr0btr.c
+++ b/storage/innodb_plugin/btr/btr0btr.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -906,28 +906,31 @@ btr_page_alloc_for_ibuf(
 /**************************************************************//**
 Allocates a new file page to be used in an index tree. NOTE: we assume
 that the caller has made the reservation for free extents!
-@return	new allocated block, x-latched; NULL if out of space */
-UNIV_INTERN
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
+static __attribute__((nonnull, warn_unused_result))
 buf_block_t*
-btr_page_alloc(
-/*===========*/
+btr_page_alloc_low(
+/*===============*/
 	dict_index_t*	index,		/*!< in: index */
 	ulint		hint_page_no,	/*!< in: hint of a good page */
 	byte		file_direction,	/*!< in: direction where a possible
 					page split is made */
 	ulint		level,		/*!< in: level where the page is placed
 					in the tree */
-	mtr_t*		mtr)		/*!< in: mtr */
+	mtr_t*		mtr,		/*!< in/out: mini-transaction
+					for the allocation */
+	mtr_t*		init_mtr)	/*!< in/out: mtr or another
+					mini-transaction in which the
+					page should be initialized.
+					If init_mtr!=mtr, but the page
+					is already X-latched in mtr, do
+					not initialize the page. */
 {
 	fseg_header_t*	seg_header;
 	page_t*		root;
-	buf_block_t*	new_block;
-	ulint		new_page_no;
-
-	if (dict_index_is_ibuf(index)) {
-
-		return(btr_page_alloc_for_ibuf(index, mtr));
-	}
 
 	root = btr_root_get(index, mtr);
 
@@ -941,17 +944,47 @@ btr_page_alloc(
 	reservation for free extents, and thus we know that a page can
 	be allocated: */
 
-	new_page_no = fseg_alloc_free_page_general(seg_header, hint_page_no,
-						   file_direction, TRUE, mtr);
-	if (new_page_no == FIL_NULL) {
+	return(fseg_alloc_free_page_general(
+		       seg_header, hint_page_no, file_direction,
+		       TRUE, mtr, init_mtr));
+}
 
-		return(NULL);
+/**************************************************************//**
+Allocates a new file page to be used in an index tree. NOTE: we assume
+that the caller has made the reservation for free extents!
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
+UNIV_INTERN
+buf_block_t*
+btr_page_alloc(
+/*===========*/
+	dict_index_t*	index,		/*!< in: index */
+	ulint		hint_page_no,	/*!< in: hint of a good page */
+	byte		file_direction,	/*!< in: direction where a possible
+					page split is made */
+	ulint		level,		/*!< in: level where the page is placed
+					in the tree */
+	mtr_t*		mtr,		/*!< in/out: mini-transaction
+					for the allocation */
+	mtr_t*		init_mtr)	/*!< in/out: mini-transaction
+					for x-latching and initializing
+					the page */
+{
+	buf_block_t*	new_block;
+
+	if (dict_index_is_ibuf(index)) {
+
+		return(btr_page_alloc_for_ibuf(index, mtr));
 	}
 
-	new_block = buf_page_get(dict_index_get_space(index),
-				 dict_table_zip_size(index->table),
-				 new_page_no, RW_X_LATCH, mtr);
-	buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
+	new_block = btr_page_alloc_low(
+		index, hint_page_no, file_direction, level, mtr, init_mtr);
+
+	if (new_block) {
+		buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
+	}
 
 	return(new_block);
 }
@@ -1087,10 +1120,10 @@ btr_page_free(
 	buf_block_t*	block,	/*!< in: block to be freed, x-latched */
 	mtr_t*		mtr)	/*!< in: mtr */
 {
-	ulint		level;
-
-	level = btr_page_get_level(buf_block_get_frame(block), mtr);
+	const page_t*	page	= buf_block_get_frame(block);
+	ulint		level	= btr_page_get_level(page, mtr);
 
+	ut_ad(fil_page_get_type(block->frame) == FIL_PAGE_INDEX);
 	btr_page_free_low(index, block, level, mtr);
 }
 
@@ -1329,16 +1362,12 @@ btr_create(
 		/* Allocate then the next page to the segment: it will be the
 		tree root page */
 
-		page_no = fseg_alloc_free_page(buf_block_get_frame(
-						       ibuf_hdr_block)
-					       + IBUF_HEADER
-					       + IBUF_TREE_SEG_HEADER,
-					       IBUF_TREE_ROOT_PAGE_NO,
-					       FSP_UP, mtr);
-		ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
-
-		block = buf_page_get(space, zip_size, page_no,
-				     RW_X_LATCH, mtr);
+		block = fseg_alloc_free_page(
+			buf_block_get_frame(ibuf_hdr_block)
+			+ IBUF_HEADER + IBUF_TREE_SEG_HEADER,
+			IBUF_TREE_ROOT_PAGE_NO,
+			FSP_UP, mtr);
+		ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
 	} else {
 #ifdef UNIV_BLOB_DEBUG
 		if ((type & DICT_CLUSTERED) && !index->blobs) {
@@ -1815,7 +1844,7 @@ btr_root_raise_and_insert(
 
 	level = btr_page_get_level(root, mtr);
 
-	new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr);
+	new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr, mtr);
 	new_page = buf_block_get_frame(new_block);
 	new_page_zip = buf_block_get_page_zip(new_block);
 	ut_a(!new_page_zip == !root_page_zip);
@@ -2551,7 +2580,7 @@ func_start:
 
 	/* 2. Allocate a new page to the index */
 	new_block = btr_page_alloc(cursor->index, hint_page_no, direction,
-				   btr_page_get_level(page, mtr), mtr);
+				   btr_page_get_level(page, mtr), mtr, mtr);
 	new_page = buf_block_get_frame(new_block);
 	new_page_zip = buf_block_get_page_zip(new_block);
 	btr_page_create(new_block, new_page_zip, cursor->index,
@@ -3001,15 +3030,16 @@ btr_node_ptr_delete(
 	ut_a(err == DB_SUCCESS);
 
 	if (!compressed) {
-		btr_cur_compress_if_useful(&cursor, mtr);
+		btr_cur_compress_if_useful(&cursor, FALSE, mtr);
 	}
 }
 
 /*************************************************************//**
 If page is the only on its level, this function moves its records to the
-father page, thus reducing the tree height. */
+father page, thus reducing the tree height.
+@return father block */
 static
-void
+buf_block_t*
 btr_lift_page_up(
 /*=============*/
 	dict_index_t*	index,	/*!< in: index tree */
@@ -3126,6 +3156,8 @@ btr_lift_page_up(
 	}
 	ut_ad(page_validate(father_page, index));
 	ut_ad(btr_check_node_ptr(index, father_block, mtr));
+
+	return(father_block);
 }
 
 /*************************************************************//**
@@ -3142,11 +3174,13 @@ UNIV_INTERN
 ibool
 btr_compress(
 /*=========*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to merge or lift;
-				the page must not be empty: in record delete
-				use btr_discard_page if the page would become
-				empty */
-	mtr_t*		mtr)	/*!< in: mtr */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to merge
+				or lift; the page must not be empty:
+				when deleting records, use btr_discard_page()
+				if the page would become empty */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
 {
 	dict_index_t*	index;
 	ulint		space;
@@ -3164,12 +3198,14 @@ btr_compress(
 	ulint*		offsets;
 	ulint		data_size;
 	ulint		n_recs;
+	ulint		nth_rec = 0; /* remove bogus warning */
 	ulint		max_ins_size;
 	ulint		max_ins_size_reorg;
 
 	block = btr_cur_get_block(cursor);
 	page = btr_cur_get_page(cursor);
 	index = btr_cur_get_index(cursor);
+
 	ut_a((ibool) !!page_is_comp(page) == dict_table_is_comp(index->table));
 
 	ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
@@ -3190,6 +3226,10 @@ btr_compress(
 	offsets = btr_page_get_father_block(NULL, heap, index, block, mtr,
 					    &father_cursor);
 
+	if (adjust) {
+		nth_rec = page_rec_get_n_recs_before(btr_cur_get_rec(cursor));
+	}
+
 	/* Decide the page to which we try to merge and which will inherit
 	the locks */
 
@@ -3216,9 +3256,9 @@ btr_compress(
 	} else {
 		/* The page is the only one on the level, lift the records
 		to the father */
-		btr_lift_page_up(index, block, mtr);
-		mem_heap_free(heap);
-		return(TRUE);
+
+		merge_block = btr_lift_page_up(index, block, mtr);
+		goto func_exit;
 	}
 
 	n_recs = page_get_n_recs(page);
@@ -3300,6 +3340,10 @@ err_exit:
 
 		btr_node_ptr_delete(index, block, mtr);
 		lock_update_merge_left(merge_block, orig_pred, block);
+
+		if (adjust) {
+			nth_rec += page_rec_get_n_recs_before(orig_pred);
+		}
 	} else {
 		rec_t*		orig_succ;
 #ifdef UNIV_BTR_DEBUG
@@ -3364,7 +3408,6 @@ err_exit:
 	}
 
 	btr_blob_dbg_remove(page, index, "btr_compress");
-	mem_heap_free(heap);
 
 	if (!dict_index_is_clust(index) && page_is_leaf(merge_page)) {
 		/* Update the free bits of the B-tree page in the
@@ -3416,6 +3459,16 @@ err_exit:
 	btr_page_free(index, block, mtr);
 
 	ut_ad(btr_check_node_ptr(index, merge_block, mtr));
+func_exit:
+	mem_heap_free(heap);
+
+	if (adjust) {
+		btr_cur_position(
+			index,
+			page_rec_get_nth(merge_block->frame, nth_rec),
+			merge_block, cursor);
+	}
+
 	return(TRUE);
 }
 
diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c
index 46e850bb218..b67da53ec8a 100644
--- a/storage/innodb_plugin/btr/btr0cur.c
+++ b/storage/innodb_plugin/btr/btr0cur.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -18,8 +18,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -1757,7 +1757,7 @@ btr_cur_update_in_place(
 	page_zip = buf_block_get_page_zip(block);
 
 	/* Check that enough space is available on the compressed page. */
-	if (UNIV_LIKELY_NULL(page_zip)
+	if (page_zip
 	    && !btr_cur_update_alloc_zip(page_zip, block, index,
 					 rec_offs_size(offsets), FALSE, mtr)) {
 		return(DB_ZIP_OVERFLOW);
@@ -1948,7 +1948,7 @@ any_extern:
 	ut_a(!page_zip || page_zip_validate(page_zip, page));
 #endif /* UNIV_ZIP_DEBUG */
 
-	if (UNIV_LIKELY_NULL(page_zip)
+	if (page_zip
 	    && !btr_cur_update_alloc_zip(page_zip, block, index,
 					 new_rec_size, TRUE, mtr)) {
 		err = DB_ZIP_OVERFLOW;
@@ -2104,7 +2104,9 @@ btr_cur_pessimistic_update(
 /*=======================*/
 	ulint		flags,	/*!< in: undo logging, locking, and rollback
 				flags */
-	btr_cur_t*	cursor,	/*!< in: cursor on the record to update */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the record to update;
+				cursor may become invalid if *big_rec == NULL
+				|| !(flags & BTR_KEEP_POS_FLAG) */
 	mem_heap_t**	heap,	/*!< in/out: pointer to memory heap, or NULL */
 	big_rec_t**	big_rec,/*!< out: big rec vector whose fields have to
 				be stored externally by the caller, or NULL */
@@ -2243,10 +2245,10 @@ btr_cur_pessimistic_update(
 	record to be inserted: we have to remember which fields were such */
 
 	ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
-	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, heap);
+	ut_ad(rec_offs_validate(rec, index, offsets));
 	n_ext += btr_push_update_extern_fields(new_entry, update, *heap);
 
-	if (UNIV_LIKELY_NULL(page_zip)) {
+	if (page_zip) {
 		ut_ad(page_is_comp(page));
 		if (page_zip_rec_needs_ext(
 			    rec_get_converted_size(index, new_entry, n_ext),
@@ -2266,6 +2268,10 @@ make_external:
 			err = DB_TOO_BIG_RECORD;
 			goto return_after_reservations;
 		}
+
+		ut_ad(page_is_leaf(page));
+		ut_ad(dict_index_is_clust(index));
+		ut_ad(flags & BTR_KEEP_POS_FLAG);
 	}
 
 	/* Store state of explicit locks on rec on the page infimum record,
@@ -2293,6 +2299,8 @@ make_external:
 	rec = btr_cur_insert_if_possible(cursor, new_entry, n_ext, mtr);
 
 	if (rec) {
+		page_cursor->rec = rec;
+
 		lock_rec_restore_from_page_infimum(btr_cur_get_block(cursor),
 						   rec, block);
 
@@ -2306,7 +2314,10 @@ make_external:
 						     rec, index, offsets, mtr);
 		}
 
-		btr_cur_compress_if_useful(cursor, mtr);
+		btr_cur_compress_if_useful(
+			cursor,
+			big_rec_vec != NULL && (flags & BTR_KEEP_POS_FLAG),
+			mtr);
 
 		if (page_zip && !dict_index_is_clust(index)
 		    && page_is_leaf(page)) {
@@ -2326,6 +2337,21 @@ make_external:
 		}
 	}
 
+	if (big_rec_vec) {
+		ut_ad(page_is_leaf(page));
+		ut_ad(dict_index_is_clust(index));
+		ut_ad(flags & BTR_KEEP_POS_FLAG);
+
+		/* btr_page_split_and_insert() in
+		btr_cur_pessimistic_insert() invokes
+		mtr_memo_release(mtr, index->lock, MTR_MEMO_X_LOCK).
+		We must keep the index->lock when we created a
+		big_rec, so that row_upd_clust_rec() can store the
+		big_rec in the same mini-transaction. */
+
+		mtr_x_lock(dict_index_get_lock(index), mtr);
+	}
+
 	/* Was the record to be updated positioned as the first user
 	record on its page? */
 	was_first = page_cur_is_before_first(page_cursor);
@@ -2341,6 +2367,7 @@ make_external:
 	ut_a(rec);
 	ut_a(err == DB_SUCCESS);
 	ut_a(dummy_big_rec == NULL);
+	page_cursor->rec = rec;
 
 	if (dict_index_is_sec_or_ibuf(index)) {
 		/* Update PAGE_MAX_TRX_ID in the index page header.
@@ -2774,10 +2801,12 @@ UNIV_INTERN
 ibool
 btr_cur_compress_if_useful(
 /*=======================*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to compress;
-				cursor does not stay valid if compression
-				occurs */
-	mtr_t*		mtr)	/*!< in: mtr */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to compress;
+				cursor does not stay valid if !adjust and
+				compression occurs */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
 {
 	ut_ad(mtr_memo_contains(mtr,
 				dict_index_get_lock(btr_cur_get_index(cursor)),
@@ -2786,7 +2815,7 @@ btr_cur_compress_if_useful(
 				MTR_MEMO_PAGE_X_FIX));
 
 	return(btr_cur_compress_recommendation(cursor, mtr)
-	       && btr_compress(cursor, mtr));
+	       && btr_compress(cursor, adjust, mtr));
 }
 
 /*******************************************************//**
@@ -3028,7 +3057,7 @@ return_after_reservations:
 	mem_heap_free(heap);
 
 	if (ret == FALSE) {
-		ret = btr_cur_compress_if_useful(cursor, mtr);
+		ret = btr_cur_compress_if_useful(cursor, FALSE, mtr);
 	}
 
 	if (n_extents > 0) {
@@ -3593,10 +3622,10 @@ btr_cur_set_ownership_of_extern_field(
 		byte_val = byte_val | BTR_EXTERN_OWNER_FLAG;
 	}
 
-	if (UNIV_LIKELY_NULL(page_zip)) {
+	if (page_zip) {
 		mach_write_to_1(data + local_len + BTR_EXTERN_LEN, byte_val);
 		page_zip_write_blob_ptr(page_zip, rec, index, offsets, i, mtr);
-	} else if (UNIV_LIKELY(mtr != NULL)) {
+	} else if (mtr != NULL) {
 
 		mlog_write_ulint(data + local_len + BTR_EXTERN_LEN, byte_val,
 				 MLOG_1BYTE, mtr);
@@ -3828,9 +3857,9 @@ The fields are stored on pages allocated from leaf node
 file segment of the index tree.
 @return	DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
 UNIV_INTERN
-ulint
-btr_store_big_rec_extern_fields_func(
-/*=================================*/
+enum db_err
+btr_store_big_rec_extern_fields(
+/*============================*/
 	dict_index_t*	index,		/*!< in: index of rec; the index tree
 					MUST be X-latched */
 	buf_block_t*	rec_block,	/*!< in/out: block containing rec */
@@ -3839,38 +3868,37 @@ btr_store_big_rec_extern_fields_func(
 					the "external storage" flags in offsets
 					will not correspond to rec when
 					this function returns */
-#ifdef UNIV_DEBUG
-	mtr_t*		local_mtr,	/*!< in: mtr containing the
-					latch to rec and to the tree */
-#endif /* UNIV_DEBUG */
-#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
-	ibool		update_in_place,/*! in: TRUE if the record is updated
-					in place (not delete+insert) */
-#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
-	const big_rec_t*big_rec_vec)	/*!< in: vector containing fields
+	const big_rec_t*big_rec_vec,	/*!< in: vector containing fields
 					to be stored externally */
-
+	mtr_t*		btr_mtr,	/*!< in: mtr containing the
+					latches to the clustered index */
+	enum blob_op	op)		/*! in: operation code */
 {
-	ulint	rec_page_no;
-	byte*	field_ref;
-	ulint	extern_len;
-	ulint	store_len;
-	ulint	page_no;
-	ulint	space_id;
-	ulint	zip_size;
-	ulint	prev_page_no;
-	ulint	hint_page_no;
-	ulint	i;
-	mtr_t	mtr;
-	mem_heap_t* heap = NULL;
+	ulint		rec_page_no;
+	byte*		field_ref;
+	ulint		extern_len;
+	ulint		store_len;
+	ulint		page_no;
+	ulint		space_id;
+	ulint		zip_size;
+	ulint		prev_page_no;
+	ulint		hint_page_no;
+	ulint		i;
+	mtr_t		mtr;
+	mtr_t*		alloc_mtr;
+	mem_heap_t*	heap = NULL;
 	page_zip_des_t*	page_zip;
-	z_stream c_stream;
+	z_stream	c_stream;
+	buf_block_t**	freed_pages	= NULL;
+	ulint		n_freed_pages	= 0;
+	enum db_err	error		= DB_SUCCESS;
 
 	ut_ad(rec_offs_validate(rec, index, offsets));
 	ut_ad(rec_offs_any_extern(offsets));
-	ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
+	ut_ad(btr_mtr);
+	ut_ad(mtr_memo_contains(btr_mtr, dict_index_get_lock(index),
 				MTR_MEMO_X_LOCK));
-	ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
+	ut_ad(mtr_memo_contains(btr_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
 	ut_ad(buf_block_get_frame(rec_block) == page_align(rec));
 	ut_a(dict_index_is_clust(index));
 
@@ -3883,7 +3911,7 @@ btr_store_big_rec_extern_fields_func(
 	rec_page_no = buf_block_get_page_no(rec_block);
 	ut_a(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
 
-	if (UNIV_LIKELY_NULL(page_zip)) {
+	if (page_zip) {
 		int	err;
 
 		/* Zlib deflate needs 128 kilobytes for the default
@@ -3899,6 +3927,42 @@ btr_store_big_rec_extern_fields_func(
 		ut_a(err == Z_OK);
 	}
 
+	if (btr_blob_op_is_update(op)) {
+		/* Avoid reusing pages that have been previously freed
+		in btr_mtr. */
+		if (btr_mtr->n_freed_pages) {
+			if (heap == NULL) {
+				heap = mem_heap_create(
+					btr_mtr->n_freed_pages
+					* sizeof *freed_pages);
+			}
+
+			freed_pages = mem_heap_alloc(
+				heap,
+				btr_mtr->n_freed_pages
+				* sizeof *freed_pages);
+			n_freed_pages = 0;
+		}
+
+		/* Because btr_mtr will be committed after mtr, it is
+		possible that the tablespace has been extended when
+		the B-tree record was updated or inserted, or it will
+		be extended while allocating pages for big_rec.
+
+		TODO: In mtr (not btr_mtr), write a redo log record
+		about extending the tablespace to its current size,
+		and remember the current size. Whenever the tablespace
+		grows as pages are allocated, write further redo log
+		records to mtr. (Currently tablespace extension is not
+		covered by the redo log. If it were, the record would
+		only be written to btr_mtr, which is committed after
+		mtr.) */
+		alloc_mtr = btr_mtr;
+	} else {
+		/* Use the local mtr for allocations. */
+		alloc_mtr = &mtr;
+	}
+
 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
 	/* All pointers to externally stored columns in the record
 	must either be zero or they must be pointers to inherited
@@ -3913,7 +3977,7 @@ btr_store_big_rec_extern_fields_func(
 		/* Either this must be an update in place,
 		or the BLOB must be inherited, or the BLOB pointer
 		must be zero (will be written in this function). */
-		ut_a(update_in_place
+		ut_a(op == BTR_STORE_UPDATE
 		     || (field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_INHERITED_FLAG)
 		     || !memcmp(field_ref, field_ref_zero,
 				BTR_EXTERN_FIELD_REF_SIZE));
@@ -3938,7 +4002,7 @@ btr_store_big_rec_extern_fields_func(
 
 		prev_page_no = FIL_NULL;
 
-		if (UNIV_LIKELY_NULL(page_zip)) {
+		if (page_zip) {
 			int	err = deflateReset(&c_stream);
 			ut_a(err == Z_OK);
 
@@ -3958,18 +4022,24 @@ btr_store_big_rec_extern_fields_func(
 				hint_page_no = prev_page_no + 1;
 			}
 
+alloc_another:
 			block = btr_page_alloc(index, hint_page_no,
-					       FSP_NO_DIR, 0, &mtr);
+					       FSP_NO_DIR, 0, alloc_mtr, &mtr);
 			if (UNIV_UNLIKELY(block == NULL)) {
-
 				mtr_commit(&mtr);
+				error = DB_OUT_OF_FILE_SPACE;
+				goto func_exit;
+			}
 
-				if (UNIV_LIKELY_NULL(page_zip)) {
-					deflateEnd(&c_stream);
-					mem_heap_free(heap);
-				}
-
-				return(DB_OUT_OF_FILE_SPACE);
+			if (rw_lock_get_x_lock_count(&block->lock) > 1) {
+				/* This page must have been freed in
+				btr_mtr previously. Put it aside, and
+				allocate another page for the BLOB data. */
+				ut_ad(alloc_mtr == btr_mtr);
+				ut_ad(btr_blob_op_is_update(op));
+				ut_ad(n_freed_pages < btr_mtr->n_freed_pages);
+				freed_pages[n_freed_pages++] = block;
+				goto alloc_another;
 			}
 
 			page_no = buf_block_get_page_no(block);
@@ -3986,7 +4056,7 @@ btr_store_big_rec_extern_fields_func(
 							SYNC_EXTERN_STORAGE);
 				prev_page = buf_block_get_frame(prev_block);
 
-				if (UNIV_LIKELY_NULL(page_zip)) {
+				if (page_zip) {
 					mlog_write_ulint(
 						prev_page + FIL_PAGE_NEXT,
 						page_no, MLOG_4BYTES, &mtr);
@@ -4003,7 +4073,7 @@ btr_store_big_rec_extern_fields_func(
 
 			}
 
-			if (UNIV_LIKELY_NULL(page_zip)) {
+			if (page_zip) {
 				int		err;
 				page_zip_des_t*	blob_page_zip;
 
@@ -4086,11 +4156,15 @@ btr_store_big_rec_extern_fields_func(
 					goto next_zip_page;
 				}
 
-				rec_block = buf_page_get(space_id, zip_size,
-							 rec_page_no,
-							 RW_X_LATCH, &mtr);
-				buf_block_dbg_add_level(rec_block,
-							SYNC_NO_ORDER_CHECK);
+				if (alloc_mtr == &mtr) {
+					rec_block = buf_page_get(
+						space_id, zip_size,
+						rec_page_no,
+						RW_X_LATCH, &mtr);
+					buf_block_dbg_add_level(
+						rec_block,
+						SYNC_NO_ORDER_CHECK);
+				}
 
 				if (err == Z_STREAM_END) {
 					mach_write_to_4(field_ref
@@ -4124,7 +4198,8 @@ btr_store_big_rec_extern_fields_func(
 
 				page_zip_write_blob_ptr(
 					page_zip, rec, index, offsets,
-					big_rec_vec->fields[i].field_no, &mtr);
+					big_rec_vec->fields[i].field_no,
+					alloc_mtr);
 
 next_zip_page:
 				prev_page_no = page_no;
@@ -4169,19 +4244,23 @@ next_zip_page:
 
 				extern_len -= store_len;
 
-				rec_block = buf_page_get(space_id, zip_size,
-							 rec_page_no,
-							 RW_X_LATCH, &mtr);
-				buf_block_dbg_add_level(rec_block,
-							SYNC_NO_ORDER_CHECK);
+				if (alloc_mtr == &mtr) {
+					rec_block = buf_page_get(
+						space_id, zip_size,
+						rec_page_no,
+						RW_X_LATCH, &mtr);
+					buf_block_dbg_add_level(
+						rec_block,
+						SYNC_NO_ORDER_CHECK);
+				}
 
 				mlog_write_ulint(field_ref + BTR_EXTERN_LEN, 0,
-						 MLOG_4BYTES, &mtr);
+						 MLOG_4BYTES, alloc_mtr);
 				mlog_write_ulint(field_ref
 						 + BTR_EXTERN_LEN + 4,
 						 big_rec_vec->fields[i].len
 						 - extern_len,
-						 MLOG_4BYTES, &mtr);
+						 MLOG_4BYTES, alloc_mtr);
 
 				if (prev_page_no == FIL_NULL) {
 					btr_blob_dbg_add_blob(
@@ -4191,18 +4270,19 @@ next_zip_page:
 
 					mlog_write_ulint(field_ref
 							 + BTR_EXTERN_SPACE_ID,
-							 space_id,
-							 MLOG_4BYTES, &mtr);
+							 space_id, MLOG_4BYTES,
+							 alloc_mtr);
 
 					mlog_write_ulint(field_ref
 							 + BTR_EXTERN_PAGE_NO,
-							 page_no,
-							 MLOG_4BYTES, &mtr);
+							 page_no, MLOG_4BYTES,
+							 alloc_mtr);
 
 					mlog_write_ulint(field_ref
 							 + BTR_EXTERN_OFFSET,
 							 FIL_PAGE_DATA,
-							 MLOG_4BYTES, &mtr);
+							 MLOG_4BYTES,
+							 alloc_mtr);
 				}
 
 				prev_page_no = page_no;
@@ -4216,8 +4296,23 @@ next_zip_page:
 		}
 	}
 
-	if (UNIV_LIKELY_NULL(page_zip)) {
+func_exit:
+	if (page_zip) {
 		deflateEnd(&c_stream);
+	}
+
+	if (n_freed_pages) {
+		ulint	i;
+
+		ut_ad(alloc_mtr == btr_mtr);
+		ut_ad(btr_blob_op_is_update(op));
+
+		for (i = 0; i < n_freed_pages; i++) {
+			btr_page_free_low(index, freed_pages[i], 0, alloc_mtr);
+		}
+	}
+
+	if (heap != NULL) {
 		mem_heap_free(heap);
 	}
 
@@ -4238,7 +4333,7 @@ next_zip_page:
 		ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
 	}
 #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
-	return(DB_SUCCESS);
+	return(error);
 }
 
 /*******************************************************************//**
@@ -4443,7 +4538,7 @@ btr_free_externally_stored_field(
 
 			btr_page_free_low(index, ext_block, 0, &mtr);
 
-			if (UNIV_LIKELY(page_zip != NULL)) {
+			if (page_zip) {
 				mach_write_to_4(field_ref + BTR_EXTERN_PAGE_NO,
 						next_page_no);
 				mach_write_to_4(field_ref + BTR_EXTERN_LEN + 4,
diff --git a/storage/innodb_plugin/fsp/fsp0fsp.c b/storage/innodb_plugin/fsp/fsp0fsp.c
index fee7fde2e5c..c84cae302a6 100644
--- a/storage/innodb_plugin/fsp/fsp0fsp.c
+++ b/storage/innodb_plugin/fsp/fsp0fsp.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -312,28 +312,38 @@ fsp_fill_free_list(
 					descriptor page and ibuf bitmap page;
 					then we do not allocate more extents */
 	ulint		space,		/*!< in: space */
-	fsp_header_t*	header,		/*!< in: space header */
-	mtr_t*		mtr);		/*!< in: mtr */
+	fsp_header_t*	header,		/*!< in/out: space header */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
+	__attribute__((nonnull));
 /**********************************************************************//**
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize file space
 fragmentation.
-@return	the allocated page number, FIL_NULL if no page could be allocated */
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
 static
-ulint
+buf_block_t*
 fseg_alloc_free_page_low(
 /*=====================*/
 	ulint		space,	/*!< in: space */
 	ulint		zip_size,/*!< in: compressed page size in bytes
 				or 0 for uncompressed pages */
 	fseg_inode_t*	seg_inode, /*!< in/out: segment inode */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
+	ulint		hint,	/*!< in: hint of which page would be
+				desirable */
 	byte		direction, /*!< in: if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
 				direction they go alphabetically: FSP_DOWN,
 				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr);	/*!< in/out: mini-transaction */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	mtr_t*		init_mtr)/*!< in/out: mtr or another mini-transaction
+				in which the page should be initialized.
+				If init_mtr!=mtr, but the page is already
+				latched in mtr, do not initialize the page. */
+	__attribute__((warn_unused_result, nonnull));
 #endif /* !UNIV_HOTBACKUP */
 
 /**********************************************************************//**
@@ -701,17 +711,18 @@ list, if not free limit == space size. This adding is necessary to make the
 descriptor defined, as they are uninitialized above the free limit.
 @return pointer to the extent descriptor, NULL if the page does not
 exist in the space or if the offset exceeds the free limit */
-UNIV_INLINE
+UNIV_INLINE __attribute__((nonnull, warn_unused_result))
 xdes_t*
 xdes_get_descriptor_with_space_hdr(
 /*===============================*/
-	fsp_header_t*	sp_header,/*!< in/out: space header, x-latched */
-	ulint		space,	/*!< in: space id */
-	ulint		offset,	/*!< in: page offset;
-				if equal to the free limit,
-				we try to add new extents to
-				the space free list */
-	mtr_t*		mtr)	/*!< in: mtr handle */
+	fsp_header_t*	sp_header,	/*!< in/out: space header, x-latched
+					in mtr */
+	ulint		space,		/*!< in: space id */
+	ulint		offset,		/*!< in: page offset; if equal
+					to the free limit, we try to
+					add new extents to the space
+					free list */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ulint	limit;
 	ulint	size;
@@ -719,11 +730,9 @@ xdes_get_descriptor_with_space_hdr(
 	ulint	descr_page_no;
 	page_t*	descr_page;
 
-	ut_ad(mtr);
 	ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
 				MTR_MEMO_X_LOCK));
-	ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_S_FIX)
-	      || mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
+	ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
 	ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
 	/* Read free limit and space size */
 	limit = mach_read_from_4(sp_header + FSP_FREE_LIMIT);
@@ -773,7 +782,7 @@ is necessary to make the descriptor defined, as they are uninitialized
 above the free limit.
 @return pointer to the extent descriptor, NULL if the page does not
 exist in the space or if the offset exceeds the free limit */
-static
+static __attribute__((nonnull, warn_unused_result))
 xdes_t*
 xdes_get_descriptor(
 /*================*/
@@ -782,7 +791,7 @@ xdes_get_descriptor(
 			or 0 for uncompressed pages */
 	ulint	offset,	/*!< in: page offset; if equal to the free limit,
 			we try to add new extents to the space free list */
-	mtr_t*	mtr)	/*!< in: mtr handle */
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
 {
 	buf_block_t*	block;
 	fsp_header_t*	sp_header;
@@ -1160,14 +1169,14 @@ fsp_header_get_tablespace_size(void)
 Tries to extend a single-table tablespace so that a page would fit in the
 data file.
 @return	TRUE if success */
-static
+static __attribute__((nonnull, warn_unused_result))
 ibool
 fsp_try_extend_data_file_with_pages(
 /*================================*/
 	ulint		space,		/*!< in: space */
 	ulint		page_no,	/*!< in: page number */
-	fsp_header_t*	header,		/*!< in: space header */
-	mtr_t*		mtr)		/*!< in: mtr */
+	fsp_header_t*	header,		/*!< in/out: space header */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ibool	success;
 	ulint	actual_size;
@@ -1192,7 +1201,7 @@ fsp_try_extend_data_file_with_pages(
 /***********************************************************************//**
 Tries to extend the last data file of a tablespace if it is auto-extending.
 @return	FALSE if not auto-extending */
-static
+static __attribute__((nonnull))
 ibool
 fsp_try_extend_data_file(
 /*=====================*/
@@ -1202,8 +1211,8 @@ fsp_try_extend_data_file(
 					the actual file size rounded down to
 					megabyte */
 	ulint		space,		/*!< in: space */
-	fsp_header_t*	header,		/*!< in: space header */
-	mtr_t*		mtr)		/*!< in: mtr */
+	fsp_header_t*	header,		/*!< in/out: space header */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ulint	size;
 	ulint	zip_size;
@@ -1339,7 +1348,7 @@ fsp_fill_free_list(
 					then we do not allocate more extents */
 	ulint		space,		/*!< in: space */
 	fsp_header_t*	header,		/*!< in/out: space header */
-	mtr_t*		mtr)		/*!< in: mtr */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ulint	limit;
 	ulint	size;
@@ -1538,29 +1547,120 @@ fsp_alloc_free_extent(
 }
 
 /**********************************************************************//**
-Allocates a single free page from a space. The page is marked as used.
-@return	the page offset, FIL_NULL if no page could be allocated */
+Allocates a single free page from a space. */
+static __attribute__((nonnull))
+void
+fsp_alloc_from_free_frag(
+/*=====================*/
+	fsp_header_t*	header,	/*!< in/out: tablespace header */
+	xdes_t*		descr,	/*!< in/out: extent descriptor */
+	ulint		bit,	/*!< in: slot to allocate in the extent */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+{
+	ulint		frag_n_used;
+
+	ut_ad(xdes_get_state(descr, mtr) == XDES_FREE_FRAG);
+	ut_a(xdes_get_bit(descr, XDES_FREE_BIT, bit, mtr));
+	xdes_set_bit(descr, XDES_FREE_BIT, bit, FALSE, mtr);
+
+	/* Update the FRAG_N_USED field */
+	frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES,
+				     mtr);
+	frag_n_used++;
+	mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used, MLOG_4BYTES,
+			 mtr);
+	if (xdes_is_full(descr, mtr)) {
+		/* The fragment is full: move it to another list */
+		flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
+			    mtr);
+		xdes_set_state(descr, XDES_FULL_FRAG, mtr);
+
+		flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE,
+			      mtr);
+		mlog_write_ulint(header + FSP_FRAG_N_USED,
+				 frag_n_used - FSP_EXTENT_SIZE, MLOG_4BYTES,
+				 mtr);
+	}
+}
+
+/**********************************************************************//**
+Gets a buffer block for an allocated page.
+
+NOTE: If init_mtr != mtr, the block will only be initialized if it was
+not previously x-latched. It is assumed that the block has been
+x-latched only by mtr, and freed in mtr in that case.
+
+@return block, initialized if init_mtr==mtr
+or rw_lock_x_lock_count(&block->lock) == 1 */
 static
-ulint
+buf_block_t*
+fsp_page_create(
+/*============*/
+	ulint	space,		/*!< in: space id of the allocated page */
+	ulint	zip_size,	/*!< in: compressed page size in bytes
+				or 0 for uncompressed pages */
+	ulint	page_no,	/*!< in: page number of the allocated page */
+	mtr_t*	mtr,		/*!< in: mini-transaction of the allocation */
+	mtr_t*	init_mtr)	/*!< in: mini-transaction for initializing
+				the page */
+{
+	buf_block_t*	block
+		= buf_page_create(space, page_no, zip_size, init_mtr);
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)
+	      == rw_lock_own(&block->lock, RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
+
+	/* Mimic buf_page_get(), but avoid the buf_pool->page_hash lookup. */
+	rw_lock_x_lock(&block->lock);
+	mutex_enter(&block->mutex);
+	buf_block_buf_fix_inc(block, __FILE__, __LINE__);
+	mutex_exit(&block->mutex);
+	mtr_memo_push(init_mtr, block, MTR_MEMO_PAGE_X_FIX);
+
+	if (init_mtr == mtr
+	    || rw_lock_get_x_lock_count(&block->lock) == 1) {
+
+		/* Initialize the page, unless it was already
+		X-latched in mtr. (In this case, we would want to
+		allocate another page that has not been freed in mtr.) */
+		ut_ad(init_mtr == mtr
+		      || !mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+
+		fsp_init_file_page(block, init_mtr);
+	}
+
+	return(block);
+}
+
+/**********************************************************************//**
+Allocates a single free page from a space. The page is marked as used.
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
+static __attribute__((nonnull, warn_unused_result))
+buf_block_t*
 fsp_alloc_free_page(
 /*================*/
 	ulint	space,	/*!< in: space id */
 	ulint	zip_size,/*!< in: compressed page size in bytes
 			or 0 for uncompressed pages */
 	ulint	hint,	/*!< in: hint of which page would be desirable */
-	mtr_t*	mtr)	/*!< in/out: mini-transaction */
+	mtr_t*	mtr,	/*!< in/out: mini-transaction */
+	mtr_t*	init_mtr)/*!< in/out: mini-transaction in which the
+			page should be initialized
+			(may be the same as mtr) */
 {
 	fsp_header_t*	header;
 	fil_addr_t	first;
 	xdes_t*		descr;
-	buf_block_t*	block;
 	ulint		free;
-	ulint		frag_n_used;
 	ulint		page_no;
 	ulint		space_size;
-	ibool		success;
 
 	ut_ad(mtr);
+	ut_ad(init_mtr);
 
 	header = fsp_get_space_header(space, zip_size, mtr);
 
@@ -1587,7 +1687,7 @@ fsp_alloc_free_page(
 			if (descr == NULL) {
 				/* No free space left */
 
-				return(FIL_NULL);
+				return(NULL);
 			}
 
 			xdes_set_state(descr, XDES_FREE_FRAG, mtr);
@@ -1632,50 +1732,18 @@ fsp_alloc_free_page(
 				" space size %lu. Page no %lu.\n",
 				(ulong) space, (ulong) space_size,
 				(ulong) page_no);
-			return(FIL_NULL);
+			return(NULL);
 		}
-		success = fsp_try_extend_data_file_with_pages(space, page_no,
-							      header, mtr);
-		if (!success) {
+		if (!fsp_try_extend_data_file_with_pages(space, page_no,
+							 header, mtr)) {
 			/* No disk space left */
-			return(FIL_NULL);
+			return(NULL);
 		}
 	}
 
-	xdes_set_bit(descr, XDES_FREE_BIT, free, FALSE, mtr);
+	fsp_alloc_from_free_frag(header, descr, free, mtr);
 
-	/* Update the FRAG_N_USED field */
-	frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES,
-				     mtr);
-	frag_n_used++;
-	mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used, MLOG_4BYTES,
-			 mtr);
-	if (xdes_is_full(descr, mtr)) {
-		/* The fragment is full: move it to another list */
-		flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
-			    mtr);
-		xdes_set_state(descr, XDES_FULL_FRAG, mtr);
-
-		flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE,
-			      mtr);
-		mlog_write_ulint(header + FSP_FRAG_N_USED,
-				 frag_n_used - FSP_EXTENT_SIZE, MLOG_4BYTES,
-				 mtr);
-	}
-
-	/* Initialize the allocated page to the buffer pool, so that it can
-	be obtained immediately with buf_page_get without need for a disk
-	read. */
-
-	buf_page_create(space, page_no, zip_size, mtr);
-
-	block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
-	buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
-
-	/* Prior contents of the page should be ignored */
-	fsp_init_file_page(block, mtr);
-
-	return(page_no);
+	return(fsp_page_create(space, zip_size, page_no, mtr, init_mtr));
 }
 
 /**********************************************************************//**
@@ -1714,6 +1782,9 @@ fsp_free_page(
 		fputs("InnoDB: Dump of descriptor: ", stderr);
 		ut_print_buf(stderr, ((byte*)descr) - 50, 200);
 		putc('\n', stderr);
+		/* Crash in debug version, so that we get a core dump
+		of this corruption. */
+		ut_ad(0);
 
 		if (state == XDES_FREE) {
 			/* We put here some fault tolerance: if the page
@@ -1732,6 +1803,9 @@ fsp_free_page(
 			"InnoDB: Dump of descriptor: ", (ulong) page);
 		ut_print_buf(stderr, ((byte*)descr) - 50, 200);
 		putc('\n', stderr);
+		/* Crash in debug version, so that we get a core dump
+		of this corruption. */
+		ut_ad(0);
 
 		/* We put here some fault tolerance: if the page
 		is already free, return without doing anything! */
@@ -1766,6 +1840,8 @@ fsp_free_page(
 			    mtr);
 		fsp_free_extent(space, zip_size, page, mtr);
 	}
+
+	mtr->n_freed_pages++;
 }
 
 /**********************************************************************//**
@@ -1898,7 +1974,6 @@ fsp_alloc_seg_inode_page(
 	fseg_inode_t*	inode;
 	buf_block_t*	block;
 	page_t*		page;
-	ulint		page_no;
 	ulint		space;
 	ulint		zip_size;
 	ulint		i;
@@ -1909,15 +1984,15 @@ fsp_alloc_seg_inode_page(
 	zip_size = dict_table_flags_to_zip_size(
 		mach_read_from_4(FSP_SPACE_FLAGS + space_header));
 
-	page_no = fsp_alloc_free_page(space, zip_size, 0, mtr);
+	block = fsp_alloc_free_page(space, zip_size, 0, mtr, mtr);
 
-	if (page_no == FIL_NULL) {
+	if (block == NULL) {
 
 		return(FALSE);
 	}
 
-	block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
 	buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
+	ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
 
 	block->check_index_page_at_flush = FALSE;
 
@@ -2322,19 +2397,20 @@ fseg_create_general(
 	}
 
 	if (page == 0) {
-		page = fseg_alloc_free_page_low(space, zip_size,
-						inode, 0, FSP_UP, mtr);
+		block = fseg_alloc_free_page_low(space, zip_size,
+						 inode, 0, FSP_UP, mtr, mtr);
 
-		if (page == FIL_NULL) {
+		if (block == NULL) {
 
 			fsp_free_seg_inode(space, zip_size, inode, mtr);
 
 			goto funct_exit;
 		}
 
-		block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
+		ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
+
 		header = byte_offset + buf_block_get_frame(block);
-		mlog_write_ulint(header - byte_offset + FIL_PAGE_TYPE,
+		mlog_write_ulint(buf_block_get_frame(block) + FIL_PAGE_TYPE,
 				 FIL_PAGE_TYPE_SYS, MLOG_2BYTES, mtr);
 	}
 
@@ -2511,8 +2587,10 @@ fseg_fill_free_list(
 Allocates a free extent for the segment: looks first in the free list of the
 segment, then tries to allocate from the space free list. NOTE that the extent
 returned still resides in the segment free list, it is not yet taken off it!
-@return allocated extent, still placed in the segment free list, NULL
-if could not be allocated */
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
 static
 xdes_t*
 fseg_alloc_free_extent(
@@ -2564,22 +2642,30 @@ fseg_alloc_free_extent(
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize file space
 fragmentation.
-@return	the allocated page number, FIL_NULL if no page could be allocated */
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
 static
-ulint
+buf_block_t*
 fseg_alloc_free_page_low(
 /*=====================*/
 	ulint		space,	/*!< in: space */
 	ulint		zip_size,/*!< in: compressed page size in bytes
 				or 0 for uncompressed pages */
 	fseg_inode_t*	seg_inode, /*!< in/out: segment inode */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
+	ulint		hint,	/*!< in: hint of which page would be
+				desirable */
 	byte		direction, /*!< in: if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
 				direction they go alphabetically: FSP_DOWN,
 				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	mtr_t*		init_mtr)/*!< in/out: mtr or another mini-transaction
+				in which the page should be initialized.
+				If init_mtr!=mtr, but the page is already
+				latched in mtr, do not initialize the page. */
 {
 	fsp_header_t*	space_header;
 	ulint		space_size;
@@ -2590,7 +2676,6 @@ fseg_alloc_free_page_low(
 	ulint		ret_page;	/*!< the allocated page offset, FIL_NULL
 					if could not be allocated */
 	xdes_t*		ret_descr;	/*!< the extent of the allocated page */
-	ibool		frag_page_allocated = FALSE;
 	ibool		success;
 	ulint		n;
 
@@ -2612,6 +2697,7 @@ fseg_alloc_free_page_low(
 	if (descr == NULL) {
 		/* Hint outside space or too high above free limit: reset
 		hint */
+		/* The file space header page is always allocated. */
 		hint = 0;
 		descr = xdes_get_descriptor(space, zip_size, hint, mtr);
 	}
@@ -2623,15 +2709,19 @@ fseg_alloc_free_page_low(
 						   mtr), seg_id))
 	    && (xdes_get_bit(descr, XDES_FREE_BIT,
 			     hint % FSP_EXTENT_SIZE, mtr) == TRUE)) {
-
+take_hinted_page:
 		/* 1. We can take the hinted page
 		=================================*/
 		ret_descr = descr;
 		ret_page = hint;
+		/* Skip the check for extending the tablespace. If the
+		page hint were not within the size of the tablespace,
+		we would have got (descr == NULL) above and reset the hint. */
+		goto got_hinted_page;
 		/*-----------------------------------------------------------*/
-	} else if ((xdes_get_state(descr, mtr) == XDES_FREE)
-		   && ((reserved - used) < reserved / FSEG_FILLFACTOR)
-		   && (used >= FSEG_FRAG_LIMIT)) {
+	} else if (xdes_get_state(descr, mtr) == XDES_FREE
+		   && reserved - used < reserved / FSEG_FILLFACTOR
+		   && used >= FSEG_FRAG_LIMIT) {
 
 		/* 2. We allocate the free extent from space and can take
 		=========================================================
@@ -2649,7 +2739,7 @@ fseg_alloc_free_page_low(
 		/* Try to fill the segment free list */
 		fseg_fill_free_list(seg_inode, space, zip_size,
 				    hint + FSP_EXTENT_SIZE, mtr);
-		ret_page = hint;
+		goto take_hinted_page;
 		/*-----------------------------------------------------------*/
 	} else if ((direction != FSP_NO_DIR)
 		   && ((reserved - used) < reserved / FSEG_FILLFACTOR)
@@ -2698,7 +2788,7 @@ fseg_alloc_free_page_low(
 			first = flst_get_first(seg_inode + FSEG_FREE, mtr);
 		} else {
 			ut_error;
-			return(FIL_NULL);
+			return(NULL);
 		}
 
 		ret_descr = xdes_lst_get_descriptor(space, zip_size,
@@ -2710,20 +2800,23 @@ fseg_alloc_free_page_low(
 	} else if (used < FSEG_FRAG_LIMIT) {
 		/* 6. We allocate an individual page from the space
 		===================================================*/
-		ret_page = fsp_alloc_free_page(space, zip_size, hint, mtr);
-		ret_descr = NULL;
-
-		frag_page_allocated = TRUE;
+		buf_block_t* block = fsp_alloc_free_page(
+			space, zip_size, hint, mtr, init_mtr);
 
-		if (ret_page != FIL_NULL) {
+		if (block != NULL) {
 			/* Put the page in the fragment page array of the
 			segment */
 			n = fseg_find_free_frag_page_slot(seg_inode, mtr);
-			ut_a(n != FIL_NULL);
+			ut_a(n != ULINT_UNDEFINED);
 
-			fseg_set_nth_frag_page_no(seg_inode, n, ret_page,
-						  mtr);
+			fseg_set_nth_frag_page_no(
+				seg_inode, n, buf_block_get_page_no(block),
+				mtr);
 		}
+
+		/* fsp_alloc_free_page() invoked fsp_init_file_page()
+		already. */
+		return(block);
 		/*-----------------------------------------------------------*/
 	} else {
 		/* 7. We allocate a new extent and take its first page
@@ -2741,7 +2834,7 @@ fseg_alloc_free_page_low(
 	if (ret_page == FIL_NULL) {
 		/* Page could not be allocated */
 
-		return(FIL_NULL);
+		return(NULL);
 	}
 
 	if (space != 0) {
@@ -2759,38 +2852,22 @@ fseg_alloc_free_page_low(
 					" the space size %lu. Page no %lu.\n",
 					(ulong) space, (ulong) space_size,
 					(ulong) ret_page);
-				return(FIL_NULL);
+				return(NULL);
 			}
 
 			success = fsp_try_extend_data_file_with_pages(
 				space, ret_page, space_header, mtr);
 			if (!success) {
 				/* No disk space left */
-				return(FIL_NULL);
+				return(NULL);
 			}
 		}
 	}
 
-	if (!frag_page_allocated) {
-		/* Initialize the allocated page to buffer pool, so that it
-		can be obtained immediately with buf_page_get without need
-		for a disk read */
-		buf_block_t*	block;
-		ulint		zip_size = dict_table_flags_to_zip_size(
-			mach_read_from_4(FSP_SPACE_FLAGS + space_header));
-
-		block = buf_page_create(space, ret_page, zip_size, mtr);
-		buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
-
-		if (UNIV_UNLIKELY(block != buf_page_get(space, zip_size,
-							ret_page, RW_X_LATCH,
-							mtr))) {
-			ut_error;
-		}
-
-		/* The prior contents of the page should be ignored */
-		fsp_init_file_page(block, mtr);
-
+got_hinted_page:
+	/* ret_descr == NULL if the block was allocated from free_frag
+	(XDES_FREE_FRAG) */
+	if (ret_descr != NULL) {
 		/* At this point we know the extent and the page offset.
 		The extent is still in the appropriate list (FSEG_NOT_FULL
 		or FSEG_FREE), and the page is not yet marked as used. */
@@ -2803,20 +2880,28 @@ fseg_alloc_free_page_low(
 		fseg_mark_page_used(seg_inode, space, zip_size, ret_page, mtr);
 	}
 
-	return(ret_page);
+	return(fsp_page_create(
+		       space, dict_table_flags_to_zip_size(
+			       mach_read_from_4(FSP_SPACE_FLAGS
+						+ space_header)),
+		       ret_page, mtr, init_mtr));
 }
 
 /**********************************************************************//**
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize file space
 fragmentation.
-@return	allocated page offset, FIL_NULL if no page could be allocated */
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
 UNIV_INTERN
-ulint
+buf_block_t*
 fseg_alloc_free_page_general(
 /*=========================*/
 	fseg_header_t*	seg_header,/*!< in/out: segment header */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
+	ulint		hint,	/*!< in: hint of which page would be
+				desirable */
 	byte		direction,/*!< in: if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
@@ -2827,15 +2912,18 @@ fseg_alloc_free_page_general(
 				with fsp_reserve_free_extents, then there
 				is no need to do the check for this individual
 				page */
-	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction handle */
+	mtr_t*		init_mtr)/*!< in/out: mtr or another mini-transaction
+				in which the page should be initialized.
+				If init_mtr!=mtr, but the page is already
+				latched in mtr, do not initialize the page. */
 {
 	fseg_inode_t*	inode;
 	ulint		space;
 	ulint		flags;
 	ulint		zip_size;
 	rw_lock_t*	latch;
-	ibool		success;
-	ulint		page_no;
+	buf_block_t*	block;
 	ulint		n_reserved;
 
 	space = page_get_space_id(page_align(seg_header));
@@ -2860,43 +2948,20 @@ fseg_alloc_free_page_general(
 
 	inode = fseg_inode_get(seg_header, space, zip_size, mtr);
 
-	if (!has_done_reservation) {
-		success = fsp_reserve_free_extents(&n_reserved, space, 2,
-						   FSP_NORMAL, mtr);
-		if (!success) {
-			return(FIL_NULL);
-		}
+	if (!has_done_reservation
+	    && !fsp_reserve_free_extents(&n_reserved, space, 2,
+					 FSP_NORMAL, mtr)) {
+		return(NULL);
 	}
 
-	page_no = fseg_alloc_free_page_low(space, zip_size,
-					   inode, hint, direction, mtr);
+	block = fseg_alloc_free_page_low(space, zip_size,
+					 inode, hint, direction,
+					 mtr, init_mtr);
 	if (!has_done_reservation) {
 		fil_space_release_free_extents(space, n_reserved);
 	}
 
-	return(page_no);
-}
-
-/**********************************************************************//**
-Allocates a single free page from a segment. This function implements
-the intelligent allocation strategy which tries to minimize file space
-fragmentation.
-@return	allocated page offset, FIL_NULL if no page could be allocated */
-UNIV_INTERN
-ulint
-fseg_alloc_free_page(
-/*=================*/
-	fseg_header_t*	seg_header,/*!< in: segment header */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
-	byte		direction,/*!< in: if the new page is needed because
-				of an index page split, and records are
-				inserted there in order, into which
-				direction they go alphabetically: FSP_DOWN,
-				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr)	/*!< in: mtr handle */
-{
-	return(fseg_alloc_free_page_general(seg_header, hint, direction,
-					    FALSE, mtr));
+	return(block);
 }
 
 /**********************************************************************//**
@@ -3412,6 +3477,8 @@ crash:
 			    descr + XDES_FLST_NODE, mtr);
 		fsp_free_extent(space, zip_size, page, mtr);
 	}
+
+	mtr->n_freed_pages++;
 }
 
 /**********************************************************************//**
diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
index 9a243d83bd5..f2b51c7ebed 100644
--- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c
+++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -1722,14 +1722,14 @@ ulint
 ibuf_add_free_page(void)
 /*====================*/
 {
-	mtr_t	mtr;
-	page_t*	header_page;
-	ulint	flags;
-	ulint	zip_size;
-	ulint	page_no;
-	page_t*	page;
-	page_t*	root;
-	page_t*	bitmap_page;
+	mtr_t		mtr;
+	page_t*		header_page;
+	ulint		flags;
+	ulint		zip_size;
+	buf_block_t*	block;
+	page_t*		page;
+	page_t*		root;
+	page_t*		bitmap_page;
 
 	mtr_start(&mtr);
 
@@ -1750,32 +1750,23 @@ ibuf_add_free_page(void)
 	of a deadlock. This is the reason why we created a special ibuf
 	header page apart from the ibuf tree. */
 
-	page_no = fseg_alloc_free_page(
+	block = fseg_alloc_free_page(
 		header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
 		&mtr);
 
-	if (page_no == FIL_NULL) {
+	if (block == NULL) {
 		mtr_commit(&mtr);
 
 		return(DB_STRONG_FAIL);
 	}
 
-	{
-		buf_block_t*	block;
-
-		block = buf_page_get(
-			IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
-
-		ibuf_enter();
-
-		mutex_enter(&ibuf_mutex);
-
-		root = ibuf_tree_root_get(&mtr);
-
-		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
+	ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
+	ibuf_enter();
+	mutex_enter(&ibuf_mutex);
+	root = ibuf_tree_root_get(&mtr);
 
-		page = buf_block_get_frame(block);
-	}
+	buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
+	page = buf_block_get_frame(block);
 
 	/* Add the page to the free list and update the ibuf size data */
 
@@ -1792,10 +1783,11 @@ ibuf_add_free_page(void)
 	(level 2 page) */
 
 	bitmap_page = ibuf_bitmap_get_map_page(
-		IBUF_SPACE_ID, page_no, zip_size, &mtr);
+		IBUF_SPACE_ID, buf_block_get_page_no(block), zip_size, &mtr);
 
 	ibuf_bitmap_page_set_bits(
-		bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr);
+		bitmap_page, buf_block_get_page_no(block), zip_size,
+		IBUF_BITMAP_IBUF, TRUE, &mtr);
 
 	mtr_commit(&mtr);
 
diff --git a/storage/innodb_plugin/include/btr0btr.h b/storage/innodb_plugin/include/btr0btr.h
index e32da9e4c86..6e7bb8fc61e 100644
--- a/storage/innodb_plugin/include/btr0btr.h
+++ b/storage/innodb_plugin/include/btr0btr.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -488,11 +488,14 @@ UNIV_INTERN
 ibool
 btr_compress(
 /*=========*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to merge or lift;
-				the page must not be empty: in record delete
-				use btr_discard_page if the page would become
-				empty */
-	mtr_t*		mtr);	/*!< in: mtr */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to merge
+				or lift; the page must not be empty:
+				when deleting records, use btr_discard_page()
+				if the page would become empty */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+	__attribute__((nonnull));
 /*************************************************************//**
 Discards a page from a B-tree. This is used to remove the last record from
 a B-tree page: the whole page must be removed at the same time. This cannot
@@ -543,7 +546,10 @@ btr_get_size(
 /**************************************************************//**
 Allocates a new file page to be used in an index tree. NOTE: we assume
 that the caller has made the reservation for free extents!
-@return	new allocated block, x-latched; NULL if out of space */
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
 UNIV_INTERN
 buf_block_t*
 btr_page_alloc(
@@ -554,7 +560,12 @@ btr_page_alloc(
 					page split is made */
 	ulint		level,		/*!< in: level where the page is placed
 					in the tree */
-	mtr_t*		mtr);		/*!< in: mtr */
+	mtr_t*		mtr,		/*!< in/out: mini-transaction
+					for the allocation */
+	mtr_t*		init_mtr)	/*!< in/out: mini-transaction
+					for x-latching and initializing
+					the page */
+	__attribute__((nonnull, warn_unused_result));
 /**************************************************************//**
 Frees a file page used in an index tree. NOTE: cannot free field external
 storage pages because the page must contain info on its level. */
diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h
index 3669ce28f02..afc111970e2 100644
--- a/storage/innodb_plugin/include/btr0cur.h
+++ b/storage/innodb_plugin/include/btr0cur.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -36,6 +36,9 @@ Created 10/16/1994 Heikki Tuuri
 #define BTR_NO_LOCKING_FLAG	2	/* do no record lock checking */
 #define BTR_KEEP_SYS_FLAG	4	/* sys fields will be found from the
 					update vector or inserted entry */
+#define BTR_KEEP_POS_FLAG	8	/* btr_cur_pessimistic_update()
+					must keep cursor position when
+					moving columns to big_rec */
 
 #ifndef UNIV_HOTBACKUP
 #include "que0types.h"
@@ -309,7 +312,9 @@ btr_cur_pessimistic_update(
 /*=======================*/
 	ulint		flags,	/*!< in: undo logging, locking, and rollback
 				flags */
-	btr_cur_t*	cursor,	/*!< in: cursor on the record to update */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the record to update;
+				cursor may become invalid if *big_rec == NULL
+				|| !(flags & BTR_KEEP_POS_FLAG) */
 	mem_heap_t**	heap,	/*!< in/out: pointer to memory heap, or NULL */
 	big_rec_t**	big_rec,/*!< out: big rec vector whose fields have to
 				be stored externally by the caller, or NULL */
@@ -376,10 +381,13 @@ UNIV_INTERN
 ibool
 btr_cur_compress_if_useful(
 /*=======================*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to compress;
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to compress;
 				cursor does not stay valid if compression
 				occurs */
-	mtr_t*		mtr);	/*!< in: mtr */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+	__attribute__((nonnull));
 /*******************************************************//**
 Removes the record on which the tree cursor is positioned. It is assumed
 that the mtr has an x-latch on the page where the cursor is positioned,
@@ -504,6 +512,27 @@ btr_cur_disown_inherited_fields(
 	const upd_t*	update,	/*!< in: update vector */
 	mtr_t*		mtr)	/*!< in/out: mini-transaction */
 	__attribute__((nonnull(2,3,4,5,6)));
+
+/** Operation code for btr_store_big_rec_extern_fields(). */
+enum blob_op {
+	/** Store off-page columns for a freshly inserted record */
+	BTR_STORE_INSERT = 0,
+	/** Store off-page columns for an insert by update */
+	BTR_STORE_INSERT_UPDATE,
+	/** Store off-page columns for an update */
+	BTR_STORE_UPDATE
+};
+
+/*******************************************************************//**
+Determine if an operation on off-page columns is an update.
+@return TRUE if op != BTR_STORE_INSERT */
+UNIV_INLINE
+ibool
+btr_blob_op_is_update(
+/*==================*/
+	enum blob_op	op)	/*!< in: operation */
+	__attribute__((warn_unused_result));
+
 /*******************************************************************//**
 Stores the fields in big_rec_vec to the tablespace and puts pointers to
 them in rec.  The extern flags in rec will have to be set beforehand.
@@ -511,52 +540,23 @@ The fields are stored on pages allocated from leaf node
 file segment of the index tree.
 @return	DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
 UNIV_INTERN
-ulint
-btr_store_big_rec_extern_fields_func(
-/*=================================*/
+enum db_err
+btr_store_big_rec_extern_fields(
+/*============================*/
 	dict_index_t*	index,		/*!< in: index of rec; the index tree
 					MUST be X-latched */
 	buf_block_t*	rec_block,	/*!< in/out: block containing rec */
-	rec_t*		rec,		/*!< in: record */
+	rec_t*		rec,		/*!< in/out: record */
 	const ulint*	offsets,	/*!< in: rec_get_offsets(rec, index);
 					the "external storage" flags in offsets
 					will not correspond to rec when
 					this function returns */
-#ifdef UNIV_DEBUG
-	mtr_t*		local_mtr,	/*!< in: mtr containing the
-					latch to rec and to the tree */
-#endif /* UNIV_DEBUG */
-#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
-	ibool		update_in_place,/*! in: TRUE if the record is updated
-					in place (not delete+insert) */
-#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
-	const big_rec_t*big_rec_vec)	/*!< in: vector containing fields
+	const big_rec_t*big_rec_vec,	/*!< in: vector containing fields
 					to be stored externally */
-	__attribute__((nonnull));
-
-/** Stores the fields in big_rec_vec to the tablespace and puts pointers to
-them in rec.  The extern flags in rec will have to be set beforehand.
-The fields are stored on pages allocated from leaf node
-file segment of the index tree.
-@param index	in: clustered index; MUST be X-latched by mtr
-@param b	in/out: block containing rec; MUST be X-latched by mtr
-@param rec	in/out: clustered index record
-@param offsets	in: rec_get_offsets(rec, index);
-		the "external storage" flags in offsets will not be adjusted
-@param mtr	in: mini-transaction that holds x-latch on index and b
-@param upd	in: TRUE if the record is updated in place (not delete+insert)
-@param big	in: vector containing fields to be stored externally
-@return	DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
-#ifdef UNIV_DEBUG
-# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
-	btr_store_big_rec_extern_fields_func(index,b,rec,offsets,mtr,upd,big)
-#elif defined UNIV_BLOB_LIGHT_DEBUG
-# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
-	btr_store_big_rec_extern_fields_func(index,b,rec,offsets,upd,big)
-#else
-# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
-	btr_store_big_rec_extern_fields_func(index,b,rec,offsets,big)
-#endif
+	mtr_t*		btr_mtr,	/*!< in: mtr containing the
+					latches to the clustered index */
+	enum blob_op	op)		/*! in: operation code */
+	__attribute__((nonnull, warn_unused_result));
 
 /*******************************************************************//**
 Frees the space in an externally stored field to the file space
diff --git a/storage/innodb_plugin/include/btr0cur.ic b/storage/innodb_plugin/include/btr0cur.ic
index cd3a5d895bb..e31f77c77eb 100644
--- a/storage/innodb_plugin/include/btr0cur.ic
+++ b/storage/innodb_plugin/include/btr0cur.ic
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -139,7 +139,7 @@ btr_cur_compress_recommendation(
 	btr_cur_t*	cursor,	/*!< in: btr cursor */
 	mtr_t*		mtr)	/*!< in: mtr */
 {
-	page_t*		page;
+	const page_t*	page;
 
 	ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
 				MTR_MEMO_PAGE_X_FIX));
@@ -197,4 +197,25 @@ btr_cur_can_delete_without_compress(
 
 	return(TRUE);
 }
+
+/*******************************************************************//**
+Determine if an operation on off-page columns is an update.
+@return TRUE if op != BTR_STORE_INSERT */
+UNIV_INLINE
+ibool
+btr_blob_op_is_update(
+/*==================*/
+	enum blob_op	op)	/*!< in: operation */
+{
+	switch (op) {
+	case BTR_STORE_INSERT:
+		return(FALSE);
+	case BTR_STORE_INSERT_UPDATE:
+	case BTR_STORE_UPDATE:
+		return(TRUE);
+	}
+
+	ut_ad(0);
+	return(FALSE);
+}
 #endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
index 489d1bec5b6..de009a4c670 100644
--- a/storage/innodb_plugin/include/buf0buf.h
+++ b/storage/innodb_plugin/include/buf0buf.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -468,6 +468,31 @@ buf_block_get_modify_clock(
 #else /* !UNIV_HOTBACKUP */
 # define buf_block_modify_clock_inc(block) ((void) 0)
 #endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
+Increments the bufferfix count. */
+UNIV_INLINE
+void
+buf_block_buf_fix_inc_func(
+/*=======================*/
+#ifdef UNIV_SYNC_DEBUG
+	const char*	file,	/*!< in: file name */
+	ulint		line,	/*!< in: line */
+#endif /* UNIV_SYNC_DEBUG */
+	buf_block_t*	block)	/*!< in/out: block to bufferfix */
+	__attribute__((nonnull));
+#ifdef UNIV_SYNC_DEBUG
+/** Increments the bufferfix count.
+@param b	in/out: block to bufferfix
+@param f	in: file name where requested
+@param l	in: line number where requested */
+# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
+#else /* UNIV_SYNC_DEBUG */
+/** Increments the bufferfix count.
+@param b	in/out: block to bufferfix
+@param f	in: file name where requested
+@param l	in: line number where requested */
+# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
+#endif /* UNIV_SYNC_DEBUG */
 /********************************************************************//**
 Calculates a page checksum which is stored to the page when it is written
 to a file. Note that we must be careful to calculate the same value
diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic
index 0fe1dbc2da5..e7308d77983 100644
--- a/storage/innodb_plugin/include/buf0buf.ic
+++ b/storage/innodb_plugin/include/buf0buf.ic
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -18,8 +18,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -916,19 +916,6 @@ buf_block_buf_fix_inc_func(
 
 	block->page.buf_fix_count++;
 }
-#ifdef UNIV_SYNC_DEBUG
-/** Increments the bufferfix count.
-@param b	in/out: block to bufferfix
-@param f	in: file name where requested
-@param l	in: line number where requested */
-# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
-#else /* UNIV_SYNC_DEBUG */
-/** Increments the bufferfix count.
-@param b	in/out: block to bufferfix
-@param f	in: file name where requested
-@param l	in: line number where requested */
-# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
-#endif /* UNIV_SYNC_DEBUG */
 
 /*******************************************************************//**
 Decrements the bufferfix count. */
diff --git a/storage/innodb_plugin/include/fsp0fsp.h b/storage/innodb_plugin/include/fsp0fsp.h
index 403e1d404a8..8506748ae03 100644
--- a/storage/innodb_plugin/include/fsp0fsp.h
+++ b/storage/innodb_plugin/include/fsp0fsp.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -176,30 +176,33 @@ fseg_n_reserved_pages(
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize
 file space fragmentation.
-@return	the allocated page offset FIL_NULL if no page could be allocated */
-UNIV_INTERN
-ulint
-fseg_alloc_free_page(
-/*=================*/
-	fseg_header_t*	seg_header, /*!< in: segment header */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
-	byte		direction, /*!< in: if the new page is needed because
+@param[in/out] seg_header	segment header
+@param[in] hint			hint of which page would be desirable
+@param[in] direction		if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
 				direction they go alphabetically: FSP_DOWN,
-				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr);	/*!< in: mtr handle */
+				FSP_UP, FSP_NO_DIR
+@param[in/out] mtr		mini-transaction
+@return	X-latched block, or NULL if no page could be allocated */
+#define fseg_alloc_free_page(seg_header, hint, direction, mtr)		\
+	fseg_alloc_free_page_general(seg_header, hint, direction,	\
+				     FALSE, mtr, mtr)
 /**********************************************************************//**
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize file space
 fragmentation.
-@return	allocated page offset, FIL_NULL if no page could be allocated */
+@retval NULL if no page could be allocated
+@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
+(init_mtr == mtr, or the page was not previously freed in mtr)
+@retval block (not allocated or initialized) otherwise */
 UNIV_INTERN
-ulint
+buf_block_t*
 fseg_alloc_free_page_general(
 /*=========================*/
 	fseg_header_t*	seg_header,/*!< in/out: segment header */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
+	ulint		hint,	/*!< in: hint of which page would be
+				desirable */
 	byte		direction,/*!< in: if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
@@ -210,8 +213,12 @@ fseg_alloc_free_page_general(
 				with fsp_reserve_free_extents, then there
 				is no need to do the check for this individual
 				page */
-	mtr_t*		mtr)	/*!< in/out: mini-transaction */
-	__attribute__((warn_unused_result, nonnull(1,5)));
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	mtr_t*		init_mtr)/*!< in/out: mtr or another mini-transaction
+				in which the page should be initialized.
+				If init_mtr!=mtr, but the page is already
+				latched in mtr, do not initialize the page. */
+	__attribute__((warn_unused_result, nonnull));
 /**********************************************************************//**
 Reserves free pages from a tablespace. All mini-transactions which may
 use several pages from the tablespace should call this function beforehand
diff --git a/storage/innodb_plugin/include/mtr0mtr.h b/storage/innodb_plugin/include/mtr0mtr.h
index 46beb63ee80..ecbfe750577 100644
--- a/storage/innodb_plugin/include/mtr0mtr.h
+++ b/storage/innodb_plugin/include/mtr0mtr.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -50,7 +50,9 @@ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
 #define	MTR_MEMO_PAGE_S_FIX	RW_S_LATCH
 #define	MTR_MEMO_PAGE_X_FIX	RW_X_LATCH
 #define	MTR_MEMO_BUF_FIX	RW_NO_LATCH
-#define MTR_MEMO_MODIFY		54
+#ifdef UNIV_DEBUG
+# define MTR_MEMO_MODIFY	54
+#endif /* UNIV_DEBUG */
 #define	MTR_MEMO_S_LOCK		55
 #define	MTR_MEMO_X_LOCK		56
 
@@ -378,11 +380,14 @@ struct mtr_struct{
 	dyn_array_t	memo;	/*!< memo stack for locks etc. */
 	dyn_array_t	log;	/*!< mini-transaction log */
 	ibool		modifications;
-				/* TRUE if the mtr made modifications to
-				buffer pool pages */
+				/*!< TRUE if the mini-transaction
+				modified buffer pool pages */
 	ulint		n_log_recs;
 				/* count of how many page initial log records
 				have been written to the mtr log */
+	ulint		n_freed_pages;
+				/* number of pages that have been freed in
+				this mini-transaction */
 	ulint		log_mode; /* specifies which operations should be
 				logged; default value MTR_LOG_ALL */
 	ib_uint64_t	start_lsn;/* start lsn of the possible log entry for
diff --git a/storage/innodb_plugin/include/mtr0mtr.ic b/storage/innodb_plugin/include/mtr0mtr.ic
index 9f92d2b06a1..4489e8e1c1e 100644
--- a/storage/innodb_plugin/include/mtr0mtr.ic
+++ b/storage/innodb_plugin/include/mtr0mtr.ic
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -45,6 +45,7 @@ mtr_start(
 	mtr->log_mode = MTR_LOG_ALL;
 	mtr->modifications = FALSE;
 	mtr->n_log_recs = 0;
+	mtr->n_freed_pages = 0;
 
 	ut_d(mtr->state = MTR_ACTIVE);
 	ut_d(mtr->magic_n = MTR_MAGIC_N);
diff --git a/storage/innodb_plugin/include/page0page.h b/storage/innodb_plugin/include/page0page.h
index ea9c212581c..e06276df2fd 100644
--- a/storage/innodb_plugin/include/page0page.h
+++ b/storage/innodb_plugin/include/page0page.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -281,16 +281,42 @@ page_get_supremum_offset(
 	const page_t*	page);	/*!< in: page which must have record(s) */
 #define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
 #define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
+
 /************************************************************//**
-Returns the middle record of record list. If there are an even number
-of records in the list, returns the first record of upper half-list.
-@return	middle record */
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
 UNIV_INTERN
+const rec_t*
+page_rec_get_nth_const(
+/*===================*/
+	const page_t*	page,	/*!< in: page */
+	ulint		nth)	/*!< in: nth record */
+	__attribute__((nonnull, warn_unused_result));
+/************************************************************//**
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
+UNIV_INLINE
+rec_t*
+page_rec_get_nth(
+/*=============*/
+	page_t*	page,	/*< in: page */
+	ulint	nth)	/*!< in: nth record */
+	__attribute__((nonnull, warn_unused_result));
+
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
+Returns the middle record of the records on the page. If there is an
+even number of records in the list, returns the first record of the
+upper half-list.
+@return	middle record */
+UNIV_INLINE
 rec_t*
 page_get_middle_rec(
 /*================*/
-	page_t*	page);	/*!< in: page */
-#ifndef UNIV_HOTBACKUP
+	page_t*	page)	/*!< in: page */
+	__attribute__((nonnull, warn_unused_result));
 /*************************************************************//**
 Compares a data tuple to a physical record. Differs from the function
 cmp_dtuple_rec_with_match in the way that the record must reside on an
@@ -345,6 +371,7 @@ page_get_n_recs(
 /***************************************************************//**
 Returns the number of records before the given record in chain.
 The number includes infimum and supremum records.
+This is the inverse function of page_rec_get_nth().
 @return	number of records */
 UNIV_INTERN
 ulint
diff --git a/storage/innodb_plugin/include/page0page.ic b/storage/innodb_plugin/include/page0page.ic
index b096a5ba321..7425d9d9cfe 100644
--- a/storage/innodb_plugin/include/page0page.ic
+++ b/storage/innodb_plugin/include/page0page.ic
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -420,7 +420,37 @@ page_rec_is_infimum(
 	return(page_rec_is_infimum_low(page_offset(rec)));
 }
 
+/************************************************************//**
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
+UNIV_INLINE
+rec_t*
+page_rec_get_nth(
+/*=============*/
+	page_t*	page,	/*!< in: page */
+	ulint	nth)	/*!< in: nth record */
+{
+	return((rec_t*) page_rec_get_nth_const(page, nth));
+}
+
 #ifndef UNIV_HOTBACKUP
+/************************************************************//**
+Returns the middle record of the records on the page. If there is an
+even number of records in the list, returns the first record of the
+upper half-list.
+@return	middle record */
+UNIV_INLINE
+rec_t*
+page_get_middle_rec(
+/*================*/
+	page_t*	page)	/*!< in: page */
+{
+	ulint	middle = (page_get_n_recs(page) + PAGE_HEAP_NO_USER_LOW) / 2;
+
+	return(page_rec_get_nth(page, middle));
+}
+
 /*************************************************************//**
 Compares a data tuple to a physical record. Differs from the function
 cmp_dtuple_rec_with_match in the way that the record must reside on an
diff --git a/storage/innodb_plugin/include/trx0rec.ic b/storage/innodb_plugin/include/trx0rec.ic
index e7e41d6d9f6..6c411047dc6 100644
--- a/storage/innodb_plugin/include/trx0rec.ic
+++ b/storage/innodb_plugin/include/trx0rec.ic
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -107,6 +107,7 @@ trx_undo_rec_copy(
 
 	len = mach_read_from_2(undo_rec)
 		- ut_align_offset(undo_rec, UNIV_PAGE_SIZE);
+	ut_ad(len < UNIV_PAGE_SIZE);
 	return(mem_heap_dup(heap, undo_rec, len));
 }
 #endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innodb_plugin/include/trx0undo.h b/storage/innodb_plugin/include/trx0undo.h
index c95f99d6417..585b5f36696 100644
--- a/storage/innodb_plugin/include/trx0undo.h
+++ b/storage/innodb_plugin/include/trx0undo.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -194,16 +194,17 @@ trx_undo_get_first_rec(
 	mtr_t*	mtr);	/*!< in: mtr */
 /********************************************************************//**
 Tries to add a page to the undo log segment where the undo log is placed.
-@return	page number if success, else FIL_NULL */
+@return	X-latched block if success, else NULL */
 UNIV_INTERN
-ulint
+buf_block_t*
 trx_undo_add_page(
 /*==============*/
 	trx_t*		trx,	/*!< in: transaction */
 	trx_undo_t*	undo,	/*!< in: undo log memory object */
-	mtr_t*		mtr);	/*!< in: mtr which does not have a latch to any
+	mtr_t*		mtr)	/*!< in: mtr which does not have a latch to any
 				undo log page; the caller must have reserved
 				the rollback segment mutex */
+	__attribute__((nonnull, warn_unused_result));
 /********************************************************************//**
 Frees the last undo log page.
 The caller must hold the rollback segment mutex. */
diff --git a/storage/innodb_plugin/page/page0cur.c b/storage/innodb_plugin/page/page0cur.c
index ab5aa257338..88ee6bc09a9 100644
--- a/storage/innodb_plugin/page/page0cur.c
+++ b/storage/innodb_plugin/page/page0cur.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -1180,14 +1180,15 @@ page_cur_insert_rec_zip_reorg(
 	/* Before trying to reorganize the page,
 	store the number of preceding records on the page. */
 	pos = page_rec_get_n_recs_before(rec);
+	ut_ad(pos > 0);
 
 	if (page_zip_reorganize(block, index, mtr)) {
 		/* The page was reorganized: Find rec by seeking to pos,
 		and update *current_rec. */
-		rec = page + PAGE_NEW_INFIMUM;
-
-		while (--pos) {
-			rec = page + rec_get_next_offs(rec, TRUE);
+		if (pos > 1) {
+			rec = page_rec_get_nth(page, pos - 1);
+		} else {
+			rec = page + PAGE_NEW_INFIMUM;
 		}
 
 		*current_rec = rec;
@@ -1283,6 +1284,12 @@ page_cur_insert_rec_zip(
 			insert_rec = page_cur_insert_rec_zip_reorg(
 				current_rec, block, index, insert_rec,
 				page, page_zip, mtr);
+#ifdef UNIV_DEBUG
+			if (insert_rec) {
+				rec_offs_make_valid(
+					insert_rec, index, offsets);
+			}
+#endif /* UNIV_DEBUG */
 		}
 
 		return(insert_rec);
diff --git a/storage/innodb_plugin/page/page0page.c b/storage/innodb_plugin/page/page0page.c
index 52f6678be0a..7b72a22fd1c 100644
--- a/storage/innodb_plugin/page/page0page.c
+++ b/storage/innodb_plugin/page/page0page.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -1475,55 +1475,54 @@ page_dir_balance_slot(
 	}
 }
 
-#ifndef UNIV_HOTBACKUP
 /************************************************************//**
-Returns the middle record of the record list. If there are an even number
-of records in the list, returns the first record of the upper half-list.
-@return	middle record */
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
 UNIV_INTERN
-rec_t*
-page_get_middle_rec(
-/*================*/
-	page_t*	page)	/*!< in: page */
+const rec_t*
+page_rec_get_nth_const(
+/*===================*/
+	const page_t*	page,	/*!< in: page */
+	ulint		nth)	/*!< in: nth record */
 {
-	page_dir_slot_t*	slot;
-	ulint			middle;
+	const page_dir_slot_t*	slot;
 	ulint			i;
 	ulint			n_owned;
-	ulint			count;
-	rec_t*			rec;
+	const rec_t*		rec;
 
-	/* This many records we must leave behind */
-	middle = (page_get_n_recs(page) + PAGE_HEAP_NO_USER_LOW) / 2;
-
-	count = 0;
+	ut_ad(nth < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
 
 	for (i = 0;; i++) {
 
 		slot = page_dir_get_nth_slot(page, i);
 		n_owned = page_dir_slot_get_n_owned(slot);
 
-		if (count + n_owned > middle) {
+		if (n_owned > nth) {
 			break;
 		} else {
-			count += n_owned;
+			nth -= n_owned;
 		}
 	}
 
 	ut_ad(i > 0);
 	slot = page_dir_get_nth_slot(page, i - 1);
-	rec = (rec_t*) page_dir_slot_get_rec(slot);
-	rec = page_rec_get_next(rec);
-
-	/* There are now count records behind rec */
+	rec = page_dir_slot_get_rec(slot);
 
-	for (i = 0; i < middle - count; i++) {
-		rec = page_rec_get_next(rec);
+	if (page_is_comp(page)) {
+		do {
+			rec = page_rec_get_next_low(rec, TRUE);
+			ut_ad(rec);
+		} while (nth--);
+	} else {
+		do {
+			rec = page_rec_get_next_low(rec, FALSE);
+			ut_ad(rec);
+		} while (nth--);
 	}
 
 	return(rec);
 }
-#endif /* !UNIV_HOTBACKUP */
 
 /***************************************************************//**
 Returns the number of records before the given record in chain.
@@ -1585,6 +1584,7 @@ page_rec_get_n_recs_before(
 	n--;
 
 	ut_ad(n >= 0);
+	ut_ad(n < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
 
 	return((ulint) n);
 }
diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c
index 56d1c1a7b88..9a603d5690f 100644
--- a/storage/innodb_plugin/row/row0ins.c
+++ b/storage/innodb_plugin/row/row0ins.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -354,9 +354,9 @@ row_ins_clust_index_entry_by_modify(
 			return(DB_LOCK_TABLE_FULL);
 
 		}
-		err = btr_cur_pessimistic_update(0, cursor,
-						 heap, big_rec, update,
-						 0, thr, mtr);
+		err = btr_cur_pessimistic_update(
+			BTR_KEEP_POS_FLAG, cursor, heap, big_rec, update,
+			0, thr, mtr);
 	}
 
 	return(err);
@@ -1998,6 +1998,7 @@ row_ins_index_entry_low(
 	ulint		modify = 0; /* remove warning */
 	rec_t*		insert_rec;
 	rec_t*		rec;
+	ulint*		offsets;
 	ulint		err;
 	ulint		n_unique;
 	big_rec_t*	big_rec			= NULL;
@@ -2101,6 +2102,64 @@ row_ins_index_entry_low(
 			err = row_ins_clust_index_entry_by_modify(
 				mode, &cursor, &heap, &big_rec, entry,
 				thr, &mtr);
+
+			if (big_rec) {
+				ut_a(err == DB_SUCCESS);
+				/* Write out the externally stored
+				columns while still x-latching
+				index->lock and block->lock. Allocate
+				pages for big_rec in the mtr that
+				modified the B-tree, but be sure to skip
+				any pages that were freed in mtr. We will
+				write out the big_rec pages before
+				committing the B-tree mini-transaction. If
+				the system crashes so that crash recovery
+				will not replay the mtr_commit(&mtr), the
+				big_rec pages will be left orphaned until
+				the pages are allocated for something else.
+
+				TODO: If the allocation extends the
+				tablespace, it will not be redo
+				logged, in either mini-transaction.
+				Tablespace extension should be
+				redo-logged in the big_rec
+				mini-transaction, so that recovery
+				will not fail when the big_rec was
+				written to the extended portion of the
+				file, in case the file was somehow
+				truncated in the crash. */
+
+				rec = btr_cur_get_rec(&cursor);
+				offsets = rec_get_offsets(
+					rec, index, NULL,
+					ULINT_UNDEFINED, &heap);
+
+				DEBUG_SYNC_C("before_row_ins_upd_extern");
+				err = btr_store_big_rec_extern_fields(
+					index, btr_cur_get_block(&cursor),
+					rec, offsets, big_rec, &mtr,
+					BTR_STORE_INSERT_UPDATE);
+				DEBUG_SYNC_C("after_row_ins_upd_extern");
+				/* If writing big_rec fails (for
+				example, because of DB_OUT_OF_FILE_SPACE),
+				the record will be corrupted. Even if
+				we did not update any externally
+				stored columns, our update could cause
+				the record to grow so that a
+				non-updated column was selected for
+				external storage. This non-update
+				would not have been written to the
+				undo log, and thus the record cannot
+				be rolled back.
+
+				However, because we have not executed
+				mtr_commit(mtr) yet, the update will
+				not be replayed in crash recovery, and
+				the following assertion failure will
+				effectively "roll back" the operation. */
+				ut_a(err == DB_SUCCESS);
+				goto stored_big_rec;
+			}
 		} else {
 			ut_ad(!n_ext);
 			err = row_ins_sec_index_entry_by_modify(
@@ -2129,9 +2188,6 @@ function_exit:
 	mtr_commit(&mtr);
 
 	if (UNIV_LIKELY_NULL(big_rec)) {
-		rec_t*	rec;
-		ulint*	offsets;
-
 		DBUG_EXECUTE_IF(
 			"row_ins_extern_checkpoint",
 			log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE););
@@ -2146,12 +2202,13 @@ function_exit:
 		offsets = rec_get_offsets(rec, index, NULL,
 					  ULINT_UNDEFINED, &heap);
 
-		DEBUG_SYNC_C("before_row_ins_upd_extern");
+		DEBUG_SYNC_C("before_row_ins_extern");
 		err = btr_store_big_rec_extern_fields(
 			index, btr_cur_get_block(&cursor),
-			rec, offsets, &mtr, FALSE, big_rec);
-		DEBUG_SYNC_C("after_row_ins_upd_extern");
+			rec, offsets, big_rec, &mtr, BTR_STORE_INSERT);
+		DEBUG_SYNC_C("after_row_ins_extern");
 
+stored_big_rec:
 		if (modify) {
 			dtuple_big_rec_free(big_rec);
 		} else {
diff --git a/storage/innodb_plugin/row/row0row.c b/storage/innodb_plugin/row/row0row.c
index 9cdbbe76e04..7ec05f01821 100644
--- a/storage/innodb_plugin/row/row0row.c
+++ b/storage/innodb_plugin/row/row0row.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -243,19 +243,20 @@ row_build(
 	}
 
 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
-	/* This condition can occur during crash recovery before
-	trx_rollback_active() has completed execution.
-
-	This condition is possible if the server crashed
-	during an insert or update before
-	btr_store_big_rec_extern_fields() did mtr_commit() all
-	BLOB pointers to the clustered index record.
-
-	If the record contains a null BLOB pointer, look up the
-	transaction that holds the implicit lock on this record, and
-	assert that it was recovered (and will soon be rolled back). */
-	ut_a(!rec_offs_any_null_extern(rec, offsets)
-	     || trx_assert_recovered(row_get_rec_trx_id(rec, index, offsets)));
+	if (rec_offs_any_null_extern(rec, offsets)) {
+		/* This condition can occur during crash recovery
+		before trx_rollback_active() has completed execution.
+
+		This condition is possible if the server crashed
+		during an insert or update-by-delete-and-insert before
+		btr_store_big_rec_extern_fields() did mtr_commit() all
+		BLOB pointers to the freshly inserted clustered index
+		record. */
+		ut_a(trx_assert_recovered(
+			     row_get_rec_trx_id(rec, index, offsets)));
+		ut_a(trx_undo_roll_ptr_is_insert(
+			     row_get_rec_roll_ptr(rec, index, offsets)));
+	}
 #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 
 	if (type != ROW_COPY_POINTERS) {
diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c
index acd72ead42f..d26b7df9b30 100644
--- a/storage/innodb_plugin/row/row0upd.c
+++ b/storage/innodb_plugin/row/row0upd.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -1978,33 +1978,62 @@ row_upd_clust_rec(
 	ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
 				    dict_table_is_comp(index->table)));
 
-	err = btr_cur_pessimistic_update(BTR_NO_LOCKING_FLAG, btr_cur,
-					 &heap, &big_rec, node->update,
-					 node->cmpl_info, thr, mtr);
-	mtr_commit(mtr);
-
-	if (err == DB_SUCCESS && big_rec) {
-		ulint		offsets_[REC_OFFS_NORMAL_SIZE];
-		rec_t*		rec;
+	err = btr_cur_pessimistic_update(
+		BTR_NO_LOCKING_FLAG | BTR_KEEP_POS_FLAG, btr_cur,
+		&heap, &big_rec, node->update, node->cmpl_info, thr, mtr);
+	if (big_rec) {
+		ulint	offsets_[REC_OFFS_NORMAL_SIZE];
+		rec_t*	rec;
 		rec_offs_init(offsets_);
 
-		DBUG_EXECUTE_IF(
-			"row_upd_extern_checkpoint",
-			log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE););
+		ut_a(err == DB_SUCCESS);
+		/* Write out the externally stored
+		columns while still x-latching
+		index->lock and block->lock. Allocate
+		pages for big_rec in the mtr that
+		modified the B-tree, but be sure to skip
+		any pages that were freed in mtr. We will
+		write out the big_rec pages before
+		committing the B-tree mini-transaction. If
+		the system crashes so that crash recovery
+		will not replay the mtr_commit(&mtr), the
+		big_rec pages will be left orphaned until
+		the pages are allocated for something else.
+
+		TODO: If the allocation extends the tablespace, it
+		will not be redo logged, in either mini-transaction.
+		Tablespace extension should be redo-logged in the
+		big_rec mini-transaction, so that recovery will not
+		fail when the big_rec was written to the extended
+		portion of the file, in case the file was somehow
+		truncated in the crash. */
 
-		mtr_start(mtr);
-		ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
 		rec = btr_cur_get_rec(btr_cur);
 		DEBUG_SYNC_C("before_row_upd_extern");
 		err = btr_store_big_rec_extern_fields(
 			index, btr_cur_get_block(btr_cur), rec,
 			rec_get_offsets(rec, index, offsets_,
 					ULINT_UNDEFINED, &heap),
-			mtr, TRUE, big_rec);
+			big_rec, mtr, BTR_STORE_UPDATE);
 		DEBUG_SYNC_C("after_row_upd_extern");
-		mtr_commit(mtr);
+		/* If writing big_rec fails (for example, because of
+		DB_OUT_OF_FILE_SPACE), the record will be corrupted.
+		Even if we did not update any externally stored
+		columns, our update could cause the record to grow so
+		that a non-updated column was selected for external
+		storage. This non-update would not have been written
+		to the undo log, and thus the record cannot be rolled
+		back.
+
+		However, because we have not executed mtr_commit(mtr)
+		yet, the update will not be replayed in crash
+		recovery, and the following assertion failure will
+		effectively "roll back" the operation. */
+		ut_a(err == DB_SUCCESS);
 	}
 
+	mtr_commit(mtr);
+
 	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
diff --git a/storage/innodb_plugin/trx/trx0rec.c b/storage/innodb_plugin/trx/trx0rec.c
index 2db98e029df..dc55690c9c3 100644
--- a/storage/innodb_plugin/trx/trx0rec.c
+++ b/storage/innodb_plugin/trx/trx0rec.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -1176,6 +1176,7 @@ trx_undo_report_row_operation(
 	trx_t*		trx;
 	trx_undo_t*	undo;
 	ulint		page_no;
+	buf_block_t*	undo_block;
 	trx_rseg_t*	rseg;
 	mtr_t		mtr;
 	ulint		err		= DB_SUCCESS;
@@ -1218,10 +1219,13 @@ trx_undo_report_row_operation(
 
 		if (UNIV_UNLIKELY(!undo)) {
 			/* Did not succeed */
+			ut_ad(err != DB_SUCCESS);
 			mutex_exit(&(trx->undo_mutex));
 
 			return(err);
 		}
+
+		ut_ad(err == DB_SUCCESS);
 	} else {
 		ut_ad(op_type == TRX_UNDO_MODIFY_OP);
 
@@ -1235,30 +1239,30 @@ trx_undo_report_row_operation(
 
 		if (UNIV_UNLIKELY(!undo)) {
 			/* Did not succeed */
+			ut_ad(err != DB_SUCCESS);
 			mutex_exit(&(trx->undo_mutex));
 			return(err);
 		}
 
+		ut_ad(err == DB_SUCCESS);
 		offsets = rec_get_offsets(rec, index, offsets,
 					  ULINT_UNDEFINED, &heap);
 	}
 
-	page_no = undo->last_page_no;
-
 	mtr_start(&mtr);
 
+	page_no = undo->last_page_no;
+	undo_block = buf_page_get_gen(
+		undo->space, undo->zip_size, page_no, RW_X_LATCH,
+		undo->guess_block, BUF_GET, __FILE__, __LINE__, &mtr);
+	buf_block_dbg_add_level(undo_block, SYNC_TRX_UNDO_PAGE);
+
 	do {
-		buf_block_t*	undo_block;
 		page_t*		undo_page;
 		ulint		offset;
 
-		undo_block = buf_page_get_gen(undo->space, undo->zip_size,
-					      page_no, RW_X_LATCH,
-					      undo->guess_block, BUF_GET,
-					      __FILE__, __LINE__, &mtr);
-		buf_block_dbg_add_level(undo_block, SYNC_TRX_UNDO_PAGE);
-
 		undo_page = buf_block_get_frame(undo_block);
+		ut_ad(page_no == buf_block_get_page_no(undo_block));
 
 		if (op_type == TRX_UNDO_INSERT_OP) {
 			offset = trx_undo_page_report_insert(
@@ -1335,12 +1339,12 @@ trx_undo_report_row_operation(
 		a pessimistic insert in a B-tree, and we must reserve the
 		counterpart of the tree latch, which is the rseg mutex. */
 
-		mutex_enter(&(rseg->mutex));
-
-		page_no = trx_undo_add_page(trx, undo, &mtr);
+		mutex_enter(&rseg->mutex);
+		undo_block = trx_undo_add_page(trx, undo, &mtr);
+		mutex_exit(&rseg->mutex);
 
-		mutex_exit(&(rseg->mutex));
-	} while (UNIV_LIKELY(page_no != FIL_NULL));
+		page_no = undo->last_page_no;
+	} while (undo_block != NULL);
 
 	/* Did not succeed: out of space */
 	err = DB_OUT_OF_FILE_SPACE;
diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c
index e9328b27bba..daa65bfcef0 100644
--- a/storage/innodb_plugin/trx/trx0sys.c
+++ b/storage/innodb_plugin/trx/trx0sys.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -247,9 +247,7 @@ trx_sys_create_doublewrite_buf(void)
 {
 	buf_block_t*	block;
 	buf_block_t*	block2;
-#ifdef UNIV_SYNC_DEBUG
 	buf_block_t*	new_block;
-#endif /* UNIV_SYNC_DEBUG */
 	byte*	doublewrite;
 	byte*	fseg_header;
 	ulint	page_no;
@@ -328,10 +326,9 @@ start_again:
 
 		for (i = 0; i < 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
 			     + FSP_EXTENT_SIZE / 2; i++) {
-			page_no = fseg_alloc_free_page(fseg_header,
-						       prev_page_no + 1,
-						       FSP_UP, &mtr);
-			if (page_no == FIL_NULL) {
+			new_block = fseg_alloc_free_page(
+				fseg_header, prev_page_no + 1, FSP_UP, &mtr);
+			if (new_block == NULL) {
 				fprintf(stderr,
 					"InnoDB: Cannot create doublewrite"
 					" buffer: you must\n"
@@ -352,13 +349,8 @@ start_again:
 			the page position in the tablespace, then the page
 			has not been written to in doublewrite. */
 
-#ifdef UNIV_SYNC_DEBUG
-			new_block =
-#endif /* UNIV_SYNC_DEBUG */
-			buf_page_get(TRX_SYS_SPACE, 0, page_no,
-				     RW_X_LATCH, &mtr);
-			buf_block_dbg_add_level(new_block,
-						SYNC_NO_ORDER_CHECK);
+			ut_ad(rw_lock_get_x_lock_count(&new_block->lock) == 1);
+			page_no = buf_block_get_page_no(new_block);
 
 			if (i == FSP_EXTENT_SIZE / 2) {
 				ut_a(page_no == FSP_EXTENT_SIZE);
diff --git a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c
index 746f0808643..6cc21d6d4c1 100644
--- a/storage/innodb_plugin/trx/trx0undo.c
+++ b/storage/innodb_plugin/trx/trx0undo.c
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 *****************************************************************************/
 
@@ -870,9 +870,9 @@ trx_undo_discard_latest_update_undo(
 #ifndef UNIV_HOTBACKUP
 /********************************************************************//**
 Tries to add a page to the undo log segment where the undo log is placed.
-@return	page number if success, else FIL_NULL */
+@return	X-latched block if success, else NULL */
 UNIV_INTERN
-ulint
+buf_block_t*
 trx_undo_add_page(
 /*==============*/
 	trx_t*		trx,	/*!< in: transaction */
@@ -882,11 +882,10 @@ trx_undo_add_page(
 				the rollback segment mutex */
 {
 	page_t*		header_page;
+	buf_block_t*	new_block;
 	page_t*		new_page;
 	trx_rseg_t*	rseg;
-	ulint		page_no;
 	ulint		n_reserved;
-	ibool		success;
 
 	ut_ad(mutex_own(&(trx->undo_mutex)));
 	ut_ad(!mutex_own(&kernel_mutex));
@@ -896,37 +895,37 @@ trx_undo_add_page(
 
 	if (rseg->curr_size == rseg->max_size) {
 
-		return(FIL_NULL);
+		return(NULL);
 	}
 
 	header_page = trx_undo_page_get(undo->space, undo->zip_size,
 					undo->hdr_page_no, mtr);
 
-	success = fsp_reserve_free_extents(&n_reserved, undo->space, 1,
-					   FSP_UNDO, mtr);
-	if (!success) {
+	if (!fsp_reserve_free_extents(&n_reserved, undo->space, 1,
+				      FSP_UNDO, mtr)) {
 
-		return(FIL_NULL);
+		return(NULL);
 	}
 
-	page_no = fseg_alloc_free_page_general(header_page + TRX_UNDO_SEG_HDR
-					       + TRX_UNDO_FSEG_HEADER,
-					       undo->top_page_no + 1, FSP_UP,
-					       TRUE, mtr);
+	new_block = fseg_alloc_free_page_general(
+		TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
+		+ header_page,
+		undo->top_page_no + 1, FSP_UP, TRUE, mtr, mtr);
 
 	fil_space_release_free_extents(undo->space, n_reserved);
 
-	if (page_no == FIL_NULL) {
+	if (new_block == NULL) {
 
 		/* No space left */
 
-		return(FIL_NULL);
+		return(NULL);
 	}
 
-	undo->last_page_no = page_no;
+	ut_ad(rw_lock_get_x_lock_count(&new_block->lock) == 1);
+	buf_block_dbg_add_level(new_block, SYNC_TRX_UNDO_PAGE);
+	undo->last_page_no = buf_block_get_page_no(new_block);
 
-	new_page = trx_undo_page_get(undo->space, undo->zip_size,
-				     page_no, mtr);
+	new_page = buf_block_get_frame(new_block);
 
 	trx_undo_page_init(new_page, undo->type, mtr);
 
@@ -935,7 +934,7 @@ trx_undo_add_page(
 	undo->size++;
 	rseg->curr_size++;
 
-	return(page_no);
+	return(new_block);
 }
 
 /********************************************************************//**
-- 
cgit v1.2.1


From c3b04553c475f5780fb3371c6a7492fc203d2dbd Mon Sep 17 00:00:00 2001
From: Joerg Bruehe 
Date: Tue, 28 Feb 2012 12:42:02 +0100
Subject: The current year is 2012, and nobody noticed ... Update the year in
 the copyright notice, file "README".

---
 README | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README b/README
index 795d325e2d5..acc98e400bd 100644
--- a/README
+++ b/README
@@ -5,7 +5,7 @@ For the avoidance of doubt, this particular copy of the software
 is released under the version 2 of the GNU General Public License. 
 MySQL is brought to you by Oracle.
 
-Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
 License information can be found in the COPYING file.
 
-- 
cgit v1.2.1


From 2efa0ec676d203083aa63123651a6e09abfd8129 Mon Sep 17 00:00:00 2001
From: Karen Langford 
Date: Tue, 28 Feb 2012 17:20:30 +0100
Subject: AIX builds fail for comments using //

---
 client/mysqldump.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/client/mysqldump.c b/client/mysqldump.c
index a69c9306b4b..8601b533849 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -2331,10 +2331,10 @@ static uint dump_routines_for_db(char *db)
           {
             if (opt_xml)
             {
-              if (i)                            // Procedures.
+              if (i)                            /* Procedures. */
                 print_xml_row(sql_file, "routine", routine_res, &row,
                               "Create Procedure");
-              else                              // Functions.
+              else                              /* Functions. */
                 print_xml_row(sql_file, "routine", routine_res, &row,
                               "Create Function");
               continue;
-- 
cgit v1.2.1


From 5b49c7ce916be1bbf306d2fd9175ed2b5ddeeed9 Mon Sep 17 00:00:00 2001
From: Joerg Bruehe 
Date: Fri, 2 Mar 2012 13:12:07 +0100
Subject: Further upgrade the yaSSL library to version 2.2.0 to pick up some
 new security fixes that are in it.

Patch provided by Georgi Kodinov.
---
 extra/yassl/README                    |  3 +--
 extra/yassl/include/openssl/ssl.h     |  4 ++--
 extra/yassl/src/yassl_imp.cpp         | 20 +++++++++++++++++++-
 extra/yassl/src/yassl_int.cpp         |  5 +++--
 extra/yassl/taocrypt/include/file.hpp | 21 ++++++++++++++-------
 extra/yassl/taocrypt/src/asn.cpp      | 26 ++++++++++++++++++++++++--
 extra/yassl/taocrypt/src/integer.cpp  |  5 ++++-
 7 files changed, 67 insertions(+), 17 deletions(-)

diff --git a/extra/yassl/README b/extra/yassl/README
index 0ca656bb932..7720a9453dd 100644
--- a/extra/yassl/README
+++ b/extra/yassl/README
@@ -21,8 +21,7 @@ See normal  build instructions below under 1.0.6.
 See libcurl build instructions below under 1.3.0 and note in 1.5.8.
 
 
-*****************yaSSL Release notes, version 1.9.9 (1/26/2010)
-yaSSL Release notes, version 2.0.0 (7/6/2010)
+*****************yaSSL Release notes, version 2.0.0 (7/6/2010)
 
     This release of yaSSL contains bug fixes, new testing certs,
     and a security patch for a potential heap overflow on forged application
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index 0ae54f070bd..0d99888da88 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2005-2007 MySQL AB, 2008 Sun Microsystems, Inc.
+   Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
    Use is subject to license terms.
 
    This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,7 @@
 #include "rsa.h"
 
 
-#define YASSL_VERSION "2.1.4"
+#define YASSL_VERSION "2.2.0"
 
 
 #if defined(__cplusplus)
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index 6d2549749f2..66a173bece8 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1087,19 +1087,37 @@ void Certificate::Process(input_buffer& input, SSL& ssl)
     uint32 list_sz;
     byte   tmp[3];
 
+    if (input.get_remaining() < sizeof(tmp)) {
+        ssl.SetError(YasslError(bad_input));
+        return;
+    }
     tmp[0] = input[AUTO];
     tmp[1] = input[AUTO];
     tmp[2] = input[AUTO];
     c24to32(tmp, list_sz);
+
+    if (list_sz > (uint)MAX_RECORD_SIZE) { // sanity check
+        ssl.SetError(YasslError(bad_input));
+        return;
+    }
     
     while (list_sz) {
         // cert size
         uint32 cert_sz;
+
+        if (input.get_remaining() < sizeof(tmp)) {
+            ssl.SetError(YasslError(bad_input));
+            return;
+        }
         tmp[0] = input[AUTO];
         tmp[1] = input[AUTO];
         tmp[2] = input[AUTO];
         c24to32(tmp, cert_sz);
         
+        if (cert_sz > (uint)MAX_RECORD_SIZE || input.get_remaining() < cert_sz){
+            ssl.SetError(YasslError(bad_input));
+            return;
+        }
         x509* myCert;
         cm.AddPeerCert(myCert = NEW_YS x509(cert_sz));
         input.read(myCert->use_buffer(), myCert->get_length());
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 15a85e36909..73f8f2330c5 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -308,8 +308,9 @@ SSL::SSL(SSL_CTX* ctx)
             SetError(YasslError(err));
             return;
         }
-        else if (serverSide) {
+        else if (serverSide && ctx->GetCiphers().setSuites_ == 0) {
             // remove RSA or DSA suites depending on cert key type
+            // but don't override user sets
             ProtocolVersion pv = secure_.get_connection().version_;
             
             bool removeDH  = secure_.use_parms().removeDH_;
diff --git a/extra/yassl/taocrypt/include/file.hpp b/extra/yassl/taocrypt/include/file.hpp
index 0f85b46fdb2..820fd8ff431 100644
--- a/extra/yassl/taocrypt/include/file.hpp
+++ b/extra/yassl/taocrypt/include/file.hpp
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2000-2007 MySQL AB
+   Copyright (C) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -39,25 +39,32 @@ public:
     explicit Source(word32 sz = 0) : buffer_(sz), current_(0) {}
     Source(const byte* b, word32 sz) : buffer_(b, sz), current_(0) {}
 
+    word32 remaining()         { if (GetError().What()) return 0;
+                                 else return buffer_.size() - current_; } 
     word32 size() const        { return buffer_.size(); }
     void   grow(word32 sz)     { buffer_.CleanGrow(sz); }
+
+    bool IsLeft(word32 sz) { if (remaining() >= sz) return true;
+                             else { SetError(CONTENT_E); return false; } }
    
     const byte*  get_buffer()  const { return buffer_.get_buffer(); }
     const byte*  get_current() const { return &buffer_[current_]; }
     word32       get_index()   const { return current_; }
-    void         set_index(word32 i) { current_ = i; }
+    void         set_index(word32 i) { if (i < size()) current_ = i; }
 
     byte operator[] (word32 i) { current_ = i; return next(); }
-    byte next() { return buffer_[current_++]; }
-    byte prev() { return buffer_[--current_]; }
+    byte next() { if (IsLeft(1)) return buffer_[current_++]; else return 0; }
+    byte prev() { if (current_)  return buffer_[--current_]; else return 0; }
 
     void add(const byte* data, word32 len)
     {
-        memcpy(buffer_.get_buffer() + current_, data, len);
-        current_ += len;
+        if (IsLeft(len)) {
+            memcpy(buffer_.get_buffer() + current_, data, len);
+            current_ += len;
+        }
     }
 
-    void advance(word32 i) { current_ += i; }
+    void advance(word32 i) { if (IsLeft(i)) current_ += i; }
     void reset(ByteBlock&);
 
     Error  GetError()              { return error_; }
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index 72cbd092f9d..a502666d15b 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2005-2007 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
+   Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
    Use is subject to license terms.
 
    This program is free software; you can redistribute it and/or modify
@@ -144,6 +144,8 @@ word32 GetLength(Source& source)
     if (b >= LONG_LENGTH) {        
         word32 bytes = b & 0x7F;
 
+        if (source.IsLeft(bytes) == false) return 0;
+
         while (bytes--) {
             b = source.next();
             length = (length << 8) | b;
@@ -578,8 +580,10 @@ void CertDecoder::StoreKey()
     read = source_.get_index() - read;
     length += read;
 
+    if (source_.GetError().What()) return;
     while (read--) source_.prev();
 
+    if (source_.IsLeft(length) == false) return;
     key_.SetSize(length);
     key_.SetKey(source_.get_current());
     source_.advance(length);
@@ -611,6 +615,8 @@ void CertDecoder::AddDSA()
     word32 length = GetLength(source_);
     length += source_.get_index() - idx;
 
+    if (source_.IsLeft(length) == false) return;
+
     key_.AddToEnd(source_.get_buffer() + idx, length);    
 }
 
@@ -620,6 +626,8 @@ word32 CertDecoder::GetAlgoId()
 {
     if (source_.GetError().What()) return 0;
     word32 length = GetSequence();
+
+    if (source_.GetError().What()) return 0;
     
     byte b = source_.next();
     if (b != OBJECT_IDENTIFIER) {
@@ -628,8 +636,9 @@ word32 CertDecoder::GetAlgoId()
     }
 
     length = GetLength(source_);
+    if (source_.IsLeft(length) == false) return 0;
+
     word32 oid = 0;
-    
     while(length--)
         oid += source_.next();        // just sum it up for now
 
@@ -662,6 +671,10 @@ word32 CertDecoder::GetSignature()
     }
 
     sigLength_ = GetLength(source_);
+    if (sigLength_ == 0 || source_.IsLeft(sigLength_) == false) {
+        source_.SetError(CONTENT_E);
+        return 0;
+    }
   
     b = source_.next();
     if (b != 0) {
@@ -728,6 +741,7 @@ void CertDecoder::GetName(NameType nt)
 
     if (length >= ASN_NAME_MAX)
         return;
+    if (source_.IsLeft(length) == false) return;
     length += source_.get_index();
     
     char* ptr;
@@ -753,7 +767,10 @@ void CertDecoder::GetName(NameType nt)
         }
 
         word32 oidSz = GetLength(source_);
+        if (source_.IsLeft(oidSz) == false) return;
+
         byte joint[2];
+        if (source_.IsLeft(sizeof(joint)) == false) return;
         memcpy(joint, source_.get_current(), sizeof(joint));
 
         // v1 name types
@@ -763,6 +780,8 @@ void CertDecoder::GetName(NameType nt)
             b              = source_.next();    // strType
             word32 strLen  = GetLength(source_);
 
+            if (source_.IsLeft(strLen) == false) return;
+
             switch (id) {
             case COMMON_NAME:
                 if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen)))
@@ -804,6 +823,7 @@ void CertDecoder::GetName(NameType nt)
 
             source_.advance(oidSz + 1);
             word32 length = GetLength(source_);
+            if (source_.IsLeft(length) == false) return;
 
             if (email) {
                 if (!(ptr = AddTag(ptr, buf_end, "/emailAddress=", 14, length))) {
@@ -837,6 +857,8 @@ void CertDecoder::GetDate(DateType dt)
     }
 
     word32 length = GetLength(source_);
+    if (source_.IsLeft(length) == false) return;
+
     byte date[MAX_DATE_SZ];
     if (length > MAX_DATE_SZ || length < MIN_DATE_SZ) {
         source_.SetError(DATE_SZ_E);
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 2d55f48e91f..bfced6d0c74 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -2587,11 +2587,14 @@ void Integer::Decode(Source& source)
     }
 
     word32 length = GetLength(source);
+    if (length == 0 || source.GetError().What()) return;
 
     if ( (b = source.next()) == 0x00)
         length--;
     else
         source.prev();
+
+    if (source.IsLeft(length) == false) return;
  
     unsigned int words = (length + WORD_SIZE - 1) / WORD_SIZE;
     words = RoundupSize(words);
-- 
cgit v1.2.1


From c72d5e80c53c53a9a847b1c3b6ac66a7ad7eb815 Mon Sep 17 00:00:00 2001
From: Sergei Golubchik 
Date: Wed, 4 Apr 2012 15:41:50 +0200
Subject: mdev-212 sporadic main.connect failures in 5.3

don't cast implicitly an int to a char, when a boolean value is desired.
---
 sql/password.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql/password.c b/sql/password.c
index c8aa90aa56d..728d6ba700a 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -503,7 +503,7 @@ check_scramble(const char *scramble_arg, const char *message,
   mysql_sha1_reset(&sha1_context);
   mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
   mysql_sha1_result(&sha1_context, hash_stage2_reassured);
-  return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
+  return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
 }
 
 
-- 
cgit v1.2.1