diff --git a/ChangeLog b/ChangeLog
index 0a4b01ef4062cdd31c1651822f6ce71ed2f4ce04..060747550b10ea3814ede999730b3569083ae211 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-11-26	The InnoDB Team
+
+	* row/row0merge.c (row_merge_drop_temp_indexes):
+	Replace the WHILE 1 with WHILE 1=1 in the SQL procedure, so that
+	the loop will actually be entered and temporary indexes be dropped
+	during crash recovery.
+
 2008-10-31	The InnoDB Team
 
 	* dict/dict0mem.c, include/dict0mem.h, include/lock0lock.h,
diff --git a/handler/win_delay_loader.cc b/handler/win_delay_loader.cc
index 7cee5cf3f3667f41bb6b6946e2c086067a0b92f2..8b69f4a6e51270853250070b34686a6e4ba3beb7 100644
--- a/handler/win_delay_loader.cc
+++ b/handler/win_delay_loader.cc
@@ -263,6 +263,11 @@ wdl_load_mapfile(
 	char*		func_addr;
 	ulint		load_addr = 0;
 	ibool		valid_load_addr = FALSE;
+#ifdef _WIN64
+	const char*	tmp_string = " Preferred load address is %16llx";
+#else
+	const char*	tmp_string = " Preferred load address is %08x";
+#endif
 
 	fp = fopen(filename, "r");
 	if (fp == NULL) {
@@ -285,8 +290,7 @@ wdl_load_mapfile(
 	/* Search start of symbol list and get the preferred load address */
 	while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
 
-		if (sscanf(tmp_buf, " Preferred load address is %16X",
-			   &load_addr) == 1) {
+		if (sscanf(tmp_buf, tmp_string, &load_addr) == 1) {
 
 			valid_load_addr = TRUE;
 		}
@@ -338,7 +342,7 @@ wdl_load_mapfile(
 			chain_header = map_cell;
 
 			map_cell->symbol = strdup(func_name);
-			map_cell->value = strtoul(tmp_buf, NULL, 0)
+			map_cell->value = (ulint) strtoull(tmp_buf, NULL, 0)
 					  - load_addr;
 			map_fold = ut_fold_string(map_cell->symbol);
 
diff --git a/include/row0uins.h b/include/row0uins.h
index 3d56cb68f37fe20cd7d2b33d8b675f1e42f75ba5..91052505aad461b3a14b34f794edb8a5731b26ed 100644
--- a/include/row0uins.h
+++ b/include/row0uins.h
@@ -20,7 +20,9 @@ Created 2/25/1997 Heikki Tuuri
 /***************************************************************
 Undoes a fresh insert of a row to a table. A fresh insert means that
 the same clustered index unique key did not have any record, even delete
-marked, at the time of the insert. */
+marked, at the time of the insert.  InnoDB is eager in a rollback:
+if it figures out that an index record will be removed in the purge
+anyway, it will remove it in the rollback. */
 UNIV_INTERN
 ulint
 row_undo_ins(
diff --git a/row/row0merge.c b/row/row0merge.c
index 634119b811e8ac1b5da4ebb3daf38c0ff0c77f31..6d9dfa9feb40694021e77054fdfca37804ee6132 100644
--- a/row/row0merge.c
+++ b/row/row0merge.c
@@ -1842,7 +1842,7 @@ row_merge_drop_temp_indexes(void)
 		"WHERE SUBSTR(NAME,0,1)='\377' FOR UPDATE;\n"
 		"BEGIN\n"
 		"\tOPEN c;\n"
-		"\tWHILE 1 LOOP\n"
+		"\tWHILE 1=1 LOOP\n"
 		"\t\tFETCH c INTO indexid;\n"
 		"\t\tIF (SQL % NOTFOUND) THEN\n"
 		"\t\t\tEXIT;\n"
diff --git a/row/row0purge.c b/row/row0purge.c
index 703ea904ffa26a2ae3d4de95821fd77d7cf6c4dd..90017fdc0099eb4f6fb6cfe304c4ebd1df4c3132 100644
--- a/row/row0purge.c
+++ b/row/row0purge.c
@@ -230,7 +230,15 @@ row_purge_remove_sec_if_poss_low_nonbuffered(
 
 	switch (search_result) {
 	case ROW_NOT_FOUND:
-		/* Not found */
+		/* Not found.  This is a legitimate condition.  In a
+		rollback, InnoDB will remove secondary recs that would
+		be purged anyway.  Then the actual purge will not find
+		the secondary index record.  Also, the purge itself is
+		eager: if it comes to consider a secondary index
+		record, and notices it does not need to exist in the
+		index, it will remove it.  Then if/when the purge
+		comes to consider the secondary index record a second
+		time, it will not exist any more in the index. */
 
 		/* fputs("PURGE:........sec entry not found\n", stderr); */
 		/* dtuple_print(stderr, entry); */
diff --git a/row/row0uins.c b/row/row0uins.c
index 75b46769c8cb5805208b59749db106f8d5fd7e47..846a897694ce09b6e83bd8a1ce70abe033ce0b41 100644
--- a/row/row0uins.c
+++ b/row/row0uins.c
@@ -277,7 +277,9 @@ row_undo_ins_parse_undo_rec(
 /***************************************************************
 Undoes a fresh insert of a row to a table. A fresh insert means that
 the same clustered index unique key did not have any record, even delete
-marked, at the time of the insert. */
+marked, at the time of the insert.  InnoDB is eager in a rollback:
+if it figures out that an index record will be removed in the purge
+anyway, it will remove it in the rollback. */
 UNIV_INTERN
 ulint
 row_undo_ins(
diff --git a/row/row0umod.c b/row/row0umod.c
index 65e72bc01a0798cd231465a84da8e2b465d79cd9..56aa1e98d187e1b09d721edee3e04cd7acf17dcc 100644
--- a/row/row0umod.c
+++ b/row/row0umod.c
@@ -314,8 +314,35 @@ row_undo_mod_del_mark_or_remove_sec_low(
 	search_result = row_search_index_entry(index, entry, mode,
 					       &pcur, &mtr);
 
-	switch (search_result) {
+	switch (UNIV_EXPECT(search_result, ROW_FOUND)) {
+		trx_t*	trx;
 	case ROW_NOT_FOUND:
+		/* In crash recovery, the secondary index record may
+		be missing if the UPDATE did not have time to insert
+		the secondary index records before the crash.  When we
+		are undoing that UPDATE in crash recovery, the record
+		may be missing.  In normal processing, the record
+		SHOULD exist. */
+
+		trx = thr_get_trx(thr);
+
+		if (!trx_is_recv(trx)) {
+			fputs("InnoDB: error in sec index entry del undo in\n"
+			      "InnoDB: ", stderr);
+			dict_index_name_print(stderr, trx, index);
+			fputs("\n"
+			      "InnoDB: tuple ", stderr);
+			dtuple_print(stderr, entry);
+			fputs("\n"
+			      "InnoDB: record ", stderr);
+			rec_print(stderr, btr_pcur_get_rec(&pcur), index);
+			putc('\n', stderr);
+			trx_print(stderr, trx, 0);
+			fputs("\n"
+			      "InnoDB: Submit a detailed bug report"
+			      " to http://bugs.mysql.com\n", stderr);
+		}
+
 		err = DB_SUCCESS;
 		goto func_exit;
 	case ROW_FOUND:
diff --git a/win-plugin/win-plugin.diff b/win-plugin/win-plugin.diff
index 760b184a8fe1f94a960d81f2407a5f0ae109938b..a9e067c6ee5f0d77a278e2d32cbac24e742f19d8 100644
--- a/win-plugin/win-plugin.diff
+++ b/win-plugin/win-plugin.diff
@@ -1,18 +1,7 @@
 diff -Nur CMakeLists.txt.orig CMakeLists.txt
 --- CMakeLists.txt.orig	2008-10-03 12:25:41 -05:00
 +++ CMakeLists.txt	2008-09-26 17:32:51 -05:00
-@@ -97,6 +97,10 @@
- IF(CYBOZU)
-   ADD_DEFINITIONS(-DCYBOZU)
- ENDIF(CYBOZU)
-+# Checks for 32-bit version. And always use 32-bit time_t for compatibility
-+IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 4)
-+  ADD_DEFINITIONS(-D_USE_32BIT_TIME_T)
-+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 4)
- 
- # in some places we use DBUG_OFF
- SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF")
-@@ -246,9 +250,9 @@
+@@ -244,9 +244,9 @@
  IF(WITH_FEDERATED_STORAGE_ENGINE)
    ADD_SUBDIRECTORY(storage/federated)
  ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
@@ -149,7 +138,7 @@ diff -Nur sql/mysqld.def.orig sql/mysqld.def
 +	localtime_r
 +	my_strdup
 
-diff -Nur ../old/sql/mysqld_x64.def.orig ./sql/mysqld_x64.def
+diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def
 --- sql/mysqld_x64.def.orig	1969-12-31 18:00:00 -06:00
 +++ sql/mysqld_x64.def		2008-10-31 02:22:04 -05:00
 @@ -0,0 +1,99 @@