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

ChangeSet@stripped, 2007-01-21 20:30:54-07:00, tsmith@stripped +4 -0
  Merge siva.hindu.god:/home/tsmith/m/inno/jan20/50
  into  siva.hindu.god:/home/tsmith/m/inno/jan20/51
  MERGE: 1.1810.2371.62

  mysql-test/r/range.result@stripped, 2007-01-21 20:30:25-07:00, tsmith@stripped +0 -0
    SCCS merged
    MERGE: 1.44.1.9

  sql/item.cc@stripped, 2007-01-21 20:30:38-07:00, tsmith@stripped +0 -0
    SCCS merged
    MERGE: 1.113.1.137

  storage/innobase/dict/dict0dict.c@stripped, 2007-01-21 20:30:40-07:00, tsmith@stripped +0 -15
    Use local
    MERGE: 1.65.20.3

  storage/innobase/dict/dict0dict.c@stripped, 2007-01-21 20:23:28-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/dict/dict0dict.c -> storage/innobase/dict/dict0dict.c

  storage/innobase/handler/ha_innodb.h@stripped, 2007-01-21 20:30:46-07:00, tsmith@stripped +0 -1
    Use local
    MERGE: 1.93.5.2

  storage/innobase/handler/ha_innodb.h@stripped, 2007-01-21 20:23:28-07:00, tsmith@stripped +0 -0
    Merge rename: sql/ha_innodb.h -> storage/innobase/handler/ha_innodb.h

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tsmith
# Host:	siva.hindu.god
# Root:	/home/tsmith/m/inno/jan20/51/RESYNC

--- 1.65.20.2/innobase/dict/dict0dict.c	2007-01-21 20:05:14 -07:00
+++ 1.100/storage/innobase/dict/dict0dict.c	2007-01-21 20:30:40 -07:00
@@ -26,9 +26,9 @@
 #include "pars0sym.h"
 #include "que0que.h"
 #include "rem0cmp.h"
-
-/* Implement isspace() in a locale-independent way. (Bug #24299) */
-#define ib_isspace(c) ((char) (c) && strchr(" \v\f\t\r\n", c))
+#ifndef UNIV_HOTBACKUP
+# include "m_ctype.h" /* my_isspace() */
+#endif /* !UNIV_HOTBACKUP */
 
 dict_sys_t*	dict_sys	= NULL;	/* the dictionary system */
 
@@ -48,8 +48,6 @@
 					creating a table or index object */
 #define DICT_POOL_PER_TABLE_HASH 512	/* buffer pool max size per table
 					hash table fixed size in bytes */
-#define DICT_POOL_PER_COL_HASH	128	/* buffer pool max size per column
-					hash table fixed size in bytes */
 #define DICT_POOL_PER_VARYING	4	/* buffer pool max size per data
 					dictionary varying size in bytes */
 
@@ -58,6 +56,42 @@
 
 #ifndef UNIV_HOTBACKUP
 /**********************************************************************
+Converts an identifier to a table name.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_table_id(
+/*===========================*/
+	char*		to,	/* out: converted identifier */
+	const char*	from,	/* in: identifier to convert */
+	ulint		len);	/* in: length of 'to', in bytes;
+				should be at least 5 * strlen(to) + 1 */
+/**********************************************************************
+Converts an identifier to UTF-8.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_id(
+/*=====================*/
+	char*		to,	/* out: converted identifier */
+	const char*	from,	/* in: identifier to convert */
+	ulint		len);	/* in: length of 'to', in bytes;
+				should be at least 3 * strlen(to) + 1 */
+/**********************************************************************
+Removes the filename encoding of a table or database name.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_filename(
+/*===========================*/
+	char*		s);	/* in: identifier; out: decoded identifier */
+/**********************************************************************
 Compares NUL-terminated UTF-8 strings case insensitively.
 
 NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
@@ -80,34 +114,19 @@
 innobase_casedn_str(
 /*================*/
 	char*	a);	/* in/out: string to put in lower case */
-#endif /* !UNIV_HOTBACKUP */
 
 /**************************************************************************
-Adds a column to the data dictionary hash table. */
-static
-void
-dict_col_add_to_cache(
-/*==================*/
-	dict_table_t*	table,	/* in: table */
-	dict_col_t*	col);	/* in: column */
-/**************************************************************************
-Repositions a column in the data dictionary hash table when the table name
-changes. */
-static
-void
-dict_col_reposition_in_cache(
-/*=========================*/
-	dict_table_t*	table,		/* in: table */
-	dict_col_t*	col,		/* in: column */
-	const char*	new_name);	/* in: new table name */
-/**************************************************************************
-Removes a column from the data dictionary hash table. */
-static
-void
-dict_col_remove_from_cache(
-/*=======================*/
-	dict_table_t*	table,	/* in: table */
-	dict_col_t*	col);	/* in: column */
+Determines the connection character set.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+struct charset_info_st*
+innobase_get_charset(
+/*=================*/
+				/* out: connection character set */
+	void*	mysql_thd);	/* in: MySQL thread handle */
+#endif /* !UNIV_HOTBACKUP */
+
 /**************************************************************************
 Removes an index from the dictionary cache. */
 static
@@ -124,18 +143,18 @@
 /*============*/
 	dict_index_t*	index1,	/* in: index to copy to */
 	dict_index_t*	index2,	/* in: index to copy from */
+	dict_table_t*	table,	/* in: table */
 	ulint		start,	/* in: first position to copy */
 	ulint		end);	/* in: last position to copy */
 /***********************************************************************
-Tries to find column names for the index in the column hash table and
-sets the col field of the index. */
+Tries to find column names for the index and sets the col field of the
+index. */
 static
-ibool
+void
 dict_index_find_cols(
 /*=================*/
-				/* out: TRUE if success */
 	dict_table_t*	table,	/* in: table */
-	dict_index_t*	index);	/* in: index */	
+	dict_index_t*	index);	/* in: index */
 /***********************************************************************
 Builds the internal dictionary cache representation for a clustered
 index, containing also system fields not defined by the user. */
@@ -147,7 +166,7 @@
 				of the clustered index */
 	dict_table_t*	table,	/* in: table */
 	dict_index_t*	index);	/* in: user representation of a clustered
-				index */	
+				index */
 /***********************************************************************
 Builds the internal dictionary cache representation for a non-clustered
 index, containing also system fields not defined by the user. */
@@ -159,7 +178,7 @@
 				of the non-clustered index */
 	dict_table_t*	table,	/* in: table */
 	dict_index_t*	index);	/* in: user representation of a non-clustered
-				index */	
+				index */
 /**************************************************************************
 Removes a foreign constraint struct from the dictionary cache. */
 static
@@ -173,7 +192,8 @@
 void
 dict_col_print_low(
 /*===============*/
-	dict_col_t*	col);	/* in: column */
+	const dict_table_t*	table,	/* in: table */
+	const dict_col_t*	col);	/* in: column */
 /**************************************************************************
 Prints an index data. */
 static
@@ -199,9 +219,10 @@
 /* Stream for storing detailed information about the latest foreign key
 and unique key errors */
 FILE*	dict_foreign_err_file		= NULL;
-mutex_t	dict_foreign_err_mutex; 	/* mutex protecting the foreign
+mutex_t	dict_foreign_err_mutex;		/* mutex protecting the foreign
 					and unique error buffers */
-	
+
+#ifndef UNIV_HOTBACKUP
 /**********************************************************************
 Makes all characters in a NUL-terminated UTF-8 string lower case. */
 
@@ -212,6 +233,7 @@
 {
 	innobase_casedn_str(a);
 }
+#endif /* !UNIV_HOTBACKUP */
 
 /************************************************************************
 Checks if the database name in two table names is the same. */
@@ -236,7 +258,7 @@
 
 /************************************************************************
 Return the end of table name where we have removed dbname and '/'. */
-static
+
 const char*
 dict_remove_db_name(
 /*================*/
@@ -244,11 +266,10 @@
 	const char*	name)	/* in: table name in the form
 				dbname '/' tablename */
 {
-	const char*	s;
-	s = strchr(name, '/');
+	const char*	s = strchr(name, '/');
 	ut_a(s);
-	if (s) s++;
-	return(s);
+
+	return(s + 1);
 }
 
 /************************************************************************
@@ -266,7 +287,7 @@
 	ut_a(s);
 	return(s - name);
 }
-	
+
 /************************************************************************
 Reserves the dictionary system mutex for MySQL. */
 
@@ -276,7 +297,7 @@
 {
 	mutex_enter(&(dict_sys->mutex));
 }
-	
+
 /************************************************************************
 Releases the dictionary system mutex for MySQL. */
 
@@ -286,7 +307,7 @@
 {
 	mutex_exit(&(dict_sys->mutex));
 }
-	
+
 /************************************************************************
 Decrements the count of open MySQL handles to a table. */
 
@@ -300,19 +321,31 @@
 	ut_a(table->n_mysql_handles_opened > 0);
 
 	table->n_mysql_handles_opened--;
-	
+
 	mutex_exit(&(dict_sys->mutex));
 }
 
+/*************************************************************************
+Gets the column data type. */
+
+void
+dict_col_copy_type_noninline(
+/*=========================*/
+	const dict_col_t*	col,	/* in: column */
+	dtype_t*		type)	/* out: data type */
+{
+	dict_col_copy_type(col, type);
+}
+
 /************************************************************************
 Gets the nth column of a table. */
 
-dict_col_t*
+const dict_col_t*
 dict_table_get_nth_col_noninline(
 /*=============================*/
-				/* out: pointer to column object */
-	dict_table_t*	table,	/* in: table */
-	ulint		pos)	/* in: position of column */
+					/* out: pointer to column object */
+	const dict_table_t*	table,	/* in: table */
+	ulint			pos)	/* in: position of column */
 {
 	return(dict_table_get_nth_col(table, pos));
 }
@@ -353,7 +386,36 @@
 {
 	return(dict_table_get_index(table, name));
 }
-	
+
+/**************************************************************************
+Returns a column's name. */
+
+const char*
+dict_table_get_col_name(
+/*====================*/
+					/* out: column name. NOTE: not
+					guaranteed to stay valid if table is
+					modified in any way (columns added,
+					etc.). */
+	const dict_table_t*	table,	/* in: table */
+	ulint			col_nr)	/* in: column number */
+{
+	ulint		i;
+	const char*	s;
+
+	ut_ad(table);
+	ut_ad(col_nr < table->n_def);
+	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+	s = table->col_names;
+
+	for (i = 0; i < col_nr; i++) {
+		s += strlen(s) + 1;
+	}
+
+	return(s);
+}
+
 /************************************************************************
 Initializes the autoinc counter. It is not an error to initialize an already
 initialized counter. */
@@ -393,7 +455,7 @@
 		value = table->autoinc;
 		table->autoinc = table->autoinc + 1;
 	}
-	
+
 	mutex_exit(&(table->autoinc_mutex));
 
 	return(value);
@@ -410,7 +472,7 @@
 	mutex_enter(&(table->autoinc_mutex));
 
 	table->autoinc = table->autoinc - 1;
-	
+
 	mutex_exit(&(table->autoinc_mutex));
 }
 
@@ -434,7 +496,7 @@
 	} else {
 		value = table->autoinc;
 	}
-	
+
 	mutex_exit(&(table->autoinc_mutex));
 
 	return(value);
@@ -479,7 +541,7 @@
 		if (value >= table->autoinc) {
 			table->autoinc = value + 1;
 		}
-	}	
+	}
 
 	mutex_exit(&(table->autoinc_mutex));
 }
@@ -496,11 +558,11 @@
 	dict_index_t*	index,	/* in: index */
 	ulint		n)	/* in: column number */
 {
-	dict_field_t*	field;
-	dict_col_t*	col;
-	ulint		pos;
-	ulint		n_fields;
-	
+	const dict_field_t*	field;
+	const dict_col_t*	col;
+	ulint			pos;
+	ulint			n_fields;
+
 	ut_ad(index);
 	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
@@ -508,11 +570,11 @@
 
 	if (index->type & DICT_CLUSTERED) {
 
-		return(col->clust_pos);
+		return(dict_col_get_clust_pos(col, index));
 	}
 
 	n_fields = dict_index_get_n_fields(index);
-	
+
 	for (pos = 0; pos < n_fields; pos++) {
 		field = dict_index_get_nth_field(index, pos);
 
@@ -536,11 +598,11 @@
 	dict_index_t*	index,	/* in: index */
 	ulint		n)	/* in: column number */
 {
-	dict_field_t*	field;
-	dict_col_t*	col;
-	ulint		pos;
-	ulint		n_fields;
-	
+	const dict_field_t*	field;
+	const dict_col_t*	col;
+	ulint			pos;
+	ulint			n_fields;
+
 	ut_ad(index);
 	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
@@ -552,7 +614,7 @@
 	col = dict_table_get_nth_col(index->table, n);
 
 	n_fields = dict_index_get_n_fields(index);
-	
+
 	for (pos = 0; pos < n_fields; pos++) {
 		field = dict_index_get_nth_field(index, pos);
 
@@ -585,14 +647,14 @@
 	dict_field_t*	field2;
 	ulint		n_fields;
 	ulint		pos;
-	
+
 	ut_ad(index);
 	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
 	field2 = dict_index_get_nth_field(index2, n);
 
 	n_fields = dict_index_get_n_fields(index);
-	
+
 	for (pos = 0; pos < n_fields; pos++) {
 		field = dict_index_get_nth_field(index, pos);
 
@@ -609,7 +671,7 @@
 }
 
 /**************************************************************************
-Returns a table object, based on table id, and memoryfixes it. */
+Returns a table object based on table id. */
 
 dict_table_t*
 dict_table_get_on_id(
@@ -619,9 +681,9 @@
 	trx_t*	trx)		/* in: transaction handle */
 {
 	dict_table_t*	table;
-	
+
 	if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0
-	   || trx->dict_operation_lock_mode == RW_X_LATCH) {
+	    || trx->dict_operation_lock_mode == RW_X_LATCH) {
 		/* It is a system table which will always exist in the table
 		cache: we avoid acquiring the dictionary mutex, because
 		if we are doing a rollback to handle an error in TABLE
@@ -631,13 +693,13 @@
 		ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 
-		return(dict_table_get_on_id_low(table_id, trx));
+		return(dict_table_get_on_id_low(table_id));
 	}
 
 	mutex_enter(&(dict_sys->mutex));
 
-	table = dict_table_get_on_id_low(table_id, trx);
-	
+	table = dict_table_get_on_id_low(table_id);
+
 	mutex_exit(&(dict_sys->mutex));
 
 	return(table);
@@ -655,7 +717,20 @@
 	ulint		n)	/* in: column number */
 {
 	return(dict_index_get_nth_col_pos(dict_table_get_first_index(table),
-								n));
+					  n));
+}
+
+/************************************************************************
+Check whether the table uses the compact page format. */
+
+ibool
+dict_table_is_comp_noninline(
+/*=========================*/
+					/* out: TRUE if table uses the
+					compact page format */
+	const dict_table_t*	table)	/* in: table */
+{
+	return(dict_table_is_comp(table));
 }
 
 /************************************************************************
@@ -670,12 +745,12 @@
 	dict_table_t*	table,	/* in: table */
 	ulint		n)	/* in: column number */
 {
-	dict_index_t*	index;
-	dict_field_t*	field;
-	dict_col_t*	col;
-	ulint		pos;
-	ulint		n_fields;
-	
+	dict_index_t*		index;
+	const dict_field_t*	field;
+	const dict_col_t*	col;
+	ulint			pos;
+	ulint			n_fields;
+
 	ut_ad(table);
 
 	col = dict_table_get_nth_col(table, n);
@@ -683,7 +758,7 @@
 	index = dict_table_get_first_index(table);
 
 	n_fields = dict_index_get_n_unique(index);
-	
+
 	for (pos = 0; pos < n_fields; pos++) {
 		field = dict_index_get_nth_field(index, pos);
 
@@ -705,35 +780,31 @@
 {
 	dict_sys = mem_alloc(sizeof(dict_sys_t));
 
-	mutex_create(&(dict_sys->mutex));
-	mutex_set_level(&(dict_sys->mutex), SYNC_DICT);
+	mutex_create(&dict_sys->mutex, SYNC_DICT);
 
-	dict_sys->table_hash = hash_create(buf_pool_get_max_size() /
-					(DICT_POOL_PER_TABLE_HASH *
-					UNIV_WORD_SIZE));
-	dict_sys->table_id_hash = hash_create(buf_pool_get_max_size() /
-					(DICT_POOL_PER_TABLE_HASH *
-					UNIV_WORD_SIZE));
-	dict_sys->col_hash = hash_create(buf_pool_get_max_size() /
-					(DICT_POOL_PER_COL_HASH *
-					UNIV_WORD_SIZE));
+	dict_sys->table_hash = hash_create(buf_pool_get_max_size()
+					   / (DICT_POOL_PER_TABLE_HASH
+					      * UNIV_WORD_SIZE));
+	dict_sys->table_id_hash = hash_create(buf_pool_get_max_size()
+					      / (DICT_POOL_PER_TABLE_HASH
+						 * UNIV_WORD_SIZE));
 	dict_sys->size = 0;
 
 	UT_LIST_INIT(dict_sys->table_LRU);
 
-	rw_lock_create(&dict_operation_lock);
-	rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION);
+	rw_lock_create(&dict_operation_lock, SYNC_DICT_OPERATION);
 
 	dict_foreign_err_file = os_file_create_tmpfile();
 	ut_a(dict_foreign_err_file);
-	mutex_create(&dict_foreign_err_mutex);
-	mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
+
+	mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
 }
 
 /**************************************************************************
-Returns a table object and memoryfixes it. NOTE! This is a high-level
-function to be used mainly from outside the 'dict' directory. Inside this
-directory dict_table_get_low is usually the appropriate function. */
+Returns a table object and optionally increment its MySQL open handle count.
+NOTE! This is a high-level function to be used mainly from outside the
+'dict' directory. Inside this directory dict_table_get_low is usually the
+appropriate function. */
 
 dict_table_t*
 dict_table_get(
@@ -741,59 +812,31 @@
 					/* out: table, NULL if
 					does not exist */
 	const char*	table_name,	/* in: table name */
-	trx_t*		trx)		/* in: transaction handle or NULL */
+	ibool		inc_mysql_count)
+     					/* in: whether to increment the open
+					handle count on the table */
 {
 	dict_table_t*	table;
 
-	UT_NOT_USED(trx);
-
 	mutex_enter(&(dict_sys->mutex));
-	
-	table = dict_table_get_low(table_name);
 
-	mutex_exit(&(dict_sys->mutex));
-
-	if (table != NULL) {
-	        if (!table->stat_initialized) {
-			dict_update_statistics(table);
-		}
-	}
-	
-	return(table);
-}
-
-/**************************************************************************
-Returns a table object and increments MySQL open handle count on the table. */
-
-dict_table_t*
-dict_table_get_and_increment_handle_count(
-/*======================================*/
-					/* out: table, NULL if
-					does not exist */
-	const char*	table_name,	/* in: table name */
-	trx_t*		trx)		/* in: transaction handle or NULL */
-{
-	dict_table_t*	table;
-
-	UT_NOT_USED(trx);
-
-	mutex_enter(&(dict_sys->mutex));
-	
 	table = dict_table_get_low(table_name);
 
-	if (table != NULL) {
-
-	        table->n_mysql_handles_opened++;
+	if (inc_mysql_count && table) {
+		table->n_mysql_handles_opened++;
 	}
 
 	mutex_exit(&(dict_sys->mutex));
 
 	if (table != NULL) {
-	        if (!table->stat_initialized && !table->ibd_file_missing) {
+		if (!table->stat_initialized) {
+			/* If table->ibd_file_missing == TRUE, this will
+			print an error message and return without doing
+			anything. */
 			dict_update_statistics(table);
 		}
 	}
-	
+
 	return(table);
 }
 
@@ -808,7 +851,8 @@
 	ulint	fold;
 	ulint	id_fold;
 	ulint	i;
-	
+	ulint	row_len;
+
 	ut_ad(table);
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -816,12 +860,12 @@
 	ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS);
 	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 	ut_ad(table->cached == FALSE);
-	
+
 	fold = ut_fold_string(table->name);
 	id_fold = ut_fold_dulint(table->id);
-	
+
 	table->cached = TRUE;
-	
+
 	/* NOTE: the system columns MUST be added in the following order
 	(so that they can be indexed by the numerical value of DATA_ROW_ID,
 	etc.) and as the last columns of the table memory object.
@@ -829,37 +873,56 @@
 	system columns. */
 
 	dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS,
-			DATA_ROW_ID | DATA_NOT_NULL, DATA_ROW_ID_LEN, 0);
+			       DATA_ROW_ID | DATA_NOT_NULL,
+			       DATA_ROW_ID_LEN);
 #if DATA_ROW_ID != 0
 #error "DATA_ROW_ID != 0"
 #endif
 	dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS,
-			DATA_TRX_ID | DATA_NOT_NULL, DATA_TRX_ID_LEN, 0);
+			       DATA_TRX_ID | DATA_NOT_NULL,
+			       DATA_TRX_ID_LEN);
 #if DATA_TRX_ID != 1
 #error "DATA_TRX_ID != 1"
 #endif
 	dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS,
-			DATA_ROLL_PTR | DATA_NOT_NULL, DATA_ROLL_PTR_LEN, 0);
+			       DATA_ROLL_PTR | DATA_NOT_NULL,
+			       DATA_ROLL_PTR_LEN);
 #if DATA_ROLL_PTR != 2
 #error "DATA_ROLL_PTR != 2"
 #endif
-	dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS,
-			DATA_MIX_ID | DATA_NOT_NULL, DATA_MIX_ID_LEN, 0);
-#if DATA_MIX_ID != 3
-#error "DATA_MIX_ID != 3"
-#endif
 
 	/* This check reminds that if a new system column is added to
-	the program, it should be dealt with here */ 
-#if DATA_N_SYS_COLS != 4
-#error "DATA_N_SYS_COLS != 4"
+	the program, it should be dealt with here */
+#if DATA_N_SYS_COLS != 3
+#error "DATA_N_SYS_COLS != 3"
 #endif
 
+	/* The lower limit for what we consider a "big" row */
+#define BIG_ROW_SIZE 1024
+
+	row_len = 0;
+	for (i = 0; i < table->n_def; i++) {
+		ulint	col_len = dict_col_get_max_size(
+			dict_table_get_nth_col(table, i));
+
+		row_len += col_len;
+
+		/* If we have a single unbounded field, or several gigantic
+		fields, mark the maximum row size as BIG_ROW_SIZE. */
+		if (row_len >= BIG_ROW_SIZE || col_len >= BIG_ROW_SIZE) {
+			row_len = BIG_ROW_SIZE;
+
+			break;
+		}
+	}
+
+	table->big_rows = row_len >= BIG_ROW_SIZE;
+
 	/* Look for a table with the same name: error if such exists */
 	{
 		dict_table_t*	table2;
 		HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2,
-				(ut_strcmp(table2->name, table->name) == 0));
+			    (ut_strcmp(table2->name, table->name) == 0));
 		ut_a(table2 == NULL);
 	}
 
@@ -867,36 +930,21 @@
 	{
 		dict_table_t*	table2;
 		HASH_SEARCH(id_hash, dict_sys->table_id_hash, id_fold, table2,
-				(ut_dulint_cmp(table2->id, table->id) == 0));
+			    (ut_dulint_cmp(table2->id, table->id) == 0));
 		ut_a(table2 == NULL);
 	}
 
-	if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
-
-		table->mix_id_len = mach_dulint_get_compressed_size(
-								table->mix_id);
-		mach_dulint_write_compressed(table->mix_id_buf, table->mix_id);
-	}
-
-	/* Add the columns to the column hash table */
-	for (i = 0; i < table->n_cols; i++) {
-		dict_col_add_to_cache(table, dict_table_get_nth_col(table, i));
-	}
-
 	/* Add table to hash table of tables */
 	HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
-								   table);
+		    table);
 
 	/* Add table to hash table of tables based on table id */
 	HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, id_fold,
-								   table);
+		    table);
 	/* Add table to LRU list of tables */
 	UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
 
-	/* If the dictionary cache grows too big, trim the table LRU list */
-
 	dict_sys->size += mem_heap_get_size(table->heap);
-	/* dict_table_LRU_trim(); */
 }
 
 /**************************************************************************
@@ -912,14 +960,14 @@
 {
 	dict_table_t*	table;
 	dict_index_t*	index;
-	
+
 	table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
 
 	while (table) {
 		index = dict_table_get_first_index(table);
 
 		while (index) {
-			if (0 == ut_dulint_cmp(id, index->tree->id)) {
+			if (0 == ut_dulint_cmp(id, index->id)) {
 				/* Found */
 
 				return(index);
@@ -953,26 +1001,26 @@
 	ulint		old_size;
 	char*		old_name;
 	ibool		success;
-	ulint		i;
-	
+
 	ut_ad(table);
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 
 	old_size = mem_heap_get_size(table->heap);
-	
+
 	fold = ut_fold_string(new_name);
-	
+
 	/* Look for a table with the same name: error if such exists */
 	{
 		dict_table_t*	table2;
 		HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2,
-				(ut_strcmp(table2->name, new_name) == 0));
+			    (ut_strcmp(table2->name, new_name) == 0));
 		if (table2) {
 			fprintf(stderr,
-"InnoDB: Error: dictionary cache already contains a table of name %s\n",
-	 							     new_name);
+				"InnoDB: Error: dictionary cache"
+				" already contains a table of name %s\n",
+				new_name);
 			return(FALSE);
 		}
 	}
@@ -983,12 +1031,14 @@
 	if (table->space != 0) {
 		if (table->dir_path_of_temp_table != NULL) {
 			fprintf(stderr,
-"InnoDB: Error: trying to rename a table %s (%s) created with CREATE\n"
-"InnoDB: TEMPORARY TABLE\n", table->name, table->dir_path_of_temp_table);
+				"InnoDB: Error: trying to rename a table"
+				" %s (%s) created with CREATE\n"
+				"InnoDB: TEMPORARY TABLE\n",
+				table->name, table->dir_path_of_temp_table);
 			success = FALSE;
 		} else {
-			success = fil_rename_tablespace(table->name,
-						table->space, new_name);
+			success = fil_rename_tablespace(
+				table->name, table->space, new_name);
 		}
 
 		if (!success) {
@@ -997,23 +1047,15 @@
 		}
 	}
 
-	/* Reposition the columns in the column hash table; they are hashed
-	according to the pair (table name, column name) */
-
-	for (i = 0; i < table->n_cols; i++) {
-		dict_col_reposition_in_cache(table,
-				dict_table_get_nth_col(table, i), new_name);
-	}
-
 	/* Remove table from the hash tables of tables */
 	HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
-					ut_fold_string(table->name), table);
+		    ut_fold_string(table->name), table);
 	old_name = mem_heap_strdup(table->heap, table->name);
 	table->name = mem_heap_strdup(table->heap, new_name);
 
 	/* Add table to hash table of tables */
 	HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
-								   table);
+		    table);
 	dict_sys->size += (mem_heap_get_size(table->heap) - old_size);
 
 	/* Update the table_name field in indexes */
@@ -1021,7 +1063,7 @@
 
 	while (index != NULL) {
 		index->table_name = table->name;
-		
+
 		index = dict_table_get_next_index(index);
 	}
 
@@ -1033,7 +1075,7 @@
 		constraints from the dictionary cache here. The foreign key
 		constraints will be inherited to the new table from the
 		system tables through a call of dict_load_foreigns. */
-	
+
 		/* Remove the foreign constraints from the cache */
 		foreign = UT_LIST_GET_LAST(table->foreign_list);
 
@@ -1049,14 +1091,14 @@
 		while (foreign != NULL) {
 			foreign->referenced_table = NULL;
 			foreign->referenced_index = NULL;
-		
+
 			foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
 		}
 
 		/* Make the list of referencing constraints empty */
 
 		UT_LIST_INIT(table->referenced_list);
-		
+
 		return(TRUE);
 	}
 
@@ -1067,14 +1109,14 @@
 	foreign = UT_LIST_GET_FIRST(table->foreign_list);
 
 	while (foreign != NULL) {
-		if (ut_strlen(foreign->foreign_table_name) <
-						ut_strlen(table->name)) {
+		if (ut_strlen(foreign->foreign_table_name)
+		    < ut_strlen(table->name)) {
 			/* Allocate a longer name buffer;
 			TODO: store buf len to save memory */
 
-			foreign->foreign_table_name = mem_heap_alloc(
-					foreign->heap,
-					ut_strlen(table->name) + 1);
+			foreign->foreign_table_name
+				= mem_heap_alloc(foreign->heap,
+						 ut_strlen(table->name) + 1);
 		}
 
 		strcpy(foreign->foreign_table_name, table->name);
@@ -1088,47 +1130,46 @@
 			old_id = mem_strdup(foreign->id);
 
 			if (ut_strlen(foreign->id) > ut_strlen(old_name)
-						+ ((sizeof dict_ibfk) - 1)
-			    && 0 == ut_memcmp(foreign->id, old_name,
-						ut_strlen(old_name))
-			    && 0 == ut_memcmp(
-					foreign->id + ut_strlen(old_name),
-					dict_ibfk, (sizeof dict_ibfk) - 1)) {
+			    + ((sizeof dict_ibfk) - 1)
+			    && !memcmp(foreign->id, old_name,
+				       ut_strlen(old_name))
+			    && !memcmp(foreign->id + ut_strlen(old_name),
+				       dict_ibfk, (sizeof dict_ibfk) - 1)) {
 
 				/* This is a generated >= 4.0.18 format id */
 
-				if (ut_strlen(table->name) > ut_strlen(old_name)) {
+				if (strlen(table->name) > strlen(old_name)) {
 					foreign->id = mem_heap_alloc(
-					     foreign->heap,
-						ut_strlen(table->name)
-						+ ut_strlen(old_id) + 1);
+						foreign->heap,
+						strlen(table->name)
+						+ strlen(old_id) + 1);
 				}
-				
+
 				/* Replace the prefix 'databasename/tablename'
 				with the new names */
 				strcpy(foreign->id, table->name);
 				strcat(foreign->id,
-						old_id + ut_strlen(old_name));
+				       old_id + ut_strlen(old_name));
 			} else {
 				/* This is a >= 4.0.18 format id where the user
 				gave the id name */
 				db_len = dict_get_db_name_len(table->name) + 1;
 
 				if (dict_get_db_name_len(table->name)
-			    	    > dict_get_db_name_len(foreign->id)) {
+				    > dict_get_db_name_len(foreign->id)) {
 
 					foreign->id = mem_heap_alloc(
-					     foreign->heap,
-				 	     db_len + ut_strlen(old_id) + 1);
+						foreign->heap,
+						db_len + strlen(old_id) + 1);
 				}
 
 				/* Replace the database prefix in id with the
 				one from table->name */
-			
+
 				ut_memcpy(foreign->id, table->name, db_len);
 
 				strcpy(foreign->id + db_len,
-						dict_remove_db_name(old_id));
+				       dict_remove_db_name(old_id));
 			}
 
 			mem_free(old_id);
@@ -1140,14 +1181,13 @@
 	foreign = UT_LIST_GET_FIRST(table->referenced_list);
 
 	while (foreign != NULL) {
-		if (ut_strlen(foreign->referenced_table_name) <
-						ut_strlen(table->name)) {
+		if (ut_strlen(foreign->referenced_table_name)
+		    < ut_strlen(table->name)) {
 			/* Allocate a longer name buffer;
 			TODO: store buf len to save memory */
 
 			foreign->referenced_table_name = mem_heap_alloc(
-					foreign->heap,
-					ut_strlen(table->name) + 1);
+				foreign->heap, strlen(table->name) + 1);
 		}
 
 		strcpy(foreign->referenced_table_name, table->name);
@@ -1177,12 +1217,12 @@
 	/* Remove the table from the hash table of id's */
 
 	HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash,
-					ut_fold_dulint(table->id), table);
+		    ut_fold_dulint(table->id), table);
 	table->id = new_id;
 
 	/* Add the table back to the hash table */
 	HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash,
-					ut_fold_dulint(table->id), table);
+		    ut_fold_dulint(table->id), table);
 }
 
 /**************************************************************************
@@ -1196,8 +1236,7 @@
 	dict_foreign_t*	foreign;
 	dict_index_t*	index;
 	ulint		size;
-	ulint		i;
-	
+
 	ut_ad(table);
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1225,7 +1264,7 @@
 	while (foreign != NULL) {
 		foreign->referenced_table = NULL;
 		foreign->referenced_index = NULL;
-		
+
 		foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
 	}
 
@@ -1237,17 +1276,11 @@
 		index = UT_LIST_GET_LAST(table->indexes);
 	}
 
-	/* Remove the columns of the table from the cache */
-	for (i = 0; i < table->n_cols; i++) {
-		dict_col_remove_from_cache(table,
-					   dict_table_get_nth_col(table, i));
-	}
-
 	/* Remove table from the hash tables of tables */
 	HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
-					ut_fold_string(table->name), table);
+		    ut_fold_string(table->name), table);
 	HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash,
-					ut_fold_dulint(table->id), table);
+		    ut_fold_dulint(table->id), table);
 
 	/* Remove table from LRU list of tables */
 	UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
@@ -1261,122 +1294,16 @@
 	dict_mem_table_free(table);
 }
 
-/**************************************************************************
-Frees tables from the end of table_LRU if the dictionary cache occupies
-too much space. Currently not used! */
-
-void
-dict_table_LRU_trim(void)
-/*=====================*/
-{
-	dict_table_t*	table;
-	dict_table_t*	prev_table;
-
-	ut_error;
-
-#ifdef UNIV_SYNC_DEBUG
-	ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
-
-	table = UT_LIST_GET_LAST(dict_sys->table_LRU);
-
-	while (table && (dict_sys->size >
-			 buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) {
-
-		prev_table = UT_LIST_GET_PREV(table_LRU, table);
-
-		if (table->mem_fix == 0) {
-			dict_table_remove_from_cache(table);
-		}
-
-		table = prev_table;
-	}
-}
-
-/**************************************************************************
-Adds a column to the data dictionary hash table. */
-static
-void
-dict_col_add_to_cache(
-/*==================*/
-	dict_table_t*	table,	/* in: table */
-	dict_col_t*	col)	/* in: column */
-{
-	ulint	fold;
-
-	ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
-	ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
-	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-	
-	fold = ut_fold_ulint_pair(ut_fold_string(table->name),
-				  ut_fold_string(col->name));
-
-	/* Look for a column with same table name and column name: error */
-	{
-		dict_col_t*	col2;
-		HASH_SEARCH(hash, dict_sys->col_hash, fold, col2,
-			(ut_strcmp(col->name, col2->name) == 0)
-			&& (ut_strcmp((col2->table)->name, table->name)
-							== 0));  
-		ut_a(col2 == NULL);
-	}
-
-	HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
-}
-
-/**************************************************************************
-Removes a column from the data dictionary hash table. */
-static
-void
-dict_col_remove_from_cache(
-/*=======================*/
-	dict_table_t*	table,	/* in: table */
-	dict_col_t*	col)	/* in: column */
-{
-	ulint		fold;
-
-	ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
-	ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
-	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-	
-	fold = ut_fold_ulint_pair(ut_fold_string(table->name),
-				  ut_fold_string(col->name));
-
-	HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col);
-}
+/*************************************************************************
+Gets the column position in the clustered index. */
 
-/**************************************************************************
-Repositions a column in the data dictionary hash table when the table name
-changes. */
-static
-void
-dict_col_reposition_in_cache(
-/*=========================*/
-	dict_table_t*	table,		/* in: table */
-	dict_col_t*	col,		/* in: column */
-	const char*	new_name)	/* in: new table name */
+ulint
+dict_col_get_clust_pos_noninline(
+/*=============================*/
+	const dict_col_t*	col,		/* in: table column */
+	const dict_index_t*	clust_index)	/* in: clustered index */
 {
-	ulint		fold;
-
-	ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
-	ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
-	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-	
-	fold = ut_fold_ulint_pair(ut_fold_string(table->name),
-				  ut_fold_string(col->name));
-
-	HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col);
-
-	fold = ut_fold_ulint_pair(ut_fold_string(new_name),
-				  ut_fold_string(col->name));
-				  
-	HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
+	return(dict_col_get_clust_pos(col, clust_index));
 }
 
 /********************************************************************
@@ -1391,12 +1318,12 @@
 {
 	/* This check reminds that if a new system column is added to
 	the program, it should be dealt with here. */
-#if DATA_N_SYS_COLS != 4
-#error "DATA_N_SYS_COLS != 4"
+#if DATA_N_SYS_COLS != 3
+#error "DATA_N_SYS_COLS != 3"
 #endif
 
 	static const char*	reserved_names[] = {
-		"DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
+		"DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR"
 	};
 
 	ulint			i;
@@ -1414,32 +1341,28 @@
 /**************************************************************************
 Adds an index to the dictionary cache. */
 
-ibool
+void
 dict_index_add_to_cache(
 /*====================*/
-				/* out: TRUE if success */
 	dict_table_t*	table,	/* in: table on which the index is */
 	dict_index_t*	index,	/* in, own: index; NOTE! The index memory
 				object is freed in this function! */
 	ulint		page_no)/* in: root page number of the index */
 {
 	dict_index_t*	new_index;
-	dict_tree_t*	tree;
-	dict_table_t*	cluster;
-	dict_field_t*	field;
 	ulint		n_ord;
-	ibool		success;
 	ulint		i;
-	
+
 	ut_ad(index);
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 	ut_ad(index->n_def == index->n_fields);
 	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
-	
+
 	ut_ad(mem_heap_validate(index->heap));
 
+#ifdef UNIV_DEBUG
 	{
 		dict_index_t*	index2;
 		index2 = UT_LIST_GET_FIRST(table->indexes);
@@ -1449,19 +1372,14 @@
 
 			index2 = UT_LIST_GET_NEXT(indexes, index2);
 		}
-
-		ut_a(UT_LIST_GET_LEN(table->indexes) == 0
-	      			|| (index->type & DICT_CLUSTERED) == 0);
 	}
+#endif /* UNIV_DEBUG */
 
-	success = dict_index_find_cols(table, index);
+	ut_a(!(index->type & DICT_CLUSTERED)
+	     || UT_LIST_GET_LEN(table->indexes) == 0);
 
-	if (!success) {
-		dict_mem_index_free(index);
+	dict_index_find_cols(table, index);
 
-		return(FALSE);
-	}
-	
 	/* Build the cache internal representation of the index,
 	containing also the added system fields */
 
@@ -1472,15 +1390,15 @@
 	}
 
 	new_index->search_info = btr_search_info_create(new_index->heap);
-	
+
 	/* Set the n_fields value in new_index to the actual defined
 	number of fields in the cache internal representation */
 
 	new_index->n_fields = new_index->n_def;
-	
+
 	/* Add the new index as the last index for the table */
 
-	UT_LIST_ADD_LAST(indexes, table->indexes, new_index);	
+	UT_LIST_ADD_LAST(indexes, table->indexes, new_index);
 	new_index->table = table;
 	new_index->table_name = table->name;
 
@@ -1494,33 +1412,18 @@
 
 	for (i = 0; i < n_ord; i++) {
 
-		field = dict_index_get_nth_field(new_index, i);
-
-		dict_field_get_col(field)->ord_part++;
+		dict_index_get_nth_field(new_index, i)->col->ord_part = 1;
 	}
 
-	if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
-		/* The index tree is found from the cluster object */
-	    
-		cluster = dict_table_get_low(table->cluster_name);
-
-		tree = dict_index_get_tree(
-					UT_LIST_GET_FIRST(cluster->indexes));
-		new_index->tree = tree;
-	} else {
-		/* Create an index tree memory object for the index */
-		tree = dict_tree_create(new_index, page_no);
-		ut_ad(tree);
-
-		new_index->tree = tree;
-	}
+	new_index->page = page_no;
+	rw_lock_create(&new_index->lock, SYNC_INDEX_TREE);
 
 	if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
 
-		new_index->stat_n_diff_key_vals =
-			mem_heap_alloc(new_index->heap,
-				(1 + dict_index_get_n_unique(new_index))
-				* sizeof(ib_longlong));
+		new_index->stat_n_diff_key_vals = mem_heap_alloc(
+			new_index->heap,
+			(1 + dict_index_get_n_unique(new_index))
+			* sizeof(ib_longlong));
 		/* Give some sensible values to stat_n_... in case we do
 		not calculate statistics quickly enough */
 
@@ -1529,18 +1432,10 @@
 			new_index->stat_n_diff_key_vals[i] = 100;
 		}
 	}
-	
-	/* Add the index to the list of indexes stored in the tree */
-	UT_LIST_ADD_LAST(tree_indexes, tree->tree_indexes, new_index); 
-	
-	/* If the dictionary cache grows too big, trim the table LRU list */
 
 	dict_sys->size += mem_heap_get_size(new_index->heap);
-	/* dict_table_LRU_trim(); */
 
 	dict_mem_index_free(index);
-
-	return(TRUE);
 }
 
 /**************************************************************************
@@ -1552,9 +1447,7 @@
 	dict_table_t*	table,	/* in: table */
 	dict_index_t*	index)	/* in, own: index */
 {
-	dict_field_t*	field;
 	ulint		size;
-	ulint		i;
 
 	ut_ad(table && index);
 	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -1563,17 +1456,7 @@
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 
-	ut_ad(UT_LIST_GET_LEN((index->tree)->tree_indexes) == 1);
-	dict_tree_free(index->tree);
-
-	/* Decrement the ord_part counts in columns which are ordering */
-	for (i = 0; i < dict_index_get_n_unique(index); i++) {
-
-		field = dict_index_get_nth_field(index, i);
-
-		ut_ad(dict_field_get_col(field)->ord_part > 0);
-		(dict_field_get_col(field)->ord_part)--;
-	}
+	rw_lock_free(&index->lock);
 
 	/* Remove the index from the list of indexes of the table */
 	UT_LIST_REMOVE(indexes, table->indexes, index);
@@ -1588,21 +1471,17 @@
 }
 
 /***********************************************************************
-Tries to find column names for the index in the column hash table and
-sets the col field of the index. */
+Tries to find column names for the index and sets the col field of the
+index. */
 static
-ibool
+void
 dict_index_find_cols(
 /*=================*/
-				/* out: TRUE if success */
 	dict_table_t*	table,	/* in: table */
-	dict_index_t*	index)	/* in: index */	
+	dict_index_t*	index)	/* in: index */
 {
-	dict_col_t*	col;
-	dict_field_t*	field;
-	ulint		fold;
 	ulint		i;
-	
+
 	ut_ad(table && index);
 	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 #ifdef UNIV_SYNC_DEBUG
@@ -1610,26 +1489,27 @@
 #endif /* UNIV_SYNC_DEBUG */
 
 	for (i = 0; i < index->n_fields; i++) {
-		field = dict_index_get_nth_field(index, i);
+		ulint		j;
+		dict_field_t*	field = dict_index_get_nth_field(index, i);
 
-		fold = ut_fold_ulint_pair(ut_fold_string(table->name),
-				  	       ut_fold_string(field->name));
-			
-		HASH_SEARCH(hash, dict_sys->col_hash, fold, col,
-				(ut_strcmp(col->name, field->name) == 0)
-				&& (ut_strcmp((col->table)->name, table->name)
-								== 0));  
-		if (col == NULL) {
+		for (j = 0; j < table->n_cols; j++) {
+			if (!strcmp(dict_table_get_col_name(table, j),
+				    field->name)) {
+				field->col = (dict_col_t*)
+					dict_table_get_nth_col(table, j);
 
- 			return(FALSE);
-		} else {
-			field->col = col;
+				goto found;
+			}
 		}
-	}
 
-	return(TRUE);
+		/* It is an error not to find a matching column. */
+		ut_error;
+
+	found:
+		;
+	}
 }
-	
+
 /***********************************************************************
 Adds a column to index. */
 
@@ -1637,18 +1517,21 @@
 dict_index_add_col(
 /*===============*/
 	dict_index_t*	index,		/* in: index */
+	dict_table_t*	table,		/* in: table */
 	dict_col_t*	col,		/* in: column */
-	ulint		order,		/* in: order criterion */
 	ulint		prefix_len)	/* in: column prefix length */
 {
 	dict_field_t*	field;
+	const char*	col_name;
 
-	dict_mem_index_add_field(index, col->name, order, prefix_len);
+	col_name = dict_table_get_col_name(table, dict_col_get_no(col));
+
+	dict_mem_index_add_field(index, col_name, prefix_len);
 
 	field = dict_index_get_nth_field(index, index->n_def - 1);
 
 	field->col = col;
-	field->fixed_len = dtype_get_fixed_size(&col->type);
+	field->fixed_len = dict_col_get_fixed_size(col);
 
 	if (prefix_len && field->fixed_len > prefix_len) {
 		field->fixed_len = prefix_len;
@@ -1662,20 +1545,9 @@
 		field->fixed_len = 0;
 	}
 
-	if (!(dtype_get_prtype(&col->type) & DATA_NOT_NULL)) {
+	if (!(col->prtype & DATA_NOT_NULL)) {
 		index->n_nullable++;
 	}
-
-	if (index->n_def > 1) {
-		const dict_field_t*	field2 =
-			dict_index_get_nth_field(index, index->n_def - 2);
-		field->fixed_offs = (!field2->fixed_len ||
-					field2->fixed_offs == ULINT_UNDEFINED)
-				? ULINT_UNDEFINED
-				: field2->fixed_len + field2->fixed_offs;
-	} else {
-		field->fixed_offs = 0;
-	}
 }
 
 /***********************************************************************
@@ -1686,19 +1558,20 @@
 /*============*/
 	dict_index_t*	index1,	/* in: index to copy to */
 	dict_index_t*	index2,	/* in: index to copy from */
+	dict_table_t*	table,	/* in: table */
 	ulint		start,	/* in: first position to copy */
 	ulint		end)	/* in: last position to copy */
 {
 	dict_field_t*	field;
 	ulint		i;
-	
+
 	/* Copy fields contained in index2 */
 
 	for (i = start; i < end; i++) {
 
 		field = dict_index_get_nth_field(index2, i);
-		dict_index_add_col(index1, field->col, field->order,
-						      field->prefix_len);
+		dict_index_add_col(index1, table, field->col,
+				   field->prefix_len);
 	}
 }
 
@@ -1712,8 +1585,6 @@
 	dict_index_t*	index,		/* in: index */
 	ulint		n_fields)	/* in: number of field types to copy */
 {
-	dtype_t*	dfield_type;
-	dtype_t*	type;
 	ulint		i;
 
 	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
@@ -1723,10 +1594,15 @@
 	}
 
 	for (i = 0; i < n_fields; i++) {
+		dict_field_t*	ifield;
+		dtype_t*	dfield_type;
+
+		ifield = dict_index_get_nth_field(index, i);
 		dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
-		type = dict_col_get_type(dict_field_get_col(
-				dict_index_get_nth_field(index, i)));
-		*dfield_type = *type;
+		dict_col_copy_type(dict_field_get_col(ifield), dfield_type);
+		if (UNIV_UNLIKELY(ifield->prefix_len)) {
+			dfield_type->len = ifield->prefix_len;
+		}
 	}
 }
 
@@ -1740,17 +1616,13 @@
 	dict_table_t*	table)	/* in: index */
 {
 	dtype_t*	dfield_type;
-	dtype_t*	type;
 	ulint		i;
 
-	ut_ad(!(table->type & DICT_UNIVERSAL));
-
 	for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
 
 		dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
-		type = dict_col_get_type(dict_table_get_nth_col(table, i));
-
-		*dfield_type = *type;
+		dict_col_copy_type(dict_table_get_nth_col(table, i),
+				   dfield_type);
 	}
 }
 
@@ -1765,14 +1637,14 @@
 				of the clustered index */
 	dict_table_t*	table,	/* in: table */
 	dict_index_t*	index)	/* in: user representation of a clustered
-				index */	
+				index */
 {
 	dict_index_t*	new_index;
 	dict_field_t*	field;
-	dict_col_t*	col;
 	ulint		fixed_size;
 	ulint		trx_id_pos;
 	ulint		i;
+	ibool*		indexed;
 
 	ut_ad(table && index);
 	ut_ad(index->type & DICT_CLUSTERED);
@@ -1783,40 +1655,25 @@
 
 	/* Create a new index object with certainly enough fields */
 	new_index = dict_mem_index_create(table->name,
-				     index->name,
-				     table->space,
-				     index->type,
-				     index->n_fields + table->n_cols);
+					  index->name, table->space,
+					  index->type,
+					  index->n_fields + table->n_cols);
 
 	/* Copy other relevant data from the old index struct to the new
 	struct: it inherits the values */
 
 	new_index->n_user_defined_cols = index->n_fields;
-	
+
 	new_index->id = index->id;
 
-	if (table->type != DICT_TABLE_ORDINARY) {
-		/* The index is mixed: copy common key prefix fields */
-		
-		dict_index_copy(new_index, index, 0, table->mix_len);
-
-		/* Add the mix id column */
-		dict_index_add_col(new_index,
-			  dict_table_get_sys_col(table, DATA_MIX_ID), 0, 0);
-
-		/* Copy the rest of fields */
-		dict_index_copy(new_index, index, table->mix_len,
-							index->n_fields);
-	} else {
-		/* Copy the fields of index */
-		dict_index_copy(new_index, index, 0, index->n_fields);
-	}
+	/* Copy the fields of index */
+	dict_index_copy(new_index, index, table, 0, index->n_fields);
 
 	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
 		/* No fixed number of fields determines an entry uniquely */
 
-		new_index->n_uniq = ULINT_MAX;
-		
+		new_index->n_uniq = REC_MAX_N_FIELDS;
+
 	} else if (index->type & DICT_UNIQUE) {
 		/* Only the fields defined so far are needed to identify
 		the index entry uniquely */
@@ -1834,26 +1691,37 @@
 
 		trx_id_pos = new_index->n_def;
 
-		ut_ad(DATA_ROW_ID == 0);
-		ut_ad(DATA_TRX_ID == 1);
-		ut_ad(DATA_ROLL_PTR == 2);
+#if DATA_ROW_ID != 0
+# error "DATA_ROW_ID != 0"
+#endif
+#if DATA_TRX_ID != 1
+# error "DATA_TRX_ID != 1"
+#endif
+#if DATA_ROLL_PTR != 2
+# error "DATA_ROLL_PTR != 2"
+#endif
 
 		if (!(index->type & DICT_UNIQUE)) {
-			dict_index_add_col(new_index,
-			   dict_table_get_sys_col(table, DATA_ROW_ID), 0, 0);
+			dict_index_add_col(new_index, table, (dict_col_t*)
+					   dict_table_get_sys_col(
+						   table, DATA_ROW_ID),
+					   0);
 			trx_id_pos++;
 		}
 
-		dict_index_add_col(new_index,
-			   dict_table_get_sys_col(table, DATA_TRX_ID), 0, 0);
-	
-		dict_index_add_col(new_index,
-			   dict_table_get_sys_col(table, DATA_ROLL_PTR), 0, 0);
+		dict_index_add_col(new_index, table, (dict_col_t*)
+				   dict_table_get_sys_col(table, DATA_TRX_ID),
+				   0);
+
+		dict_index_add_col(new_index, table, (dict_col_t*)
+				   dict_table_get_sys_col(table,
+							  DATA_ROLL_PTR),
+				   0);
 
 		for (i = 0; i < trx_id_pos; i++) {
 
-			fixed_size = dtype_get_fixed_size(
-				dict_index_get_nth_type(new_index, i));
+			fixed_size = dict_col_get_fixed_size(
+				dict_index_get_nth_col(new_index, i));
 
 			if (fixed_size == 0) {
 				new_index->trx_id_offset = 0;
@@ -1873,12 +1741,9 @@
 
 	}
 
-	/* Set auxiliary variables in table columns as undefined */
-	for (i = 0; i < table->n_cols; i++) {
-
-		col = dict_table_get_nth_col(table, i);
-		col->aux = ULINT_UNDEFINED;
-	}
+	/* Remember the table columns already contained in new_index */
+	indexed = mem_alloc(table->n_cols * sizeof *indexed);
+	memset(indexed, 0, table->n_cols * sizeof *indexed);
 
 	/* Mark with 0 the table columns already contained in new_index */
 	for (i = 0; i < new_index->n_def; i++) {
@@ -1890,41 +1755,32 @@
 
 		if (field->prefix_len == 0) {
 
-		        field->col->aux = 0;
+			indexed[field->col->ind] = TRUE;
 		}
 	}
-	
+
 	/* Add to new_index non-system columns of table not yet included
 	there */
-	for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) {
+	for (i = 0; i + DATA_N_SYS_COLS < (ulint) table->n_cols; i++) {
 
-		col = dict_table_get_nth_col(table, i);
-		ut_ad(col->type.mtype != DATA_SYS);
+		dict_col_t*	col = (dict_col_t*)
+			dict_table_get_nth_col(table, i);
+		ut_ad(col->mtype != DATA_SYS);
 
-		if (col->aux == ULINT_UNDEFINED) {
-			dict_index_add_col(new_index, col, 0, 0);
+		if (!indexed[col->ind]) {
+			dict_index_add_col(new_index, table, col, 0);
 		}
 	}
 
-	ut_ad((index->type & DICT_IBUF)
-				|| (UT_LIST_GET_LEN(table->indexes) == 0));
-
-	/* Store to the column structs the position of the table columns
-	in the clustered index */
-
-	for (i = 0; i < new_index->n_def; i++) {
-		field = dict_index_get_nth_field(new_index, i);
+	mem_free(indexed);
 
-		if (field->prefix_len == 0) {
+	ut_ad((index->type & DICT_IBUF)
+	      || (UT_LIST_GET_LEN(table->indexes) == 0));
 
-		        field->col->clust_pos = i;
-		}
-	}
-	
 	new_index->cached = TRUE;
 
 	return(new_index);
-}	
+}
 
 /***********************************************************************
 Builds the internal dictionary cache representation for a non-clustered
@@ -1937,12 +1793,13 @@
 				of the non-clustered index */
 	dict_table_t*	table,	/* in: table */
 	dict_index_t*	index)	/* in: user representation of a non-clustered
-				index */	
+				index */
 {
 	dict_field_t*	field;
 	dict_index_t*	new_index;
 	dict_index_t*	clust_index;
 	ulint		i;
+	ibool*		indexed;
 
 	ut_ad(table && index);
 	ut_ad(0 == (index->type & DICT_CLUSTERED));
@@ -1953,36 +1810,29 @@
 
 	/* The clustered index should be the first in the list of indexes */
 	clust_index = UT_LIST_GET_FIRST(table->indexes);
-	
+
 	ut_ad(clust_index);
 	ut_ad(clust_index->type & DICT_CLUSTERED);
 	ut_ad(!(clust_index->type & DICT_UNIVERSAL));
 
 	/* Create a new index */
-	new_index = dict_mem_index_create(table->name,
-				     index->name,
-				     index->space,
-				     index->type,
-				     index->n_fields
-				     + 1 + clust_index->n_uniq);
+	new_index = dict_mem_index_create(
+		table->name, index->name, index->space, index->type,
+		index->n_fields + 1 + clust_index->n_uniq);
 
 	/* Copy other relevant data from the old index
 	struct to the new struct: it inherits the values */
 
 	new_index->n_user_defined_cols = index->n_fields;
-	
+
 	new_index->id = index->id;
 
 	/* Copy fields from index to new_index */
-	dict_index_copy(new_index, index, 0, index->n_fields);
+	dict_index_copy(new_index, index, table, 0, index->n_fields);
 
-	/* Set the auxiliary variables in the clust_index unique columns
-	as undefined */
-	for (i = 0; i < clust_index->n_uniq; i++) {
-
-		field = dict_index_get_nth_field(clust_index, i);
-		field->col->aux = ULINT_UNDEFINED;
-	}
+	/* Remember the table columns already contained in new_index */
+	indexed = mem_alloc(table->n_cols * sizeof *indexed);
+	memset(indexed, 0, table->n_cols * sizeof *indexed);
 
 	/* Mark with 0 table columns already contained in new_index */
 	for (i = 0; i < new_index->n_def; i++) {
@@ -1994,7 +1844,7 @@
 
 		if (field->prefix_len == 0) {
 
-		        field->col->aux = 0;
+			indexed[field->col->ind] = TRUE;
 		}
 	}
 
@@ -2005,12 +1855,14 @@
 
 		field = dict_index_get_nth_field(clust_index, i);
 
-		if (field->col->aux == ULINT_UNDEFINED) {
-			dict_index_add_col(new_index, field->col, 0,
-						      field->prefix_len);
+		if (!indexed[field->col->ind]) {
+			dict_index_add_col(new_index, table, field->col,
+					   field->prefix_len);
 		}
 	}
 
+	mem_free(indexed);
+
 	if ((index->type) & DICT_UNIQUE) {
 		new_index->n_uniq = index->n_fields;
 	} else {
@@ -2025,7 +1877,7 @@
 	new_index->cached = TRUE;
 
 	return(new_index);
-}	
+}
 
 /*====================== FOREIGN KEY PROCESSING ========================*/
 
@@ -2040,7 +1892,7 @@
 	dict_table_t*	table)	/* in: InnoDB table */
 {
 	if (UT_LIST_GET_LEN(table->referenced_list) > 0) {
-		
+
 		return(TRUE);
 	}
 
@@ -2070,15 +1922,17 @@
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 	ut_a(foreign);
-	
+
 	if (foreign->referenced_table) {
 		UT_LIST_REMOVE(referenced_list,
-			foreign->referenced_table->referenced_list, foreign);
+			       foreign->referenced_table->referenced_list,
+			       foreign);
 	}
 
 	if (foreign->foreign_table) {
 		UT_LIST_REMOVE(foreign_list,
-			foreign->foreign_table->foreign_list, foreign);
+			       foreign->foreign_table->foreign_list,
+			       foreign);
 	}
 
 	dict_foreign_free(foreign);
@@ -2111,7 +1965,7 @@
 
 		foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
 	}
-	
+
 	foreign = UT_LIST_GET_FIRST(table->referenced_list);
 
 	while (foreign) {
@@ -2124,8 +1978,9 @@
 	}
 
 	return(NULL);
-}	
+}
 
+#ifndef UNIV_HOTBACKUP
 /*************************************************************************
 Tries to find an index whose first fields are the columns in the array,
 in the same order. */
@@ -2139,43 +1994,46 @@
 	ulint		n_cols,	/* in: number of columns */
 	dict_index_t*	types_idx, /* in: NULL or an index to whose types the
 				   column types must match */
-	ibool		check_charsets)	/* in: whether to check charsets.
-					only has an effect if types_idx !=
-					NULL. */
+	ibool		check_charsets)
+				/* in: whether to check charsets.
+				only has an effect if types_idx != NULL */
 {
-#ifndef UNIV_HOTBACKUP
 	dict_index_t*	index;
+	dict_field_t*	field;
 	const char*	col_name;
 	ulint		i;
-	
+
 	index = dict_table_get_first_index(table);
 
 	while (index != NULL) {
 		if (dict_index_get_n_fields(index) >= n_cols) {
 
 			for (i = 0; i < n_cols; i++) {
-				col_name = dict_index_get_nth_field(index, i)
-							->col->name;
-				if (dict_index_get_nth_field(index, i)
-						->prefix_len != 0) {
+				field = dict_index_get_nth_field(index, i);
+
+				col_name = dict_table_get_col_name(
+					table, dict_col_get_no(field->col));
+
+				if (field->prefix_len != 0) {
 					/* We do not accept column prefix
 					indexes here */
-					
+
 					break;
 				}
 
 				if (0 != innobase_strcasecmp(columns[i],
-								col_name)) {
-				  	break;
+							     col_name)) {
+					break;
 				}
 
-				if (types_idx && !cmp_types_are_equal(
-				     dict_index_get_nth_type(index, i),
-				     dict_index_get_nth_type(types_idx, i),
-				     check_charsets)) {
+				if (types_idx && !cmp_cols_are_equal(
+					    dict_index_get_nth_col(index, i),
+					    dict_index_get_nth_col(types_idx,
+								   i),
+					    check_charsets)) {
 
-				  	break;
-				}		
+					break;
+				}
 			}
 
 			if (i == n_cols) {
@@ -2189,12 +2047,6 @@
 	}
 
 	return(NULL);
-#else /* UNIV_HOTBACKUP */
-	/* This function depends on MySQL code that is not included in
-	InnoDB Hot Backup builds.  Besides, this function should never
-	be called in InnoDB Hot Backup. */
-	ut_error;
-#endif /* UNIV_HOTBACKUP */
 }
 
 /**************************************************************************
@@ -2230,11 +2082,12 @@
 	putc('\n', file);
 	if (fk->foreign_index) {
 		fputs("The index in the foreign key in table is ", file);
-		ut_print_name(file, NULL, fk->foreign_index->name);
+		ut_print_name(file, NULL, FALSE, fk->foreign_index->name);
 		fputs("\n"
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n"
-"for correct foreign key definition.\n",
-		file);
+		      "See http://dev.mysql.com/doc/refman/5.1/en/"
+		      "innodb-foreign-key-constraints.html\n"
+		      "for correct foreign key definition.\n",
+		      file);
 	}
 	mutex_exit(&dict_foreign_err_mutex);
 }
@@ -2258,17 +2111,17 @@
 	dict_foreign_t*	for_in_cache		= NULL;
 	dict_index_t*	index;
 	ibool		added_to_referenced_list= FALSE;
-	FILE*		ef 			= dict_foreign_err_file;
+	FILE*		ef			= dict_foreign_err_file;
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 
 	for_table = dict_table_check_if_in_cache_low(
-					foreign->foreign_table_name);
-	
+		foreign->foreign_table_name);
+
 	ref_table = dict_table_check_if_in_cache_low(
-					foreign->referenced_table_name);
+		foreign->referenced_table_name);
 	ut_a(for_table || ref_table);
 
 	if (for_table) {
@@ -2287,62 +2140,73 @@
 	}
 
 	if (for_in_cache->referenced_table == NULL && ref_table) {
-		index = dict_foreign_find_index(ref_table,
+		index = dict_foreign_find_index(
+			ref_table,
 			(const char**) for_in_cache->referenced_col_names,
-			for_in_cache->n_fields,
-			for_in_cache->foreign_index, check_charsets);
+			for_in_cache->n_fields, for_in_cache->foreign_index,
+			check_charsets);
 
 		if (index == NULL) {
-			dict_foreign_error_report(ef, for_in_cache,
-"there is no index in referenced table which would contain\n"
-"the columns as the first columns, or the data types in the\n"
-"referenced table do not match to the ones in table.");
+			dict_foreign_error_report(
+				ef, for_in_cache,
+				"there is no index in referenced table"
+				" which would contain\n"
+				"the columns as the first columns,"
+				" or the data types in the\n"
+				"referenced table do not match"
+				" the ones in table.");
 
 			if (for_in_cache == foreign) {
 				mem_heap_free(foreign->heap);
 			}
 
-		    	return(DB_CANNOT_ADD_CONSTRAINT);
+			return(DB_CANNOT_ADD_CONSTRAINT);
 		}
 
 		for_in_cache->referenced_table = ref_table;
 		for_in_cache->referenced_index = index;
 		UT_LIST_ADD_LAST(referenced_list,
-					ref_table->referenced_list,
-					for_in_cache);
+				 ref_table->referenced_list,
+				 for_in_cache);
 		added_to_referenced_list = TRUE;
 	}
 
 	if (for_in_cache->foreign_table == NULL && for_table) {
-		index = dict_foreign_find_index(for_table,
+		index = dict_foreign_find_index(
+			for_table,
 			(const char**) for_in_cache->foreign_col_names,
 			for_in_cache->n_fields,
 			for_in_cache->referenced_index, check_charsets);
 
 		if (index == NULL) {
-			dict_foreign_error_report(ef, for_in_cache,
-"there is no index in the table which would contain\n"
-"the columns as the first columns, or the data types in the\n"
-"table do not match to the ones in the referenced table.");
+			dict_foreign_error_report(
+				ef, for_in_cache,
+				"there is no index in the table"
+				" which would contain\n"
+				"the columns as the first columns,"
+				" or the data types in the\n"
+				"table do not match"
+				" the ones in the referenced table.");
 
 			if (for_in_cache == foreign) {
 				if (added_to_referenced_list) {
-					UT_LIST_REMOVE(referenced_list,
+					UT_LIST_REMOVE(
+						referenced_list,
 						ref_table->referenced_list,
 						for_in_cache);
 				}
-			
+
 				mem_heap_free(foreign->heap);
 			}
 
-		    	return(DB_CANNOT_ADD_CONSTRAINT);
+			return(DB_CANNOT_ADD_CONSTRAINT);
 		}
 
 		for_in_cache->foreign_table = for_table;
 		for_in_cache->foreign_index = index;
 		UT_LIST_ADD_LAST(foreign_list,
-					for_table->foreign_list,
-					for_in_cache);
+				 for_table->foreign_list,
+				 for_in_cache);
 	}
 
 	return(DB_SUCCESS);
@@ -2377,13 +2241,13 @@
 			ulint	i;
 			for (i = 0; string[i]; i++) {
 				if (toupper((int)(unsigned char)(ptr[i]))
-						!= toupper((int)(unsigned char)
-						(string[i]))) {
+				    != toupper((int)(unsigned char)
+					       (string[i]))) {
 					goto nomatch;
 				}
 			}
 			break;
-		nomatch:
+nomatch:
 			;
 		}
 	}
@@ -2393,12 +2257,13 @@
 
 /*************************************************************************
 Accepts a specified string. Comparisons are case-insensitive. */
-
+static
 const char*
 dict_accept(
 /*========*/
 				/* out: if string was accepted, the pointer
 				is moved after that, else ptr is returned */
+	struct charset_info_st*	cs,/* in: the character set of ptr */
 	const char*	ptr,	/* in: scan from this */
 	const char*	string,	/* in: accept only this string as the next
 				non-whitespace string */
@@ -2408,15 +2273,15 @@
 	const char*	old_ptr2;
 
 	*success = FALSE;
-	
-	while (ib_isspace(*ptr)) {
+
+	while (my_isspace(cs, *ptr)) {
 		ptr++;
 	}
 
 	old_ptr2 = ptr;
-	
+
 	ptr = dict_scan_to(ptr, string);
-	
+
 	if (*ptr == '\0' || old_ptr2 != ptr) {
 		return(old_ptr);
 	}
@@ -2434,12 +2299,15 @@
 dict_scan_id(
 /*=========*/
 				/* out: scanned to */
+	struct charset_info_st*	cs,/* in: the character set of ptr */
 	const char*	ptr,	/* in: scanned to */
 	mem_heap_t*	heap,	/* in: heap where to allocate the id
 				(NULL=id will not be allocated, but it
 				will point to string near ptr) */
 	const char**	id,	/* out,own: the id; NULL if no id was
 				scannable */
+	ibool		table_id,/* in: TRUE=convert the allocated id
+				as a table name; FALSE=convert to UTF-8 */
 	ibool		accept_also_dot)
 				/* in: TRUE if also a dot can appear in a
 				non-quoted id; in a quoted id it can appear
@@ -2448,13 +2316,12 @@
 	char		quote	= '\0';
 	ulint		len	= 0;
 	const char*	s;
-	char*		d;
-	ulint		id_len;
-	byte*		b;
+	char*		str;
+	char*		dst;
 
 	*id = NULL;
 
-	while (ib_isspace(*ptr)) {
+	while (my_isspace(cs, *ptr)) {
 		ptr++;
 	}
 
@@ -2485,7 +2352,7 @@
 			len++;
 		}
 	} else {
-		while (!ib_isspace(*ptr) && *ptr != '(' && *ptr != ')'
+		while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')'
 		       && (accept_also_dot || *ptr != '.')
 		       && *ptr != ',' && *ptr != '\0') {
 
@@ -2495,43 +2362,50 @@
 		len = ptr - s;
 	}
 
-	if (quote && heap) {
-		*id = d = mem_heap_alloc(heap, len + 1);
+	if (UNIV_UNLIKELY(!heap)) {
+		/* no heap given: id will point to source string */
+		*id = s;
+		return(ptr);
+	}
+
+	if (quote) {
+		char*	d;
+		str = d = mem_heap_alloc(heap, len + 1);
 		while (len--) {
 			if ((*d++ = *s++) == quote) {
 				s++;
 			}
 		}
 		*d++ = 0;
-		ut_a(*s == quote);
-		ut_a(s + 1 == ptr);
-	} else if (heap) {
-		*id = mem_heap_strdupl(heap, s, len);
+		len = d - str;
+		ut_ad(*s == quote);
+		ut_ad(s + 1 == ptr);
 	} else {
-		/* no heap given: id will point to source string */
-		*id = s;
+		str = mem_heap_strdupl(heap, s, len);
 	}
 
-	if (heap && !quote) {
-		/* EMS MySQL Manager sometimes adds characters 0xA0 (in
-		latin1, a 'non-breakable space') to the end of a table name.
-		After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2
-		and 0xA0 are at the end of the string, and ib_isspace()
-		does not work for multi-byte UTF-8 characters.
-
-		In MySQL 5.1 we lex the string using thd->charset_info, and
-		my_isspace(). This workaround is not needed there. */
-
-		b = (byte*)(*id);
-		id_len = strlen((char*) b);
-		
-		if (id_len >= 3 && b[id_len - 1] == 0xA0
-			       && b[id_len - 2] == 0xC2) {
-
-			/* Strip the 2 last bytes */
+	if (!table_id) {
+convert_id:
+		/* Convert the identifier from connection character set
+		to UTF-8. */
+		len = 3 * len + 1;
+		*id = dst = mem_heap_alloc(heap, len);
+
+		innobase_convert_from_id(dst, str, len);
+	} else if (!strncmp(str, srv_mysql50_table_name_prefix,
+			    sizeof srv_mysql50_table_name_prefix)) {
+		/* This is a pre-5.1 table name
+		containing chars other than [A-Za-z0-9].
+		Discard the prefix and use raw UTF-8 encoding. */
+		str += sizeof srv_mysql50_table_name_prefix;
+		len -= sizeof srv_mysql50_table_name_prefix;
+		goto convert_id;
+	} else {
+		/* Encode using filename-safe characters. */
+		len = 5 * len + 1;
+		*id = dst = mem_heap_alloc(heap, len);
 
-			b[id_len - 2] = '\0';
-		}
+		innobase_convert_from_table_id(dst, str, len);
 	}
 
 	return(ptr);
@@ -2543,22 +2417,21 @@
 const char*
 dict_scan_col(
 /*==========*/
-				/* out: scanned to */
-	const char*	ptr,	/* in: scanned to */
-	ibool*		success,/* out: TRUE if success */
-	dict_table_t*	table,	/* in: table in which the column is */
-	dict_col_t**	column,	/* out: pointer to column if success */
-	mem_heap_t*	heap,	/* in: heap where to allocate the name */
-	const char**	name)	/* out,own: the column name; NULL if no name
-				was scannable */
+					/* out: scanned to */
+	struct charset_info_st*	cs,	/* in: the character set of ptr */
+	const char*		ptr,	/* in: scanned to */
+	ibool*			success,/* out: TRUE if success */
+	dict_table_t*		table,	/* in: table in which the column is */
+	const dict_col_t**	column,	/* out: pointer to column if success */
+	mem_heap_t*		heap,	/* in: heap where to allocate */
+	const char**		name)	/* out,own: the column name;
+					NULL if no name was scannable */
 {
-#ifndef UNIV_HOTBACKUP
-	dict_col_t*	col;
 	ulint		i;
 
 	*success = FALSE;
 
-	ptr = dict_scan_id(ptr, heap, name, TRUE);
+	ptr = dict_scan_id(cs, ptr, heap, name, FALSE, TRUE);
 
 	if (*name == NULL) {
 
@@ -2569,29 +2442,24 @@
 		*success = TRUE;
 		*column = NULL;
 	} else {
-	    	for (i = 0; i < dict_table_get_n_cols(table); i++) {
+		for (i = 0; i < dict_table_get_n_cols(table); i++) {
 
-			col = dict_table_get_nth_col(table, i);
+			const char*	col_name = dict_table_get_col_name(
+				table, i);
 
-			if (0 == innobase_strcasecmp(col->name, *name)) {
-		    		/* Found */
+			if (0 == innobase_strcasecmp(col_name, *name)) {
+				/* Found */
 
-		    		*success = TRUE;
-		    		*column = col;
-		    		strcpy((char*) *name, col->name);
+				*success = TRUE;
+				*column = dict_table_get_nth_col(table, i);
+				strcpy((char*) *name, col_name);
 
-		    		break;
+				break;
 			}
 		}
 	}
-	
+
 	return(ptr);
-#else /* UNIV_HOTBACKUP */
-	/* This function depends on MySQL code that is not included in
-	InnoDB Hot Backup builds.  Besides, this function should never
-	be called in InnoDB Hot Backup. */
-	ut_error;
-#endif /* UNIV_HOTBACKUP */
 }
 
 /*************************************************************************
@@ -2601,6 +2469,7 @@
 dict_scan_table_name(
 /*=================*/
 				/* out: scanned to */
+	struct charset_info_st*	cs,/* in: the character set of ptr */
 	const char*	ptr,	/* in: scanned to */
 	dict_table_t**	table,	/* out: table object or NULL */
 	const char*	name,	/* in: foreign key table name */
@@ -2609,7 +2478,6 @@
 	const char**	ref_name)/* out,own: the table name;
 				NULL if no name was scannable */
 {
-#ifndef UNIV_HOTBACKUP
 	const char*	database_name	= NULL;
 	ulint		database_name_len = 0;
 	const char*	table_name	= NULL;
@@ -2619,11 +2487,11 @@
 
 	*success = FALSE;
 	*table = NULL;
-	
-	ptr = dict_scan_id(ptr, heap, &scan_name, FALSE);	
+
+	ptr = dict_scan_id(cs, ptr, heap, &scan_name, TRUE, FALSE);
 
 	if (scan_name == NULL) {
-		
+
 		return(ptr);	/* Syntax error */
 	}
 
@@ -2635,7 +2503,7 @@
 		database_name = scan_name;
 		database_name_len = strlen(database_name);
 
-		ptr = dict_scan_id(ptr, heap, &table_name, FALSE);
+		ptr = dict_scan_id(cs, ptr, heap, &table_name, TRUE, FALSE);
 
 		if (table_name == NULL) {
 
@@ -2646,9 +2514,9 @@
 		earlier, we must allow the dot separator between the database
 		name and the table name also to appear within a quoted
 		identifier! InnoDB used to print a constraint as:
-			... REFERENCES `databasename.tablename` ...
+		... REFERENCES `databasename.tablename` ...
 		starting from 4.0.18 it is
-			... REFERENCES `databasename`.`tablename` ... */
+		... REFERENCES `databasename`.`tablename` ... */
 		const char* s;
 
 		for (s = scan_name; *s; s++) {
@@ -2691,12 +2559,6 @@
 	*table = dict_table_get_low(ref);
 
 	return(ptr);
-#else /* UNIV_HOTBACKUP */
-	/* This function depends on MySQL code that is not included in
-	InnoDB Hot Backup builds.  Besides, this function should never
-	be called in InnoDB Hot Backup. */
-	ut_error;
-#endif /* UNIV_HOTBACKUP */
 }
 
 /*************************************************************************
@@ -2706,20 +2568,21 @@
 dict_skip_word(
 /*===========*/
 				/* out: scanned to */
+	struct charset_info_st*	cs,/* in: the character set of ptr */
 	const char*	ptr,	/* in: scanned to */
 	ibool*		success)/* out: TRUE if success, FALSE if just spaces
 				left in string or a syntax error */
 {
 	const char*	start;
-	
+
 	*success = FALSE;
 
-	ptr = dict_scan_id(ptr, NULL, &start, TRUE);
+	ptr = dict_scan_id(cs, ptr, NULL, &start, FALSE, TRUE);
 
 	if (start) {
 		*success = TRUE;
 	}
-	
+
 	return(ptr);
 }
 
@@ -2741,8 +2604,8 @@
 	char*		str;
 	const char*	sptr;
 	char*		ptr;
- 	/* unclosed quote character (0 if none) */
- 	char		quote	= 0;
+	/* unclosed quote character (0 if none) */
+	char		quote	= 0;
 
 	str = mem_alloc(strlen(sql_string) + 1);
 
@@ -2770,8 +2633,8 @@
 			/* Starting quote: remember the quote character. */
 			quote = *sptr;
 		} else if (*sptr == '#'
-                           || (sptr[0] == '-' && sptr[1] == '-' &&
-                               sptr[2] == ' ')) {
+			   || (sptr[0] == '-' && sptr[1] == '-'
+			       && sptr[2] == ' ')) {
 			for (;;) {
 				/* In Unix a newline is 0x0A while in Windows
 				it is 0x0D followed by 0x0A */
@@ -2789,7 +2652,7 @@
 			for (;;) {
 				if (*sptr == '*' && *(sptr + 1) == '/') {
 
-				     	sptr += 2;
+					sptr += 2;
 
 					goto scan_more;
 				}
@@ -2837,12 +2700,13 @@
 		if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len
 		    && 0 == ut_memcmp(foreign->id, table->name, len)
 		    && 0 == ut_memcmp(foreign->id + len,
-				dict_ibfk, (sizeof dict_ibfk) - 1)
+				      dict_ibfk, (sizeof dict_ibfk) - 1)
 		    && foreign->id[len + ((sizeof dict_ibfk) - 1)] != '0') {
 			/* It is of the >= 4.0.18 format */
 
-			id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1),
-					&endp, 10);
+			id = strtoul(foreign->id + len
+				     + ((sizeof dict_ibfk) - 1),
+				     &endp, 10);
 			if (*endp == '\0') {
 				ut_a(id != biggest_id);
 
@@ -2892,6 +2756,7 @@
 				/* out: error code or DB_SUCCESS */
 	trx_t*		trx,	/* in: transaction */
 	mem_heap_t*	heap,	/* in: memory heap */
+	struct charset_info_st*	cs,/* in: the character set of sql_string */
 	const char*	sql_string,
 				/* in: CREATE TABLE or ALTER TABLE statement
 				where foreign keys are declared like:
@@ -2912,7 +2777,7 @@
 	ulint		highest_id_so_far	= 0;
 	dict_index_t*	index;
 	dict_foreign_t*	foreign;
- 	const char*	ptr			= sql_string;
+	const char*	ptr			= sql_string;
 	const char*	start_of_latest_foreign	= sql_string;
 	FILE*		ef			= dict_foreign_err_file;
 	const char*	constraint_name;
@@ -2925,10 +2790,10 @@
 	ibool		is_on_delete;
 	ulint		n_on_deletes;
 	ulint		n_on_updates;
-	dict_col_t*	columns[500];
+	const dict_col_t*columns[500];
 	const char*	column_names[500];
 	const char*	referenced_table_name;
-	
+
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
@@ -2939,8 +2804,9 @@
 		mutex_enter(&dict_foreign_err_mutex);
 		dict_foreign_error_report_low(ef, name);
 		fprintf(ef,
-"Cannot find the table in the internal data dictionary of InnoDB.\n"
-"Create table statement:\n%s\n", sql_string);
+			"Cannot find the table in the internal"
+			" data dictionary of InnoDB.\n"
+			"Create table statement:\n%s\n", sql_string);
 		mutex_exit(&dict_foreign_err_mutex);
 
 		return(DB_ERROR);
@@ -2949,14 +2815,14 @@
 	/* First check if we are actually doing an ALTER TABLE, and in that
 	case look for the table being altered */
 
-	ptr = dict_accept(ptr, "ALTER", &success);
+	ptr = dict_accept(cs, ptr, "ALTER", &success);
 
 	if (!success) {
 
 		goto loop;
 	}
 
-	ptr = dict_accept(ptr, "TABLE", &success);
+	ptr = dict_accept(cs, ptr, "TABLE", &success);
 
 	if (!success) {
 
@@ -2965,11 +2831,13 @@
 
 	/* We are doing an ALTER TABLE: scan the table name we are altering */
 
-	ptr = dict_scan_table_name(ptr, &table_to_alter, name,
-				&success, heap, &referenced_table_name);
+	ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name,
+				   &success, heap, &referenced_table_name);
 	if (!success) {
 		fprintf(stderr,
-"InnoDB: Error: could not find the table being ALTERED in:\n%s\n", sql_string);
+			"InnoDB: Error: could not find"
+			" the table being ALTERED in:\n%s\n",
+			sql_string);
 
 		return(DB_ERROR);
 	}
@@ -2987,7 +2855,7 @@
 		highest_id_so_far = 0;
 	} else {
 		highest_id_so_far = dict_table_get_highest_foreign_id(
-							table_to_alter);
+			table_to_alter);
 	}
 
 	/* Scan for foreign key declarations in a loop */
@@ -3005,21 +2873,22 @@
 		of the constraint to system tables. */
 		ptr = ptr1;
 
-		ptr = dict_accept(ptr, "CONSTRAINT", &success);
+		ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
 
 		ut_a(success);
 
-		if (!ib_isspace(*ptr) && *ptr != '"' && *ptr != '`') {
-	        	goto loop;
+		if (!my_isspace(cs, *ptr) && *ptr != '"' && *ptr != '`') {
+			goto loop;
 		}
 
-		while (ib_isspace(*ptr)) {
+		while (my_isspace(cs, *ptr)) {
 			ptr++;
 		}
 
 		/* read constraint name unless got "CONSTRAINT FOREIGN" */
 		if (ptr != ptr2) {
-			ptr = dict_scan_id(ptr, heap, &constraint_name, FALSE);
+			ptr = dict_scan_id(cs, ptr, heap,
+					   &constraint_name, FALSE, FALSE);
 		}
 	} else {
 		ptr = ptr2;
@@ -3027,65 +2896,65 @@
 
 	if (*ptr == '\0') {
 		/* The proper way to reject foreign keys for temporary
-		   tables would be to split the lexing and syntactical
-		   analysis of foreign key clauses from the actual adding
-		   of them, so that ha_innodb.cc could first parse the SQL
-		   command, determine if there are any foreign keys, and
-		   if so, immediately reject the command if the table is a
-		   temporary one. For now, this kludge will work. */
-		if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0))
-		{
-			return DB_CANNOT_ADD_CONSTRAINT;
+		tables would be to split the lexing and syntactical
+		analysis of foreign key clauses from the actual adding
+		of them, so that ha_innodb.cc could first parse the SQL
+		command, determine if there are any foreign keys, and
+		if so, immediately reject the command if the table is a
+		temporary one. For now, this kludge will work. */
+		if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0)) {
+
+			return(DB_CANNOT_ADD_CONSTRAINT);
 		}
-		
+
 		/**********************************************************/
 		/* The following call adds the foreign key constraints
 		to the data dictionary system tables on disk */
-		
+
 		error = dict_create_add_foreigns_to_dictionary(
-						highest_id_so_far, table, trx);
+			highest_id_so_far, table, trx);
 		return(error);
 	}
 
 	start_of_latest_foreign = ptr;
 
-	ptr = dict_accept(ptr, "FOREIGN", &success);		
-	
+	ptr = dict_accept(cs, ptr, "FOREIGN", &success);
+
 	if (!success) {
 		goto loop;
 	}
 
-	if (!ib_isspace(*ptr)) {
-	        goto loop;
+	if (!my_isspace(cs, *ptr)) {
+		goto loop;
 	}
 
-	ptr = dict_accept(ptr, "KEY", &success);
+	ptr = dict_accept(cs, ptr, "KEY", &success);
 
 	if (!success) {
 		goto loop;
 	}
 
-	ptr = dict_accept(ptr, "(", &success);
+	ptr = dict_accept(cs, ptr, "(", &success);
 
 	if (!success) {
 		/* MySQL allows also an index id before the '('; we
 		skip it */
-		ptr = dict_skip_word(ptr, &success);
+		ptr = dict_skip_word(cs, ptr, &success);
 
 		if (!success) {
-			dict_foreign_report_syntax_err(name,
-					start_of_latest_foreign, ptr);
+			dict_foreign_report_syntax_err(
+				name, start_of_latest_foreign, ptr);
 
 			return(DB_CANNOT_ADD_CONSTRAINT);
 		}
 
-		ptr = dict_accept(ptr, "(", &success);
+		ptr = dict_accept(cs, ptr, "(", &success);
 
 		if (!success) {
 			/* We do not flag a syntax error here because in an
 			ALTER TABLE we may also have DROP FOREIGN KEY abc */
 
-		        goto loop;
+			goto loop;
 		}
 	}
 
@@ -3094,31 +2963,31 @@
 	/* Scan the columns in the first list */
 col_loop1:
 	ut_a(i < (sizeof column_names) / sizeof *column_names);
-	ptr = dict_scan_col(ptr, &success, table, columns + i,
-				heap, column_names + i);
+	ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
+			    heap, column_names + i);
 	if (!success) {
 		mutex_enter(&dict_foreign_err_mutex);
 		dict_foreign_error_report_low(ef, name);
 		fprintf(ef, "%s:\nCannot resolve column name close to:\n%s\n",
-					start_of_latest_foreign, ptr);
+			start_of_latest_foreign, ptr);
 		mutex_exit(&dict_foreign_err_mutex);
 
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
 	i++;
-	
-	ptr = dict_accept(ptr, ",", &success);
+
+	ptr = dict_accept(cs, ptr, ",", &success);
 
 	if (success) {
 		goto col_loop1;
 	}
-	
-	ptr = dict_accept(ptr, ")", &success);
+
+	ptr = dict_accept(cs, ptr, ")", &success);
 
 	if (!success) {
-		dict_foreign_report_syntax_err(name, start_of_latest_foreign,
-									ptr);
+		dict_foreign_report_syntax_err(
+			name, start_of_latest_foreign, ptr);
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
@@ -3131,21 +3000,22 @@
 		mutex_enter(&dict_foreign_err_mutex);
 		dict_foreign_error_report_low(ef, name);
 		fputs("There is no index in table ", ef);
-		ut_print_name(ef, NULL, name);
+		ut_print_name(ef, NULL, TRUE, name);
 		fprintf(ef, " where the columns appear\n"
-"as the first columns. Constraint:\n%s\n"
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n"
-"for correct foreign key definition.\n",
+			"as the first columns. Constraint:\n%s\n"
+			"See http://dev.mysql.com/doc/refman/5.1/en/"
+			"innodb-foreign-key-constraints.html\n"
+			"for correct foreign key definition.\n",
 			start_of_latest_foreign);
 		mutex_exit(&dict_foreign_err_mutex);
 
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
-	ptr = dict_accept(ptr, "REFERENCES", &success);
+	ptr = dict_accept(cs, ptr, "REFERENCES", &success);
 
-	if (!success || !ib_isspace(*ptr)) {
-		dict_foreign_report_syntax_err(name, start_of_latest_foreign,
-									ptr);
+	if (!success || !my_isspace(cs, *ptr)) {
+		dict_foreign_report_syntax_err(
+			name, start_of_latest_foreign, ptr);
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
@@ -3154,7 +3024,7 @@
 	foreign = dict_mem_foreign_create();
 
 	if (constraint_name) {
-		ulint	db_len;	
+		ulint	db_len;
 
 		/* Catenate 'databasename/' to the constraint name specified
 		by the user: we conceive the constraint as belonging to the
@@ -3163,8 +3033,8 @@
 
 		db_len = dict_get_db_name_len(table->name);
 
-		foreign->id = mem_heap_alloc(foreign->heap,
-				db_len + strlen(constraint_name) + 2);
+		foreign->id = mem_heap_alloc(
+			foreign->heap, db_len + strlen(constraint_name) + 2);
 
 		ut_memcpy(foreign->id, table->name, db_len);
 		foreign->id[db_len] = '/';
@@ -3173,18 +3043,20 @@
 
 	foreign->foreign_table = table;
 	foreign->foreign_table_name = mem_heap_strdup(foreign->heap,
-							table->name);
+						      table->name);
 	foreign->foreign_index = index;
 	foreign->n_fields = i;
 	foreign->foreign_col_names = mem_heap_alloc(foreign->heap,
-							i * sizeof(void*));
+						    i * sizeof(void*));
 	for (i = 0; i < foreign->n_fields; i++) {
-		foreign->foreign_col_names[i] =
-			mem_heap_strdup(foreign->heap, columns[i]->name);
+		foreign->foreign_col_names[i] = mem_heap_strdup(
+			foreign->heap,
+			dict_table_get_col_name(table,
+						dict_col_get_no(columns[i])));
 	}
-	
-	ptr = dict_scan_table_name(ptr, &referenced_table, name,
-				&success, heap, &referenced_table_name);
+
+	ptr = dict_scan_table_name(cs, ptr, &referenced_table, name,
+				   &success, heap, &referenced_table_name);
 
 	/* Note that referenced_table can be NULL if the user has suppressed
 	checking of foreign key constraints! */
@@ -3201,13 +3073,13 @@
 
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
-	
-	ptr = dict_accept(ptr, "(", &success);
+
+	ptr = dict_accept(cs, ptr, "(", &success);
 
 	if (!success) {
 		dict_foreign_free(foreign);
 		dict_foreign_report_syntax_err(name, start_of_latest_foreign,
-									ptr);
+					       ptr);
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
@@ -3215,10 +3087,10 @@
 	i = 0;
 
 col_loop2:
-	ptr = dict_scan_col(ptr, &success, referenced_table, columns + i,
-				heap, column_names + i);
+	ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i,
+			    heap, column_names + i);
 	i++;
-	
+
 	if (!success) {
 		dict_foreign_free(foreign);
 
@@ -3232,45 +3104,45 @@
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
-	ptr = dict_accept(ptr, ",", &success);
+	ptr = dict_accept(cs, ptr, ",", &success);
 
 	if (success) {
 		goto col_loop2;
 	}
-	
-	ptr = dict_accept(ptr, ")", &success);
+
+	ptr = dict_accept(cs, ptr, ")", &success);
 
 	if (!success || foreign->n_fields != i) {
 		dict_foreign_free(foreign);
-		
+
 		dict_foreign_report_syntax_err(name, start_of_latest_foreign,
-									ptr);
+					       ptr);
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
 	n_on_deletes = 0;
 	n_on_updates = 0;
-	
+
 scan_on_conditions:
 	/* Loop here as long as we can find ON ... conditions */
 
-	ptr = dict_accept(ptr, "ON", &success);
+	ptr = dict_accept(cs, ptr, "ON", &success);
 
 	if (!success) {
 
 		goto try_find_index;
 	}
 
-	ptr = dict_accept(ptr, "DELETE", &success);
+	ptr = dict_accept(cs, ptr, "DELETE", &success);
 
 	if (!success) {
-		ptr = dict_accept(ptr, "UPDATE", &success);
+		ptr = dict_accept(cs, ptr, "UPDATE", &success);
 
 		if (!success) {
 			dict_foreign_free(foreign);
-		
-			dict_foreign_report_syntax_err(name,
-						start_of_latest_foreign, ptr);
+
+			dict_foreign_report_syntax_err(
+				name, start_of_latest_foreign, ptr);
 			return(DB_CANNOT_ADD_CONSTRAINT);
 		}
 
@@ -3281,13 +3153,13 @@
 		n_on_deletes++;
 	}
 
-	ptr = dict_accept(ptr, "RESTRICT", &success);
+	ptr = dict_accept(cs, ptr, "RESTRICT", &success);
 
 	if (success) {
 		goto scan_on_conditions;
 	}
 
-	ptr = dict_accept(ptr, "CASCADE", &success);
+	ptr = dict_accept(cs, ptr, "CASCADE", &success);
 
 	if (success) {
 		if (is_on_delete) {
@@ -3299,16 +3171,16 @@
 		goto scan_on_conditions;
 	}
 
-	ptr = dict_accept(ptr, "NO", &success);
+	ptr = dict_accept(cs, ptr, "NO", &success);
 
 	if (success) {
-		ptr = dict_accept(ptr, "ACTION", &success);
+		ptr = dict_accept(cs, ptr, "ACTION", &success);
 
 		if (!success) {
 			dict_foreign_free(foreign);
-			dict_foreign_report_syntax_err(name,
-					start_of_latest_foreign, ptr);
-		
+			dict_foreign_report_syntax_err(
+				name, start_of_latest_foreign, ptr);
+
 			return(DB_CANNOT_ADD_CONSTRAINT);
 		}
 
@@ -3321,28 +3193,27 @@
 		goto scan_on_conditions;
 	}
 
-	ptr = dict_accept(ptr, "SET", &success);
+	ptr = dict_accept(cs, ptr, "SET", &success);
 
 	if (!success) {
 		dict_foreign_free(foreign);
 		dict_foreign_report_syntax_err(name, start_of_latest_foreign,
-									ptr);
+					       ptr);
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
-	ptr = dict_accept(ptr, "NULL", &success);
+	ptr = dict_accept(cs, ptr, "NULL", &success);
 
 	if (!success) {
 		dict_foreign_free(foreign);
 		dict_foreign_report_syntax_err(name, start_of_latest_foreign,
-									ptr);
+					       ptr);
 		return(DB_CANNOT_ADD_CONSTRAINT);
 	}
 
 	for (j = 0; j < foreign->n_fields; j++) {
-		if ((dict_index_get_nth_type(
-				foreign->foreign_index, j)->prtype)
-				& DATA_NOT_NULL) {
+		if ((dict_index_get_nth_col(foreign->foreign_index, j)->prtype)
+		    & DATA_NOT_NULL) {
 
 			/* It is not sensible to define SET NULL
 			if the column is not allowed to be NULL! */
@@ -3352,8 +3223,10 @@
 			mutex_enter(&dict_foreign_err_mutex);
 			dict_foreign_error_report_low(ef, name);
 			fprintf(ef, "%s:\n"
-		"You have defined a SET NULL condition though some of the\n"
-		"columns are defined as NOT NULL.\n", start_of_latest_foreign);
+				"You have defined a SET NULL condition"
+				" though some of the\n"
+				"columns are defined as NOT NULL.\n",
+				start_of_latest_foreign);
 			mutex_exit(&dict_foreign_err_mutex);
 
 			return(DB_CANNOT_ADD_CONSTRAINT);
@@ -3365,19 +3238,20 @@
 	} else {
 		foreign->type |= DICT_FOREIGN_ON_UPDATE_SET_NULL;
 	}
-	
+
 	goto scan_on_conditions;
 
 try_find_index:
 	if (n_on_deletes > 1 || n_on_updates > 1) {
 		/* It is an error to define more than 1 action */
-		
+
 		dict_foreign_free(foreign);
 
 		mutex_enter(&dict_foreign_err_mutex);
 		dict_foreign_error_report_low(ef, name);
 		fprintf(ef, "%s:\n"
-"You have twice an ON DELETE clause or twice an ON UPDATE clause.\n",
+			"You have twice an ON DELETE clause"
+			" or twice an ON UPDATE clause.\n",
 			start_of_latest_foreign);
 		mutex_exit(&dict_foreign_err_mutex);
 
@@ -3390,20 +3264,28 @@
 
 	if (referenced_table) {
 		index = dict_foreign_find_index(referenced_table,
-			column_names, i, foreign->foreign_index, TRUE);
+						column_names, i,
+						foreign->foreign_index, TRUE);
 		if (!index) {
 			dict_foreign_free(foreign);
 			mutex_enter(&dict_foreign_err_mutex);
 			dict_foreign_error_report_low(ef, name);
 			fprintf(ef, "%s:\n"
-"Cannot find an index in the referenced table where the\n"
-"referenced columns appear as the first columns, or column types\n"
-"in the table and the referenced table do not match for constraint.\n"
-"Note that the internal storage type of ENUM and SET changed in\n"
-"tables created with >= InnoDB-4.1.12, and such columns in old tables\n"
-"cannot be referenced by such columns in new tables.\n"
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n"
-"for correct foreign key definition.\n",
+				"Cannot find an index in the"
+				" referenced table where the\n"
+				"referenced columns appear as the"
+				" first columns, or column types\n"
+				"in the table and the referenced table"
+				" do not match for constraint.\n"
+				"Note that the internal storage type of"
+				" ENUM and SET changed in\n"
+				"tables created with >= InnoDB-4.1.12,"
+				" and such columns in old tables\n"
+				"cannot be referenced by such columns"
+				" in new tables.\n"
+				"See http://dev.mysql.com/doc/refman/5.1/en/"
+				"innodb-foreign-key-constraints.html\n"
+				"for correct foreign key definition.\n",
 				start_of_latest_foreign);
 			mutex_exit(&dict_foreign_err_mutex);
 
@@ -3417,29 +3299,48 @@
 	foreign->referenced_index = index;
 	foreign->referenced_table = referenced_table;
 
-	foreign->referenced_table_name = mem_heap_strdup(foreign->heap,
-						referenced_table_name);
-					
+	foreign->referenced_table_name
+		= mem_heap_strdup(foreign->heap, referenced_table_name);
+
 	foreign->referenced_col_names = mem_heap_alloc(foreign->heap,
-							i * sizeof(void*));
+						       i * sizeof(void*));
 	for (i = 0; i < foreign->n_fields; i++) {
 		foreign->referenced_col_names[i]
 			= mem_heap_strdup(foreign->heap, column_names[i]);
 	}
 
 	/* We found an ok constraint definition: add to the lists */
-	
+
 	UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign);
 
 	if (referenced_table) {
 		UT_LIST_ADD_LAST(referenced_list,
-					referenced_table->referenced_list,
-								foreign);
+				 referenced_table->referenced_list,
+				 foreign);
 	}
 
 	goto loop;
 }
 
+/**************************************************************************
+Determines whether a string starts with the specified keyword. */
+
+ibool
+dict_str_starts_with_keyword(
+/*=========================*/
+					/* out: TRUE if str starts
+					with keyword */
+	void*		mysql_thd,	/* in: MySQL thread handle */
+	const char*	str,		/* in: string to scan for keyword */
+	const char*	keyword)	/* in: keyword to look for */
+{
+	struct charset_info_st*	cs	= innobase_get_charset(mysql_thd);
+	ibool			success;
+
+	dict_accept(cs, str, keyword, &success);
+	return(success);
+}
+
 /*************************************************************************
 Scans a table create SQL string and adds to the data dictionary the foreign
 key constraints declared in the string. This function should be called after
@@ -3467,20 +3368,23 @@
 					code DB_CANNOT_ADD_CONSTRAINT if
 					any foreign keys are found. */
 {
-	char*		str;
-	ulint		err;
-	mem_heap_t*	heap;
+	char*			str;
+	ulint			err;
+	mem_heap_t*		heap;
+
+	ut_a(trx && trx->mysql_thd);
 
 	str = dict_strip_comments(sql_string);
 	heap = mem_heap_create(10000);
 
-	err = dict_create_foreign_constraints_low(trx, heap, str, name,
+	err = dict_create_foreign_constraints_low(
+		trx, heap, innobase_get_charset(trx->mysql_thd), str, name,
 		reject_fks);
 
 	mem_heap_free(heap);
 	mem_free(str);
 
-	return(err);	
+	return(err);
 }
 
 /**************************************************************************
@@ -3502,13 +3406,18 @@
 	const char***	constraints_to_drop)	/* out: id's of the
 						constraints to drop */
 {
-	dict_foreign_t*	foreign;
-	ibool		success;
-	char*		str;
-	const char*	ptr;
-	const char*	id;
-	FILE*		ef	= dict_foreign_err_file;
-	
+	dict_foreign_t*		foreign;
+	ibool			success;
+	char*			str;
+	const char*		ptr;
+	const char*		id;
+	FILE*			ef	= dict_foreign_err_file;
+	struct charset_info_st*	cs;
+
+	ut_a(trx && trx->mysql_thd);
+
+	cs = innobase_get_charset(trx->mysql_thd);
+
 	*n = 0;
 
 	*constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*));
@@ -3524,32 +3433,32 @@
 
 	if (*ptr == '\0') {
 		mem_free(str);
-		
+
 		return(DB_SUCCESS);
 	}
 
-	ptr = dict_accept(ptr, "DROP", &success);
+	ptr = dict_accept(cs, ptr, "DROP", &success);
 
-	if (!ib_isspace(*ptr)) {
+	if (!my_isspace(cs, *ptr)) {
 
-	        goto loop;
+		goto loop;
 	}
 
-	ptr = dict_accept(ptr, "FOREIGN", &success);
-	
+	ptr = dict_accept(cs, ptr, "FOREIGN", &success);
+
 	if (!success) {
 
-	        goto loop;
+		goto loop;
 	}
 
-	ptr = dict_accept(ptr, "KEY", &success);
+	ptr = dict_accept(cs, ptr, "KEY", &success);
 
 	if (!success) {
 
 		goto syntax_error;
 	}
 
-	ptr = dict_scan_id(ptr, heap, &id, TRUE);
+	ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE);
 
 	if (id == NULL) {
 
@@ -3559,7 +3468,7 @@
 	ut_a(*n < 1000);
 	(*constraints_to_drop)[*n] = id;
 	(*n)++;
-	
+
 	/* Look for the given constraint id */
 
 	foreign = UT_LIST_GET_FIRST(table->foreign_list);
@@ -3568,11 +3477,11 @@
 		if (0 == strcmp(foreign->id, id)
 		    || (strchr(foreign->id, '/')
 			&& 0 == strcmp(id,
-					dict_remove_db_name(foreign->id)))) {
+				       dict_remove_db_name(foreign->id)))) {
 			/* Found */
 			break;
 		}
-		
+
 		foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
 	}
 
@@ -3580,14 +3489,14 @@
 		mutex_enter(&dict_foreign_err_mutex);
 		rewind(ef);
 		ut_print_timestamp(ef);
-		fputs(
-	" Error in dropping of a foreign key constraint of table ", ef);
-		ut_print_name(ef, NULL, table->name);
+		fputs(" Error in dropping of a foreign key constraint"
+		      " of table ", ef);
+		ut_print_name(ef, NULL, TRUE, table->name);
 		fputs(",\n"
-			"in SQL command\n", ef);
+		      "in SQL command\n", ef);
 		fputs(str, ef);
 		fputs("\nCannot find a constraint with the given id ", ef);
-		ut_print_name(ef, NULL, id);
+		ut_print_name(ef, NULL, FALSE, id);
 		fputs(".\n", ef);
 		mutex_exit(&dict_foreign_err_mutex);
 
@@ -3596,15 +3505,15 @@
 		return(DB_CANNOT_DROP_CONSTRAINT);
 	}
 
-	goto loop;	
+	goto loop;
 
 syntax_error:
 	mutex_enter(&dict_foreign_err_mutex);
 	rewind(ef);
 	ut_print_timestamp(ef);
-	fputs(
-	" Syntax error in dropping of a foreign key constraint of table ", ef);
-	ut_print_name(ef, NULL, table->name);
+	fputs(" Syntax error in dropping of a"
+	      " foreign key constraint of table ", ef);
+	ut_print_name(ef, NULL, TRUE, table->name);
 	fprintf(ef, ",\n"
 		"close to:\n%s\n in SQL command\n%s\n", ptr, str);
 	mutex_exit(&dict_foreign_err_mutex);
@@ -3613,9 +3522,11 @@
 
 	return(DB_CANNOT_DROP_CONSTRAINT);
 }
+#endif /* UNIV_HOTBACKUP */
 
 /*==================== END OF FOREIGN KEY PROCESSING ====================*/
 
+#ifdef UNIV_DEBUG
 /**************************************************************************
 Returns an index object if it is found in the dictionary cache. */
 
@@ -3625,7 +3536,6 @@
 				/* out: index, NULL if not found */
 	dulint	index_id)	/* in: index id */
 {
-	dict_table_t*	table;
 	dict_index_t*	index;
 
 	if (dict_sys == NULL) {
@@ -3633,273 +3543,69 @@
 	}
 
 	mutex_enter(&(dict_sys->mutex));
-	
-	table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
 
-	while (table) {
-		index = UT_LIST_GET_FIRST(table->indexes);
+	index = dict_index_find_on_id_low(index_id);
 
-		while (index) {
-			if (0 == ut_dulint_cmp(index->id, index_id)) {
-
-				goto found;
-			}
-
-			index = UT_LIST_GET_NEXT(indexes, index);
-		}
-
-		table = UT_LIST_GET_NEXT(table_LRU, table);
-	}
-
-	index = NULL;
-found:
 	mutex_exit(&(dict_sys->mutex));
 
 	return(index);
 }
+#endif /* UNIV_DEBUG */
 
-/**************************************************************************
-Creates an index tree struct. */
-
-dict_tree_t*
-dict_tree_create(
-/*=============*/
-				/* out, own: created tree */
-	dict_index_t*	index,	/* in: the index for which to create: in the
-				case of a mixed tree, this should be the
-				index of the cluster object */
-	ulint		page_no)/* in: root page number of the index */
-{
-	dict_tree_t*	tree;
-
-	tree = mem_alloc(sizeof(dict_tree_t));
-
-	/* Inherit info from the index */
-
-	tree->type = index->type;
-	tree->space = index->space;
-	tree->page = page_no;
-
-	tree->id = index->id;
-	
-	UT_LIST_INIT(tree->tree_indexes);
-
-	tree->magic_n = DICT_TREE_MAGIC_N;
-
-	rw_lock_create(&(tree->lock));
-
-	rw_lock_set_level(&(tree->lock), SYNC_INDEX_TREE);
-
-	return(tree);
-}
-
-/**************************************************************************
-Frees an index tree struct. */
-
-void
-dict_tree_free(
-/*===========*/
-	dict_tree_t*	tree)	/* in, own: index tree */
-{
-	ut_a(tree);
-	ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
-
-	rw_lock_free(&(tree->lock));
-	mem_free(tree);
-}
-
-/**************************************************************************
-In an index tree, finds the index corresponding to a record in the tree. */
-UNIV_INLINE
-dict_index_t*
-dict_tree_find_index_low(
-/*=====================*/
-				/* out: index */
-	dict_tree_t*	tree,	/* in: index tree */
-	rec_t*		rec)	/* in: record for which to find correct
-				index */
-{
-	dict_index_t*	index;
-	dict_table_t*	table;
-	dulint		mix_id;
-	ulint		len;
-	
-	index = UT_LIST_GET_FIRST(tree->tree_indexes);
-	ut_ad(index);
-	table = index->table;
-	
-	if ((index->type & DICT_CLUSTERED)
-			&& UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) {
-
-		/* Get the mix id of the record */
-		ut_a(!table->comp);
-
-		mix_id = mach_dulint_read_compressed(
-			rec_get_nth_field_old(rec, table->mix_len, &len));
-
-		while (ut_dulint_cmp(table->mix_id, mix_id) != 0) {
-
-			index = UT_LIST_GET_NEXT(tree_indexes, index);
-			table = index->table;
-			ut_ad(index);
-		}
-	}
-
-	return(index);
-}
-
-/**************************************************************************
-In an index tree, finds the index corresponding to a record in the tree. */
-
-dict_index_t*
-dict_tree_find_index(
-/*=================*/
-				/* out: index */
-	dict_tree_t*	tree,	/* in: index tree */
-	rec_t*		rec)	/* in: record for which to find correct
-				index */
-{
-	dict_index_t*	index;
-	
-	index = dict_tree_find_index_low(tree, rec);
-	
-	return(index);
-}
-
-/**************************************************************************
-In an index tree, finds the index corresponding to a dtuple which is used
-in a search to a tree. */
-
-dict_index_t*
-dict_tree_find_index_for_tuple(
-/*===========================*/
-				/* out: index; NULL if the tuple does not
-				contain the mix id field in a mixed tree */
-	dict_tree_t*	tree,	/* in: index tree */
-	dtuple_t*	tuple)	/* in: tuple for which to find index */
-{
-	dict_index_t*	index;
-	dict_table_t*	table;
-	dulint		mix_id;
-
-	ut_ad(dtuple_check_typed(tuple));
-	
-	if (UT_LIST_GET_LEN(tree->tree_indexes) == 1) {
-
-		return(UT_LIST_GET_FIRST(tree->tree_indexes));
-	}
-
-	index = UT_LIST_GET_FIRST(tree->tree_indexes);
-	ut_ad(index);
-	table = index->table;
-
-	if (dtuple_get_n_fields(tuple) <= table->mix_len) {
-
-		return(NULL);
-	}
-
-	/* Get the mix id of the record */
-
-	mix_id = mach_dulint_read_compressed(
-			dfield_get_data(
-				dtuple_get_nth_field(tuple, table->mix_len)));
-
-	while (ut_dulint_cmp(table->mix_id, mix_id) != 0) {
-
-		index = UT_LIST_GET_NEXT(tree_indexes, index);
-		table = index->table;
-		ut_ad(index);
-	}
-
-	return(index);
-}
-
-/***********************************************************************
-Checks if a table which is a mixed cluster member owns a record. */
-
-ibool
-dict_is_mixed_table_rec(
-/*====================*/
-				/* out: TRUE if the record belongs to this
-				table */
-	dict_table_t*	table,	/* in: table in a mixed cluster */
-	rec_t*		rec)	/* in: user record in the clustered index */
-{
-	byte*	mix_id_field;
-	ulint	len;
-
-	ut_ad(!table->comp);
-
-	mix_id_field = rec_get_nth_field_old(rec,
-					table->mix_len, &len);
-
-	return(len == table->mix_id_len
-		&& !ut_memcmp(table->mix_id_buf, mix_id_field, len));
-}
-
+#ifdef UNIV_DEBUG
 /**************************************************************************
 Checks that a tuple has n_fields_cmp value in a sensible range, so that
 no comparison can occur with the page number field in a node pointer. */
 
 ibool
-dict_tree_check_search_tuple(
-/*=========================*/
+dict_index_check_search_tuple(
+/*==========================*/
 				/* out: TRUE if ok */
-	dict_tree_t*	tree,	/* in: index tree */
+	dict_index_t*	index,	/* in: index tree */
 	dtuple_t*	tuple)	/* in: tuple used in a search */
 {
-	dict_index_t*	index;
-
-	index = dict_tree_find_index_for_tuple(tree, tuple);
-
-	if (index == NULL) {
-
-		return(TRUE);
-	}
-
+	ut_a(index);
 	ut_a(dtuple_get_n_fields_cmp(tuple)
-				<= dict_index_get_n_unique_in_tree(index));
+	     <= dict_index_get_n_unique_in_tree(index));
 	return(TRUE);
 }
+#endif /* UNIV_DEBUG */
 
 /**************************************************************************
 Builds a node pointer out of a physical record and a page number. */
 
 dtuple_t*
-dict_tree_build_node_ptr(
-/*=====================*/
+dict_index_build_node_ptr(
+/*======================*/
 				/* out, own: node pointer */
-	dict_tree_t*	tree,	/* in: index tree */
+	dict_index_t*	index,	/* in: index tree */
 	rec_t*		rec,	/* in: record for which to build node
 				pointer */
 	ulint		page_no,/* in: page number to put in node pointer */
 	mem_heap_t*	heap,	/* in: memory heap where pointer created */
-	ulint           level)  /* in: level of rec in tree: 0 means leaf
+	ulint		level)	/* in: level of rec in tree: 0 means leaf
 				level */
 {
 	dtuple_t*	tuple;
-	dict_index_t*	ind;
 	dfield_t*	field;
 	byte*		buf;
 	ulint		n_unique;
 
-	ind = dict_tree_find_index_low(tree, rec);
-	
-	if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
+	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
 		/* In a universal index tree, we take the whole record as
-		the node pointer if the reord is on the leaf level,
+		the node pointer if the record is on the leaf level,
 		on non-leaf levels we remove the last field, which
 		contains the page number of the child page */
 
-		ut_a(!ind->table->comp);
+		ut_a(!dict_table_is_comp(index->table));
 		n_unique = rec_get_n_fields_old(rec);
 
 		if (level > 0) {
-		        ut_a(n_unique > 1);
-		        n_unique--;
+			ut_a(n_unique > 1);
+			n_unique--;
 		}
-	} else {	
-		n_unique = dict_index_get_n_unique_in_tree(ind);
+	} else {
+		n_unique = dict_index_get_n_unique_in_tree(index);
 	}
 
 	tuple = dtuple_create(heap, n_unique + 1);
@@ -3909,52 +3615,50 @@
 	levels in the tree there may be identical node pointers with a
 	different page number; therefore, we set the n_fields_cmp to one
 	less: */
-	
+
 	dtuple_set_n_fields_cmp(tuple, n_unique);
 
-	dict_index_copy_types(tuple, ind, n_unique);
-	
+	dict_index_copy_types(tuple, index, n_unique);
+
 	buf = mem_heap_alloc(heap, 4);
 
 	mach_write_to_4(buf, page_no);
-	
+
 	field = dtuple_get_nth_field(tuple, n_unique);
 	dfield_set_data(field, buf, 4);
 
-	dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4, 0);
+	dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4);
 
-	rec_copy_prefix_to_dtuple(tuple, rec, ind, n_unique, heap);
-	dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple) |
-					REC_STATUS_NODE_PTR);
+	rec_copy_prefix_to_dtuple(tuple, rec, index, n_unique, heap);
+	dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple)
+			     | REC_STATUS_NODE_PTR);
 
 	ut_ad(dtuple_check_typed(tuple));
 
 	return(tuple);
-}	
-	
+}
+
 /**************************************************************************
 Copies an initial segment of a physical record, long enough to specify an
 index entry uniquely. */
 
 rec_t*
-dict_tree_copy_rec_order_prefix(
-/*============================*/
+dict_index_copy_rec_order_prefix(
+/*=============================*/
 				/* out: pointer to the prefix record */
-	dict_tree_t*	tree,	/* in: index tree */
+	dict_index_t*	index,	/* in: index tree */
 	rec_t*		rec,	/* in: record for which to copy prefix */
 	ulint*		n_fields,/* out: number of fields copied */
 	byte**		buf,	/* in/out: memory buffer for the copied prefix,
 				or NULL */
 	ulint*		buf_size)/* in/out: buffer size */
 {
-	dict_index_t*	index;
 	ulint		n;
 
 	UNIV_PREFETCH_R(rec);
-	index = dict_tree_find_index_low(tree, rec);
 
-	if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
-		ut_a(!index->table->comp);
+	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
+		ut_a(!dict_table_is_comp(index->table));
 		n = rec_get_n_fields_old(rec);
 	} else {
 		n = dict_index_get_n_unique_in_tree(index);
@@ -3968,32 +3672,30 @@
 Builds a typed data tuple out of a physical record. */
 
 dtuple_t*
-dict_tree_build_data_tuple(
-/*=======================*/
+dict_index_build_data_tuple(
+/*========================*/
 				/* out, own: data tuple */
-	dict_tree_t*	tree,	/* in: index tree */
+	dict_index_t*	index,	/* in: index tree */
 	rec_t*		rec,	/* in: record for which to build data tuple */
 	ulint		n_fields,/* in: number of data fields */
 	mem_heap_t*	heap)	/* in: memory heap where tuple created */
 {
 	dtuple_t*	tuple;
-	dict_index_t*	ind;
 
-	ind = dict_tree_find_index_low(tree, rec);
+	ut_ad(dict_table_is_comp(index->table)
+	      || n_fields <= rec_get_n_fields_old(rec));
 
-	ut_ad(ind->table->comp || n_fields <= rec_get_n_fields_old(rec));
-	
-	tuple = dtuple_create(heap, n_fields); 
+	tuple = dtuple_create(heap, n_fields);
 
-	dict_index_copy_types(tuple, ind, n_fields);
+	dict_index_copy_types(tuple, index, n_fields);
 
-	rec_copy_prefix_to_dtuple(tuple, rec, ind, n_fields, heap);
+	rec_copy_prefix_to_dtuple(tuple, rec, index, n_fields, heap);
 
 	ut_ad(dtuple_check_typed(tuple));
 
 	return(tuple);
-}	
-	
+}
+
 /*************************************************************************
 Calculates the minimum record length in an index. */
 
@@ -4005,19 +3707,21 @@
 	ulint	sum	= 0;
 	ulint	i;
 
-	if (UNIV_LIKELY(index->table->comp)) {
+	if (dict_table_is_comp(index->table)) {
 		ulint nullable = 0;
 		sum = REC_N_NEW_EXTRA_BYTES;
 		for (i = 0; i < dict_index_get_n_fields(index); i++) {
-			dtype_t*t = dict_index_get_nth_type(index, i);
-			ulint	size = dtype_get_fixed_size(t);
+			const dict_col_t*	col
+				= dict_index_get_nth_col(index, i);
+			ulint	size = dict_col_get_fixed_size(col);
 			sum += size;
 			if (!size) {
-				size = dtype_get_len(t);
+				size = col->len;
 				sum += size < 128 ? 1 : 2;
 			}
-			if (!(dtype_get_prtype(t) & DATA_NOT_NULL))
+			if (!(col->prtype & DATA_NOT_NULL)) {
 				nullable++;
+			}
 		}
 
 		/* round the NULL flags up to full bytes */
@@ -4027,7 +3731,8 @@
 	}
 
 	for (i = 0; i < dict_index_get_n_fields(index); i++) {
-		sum += dtype_get_fixed_size(dict_index_get_nth_type(index, i));
+		sum += dict_col_get_fixed_size(
+			dict_index_get_nth_col(index, i));
 	}
 
 	if (sum > 127) {
@@ -4050,8 +3755,8 @@
 /*=======================*/
 	dict_table_t*	table,		/* in: table */
 	ibool		has_dict_mutex __attribute__((unused)))
-                                        /* in: TRUE if the caller has the
-					dictionary mutex */	
+					/* in: TRUE if the caller has the
+					dictionary mutex */
 {
 	dict_index_t*	index;
 	ulint		size;
@@ -4061,8 +3766,10 @@
 		ut_print_timestamp(stderr);
 		fprintf(stderr,
 			"  InnoDB: cannot calculate statistics for table %s\n"
-"InnoDB: because the .ibd file is missing.  For help, please refer to\n"
-"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n",
+			"InnoDB: because the .ibd file is missing.  For help,"
+			" please refer to\n"
+			"InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
+			"innodb-troubleshooting.html\n",
 			table->name);
 
 		return;
@@ -4079,11 +3786,11 @@
 	/* Find out the sizes of the indexes and how many different values
 	for the key they approximately have */
 
-	index = dict_table_get_first_index(table);	
+	index = dict_table_get_first_index(table);
 
 	if (index == NULL) {
 		/* Table definition is corrupt */
-	
+
 		return;
 	}
 
@@ -4102,7 +3809,7 @@
 		}
 
 		index->stat_n_leaf_pages = size;
-		
+
 		btr_estimate_number_of_different_key_vals(index);
 
 		index = dict_table_get_next_index(index);
@@ -4111,16 +3818,16 @@
 	index = dict_table_get_first_index(table);
 
 	table->stat_n_rows = index->stat_n_diff_key_vals[
-					dict_index_get_n_unique(index)];
+		dict_index_get_n_unique(index)];
 
 	table->stat_clustered_index_size = index->stat_index_size;
 
 	table->stat_sum_of_other_index_sizes = sum_of_index_sizes
-						- index->stat_index_size;
+		- index->stat_index_size;
 
 	table->stat_initialized = TRUE;
 
-        table->stat_modified_counter = 0;
+	table->stat_modified_counter = 0;
 }
 
 /*************************************************************************
@@ -4136,6 +3843,18 @@
 }
 
 /**************************************************************************
+A noninlined version of dict_table_get_low. */
+
+dict_table_t*
+dict_table_get_low_noninlined(
+/*==========================*/
+					/* out: table, NULL if not found */
+	const char*	table_name)	/* in: table name */
+{
+	return(dict_table_get_low(table_name));
+}
+
+/**************************************************************************
 Prints info of a foreign key constraint. */
 static
 void
@@ -4159,7 +3878,7 @@
 	fprintf(stderr, " )\n"
 		"             REFERENCES %s (",
 		foreign->referenced_table_name);
-	
+
 	for (i = 0; i < foreign->n_fields; i++) {
 		fprintf(stderr, " %s", foreign->referenced_col_names[i]);
 	}
@@ -4195,7 +3914,7 @@
 	table = dict_table_get_low(name);
 
 	ut_a(table);
-	
+
 	dict_table_print_low(table);
 	mutex_exit(&(dict_sys->mutex));
 }
@@ -4217,20 +3936,21 @@
 #endif /* UNIV_SYNC_DEBUG */
 
 	dict_update_statistics_low(table, TRUE);
-	
+
 	fprintf(stderr,
-"--------------------------------------\n"
-"TABLE: name %s, id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n"
-"  COLUMNS: ",
-			table->name,
-			(ulong) ut_dulint_get_high(table->id),
-			(ulong) ut_dulint_get_low(table->id),
-			(ulong) table->n_cols,
-		        (ulong) UT_LIST_GET_LEN(table->indexes),
-			(ulong) table->stat_n_rows);
+		"--------------------------------------\n"
+		"TABLE: name %s, id %lu %lu, columns %lu, indexes %lu,"
+		" appr.rows %lu\n"
+		"  COLUMNS: ",
+		table->name,
+		(ulong) ut_dulint_get_high(table->id),
+		(ulong) ut_dulint_get_low(table->id),
+		(ulong) table->n_cols,
+		(ulong) UT_LIST_GET_LEN(table->indexes),
+		(ulong) table->stat_n_rows);
 
-	for (i = 0; i < table->n_cols - 1; i++) {
-		dict_col_print_low(dict_table_get_nth_col(table, i));
+	for (i = 0; i + 1 < (ulint) table->n_cols; i++) {
+		dict_col_print_low(table, dict_table_get_nth_col(table, i));
 		fputs("; ", stderr);
 	}
 
@@ -4264,18 +3984,20 @@
 void
 dict_col_print_low(
 /*===============*/
-	dict_col_t*	col)	/* in: column */
+	const dict_table_t*	table,	/* in: table */
+	const dict_col_t*	col)	/* in: column */
 {
-	dtype_t*	type;
+	dtype_t	type;
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 
-	type = dict_col_get_type(col);
-	fprintf(stderr, "%s: ", col->name);
+	dict_col_copy_type(col, &type);
+	fprintf(stderr, "%s: ", dict_table_get_col_name(table,
+							dict_col_get_no(col)));
 
-	dtype_print(type);
+	dtype_print(&type);
 }
 
 /**************************************************************************
@@ -4286,7 +4008,6 @@
 /*=================*/
 	dict_index_t*	index)	/* in: index */
 {
-	dict_tree_t*	tree;
 	ib_longlong	n_vals;
 	ulint		i;
 
@@ -4294,30 +4015,31 @@
 	ut_ad(mutex_own(&(dict_sys->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
 
-	tree = index->tree;
-
 	if (index->n_user_defined_cols > 0) {
 		n_vals = index->stat_n_diff_key_vals[
-					index->n_user_defined_cols];
+			index->n_user_defined_cols];
 	} else {
 		n_vals = index->stat_n_diff_key_vals[1];
 	}
 
 	fprintf(stderr,
-		"  INDEX: name %s, id %lu %lu, fields %lu/%lu, type %lu\n"
+		"  INDEX: name %s, id %lu %lu, fields %lu/%lu,"
+		" uniq %lu, type %lu\n"
 		"   root page %lu, appr.key vals %lu,"
 		" leaf pages %lu, size pages %lu\n"
 		"   FIELDS: ",
 		index->name,
-		(ulong) ut_dulint_get_high(tree->id),
-		(ulong) ut_dulint_get_low(tree->id),
+		(ulong) ut_dulint_get_high(index->id),
+		(ulong) ut_dulint_get_low(index->id),
 		(ulong) index->n_user_defined_cols,
-		(ulong) index->n_fields, (ulong) index->type,
-		(ulong) tree->page,
+		(ulong) index->n_fields,
+		(ulong) index->n_uniq,
+		(ulong) index->type,
+		(ulong) index->page,
 		(ulong) n_vals,
 		(ulong) index->stat_n_leaf_pages,
 		(ulong) index->stat_index_size);
-			
+
 	for (i = 0; i < index->n_fields; i++) {
 		dict_field_print_low(dict_index_get_nth_field(index, i));
 	}
@@ -4325,9 +4047,9 @@
 	putc('\n', stderr);
 
 #ifdef UNIV_BTR_PRINT
-	btr_print_size(tree);
+	btr_print_size(index);
 
-	btr_print_tree(tree, 7);
+	btr_print_index(index, 7);
 #endif /* UNIV_BTR_PRINT */
 }
 
@@ -4363,33 +4085,33 @@
 {
 	const char*	stripped_id;
 	ulint	i;
-	
+
 	if (strchr(foreign->id, '/')) {
 		/* Strip the preceding database name from the constraint id */
 		stripped_id = foreign->id + 1
-				+ dict_get_db_name_len(foreign->id);
+			+ dict_get_db_name_len(foreign->id);
 	} else {
 		stripped_id = foreign->id;
 	}
 
 	putc(',', file);
-	
+
 	if (add_newline) {
 		/* SHOW CREATE TABLE wants constraints each printed nicely
 		on its own line, while error messages want no newlines
 		inserted. */
 		fputs("\n ", file);
 	}
-	
+
 	fputs(" CONSTRAINT ", file);
-	ut_print_name(file, trx, stripped_id);
+	ut_print_name(file, trx, FALSE, stripped_id);
 	fputs(" FOREIGN KEY (", file);
 
 	for (i = 0;;) {
-		ut_print_name(file, trx, foreign->foreign_col_names[i]);
+		ut_print_name(file, trx, FALSE, foreign->foreign_col_names[i]);
 		if (++i < foreign->n_fields) {
 			fputs(", ", file);
-	        } else {
+		} else {
 			break;
 		}
 	}
@@ -4397,29 +4119,22 @@
 	fputs(") REFERENCES ", file);
 
 	if (dict_tables_have_same_db(foreign->foreign_table_name,
-					foreign->referenced_table_name)) {
+				     foreign->referenced_table_name)) {
 		/* Do not print the database name of the referenced table */
-		ut_print_name(file, trx, dict_remove_db_name(
-					foreign->referenced_table_name));
+		ut_print_name(file, trx, TRUE,
+			      dict_remove_db_name(
+				      foreign->referenced_table_name));
 	} else {
-		/* Look for the '/' in the table name */
-
-		i = 0;
-		while (foreign->referenced_table_name[i] != '/') {
-			i++;
-		}
-
-		ut_print_namel(file, trx, foreign->referenced_table_name, i);
-		putc('.', file);
-		ut_print_name(file, trx,
-				foreign->referenced_table_name + i + 1);
+		ut_print_name(file, trx, TRUE,
+			      foreign->referenced_table_name);
 	}
 
 	putc(' ', file);
 	putc('(', file);
 
 	for (i = 0;;) {
-		ut_print_name(file, trx, foreign->referenced_col_names[i]);
+		ut_print_name(file, trx, FALSE,
+			      foreign->referenced_col_names[i]);
 		if (++i < foreign->n_fields) {
 			fputs(", ", file);
 		} else {
@@ -4432,7 +4147,7 @@
 	if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) {
 		fputs(" ON DELETE CASCADE", file);
 	}
-	
+
 	if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) {
 		fputs(" ON DELETE SET NULL", file);
 	}
@@ -4444,7 +4159,7 @@
 	if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) {
 		fputs(" ON UPDATE CASCADE", file);
 	}
-	
+
 	if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) {
 		fputs(" ON UPDATE SET NULL", file);
 	}
@@ -4483,7 +4198,7 @@
 	while (foreign != NULL) {
 		if (create_table_format) {
 			dict_print_info_on_foreign_key_in_create_format(
-						file, trx, foreign, TRUE);
+				file, trx, foreign, TRUE);
 		} else {
 			ulint	i;
 			fputs("; (", file);
@@ -4493,20 +4208,21 @@
 					putc(' ', file);
 				}
 
-				ut_print_name(file, trx,
-					foreign->foreign_col_names[i]);
+				ut_print_name(file, trx, FALSE,
+					      foreign->foreign_col_names[i]);
 			}
 
 			fputs(") REFER ", file);
-			ut_print_name(file, trx,
-					foreign->referenced_table_name);
+			ut_print_name(file, trx, TRUE,
+				      foreign->referenced_table_name);
 			putc('(', file);
 
 			for (i = 0; i < foreign->n_fields; i++) {
 				if (i) {
 					putc(' ', file);
 				}
-				ut_print_name(file, trx,
+				ut_print_name(
+					file, trx, FALSE,
 					foreign->referenced_col_names[i]);
 			}
 
@@ -4515,7 +4231,7 @@
 			if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) {
 				fputs(" ON DELETE CASCADE", file);
 			}
-	
+
 			if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
 				fputs(" ON DELETE SET NULL", file);
 			}
@@ -4527,7 +4243,7 @@
 			if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) {
 				fputs(" ON UPDATE CASCADE", file);
 			}
-	
+
 			if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) {
 				fputs(" ON UPDATE SET NULL", file);
 			}
@@ -4553,7 +4269,7 @@
 	const dict_index_t*	index)	/* in: index to print */
 {
 	fputs("index ", file);
-	ut_print_name(file, trx, index->name);
+	ut_print_name(file, trx, FALSE, index->name);
 	fputs(" of table ", file);
-	ut_print_name(file, trx, index->table_name);
+	ut_print_name(file, trx, TRUE, index->table_name);
 }

--- 1.93.5.1/sql/ha_innodb.h	2007-01-21 17:58:00 -07:00
+++ 1.133/storage/innobase/handler/ha_innodb.h	2007-01-21 20:30:46 -07:00
@@ -6,12 +6,12 @@
 
    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
+   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 */
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA */
 
 /*
   This file is based on ha_berkeley.h of MySQL distribution
@@ -32,9 +32,11 @@
 } INNOBASE_SHARE;
 
 
+struct row_prebuilt_struct;
+
 my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
-                                                  uint full_name_len,
-                                                  ulonglong *unused);
+						  uint full_name_len,
+						  ulonglong *unused);
 
 /* The class defining a handle to an Innodb table */
 class ha_innobase: public handler
@@ -46,20 +48,20 @@
 	THD*		user_thd;	/* the thread handle of the user
 					currently using the handle; this is
 					set in external_lock function */
-	query_id_t      last_query_id;  /* the latest query id where the
+	query_id_t	last_query_id;	/* the latest query id where the
 					handle was used */
-  	THR_LOCK_DATA 	lock;
-	INNOBASE_SHARE  *share;
+	THR_LOCK_DATA	lock;
+	INNOBASE_SHARE	*share;
 
-  	byte*		upd_buff;	/* buffer used in updates */
-  	byte*		key_val_buff;	/* buffer used in converting
-  					search key values from MySQL format
-  					to Innodb format */
+	byte*		upd_buff;	/* buffer used in updates */
+	byte*		key_val_buff;	/* buffer used in converting
+					search key values from MySQL format
+					to Innodb format */
 	ulong		upd_and_key_val_buff_len;
 					/* the length of each of the previous
 					two buffers */
-  	ulong 		int_table_flags;
-  	uint 		primary_key;
+	ulong		int_table_flags;
+	uint		primary_key;
 	ulong		start_of_scan;	/* this is set to 1 when we are
 					starting a table scan but have not
 					yet fetched any row, else 0 */
@@ -69,7 +71,7 @@
 	uint		num_write_row;	/* number of write_row() calls */
 
 	uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
-					       const byte* record);
+		const byte* record);
 	int update_thd(THD* thd);
 	int change_active_index(uint keynr);
 	int general_fetch(byte* buf, uint direction, uint match_mode);
@@ -77,27 +79,27 @@
 
 	/* Init values for the class: */
  public:
-  	ha_innobase(TABLE *table_arg);
-  	~ha_innobase() {}
+	ha_innobase(handlerton *hton, TABLE_SHARE *table_arg);
+	~ha_innobase() {}
 	/*
 	  Get the row type from the storage engine.  If this method returns
 	  ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
 	*/
 	enum row_type get_row_type() const;
 
-  	const char* table_type() const { return("InnoDB");}
+	const char* table_type() const { return("InnoDB");}
 	const char *index_type(uint key_number) { return "BTREE"; }
-  	const char** bas_ext() const;
- 	ulong table_flags() const { return int_table_flags; }
+	const char** bas_ext() const;
+	ulonglong table_flags() const { return int_table_flags; }
 	ulong index_flags(uint idx, uint part, bool all_parts) const
 	{
 	  return (HA_READ_NEXT |
 		  HA_READ_PREV |
 		  HA_READ_ORDER |
 		  HA_READ_RANGE |
-                  HA_KEYREAD_ONLY);
+		  HA_KEYREAD_ONLY);
 	}
-  	uint max_supported_keys()          const { return MAX_KEY; }
+	uint max_supported_keys()	   const { return MAX_KEY; }
 				/* An InnoDB page must store >= 2 keys;
 				a secondary key record must also contain the
 				primary key value:
@@ -105,96 +107,102 @@
 				less than 1 / 4 of page size which is 16 kB;
 				but currently MySQL does not work with keys
 				whose size is > MAX_KEY_LENGTH */
-  	uint max_supported_key_length() const { return 3500; }
-  	uint max_supported_key_part_length() const;
+	uint max_supported_key_length() const { return 3500; }
+	uint max_supported_key_part_length() const;
 	const key_map *keys_to_use_for_scanning() { return &key_map_full; }
-  	bool has_transactions()  { return 1;}
 
-  	int open(const char *name, int mode, uint test_if_locked);
-  	int close(void);
-  	double scan_time();
+	int open(const char *name, int mode, uint test_if_locked);
+	int close(void);
+	double scan_time();
 	double read_time(uint index, uint ranges, ha_rows rows);
 
-  	int write_row(byte * buf);
-  	int update_row(const byte * old_data, byte * new_data);
-  	int delete_row(const byte * buf);
+	int write_row(byte * buf);
+	int update_row(const byte * old_data, byte * new_data);
+	int delete_row(const byte * buf);
+	bool was_semi_consistent_read();
+	void try_semi_consistent_read(bool yes);
 	void unlock_row();
 
-  	int index_init(uint index);
-  	int index_end();
-  	int index_read(byte * buf, const byte * key,
-		       uint key_len, enum ha_rkey_function find_flag);
-  	int index_read_idx(byte * buf, uint index, const byte * key,
+	int index_init(uint index, bool sorted);
+	int index_end();
+	int index_read(byte * buf, const byte * key,
+		uint key_len, enum ha_rkey_function find_flag);
+	int index_read_idx(byte * buf, uint index, const byte * key,
 			   uint key_len, enum ha_rkey_function find_flag);
 	int index_read_last(byte * buf, const byte * key, uint key_len);
-  	int index_next(byte * buf);
-  	int index_next_same(byte * buf, const byte *key, uint keylen);
-  	int index_prev(byte * buf);
-  	int index_first(byte * buf);
-  	int index_last(byte * buf);
-
-  	int rnd_init(bool scan);
-  	int rnd_end();
-  	int rnd_next(byte *buf);
-  	int rnd_pos(byte * buf, byte *pos);
-
-  	void position(const byte *record);
-  	int info(uint);
-        int analyze(THD* thd,HA_CHECK_OPT* check_opt);
-        int optimize(THD* thd,HA_CHECK_OPT* check_opt);
+	int index_next(byte * buf);
+	int index_next_same(byte * buf, const byte *key, uint keylen);
+	int index_prev(byte * buf);
+	int index_first(byte * buf);
+	int index_last(byte * buf);
+
+	int rnd_init(bool scan);
+	int rnd_end();
+	int rnd_next(byte *buf);
+	int rnd_pos(byte * buf, byte *pos);
+
+	void position(const byte *record);
+	int info(uint);
+	int analyze(THD* thd,HA_CHECK_OPT* check_opt);
+	int optimize(THD* thd,HA_CHECK_OPT* check_opt);
 	int discard_or_import_tablespace(my_bool discard);
-  	int extra(enum ha_extra_function operation);
-  	int external_lock(THD *thd, int lock_type);
+	int extra(enum ha_extra_function operation);
+        int reset();
+	int external_lock(THD *thd, int lock_type);
 	int transactional_table_lock(THD *thd, int lock_type);
-        int start_stmt(THD *thd, thr_lock_type lock_type);
-
-  	void position(byte *record);
-  	ha_rows records_in_range(uint inx, key_range *min_key, key_range
+	int start_stmt(THD *thd, thr_lock_type lock_type);
+	void position(byte *record);
+	ha_rows records_in_range(uint inx, key_range *min_key, key_range
 								*max_key);
 	ha_rows estimate_rows_upper_bound();
 
-  	int create(const char *name, register TABLE *form,
+	int create(const char *name, register TABLE *form,
 					HA_CREATE_INFO *create_info);
 	int delete_all_rows();
-  	int delete_table(const char *name);
+	int delete_table(const char *name);
 	int rename_table(const char* from, const char* to);
 	int check(THD* thd, HA_CHECK_OPT* check_opt);
-        char* update_table_comment(const char* comment);
+	char* update_table_comment(const char* comment);
 	char* get_foreign_key_create_info();
-        int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
+	int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
 	bool can_switch_engines();
-  	uint referenced_by_foreign_key();
+	uint referenced_by_foreign_key();
 	void free_foreign_key_create_info(char* str);
-  	THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
-			     		enum thr_lock_type lock_type);
+	THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
+					enum thr_lock_type lock_type);
 	void init_table_handle_for_HANDLER();
-	ulonglong get_auto_increment();
+        virtual void get_auto_increment(ulonglong offset, ulonglong increment,
+                                        ulonglong nb_desired_values,
+                                        ulonglong *first_value,
+                                        ulonglong *nb_reserved_values);
 	int reset_auto_increment(ulonglong value);
 
 	virtual bool get_error_message(int error, String *buf);
 
-        uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
-        /*
-          ask handler about permission to cache table during query registration
-        */
-        my_bool register_query_cache_table(THD *thd, char *table_key,
+	uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
+	/*
+	  ask handler about permission to cache table during query registration
+	*/
+	my_bool register_query_cache_table(THD *thd, char *table_key,
 					   uint key_length,
 					   qc_engine_callback *call_back,
 					   ulonglong *engine_data)
-        {
-          *call_back= innobase_query_caching_of_table_permitted;
-          *engine_data= 0;
-          return innobase_query_caching_of_table_permitted(thd, table_key,
-                                                           key_length,
-                                                           engine_data);
-        }
-        static char *get_mysql_bin_log_name();
-        static ulonglong get_mysql_bin_log_pos();
-        bool primary_key_is_clustered() { return true; }
-        int cmp_ref(const byte *ref1, const byte *ref2);
+	{
+	  *call_back= innobase_query_caching_of_table_permitted;
+	  *engine_data= 0;
+	  return innobase_query_caching_of_table_permitted(thd, table_key,
+							   key_length,
+							   engine_data);
+	}
+	static char *get_mysql_bin_log_name();
+	static ulonglong get_mysql_bin_log_pos();
+	bool primary_key_is_clustered() { return true; }
+	int cmp_ref(const byte *ref1, const byte *ref2);
+	bool check_if_incompatible_data(HA_CREATE_INFO *info,
+					uint table_changes);
 };
 
-extern struct show_var_st innodb_status_variables[];
+extern SHOW_VAR innodb_status_variables[];
 extern ulong innobase_fast_shutdown;
 extern ulong innobase_large_page_size;
 extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
@@ -210,18 +218,13 @@
 extern char *innobase_unix_file_flush_method;
 /* The following variables have to be my_bool for SHOW VARIABLES to work */
 extern my_bool innobase_log_archive,
-               innobase_use_doublewrite,
-               innobase_use_checksums,
-               innobase_use_large_pages,
-               innobase_use_native_aio,
-	       innobase_file_per_table, innobase_locks_unsafe_for_binlog,
-	       innobase_rollback_on_timeout,
-               innobase_create_status_file;
-extern my_bool innobase_very_fast_shutdown; /* set this to 1 just before
-					    calling innobase_end() if you want
-					    InnoDB to shut down without
-					    flushing the buffer pool: this
-					    is equivalent to a 'crash' */
+	innobase_use_doublewrite,
+	innobase_use_checksums,
+	innobase_use_large_pages,
+	innobase_use_native_aio,
+	innobase_file_per_table, innobase_locks_unsafe_for_binlog,
+	innobase_rollback_on_timeout,
+	innobase_create_status_file;
 extern "C" {
 extern ulong srv_max_buf_pool_modified_pct;
 extern ulong srv_max_purge_lag;
@@ -234,9 +237,9 @@
 extern ulong srv_flush_log_at_trx_commit;
 }
 
-bool innobase_init(void);
-bool innobase_end(void);
-bool innobase_flush_logs(void);
+int innobase_init(void);
+int innobase_end(handlerton *hton, ha_panic_function type);
+bool innobase_flush_logs(handlerton *hton);
 uint innobase_get_free_space(void);
 
 /*
@@ -245,24 +248,22 @@
 */
 #if 0
 int innobase_report_binlog_offset_and_commit(
-        THD*    thd,
+	THD*	thd,
 	void*	trx_handle,
-        char*   log_file_name,
-        my_off_t end_offset);
+	char*	log_file_name,
+	my_off_t end_offset);
 int innobase_commit_complete(void* trx_handle);
 void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
 #endif
 
-int innobase_drop_database(char *path);
-bool innodb_show_status(THD* thd);
-bool innodb_mutex_show_status(THD* thd);
-void innodb_export_status(void);
+void innobase_drop_database(handlerton *hton, char *path);
+bool innobase_show_status(handlerton *hton, THD* thd, stat_print_fn*, enum ha_stat_type);
 
-void innobase_release_temporary_latches(THD *thd);
+int innobase_release_temporary_latches(handlerton *hton, THD *thd);
 
-void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
+void innobase_store_binlog_offset_and_flush_log(handlerton *hton, char *binlog_name,longlong offset);
 
-int innobase_start_trx_and_assign_read_view(THD* thd);
+int innobase_start_trx_and_assign_read_view(handlerton *hton, THD* thd);
 
 /***********************************************************************
 This function is used to prepare X/Open XA distributed transaction   */
@@ -270,6 +271,7 @@
 int innobase_xa_prepare(
 /*====================*/
 			/* out: 0 or error number */
+        handlerton *hton, /* in: innobase hton */
 	THD*	thd,	/* in: handle to the MySQL thread of the user
 			whose XA transaction should be prepared */
 	bool	all);	/* in: TRUE - commit transaction
@@ -282,7 +284,8 @@
 /*====================*/
 				/* out: number of prepared transactions
 				stored in xid_list */
-	XID*    xid_list, 	/* in/out: prepared transactions */
+        handlerton *hton, /* in: innobase hton */
+	XID*	xid_list,	/* in/out: prepared transactions */
 	uint	len);		/* in: number of slots in xid_list */
 
 /***********************************************************************
@@ -292,6 +295,7 @@
 int innobase_commit_by_xid(
 /*=======================*/
 			/* out: 0 or error number */
+        handlerton *hton, /* in: innobase hton */
 	XID*	xid);	/* in : X/Open XA Transaction Identification */
 
 /***********************************************************************
@@ -300,6 +304,7 @@
 
 int innobase_rollback_by_xid(
 			/* out: 0 or error number */
+        handlerton *hton, /* in: innobase hton */
 	XID	*xid);	/* in : X/Open XA Transaction Identification */
 
 
@@ -310,9 +315,10 @@
 using a cursor. */
 
 void*
-innobase_create_cursor_view(void);
-/*=============================*/
-				/* out: Pointer to cursor view or NULL */
+innobase_create_cursor_view(
+			  /* out: Pointer to cursor view or NULL */
+        handlerton *hton, /* in: innobase hton */
+	THD* thd);	  /* in: user thread handle */
 
 /***********************************************************************
 Close the given consistent cursor view of a transaction and restore
@@ -322,8 +328,11 @@
 void
 innobase_close_cursor_view(
 /*=======================*/
+        handlerton *hton, /* in: innobase hton */
+	THD*	thd,		/* in: user thread handle */
 	void*	curview);	/* in: Consistent read view to be closed */
 
+
 /***********************************************************************
 Set the given consistent cursor view to a transaction which is created
 if the corresponding MySQL thread still lacks one. If the given
@@ -333,4 +342,6 @@
 void
 innobase_set_cursor_view(
 /*=====================*/
+        handlerton *hton, /* in: innobase hton */
+	THD*	thd,		/* in: user thread handle */
 	void*	curview);	/* in: Consistent read view to be set */
Thread
bk commit into 5.1 tree (tsmith:1.2425)tim22 Jan