Commit 9b765549 authored by marko's avatar marko

branches/zip: Merge revisions 1271:1322 from trunk.

parent d5028fac
...@@ -1977,9 +1977,12 @@ dict_foreign_find_index( ...@@ -1977,9 +1977,12 @@ dict_foreign_find_index(
ulint n_cols, /* in: number of columns */ ulint n_cols, /* in: number of columns */
dict_index_t* types_idx, /* in: NULL or an index to whose types the dict_index_t* types_idx, /* in: NULL or an index to whose types the
column types must match */ column types must match */
ibool check_charsets) ibool check_charsets,
/* in: whether to check charsets. /* in: whether to check charsets.
only has an effect if types_idx != NULL */ only has an effect if types_idx != NULL */
ulint check_null)
/* in: nonzero if none of the columns must
be declared NOT NULL */
{ {
dict_index_t* index; dict_index_t* index;
dict_field_t* field; dict_field_t* field;
...@@ -2009,6 +2012,12 @@ dict_foreign_find_index( ...@@ -2009,6 +2012,12 @@ dict_foreign_find_index(
break; break;
} }
if (check_null
&& (field->col->prtype & DATA_NOT_NULL)) {
return(NULL);
}
if (types_idx && !cmp_cols_are_equal( if (types_idx && !cmp_cols_are_equal(
dict_index_get_nth_col(index, i), dict_index_get_nth_col(index, i),
dict_index_get_nth_col(types_idx, dict_index_get_nth_col(types_idx,
...@@ -2125,7 +2134,7 @@ dict_foreign_add_to_cache( ...@@ -2125,7 +2134,7 @@ dict_foreign_add_to_cache(
ref_table, ref_table,
(const char**) for_in_cache->referenced_col_names, (const char**) for_in_cache->referenced_col_names,
for_in_cache->n_fields, for_in_cache->foreign_index, for_in_cache->n_fields, for_in_cache->foreign_index,
check_charsets); check_charsets, FALSE);
if (index == NULL) { if (index == NULL) {
dict_foreign_error_report( dict_foreign_error_report(
...@@ -2157,7 +2166,10 @@ dict_foreign_add_to_cache( ...@@ -2157,7 +2166,10 @@ dict_foreign_add_to_cache(
for_table, for_table,
(const char**) for_in_cache->foreign_col_names, (const char**) for_in_cache->foreign_col_names,
for_in_cache->n_fields, for_in_cache->n_fields,
for_in_cache->referenced_index, check_charsets); for_in_cache->referenced_index, check_charsets,
for_in_cache->type
& (DICT_FOREIGN_ON_DELETE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_SET_NULL));
if (index == NULL) { if (index == NULL) {
dict_foreign_error_report( dict_foreign_error_report(
...@@ -2167,7 +2179,9 @@ dict_foreign_add_to_cache( ...@@ -2167,7 +2179,9 @@ dict_foreign_add_to_cache(
"the columns as the first columns," "the columns as the first columns,"
" or the data types in the\n" " or the data types in the\n"
"table do not match" "table do not match"
" the ones in the referenced table."); " the ones in the referenced table\n"
"or one of the ON ... SET NULL columns"
" is declared NOT NULL.");
if (for_in_cache == foreign) { if (for_in_cache == foreign) {
if (added_to_referenced_list) { if (added_to_referenced_list) {
...@@ -2973,7 +2987,8 @@ dict_create_foreign_constraints_low( ...@@ -2973,7 +2987,8 @@ dict_create_foreign_constraints_low(
/* Try to find an index which contains the columns /* Try to find an index which contains the columns
as the first fields and in the right order */ as the first fields and in the right order */
index = dict_foreign_find_index(table, column_names, i, NULL, TRUE); index = dict_foreign_find_index(table, column_names, i,
NULL, TRUE, FALSE);
if (!index) { if (!index) {
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
...@@ -3244,7 +3259,8 @@ dict_create_foreign_constraints_low( ...@@ -3244,7 +3259,8 @@ dict_create_foreign_constraints_low(
if (referenced_table) { if (referenced_table) {
index = dict_foreign_find_index(referenced_table, index = dict_foreign_find_index(referenced_table,
column_names, i, column_names, i,
foreign->foreign_index, TRUE); foreign->foreign_index,
TRUE, FALSE);
if (!index) { if (!index) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
......
...@@ -56,53 +56,6 @@ bool innodb_inited= 0; ...@@ -56,53 +56,6 @@ bool innodb_inited= 0;
*/ */
static handlerton *legacy_innodb_hton; static handlerton *legacy_innodb_hton;
/*-----------------------------------------------------------------*/
/* These variables are used to implement (semi-)synchronous MySQL binlog
replication for InnoDB tables. */
pthread_cond_t innobase_repl_cond; /* Posix cond variable;
this variable is signaled
when enough binlog has been
sent to slave, so that a
waiting trx can return the
'ok' message to the client
for a commit */
pthread_mutex_t innobase_repl_cond_mutex; /* Posix cond variable mutex
that also protects the next
innobase_repl_... variables */
uint innobase_repl_state; /* 1 if synchronous replication
is switched on and is working
ok; else 0 */
uint innobase_repl_file_name_inited = 0; /* This is set to 1 when
innobase_repl_file_name
contains meaningful data */
char* innobase_repl_file_name; /* The binlog name up to which
we have sent some binlog to
the slave */
my_off_t innobase_repl_pos; /* The position in that file
up to which we have sent the
binlog to the slave */
uint innobase_repl_n_wait_threads = 0; /* This tells how many
transactions currently are
waiting for the binlog to be
sent to the client */
uint innobase_repl_wait_file_name_inited = 0; /* This is set to 1
when we know the 'smallest'
wait position */
char* innobase_repl_wait_file_name; /* NULL, or the 'smallest'
innobase_repl_file_name that
a transaction is waiting for */
my_off_t innobase_repl_wait_pos; /* The smallest position in
that file that a trx is
waiting for: the trx can
proceed and send an 'ok' to
the client when MySQL has sent
the binlog up to this position
to the slave */
/*-----------------------------------------------------------------*/
/* Store MySQL definition of 'byte': in Linux it is char while InnoDB /* Store MySQL definition of 'byte': in Linux it is char while InnoDB
uses unsigned char; the header univ.i which we include next defines uses unsigned char; the header univ.i which we include next defines
'byte' as a macro which expands to 'unsigned char' */ 'byte' as a macro which expands to 'unsigned char' */
...@@ -221,6 +174,139 @@ static handler *innobase_create_handler(handlerton *hton, ...@@ -221,6 +174,139 @@ static handler *innobase_create_handler(handlerton *hton,
return new (mem_root) ha_innobase(hton, table); return new (mem_root) ha_innobase(hton, table);
} }
/***********************************************************************
This function is used to prepare X/Open XA distributed transaction */
static
int
innobase_xa_prepare(
/*================*/
/* out: 0 or error number */
handlerton* hton,
THD* thd, /* in: handle to the MySQL thread of the user
whose XA transaction should be prepared */
bool all); /* in: TRUE - commit transaction
FALSE - the current SQL statement ended */
/***********************************************************************
This function is used to recover X/Open XA distributed transactions */
static
int
innobase_xa_recover(
/*================*/
/* out: number of prepared transactions
stored in xid_list */
handlerton* hton,
XID* xid_list, /* in/out: prepared transactions */
uint len); /* in: number of slots in xid_list */
/***********************************************************************
This function is used to commit one X/Open XA distributed transaction
which is in the prepared state */
static
int
innobase_commit_by_xid(
/*===================*/
/* out: 0 or error number */
handlerton* hton,
XID* xid); /* in: X/Open XA transaction identification */
/***********************************************************************
This function is used to rollback one X/Open XA distributed transaction
which is in the prepared state */
static
int
innobase_rollback_by_xid(
/*=====================*/
/* out: 0 or error number */
handlerton* hton,
XID *xid); /* in: X/Open XA transaction identification */
/***********************************************************************
Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records
using a cursor. */
static
void*
innobase_create_cursor_view(
/*========================*/
/* out: pointer to cursor view or NULL */
handlerton* hton, /* in: innobase hton */
THD* thd); /* in: user thread handle */
/***********************************************************************
Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is
restored to a transaction read view. */
static
void
innobase_set_cursor_view(
/*=====================*/
handlerton* hton,
THD* thd, /* in: user thread handle */
void* curview);/* in: Consistent cursor view to be set */
/***********************************************************************
Close the given consistent cursor view of a transaction and restore
global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */
static
void
innobase_close_cursor_view(
/*=======================*/
handlerton* hton,
THD* thd, /* in: user thread handle */
void* curview);/* in: Consistent read view to be closed */
/*********************************************************************
Removes all tables in the named database inside InnoDB. */
static
void
innobase_drop_database(
/*===================*/
/* out: error number */
handlerton* hton, /* in: handlerton of Innodb */
char* path); /* in: database path; inside InnoDB the name
of the last directory in the path is used as
the database name: for example, in 'mysql/data/test'
the database name is 'test' */
/***********************************************************************
Closes an InnoDB database. */
static
int
innobase_end(handlerton *hton, ha_panic_function type);
/*********************************************************************
Creates an InnoDB transaction struct for the thd if it does not yet have one.
Starts a new InnoDB transaction if a transaction is not yet started. And
assigns a new snapshot for a consistent read if the transaction does not yet
have one. */
static
int
innobase_start_trx_and_assign_read_view(
/*====================================*/
/* out: 0 */
handlerton* hton, /* in: Innodb handlerton */
THD* thd); /* in: MySQL thread handle of the user for whom
the transaction should be committed */
/********************************************************************
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
the logs, and the name of this function should be innobase_checkpoint. */
static
bool
innobase_flush_logs(
/*================*/
/* out: TRUE if error */
handlerton* hton); /* in: InnoDB handlerton */
/****************************************************************************
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
Monitor to the client. */
static
bool
innodb_show_status(
/*===============*/
handlerton* hton, /* in: the innodb handlerton */
THD* thd, /* in: the MySQL query thread of the caller */
stat_print_fn *stat_print);
static
bool innobase_show_status(handlerton *hton, THD* thd,
stat_print_fn* stat_print,
enum ha_stat_type stat_type);
/********************************************************************* /*********************************************************************
Commits a transaction in an InnoDB database. */ Commits a transaction in an InnoDB database. */
...@@ -378,11 +464,24 @@ innobase_release_stat_resources( ...@@ -378,11 +464,24 @@ innobase_release_stat_resources(
} }
} }
/************************************************************************
Obtain the InnoDB transaction of a MySQL thread. */
inline
trx_t*&
thd_to_trx(
/*=======*/
/* out: reference to transaction pointer */
THD* thd, /* in: MySQL thread */
handlerton* hton) /* in: InnoDB handlerton */
{
return(*(trx_t**) thd_ha_data(thd, hton));
}
/************************************************************************ /************************************************************************
Call this function when mysqld passes control to the client. That is to Call this function when mysqld passes control to the client. That is to
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
documentation, see handler.cc. */ documentation, see handler.cc. */
static
int int
innobase_release_temporary_latches( innobase_release_temporary_latches(
/*===============================*/ /*===============================*/
...@@ -396,7 +495,7 @@ innobase_release_temporary_latches( ...@@ -396,7 +495,7 @@ innobase_release_temporary_latches(
return 0; return 0;
} }
trx = (trx_t*) thd->ha_data[hton->slot]; trx = thd_to_trx(thd, hton);
if (trx) { if (trx) {
innobase_release_stat_resources(trx); innobase_release_stat_resources(trx);
...@@ -855,12 +954,10 @@ check_trx_exists( ...@@ -855,12 +954,10 @@ check_trx_exists(
handlerton* hton, /* in: handlerton for innodb */ handlerton* hton, /* in: handlerton for innodb */
THD* thd) /* in: user thread handle */ THD* thd) /* in: user thread handle */
{ {
trx_t* trx; trx_t*& trx = thd_to_trx(thd, hton);
ut_ad(thd == current_thd); ut_ad(thd == current_thd);
trx = (trx_t*) thd->ha_data[hton->slot];
if (trx == NULL) { if (trx == NULL) {
DBUG_ASSERT(thd != NULL); DBUG_ASSERT(thd != NULL);
trx = trx_allocate_for_mysql(); trx = trx_allocate_for_mysql();
...@@ -872,8 +969,6 @@ check_trx_exists( ...@@ -872,8 +969,6 @@ check_trx_exists(
/* Update the info whether we should skip XA steps that eat /* Update the info whether we should skip XA steps that eat
CPU time */ CPU time */
trx->support_xa = (ibool)(thd->variables.innodb_support_xa); trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
thd->ha_data[hton->slot] = trx;
} else { } else {
if (trx->magic_n != TRX_MAGIC_N) { if (trx->magic_n != TRX_MAGIC_N) {
mem_analyze_corruption(trx); mem_analyze_corruption(trx);
...@@ -1324,7 +1419,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) ...@@ -1324,7 +1419,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/************************************************************************* /*************************************************************************
Opens an InnoDB database. */ Opens an InnoDB database. */
static
int int
innobase_init(void *p) innobase_init(void *p)
/*===============*/ /*===============*/
...@@ -1591,7 +1686,7 @@ innobase_init(void *p) ...@@ -1591,7 +1686,7 @@ innobase_init(void *p)
/*********************************************************************** /***********************************************************************
Closes an InnoDB database. */ Closes an InnoDB database. */
static
int int
innobase_end(handlerton *hton, ha_panic_function type) innobase_end(handlerton *hton, ha_panic_function type)
/*==============*/ /*==============*/
...@@ -1629,7 +1724,7 @@ innobase_end(handlerton *hton, ha_panic_function type) ...@@ -1629,7 +1724,7 @@ innobase_end(handlerton *hton, ha_panic_function type)
/******************************************************************** /********************************************************************
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
the logs, and the name of this function should be innobase_checkpoint. */ the logs, and the name of this function should be innobase_checkpoint. */
static
bool bool
innobase_flush_logs(handlerton *hton) innobase_flush_logs(handlerton *hton)
/*=====================*/ /*=====================*/
...@@ -1665,7 +1760,7 @@ Creates an InnoDB transaction struct for the thd if it does not yet have one. ...@@ -1665,7 +1760,7 @@ Creates an InnoDB transaction struct for the thd if it does not yet have one.
Starts a new InnoDB transaction if a transaction is not yet started. And Starts a new InnoDB transaction if a transaction is not yet started. And
assigns a new snapshot for a consistent read if the transaction does not yet assigns a new snapshot for a consistent read if the transaction does not yet
have one. */ have one. */
static
int int
innobase_start_trx_and_assign_read_view( innobase_start_trx_and_assign_read_view(
/*====================================*/ /*====================================*/
...@@ -1879,7 +1974,7 @@ innobase_report_binlog_offset_and_commit( ...@@ -1879,7 +1974,7 @@ innobase_report_binlog_offset_and_commit(
#if 0 #if 0
/*********************************************************************** /***********************************************************************
This function stores the binlog offset and flushes logs. */ This function stores the binlog offset and flushes logs. */
static
void void
innobase_store_binlog_offset_and_flush_log( innobase_store_binlog_offset_and_flush_log(
/*=======================================*/ /*=======================================*/
...@@ -1922,7 +2017,7 @@ innobase_commit_complete( ...@@ -1922,7 +2017,7 @@ innobase_commit_complete(
{ {
trx_t* trx; trx_t* trx;
trx = (trx_t*) thd->ha_data[hton->slot]; trx = thd_to_trx(thd, hton);
if (trx && trx->active_trans) { if (trx && trx->active_trans) {
...@@ -2146,7 +2241,7 @@ innobase_close_connection( ...@@ -2146,7 +2241,7 @@ innobase_close_connection(
{ {
trx_t* trx; trx_t* trx;
trx = (trx_t*)thd->ha_data[hton->slot]; trx = thd_to_trx(thd, hton);
ut_a(trx); ut_a(trx);
...@@ -2333,7 +2428,7 @@ ha_innobase::open( ...@@ -2333,7 +2428,7 @@ ha_innobase::open(
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
} }
if (ib_table->ibd_file_missing && !thd->tablespace_op) { if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
sql_print_error("MySQL is trying to open a table handle but " sql_print_error("MySQL is trying to open a table handle but "
"the .ibd file for\ntable %s does not exist.\n" "the .ibd file for\ntable %s does not exist.\n"
...@@ -3232,29 +3327,27 @@ ha_innobase::write_row( ...@@ -3232,29 +3327,27 @@ ha_innobase::write_row(
longlong auto_inc; longlong auto_inc;
longlong dummy; longlong dummy;
ibool auto_inc_used= FALSE; ibool auto_inc_used= FALSE;
THD* thd = current_thd;
trx_t* trx = thd_to_trx(thd, ht);
DBUG_ENTER("ha_innobase::write_row"); DBUG_ENTER("ha_innobase::write_row");
if (prebuilt->trx != if (prebuilt->trx != trx) {
(trx_t*) current_thd->ha_data[ht->slot]) {
sql_print_error("The transaction object for the table handle is at " sql_print_error("The transaction object for the table handle is at "
"%p, but for the current thread it is at %p", "%p, but for the current thread it is at %p",
prebuilt->trx, prebuilt->trx, trx);
(trx_t*) current_thd->ha_data[ht->slot]);
fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
fputs("\n" fputs("\n"
"InnoDB: Dump of 200 bytes around transaction.all: ", "InnoDB: Dump of 200 bytes around ha_data: ",
stderr); stderr);
ut_print_buf(stderr, ut_print_buf(stderr, ((const byte*) trx) - 100, 200);
((byte*)(&(current_thd->ha_data[ht->slot]))) - 100,
200);
putc('\n', stderr); putc('\n', stderr);
ut_error; ut_error;
} }
statistic_increment(current_thd->status_var.ha_write_count, statistic_increment(thd->status_var.ha_write_count,
&LOCK_status); &LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
...@@ -3620,11 +3713,11 @@ ha_innobase::update_row( ...@@ -3620,11 +3713,11 @@ ha_innobase::update_row(
{ {
upd_t* uvect; upd_t* uvect;
int error = 0; int error = 0;
trx_t* trx = thd_to_trx(current_thd, ht);
DBUG_ENTER("ha_innobase::update_row"); DBUG_ENTER("ha_innobase::update_row");
ut_a(prebuilt->trx == ut_a(prebuilt->trx == trx);
(trx_t*) current_thd->ha_data[ht->slot]);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time(); table->timestamp_field->set_time();
...@@ -3633,7 +3726,7 @@ ha_innobase::update_row( ...@@ -3633,7 +3726,7 @@ ha_innobase::update_row(
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id; last_query_id = user_thd->query_id;
innobase_release_stat_resources(prebuilt->trx); innobase_release_stat_resources(trx);
} }
if (prebuilt->upd_node) { if (prebuilt->upd_node) {
...@@ -3654,11 +3747,11 @@ ha_innobase::update_row( ...@@ -3654,11 +3747,11 @@ ha_innobase::update_row(
assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW); assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
innodb_srv_conc_enter_innodb(prebuilt->trx); innodb_srv_conc_enter_innodb(trx);
error = row_update_for_mysql((byte*) old_row, prebuilt); error = row_update_for_mysql((byte*) old_row, prebuilt);
innodb_srv_conc_exit_innodb(prebuilt->trx); innodb_srv_conc_exit_innodb(trx);
error = convert_error_code_to_mysql(error, user_thd); error = convert_error_code_to_mysql(error, user_thd);
...@@ -3680,17 +3773,17 @@ ha_innobase::delete_row( ...@@ -3680,17 +3773,17 @@ ha_innobase::delete_row(
const mysql_byte* record) /* in: a row in MySQL format */ const mysql_byte* record) /* in: a row in MySQL format */
{ {
int error = 0; int error = 0;
trx_t* trx = thd_to_trx(current_thd, ht);
DBUG_ENTER("ha_innobase::delete_row"); DBUG_ENTER("ha_innobase::delete_row");
ut_a(prebuilt->trx == ut_a(prebuilt->trx == trx);
(trx_t*) current_thd->ha_data[ht->slot]);
if (last_query_id != user_thd->query_id) { if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id; last_query_id = user_thd->query_id;
innobase_release_stat_resources(prebuilt->trx); innobase_release_stat_resources(trx);
} }
if (!prebuilt->upd_node) { if (!prebuilt->upd_node) {
...@@ -3701,11 +3794,11 @@ ha_innobase::delete_row( ...@@ -3701,11 +3794,11 @@ ha_innobase::delete_row(
prebuilt->upd_node->is_delete = TRUE; prebuilt->upd_node->is_delete = TRUE;
innodb_srv_conc_enter_innodb(prebuilt->trx); innodb_srv_conc_enter_innodb(trx);
error = row_update_for_mysql((byte*) record, prebuilt); error = row_update_for_mysql((byte*) record, prebuilt);
innodb_srv_conc_exit_innodb(prebuilt->trx); innodb_srv_conc_exit_innodb(trx);
error = convert_error_code_to_mysql(error, user_thd); error = convert_error_code_to_mysql(error, user_thd);
...@@ -3733,7 +3826,7 @@ ha_innobase::unlock_row(void) ...@@ -3733,7 +3826,7 @@ ha_innobase::unlock_row(void)
sql_print_error("last_query_id is %lu != user_thd_query_id is " sql_print_error("last_query_id is %lu != user_thd_query_id is "
"%lu", (ulong) last_query_id, "%lu", (ulong) last_query_id,
(ulong) user_thd->query_id); (ulong) user_thd->query_id);
mem_analyze_corruption((byte *) prebuilt->trx); mem_analyze_corruption(prebuilt->trx);
ut_error; ut_error;
} }
...@@ -3775,8 +3868,7 @@ void ...@@ -3775,8 +3868,7 @@ void
ha_innobase::try_semi_consistent_read(bool yes) ha_innobase::try_semi_consistent_read(bool yes)
/*===========================================*/ /*===========================================*/
{ {
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
/* Row read type is set to semi consistent read if this was /* Row read type is set to semi consistent read if this was
requested by the MySQL and either innodb_locks_unsafe_for_binlog requested by the MySQL and either innodb_locks_unsafe_for_binlog
...@@ -3941,8 +4033,7 @@ ha_innobase::index_read( ...@@ -3941,8 +4033,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read"); DBUG_ENTER("index_read");
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
statistic_increment(current_thd->status_var.ha_read_key_count, statistic_increment(current_thd->status_var.ha_read_key_count,
&LOCK_status); &LOCK_status);
...@@ -4050,13 +4141,12 @@ ha_innobase::change_active_index( ...@@ -4050,13 +4141,12 @@ ha_innobase::change_active_index(
InnoDB */ InnoDB */
{ {
KEY* key=0; KEY* key=0;
statistic_increment(current_thd->status_var.ha_read_key_count, THD* thd = current_thd;
&LOCK_status); statistic_increment(thd->status_var.ha_read_key_count, &LOCK_status);
DBUG_ENTER("change_active_index"); DBUG_ENTER("change_active_index");
ut_ad(user_thd == current_thd); ut_ad(user_thd == thd);
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
active_index = keynr; active_index = keynr;
...@@ -4144,8 +4234,7 @@ ha_innobase::general_fetch( ...@@ -4144,8 +4234,7 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch"); DBUG_ENTER("general_fetch");
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
innodb_srv_conc_enter_innodb(prebuilt->trx); innodb_srv_conc_enter_innodb(prebuilt->trx);
...@@ -4377,8 +4466,7 @@ ha_innobase::rnd_pos( ...@@ -4377,8 +4466,7 @@ ha_innobase::rnd_pos(
statistic_increment(current_thd->status_var.ha_read_rnd_count, statistic_increment(current_thd->status_var.ha_read_rnd_count,
&LOCK_status); &LOCK_status);
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we /* No primary key was defined for the table and we
...@@ -4426,8 +4514,7 @@ ha_innobase::position( ...@@ -4426,8 +4514,7 @@ ha_innobase::position(
{ {
uint len; uint len;
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we /* No primary key was defined for the table and we
...@@ -4931,9 +5018,9 @@ ha_innobase::discard_or_import_tablespace( ...@@ -4931,9 +5018,9 @@ ha_innobase::discard_or_import_tablespace(
DBUG_ENTER("ha_innobase::discard_or_import_tablespace"); DBUG_ENTER("ha_innobase::discard_or_import_tablespace");
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); ut_a(prebuilt->trx);
ut_a(prebuilt->trx == ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
(trx_t*) current_thd->ha_data[ht->slot]); ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
dict_table = prebuilt->table; dict_table = prebuilt->table;
trx = prebuilt->trx; trx = prebuilt->trx;
...@@ -5074,7 +5161,7 @@ ha_innobase::delete_table( ...@@ -5074,7 +5161,7 @@ ha_innobase::delete_table(
/********************************************************************* /*********************************************************************
Removes all tables in the named database inside InnoDB. */ Removes all tables in the named database inside InnoDB. */
static
void void
innobase_drop_database( innobase_drop_database(
/*===================*/ /*===================*/
...@@ -5259,8 +5346,7 @@ ha_innobase::records_in_range( ...@@ -5259,8 +5346,7 @@ ha_innobase::records_in_range(
DBUG_ENTER("records_in_range"); DBUG_ENTER("records_in_range");
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
prebuilt->trx->op_info = (char*)"estimating records in index range"; prebuilt->trx->op_info = (char*)"estimating records in index range";
...@@ -5690,8 +5776,7 @@ ha_innobase::check( ...@@ -5690,8 +5776,7 @@ ha_innobase::check(
ulint ret; ulint ret;
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
if (prebuilt->mysql_template == NULL) { if (prebuilt->mysql_template == NULL) {
/* Build the template; we will use a dummy template /* Build the template; we will use a dummy template
...@@ -5988,8 +6073,7 @@ ha_innobase::can_switch_engines(void) ...@@ -5988,8 +6073,7 @@ ha_innobase::can_switch_engines(void)
DBUG_ENTER("ha_innobase::can_switch_engines"); DBUG_ENTER("ha_innobase::can_switch_engines");
ut_a(prebuilt->trx == ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
(trx_t*) current_thd->ha_data[ht->slot]);
prebuilt->trx->op_info = prebuilt->trx->op_info =
"determining if there are foreign key constraints"; "determining if there are foreign key constraints";
...@@ -6097,7 +6181,7 @@ on that table. ...@@ -6097,7 +6181,7 @@ on that table.
MySQL-5.0 also calls this before each statement in an execution of a stored MySQL-5.0 also calls this before each statement in an execution of a stored
procedure. To make the execution more deterministic for binlogging, MySQL-5.0 procedure. To make the execution more deterministic for binlogging, MySQL-5.0
locks all tables involved in a stored procedure with full explicit table locks all tables involved in a stored procedure with full explicit table
locks (thd->in_lock_tables is true in ::store_lock()) before executing the locks (thd_in_lock_tables(thd) holds in store_lock()) before executing the
procedure. */ procedure. */
int int
...@@ -6270,16 +6354,16 @@ ha_innobase::external_lock( ...@@ -6270,16 +6354,16 @@ ha_innobase::external_lock(
VERY easily deadlocks. VERY easily deadlocks.
We do not set InnoDB table locks if user has not explicitly We do not set InnoDB table locks if user has not explicitly
requested a table lock. Note that thd->in_lock_tables requested a table lock. Note that thd_in_lock_tables(thd)
can be TRUE on some cases e.g. at the start of a stored can hold in some cases, e.g., at the start of a stored
procedure call (SQLCOM_CALL). */ procedure call (SQLCOM_CALL). */
if (prebuilt->select_lock_type != LOCK_NONE) { if (prebuilt->select_lock_type != LOCK_NONE) {
if (thd->in_lock_tables && if (thd->lex->sql_command == SQLCOM_LOCK_TABLES
thd->lex->sql_command == SQLCOM_LOCK_TABLES && && thd->variables.innodb_table_locks
thd->variables.innodb_table_locks && && (thd->options & OPTION_NOT_AUTOCOMMIT)
(thd->options & OPTION_NOT_AUTOCOMMIT)) { && thd_in_lock_tables(thd)) {
ulint error = row_lock_table_for_mysql( ulint error = row_lock_table_for_mysql(
prebuilt, NULL, 0); prebuilt, NULL, 0);
...@@ -6357,7 +6441,8 @@ ha_innobase::transactional_table_lock( ...@@ -6357,7 +6441,8 @@ ha_innobase::transactional_table_lock(
update_thd(thd); update_thd(thd);
if (prebuilt->table->ibd_file_missing && !current_thd->tablespace_op) { if (prebuilt->table->ibd_file_missing
&& !thd_tablespace_op(current_thd)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB error:\n" fprintf(stderr, " InnoDB error:\n"
"MySQL is trying to use a table handle but the .ibd file for\n" "MySQL is trying to use a table handle but the .ibd file for\n"
...@@ -6402,7 +6487,7 @@ ha_innobase::transactional_table_lock( ...@@ -6402,7 +6487,7 @@ ha_innobase::transactional_table_lock(
trx->active_trans = 1; trx->active_trans = 1;
} }
if (thd->in_lock_tables && thd->variables.innodb_table_locks) { if (thd->variables.innodb_table_locks && thd_in_lock_tables(thd)) {
ulint error = DB_SUCCESS; ulint error = DB_SUCCESS;
error = row_lock_table_for_mysql(prebuilt, NULL, 0); error = row_lock_table_for_mysql(prebuilt, NULL, 0);
...@@ -6442,7 +6527,7 @@ innodb_export_status() ...@@ -6442,7 +6527,7 @@ innodb_export_status()
/**************************************************************************** /****************************************************************************
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
Monitor to the client. */ Monitor to the client. */
static
bool bool
innodb_show_status( innodb_show_status(
/*===============*/ /*===============*/
...@@ -6632,6 +6717,7 @@ innodb_mutex_show_status( ...@@ -6632,6 +6717,7 @@ innodb_mutex_show_status(
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
static
bool innobase_show_status(handlerton *hton, THD* thd, bool innobase_show_status(handlerton *hton, THD* thd,
stat_print_fn* stat_print, stat_print_fn* stat_print,
enum ha_stat_type stat_type) enum ha_stat_type stat_type)
...@@ -6755,14 +6841,16 @@ ha_innobase::store_lock( ...@@ -6755,14 +6841,16 @@ ha_innobase::store_lock(
thd->variables.tx_isolation); thd->variables.tx_isolation);
} }
const bool in_lock_tables = thd_in_lock_tables(thd);
if (thd->lex->sql_command == SQLCOM_DROP_TABLE) { if (thd->lex->sql_command == SQLCOM_DROP_TABLE) {
/* MySQL calls this function in DROP TABLE though this table /* MySQL calls this function in DROP TABLE though this table
handle may belong to another thd that is running a query. Let handle may belong to another thd that is running a query. Let
us in that case skip any changes to the prebuilt struct. */ us in that case skip any changes to the prebuilt struct. */
} else if ((lock_type == TL_READ && thd->in_lock_tables) || } else if ((lock_type == TL_READ && in_lock_tables) ||
(lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) || (lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables) ||
lock_type == TL_READ_WITH_SHARED_LOCKS || lock_type == TL_READ_WITH_SHARED_LOCKS ||
lock_type == TL_READ_NO_INSERT || lock_type == TL_READ_NO_INSERT ||
(thd->lex->sql_command != SQLCOM_SELECT (thd->lex->sql_command != SQLCOM_SELECT
...@@ -6833,7 +6921,7 @@ ha_innobase::store_lock( ...@@ -6833,7 +6921,7 @@ ha_innobase::store_lock(
/* Starting from 5.0.7, we weaken also the table locks /* Starting from 5.0.7, we weaken also the table locks
set at the start of a MySQL stored procedure call, just like set at the start of a MySQL stored procedure call, just like
we weaken the locks set at the start of an SQL statement. we weaken the locks set at the start of an SQL statement.
MySQL does set thd->in_lock_tables TRUE there, but in reality MySQL does set in_lock_tables TRUE there, but in reality
we do not need table locks to make the execution of a we do not need table locks to make the execution of a
single transaction stored procedure call deterministic single transaction stored procedure call deterministic
(if it does not use a consistent read). */ (if it does not use a consistent read). */
...@@ -6861,14 +6949,14 @@ ha_innobase::store_lock( ...@@ -6861,14 +6949,14 @@ ha_innobase::store_lock(
We especially allow multiple writers if MySQL is at the We especially allow multiple writers if MySQL is at the
start of a stored procedure call (SQLCOM_CALL) or a start of a stored procedure call (SQLCOM_CALL) or a
stored function call (MySQL does have thd->in_lock_tables stored function call (MySQL does have in_lock_tables
TRUE there). */ TRUE there). */
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
&& lock_type <= TL_WRITE) && lock_type <= TL_WRITE)
&& !(thd->in_lock_tables && !(in_lock_tables
&& thd->lex->sql_command == SQLCOM_LOCK_TABLES) && thd->lex->sql_command == SQLCOM_LOCK_TABLES)
&& !thd->tablespace_op && !thd_tablespace_op(thd)
&& thd->lex->sql_command != SQLCOM_TRUNCATE && thd->lex->sql_command != SQLCOM_TRUNCATE
&& thd->lex->sql_command != SQLCOM_OPTIMIZE && thd->lex->sql_command != SQLCOM_OPTIMIZE
...@@ -6895,7 +6983,7 @@ ha_innobase::store_lock( ...@@ -6895,7 +6983,7 @@ ha_innobase::store_lock(
We especially allow concurrent inserts if MySQL is at the We especially allow concurrent inserts if MySQL is at the
start of a stored procedure call (SQLCOM_CALL) start of a stored procedure call (SQLCOM_CALL)
(MySQL does have thd->in_lock_tables TRUE there). */ (MySQL does have in_lock_tables TRUE there). */
if (lock_type == TL_READ_NO_INSERT if (lock_type == TL_READ_NO_INSERT
&& thd->lex->sql_command != SQLCOM_LOCK_TABLES) { && thd->lex->sql_command != SQLCOM_LOCK_TABLES) {
...@@ -7337,7 +7425,7 @@ innobase_query_is_update(void) ...@@ -7337,7 +7425,7 @@ innobase_query_is_update(void)
/*********************************************************************** /***********************************************************************
This function is used to prepare X/Open XA distributed transaction */ This function is used to prepare X/Open XA distributed transaction */
static
int int
innobase_xa_prepare( innobase_xa_prepare(
/*================*/ /*================*/
...@@ -7433,7 +7521,7 @@ innobase_xa_prepare( ...@@ -7433,7 +7521,7 @@ innobase_xa_prepare(
/*********************************************************************** /***********************************************************************
This function is used to recover X/Open XA distributed transactions */ This function is used to recover X/Open XA distributed transactions */
static
int int
innobase_xa_recover( innobase_xa_recover(
/*================*/ /*================*/
...@@ -7454,7 +7542,7 @@ innobase_xa_recover( ...@@ -7454,7 +7542,7 @@ innobase_xa_recover(
/*********************************************************************** /***********************************************************************
This function is used to commit one X/Open XA distributed transaction This function is used to commit one X/Open XA distributed transaction
which is in the prepared state */ which is in the prepared state */
static
int int
innobase_commit_by_xid( innobase_commit_by_xid(
/*===================*/ /*===================*/
...@@ -7478,7 +7566,7 @@ innobase_commit_by_xid( ...@@ -7478,7 +7566,7 @@ innobase_commit_by_xid(
/*********************************************************************** /***********************************************************************
This function is used to rollback one X/Open XA distributed transaction This function is used to rollback one X/Open XA distributed transaction
which is in the prepared state */ which is in the prepared state */
static
int int
innobase_rollback_by_xid( innobase_rollback_by_xid(
/*=====================*/ /*=====================*/
...@@ -7502,9 +7590,10 @@ Create a consistent view for a cursor based on current transaction ...@@ -7502,9 +7590,10 @@ Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one. which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records This consistent view is then used inside of MySQL when accessing records
using a cursor. */ using a cursor. */
static
void* void*
innobase_create_cursor_view( innobase_create_cursor_view(
/*========================*/
/* out: pointer to cursor view or NULL */ /* out: pointer to cursor view or NULL */
handlerton *hton, /* in: innobase hton */ handlerton *hton, /* in: innobase hton */
THD* thd) /* in: user thread handle */ THD* thd) /* in: user thread handle */
...@@ -7517,9 +7606,10 @@ innobase_create_cursor_view( ...@@ -7517,9 +7606,10 @@ innobase_create_cursor_view(
Close the given consistent cursor view of a transaction and restore Close the given consistent cursor view of a transaction and restore
global read view to a transaction read view. Transaction is created if the global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */ corresponding MySQL thread still lacks one. */
static
void void
innobase_close_cursor_view( innobase_close_cursor_view(
/*=======================*/
handlerton *hton, handlerton *hton,
THD* thd, /* in: user thread handle */ THD* thd, /* in: user thread handle */
void* curview)/* in: Consistent read view to be closed */ void* curview)/* in: Consistent read view to be closed */
...@@ -7533,7 +7623,7 @@ Set the given consistent cursor view to a transaction which is created ...@@ -7533,7 +7623,7 @@ Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is consistent cursor view is NULL global read view of a transaction is
restored to a transaction read view. */ restored to a transaction read view. */
static
void void
innobase_set_cursor_view( innobase_set_cursor_view(
/*=====================*/ /*=====================*/
......
...@@ -238,11 +238,6 @@ extern ulong srv_commit_concurrency; ...@@ -238,11 +238,6 @@ extern ulong srv_commit_concurrency;
extern ulong srv_flush_log_at_trx_commit; extern ulong srv_flush_log_at_trx_commit;
} }
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);
/* /*
don't delete it - it may be re-enabled later don't delete it - it may be re-enabled later
as an optimization for the most common case InnoDB+binlog as an optimization for the most common case InnoDB+binlog
...@@ -256,93 +251,3 @@ int innobase_report_binlog_offset_and_commit( ...@@ -256,93 +251,3 @@ int innobase_report_binlog_offset_and_commit(
int innobase_commit_complete(void* trx_handle); int innobase_commit_complete(void* trx_handle);
void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset); void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
#endif #endif
void innobase_drop_database(handlerton *hton, char *path);
bool innobase_show_status(handlerton *hton, THD* thd, stat_print_fn*, enum ha_stat_type);
int innobase_release_temporary_latches(handlerton *hton, THD *thd);
void innobase_store_binlog_offset_and_flush_log(handlerton *hton, char *binlog_name,longlong offset);
int innobase_start_trx_and_assign_read_view(handlerton *hton, THD* thd);
/***********************************************************************
This function is used to prepare X/Open XA distributed transaction */
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
FALSE - the current SQL statement ended */
/***********************************************************************
This function is used to recover X/Open XA distributed transactions */
int innobase_xa_recover(
/*====================*/
/* out: number of prepared transactions
stored in xid_list */
handlerton *hton, /* in: innobase hton */
XID* xid_list, /* in/out: prepared transactions */
uint len); /* in: number of slots in xid_list */
/***********************************************************************
This function is used to commit one X/Open XA distributed transaction
which is in the prepared state */
int innobase_commit_by_xid(
/*=======================*/
/* out: 0 or error number */
handlerton *hton, /* in: innobase hton */
XID* xid); /* in : X/Open XA Transaction Identification */
/***********************************************************************
This function is used to rollback one X/Open XA distributed transaction
which is in the prepared state */
int innobase_rollback_by_xid(
/* out: 0 or error number */
handlerton *hton, /* in: innobase hton */
XID *xid); /* in : X/Open XA Transaction Identification */
/***********************************************************************
Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records
using a cursor. */
void*
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
global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */
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
consistent cursor view is NULL global read view of a transaction is
restored to a transaction read view. */
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 */
...@@ -6,6 +6,16 @@ Mutex, the basic synchronization primitive ...@@ -6,6 +6,16 @@ Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri Created 9/5/1995 Heikki Tuuri
*******************************************************/ *******************************************************/
#if defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
/* %z0: Use the size of operand %0 which in our case is *m to determine
instruction size, it should end up as xchgl. "1" in the input constraint,
says that "in" has to go in the same place as "out".*/
#define TAS(m, in, out) \
asm volatile ("xchg%z0 %2, %0" \
: "=g" (*(m)), "=r" (out) \
: "1" (in)) /* Note: "1" here refers to "=r" (out) */
#endif
/********************************************************************** /**********************************************************************
Sets the waiters field in a mutex. */ Sets the waiters field in a mutex. */
...@@ -89,20 +99,10 @@ mutex_test_and_set( ...@@ -89,20 +99,10 @@ mutex_test_and_set(
return(res); return(res);
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
ulint* lw;
ulint res; ulint res;
lw = &(mutex->lock_word); TAS(&mutex->lock_word, 1, res);
/* In assembly we use the so-called AT & T syntax where
the order of operands is inverted compared to the ordinary Intel
syntax. The 'l' after the mnemonics denotes a 32-bit operation.
The line after the code tells which values come out of the asm
code, and the second line tells the input to the asm code. */
asm volatile("movl $1, %%eax; xchgl (%%ecx), %%eax" :
"=eax" (res), "=m" (*lw) :
"ecx" (lw));
return(res); return(res);
#else #else
ibool ret; ibool ret;
...@@ -141,20 +141,9 @@ mutex_reset_lock_word( ...@@ -141,20 +141,9 @@ mutex_reset_lock_word(
__asm MOV ECX, lw __asm MOV ECX, lw
__asm XCHG EDX, DWORD PTR [ECX] __asm XCHG EDX, DWORD PTR [ECX]
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
ulint* lw; ulint res;
lw = &(mutex->lock_word);
/* In assembly we use the so-called AT & T syntax where
the order of operands is inverted compared to the ordinary Intel
syntax. The 'l' after the mnemonics denotes a 32-bit operation. */
asm volatile("movl $0, %%eax; xchgl (%%ecx), %%eax" : TAS(&mutex->lock_word, 0, res);
"=m" (*lw) :
"ecx" (lw) :
"eax"); /* gcc does not seem to understand
that our asm code resets eax: tell it
explicitly that after the third ':' */
#else #else
mutex->lock_word = 0; mutex->lock_word = 0;
......
...@@ -43,12 +43,21 @@ if we are compiling on Windows. */ ...@@ -43,12 +43,21 @@ if we are compiling on Windows. */
# undef VERSION # undef VERSION
/* Include the header file generated by GNU autoconf */ /* Include the header file generated by GNU autoconf */
# ifndef __WIN__
# include "config.h" # include "config.h"
# endif
# ifdef HAVE_SCHED_H # ifdef HAVE_SCHED_H
# include <sched.h> # include <sched.h>
# endif # endif
/* When compiling for Itanium IA64, undefine the flag below to prevent use
of the 32-bit x86 assembler in mutex operations. */
# if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64)
# define UNIV_CAN_USE_X86_ASSEMBLER
# endif
/* We only try to do explicit inlining of functions with gcc and /* We only try to do explicit inlining of functions with gcc and
Microsoft Visual C++ */ Microsoft Visual C++ */
......
...@@ -3447,8 +3447,6 @@ SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over'; ...@@ -3447,8 +3447,6 @@ SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
a a
1 1
drop table t2, t1; drop table t2, t1;
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
ERROR HY000: The used table type doesn't support SPATIAL indexes
CREATE TABLE t1 ( a int ) ENGINE=innodb; CREATE TABLE t1 ( a int ) ENGINE=innodb;
BEGIN; BEGIN;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
...@@ -3473,3 +3471,12 @@ t2 CREATE TABLE `t2` ( ...@@ -3473,3 +3471,12 @@ t2 CREATE TABLE `t2` (
CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2, t1; DROP TABLE t2, t1;
CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
ALTER TABLE t2 MODIFY a INT NOT NULL;
ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150)
DELETE FROM t1;
DROP TABLE t2,t1;
...@@ -52,7 +52,7 @@ INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2), ...@@ -52,7 +52,7 @@ INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),
update t1 set parent_id=parent_id+100; update t1 set parent_id=parent_id+100;
select * from t1 where parent_id=102; select * from t1 where parent_id=102;
update t1 set id=id+1000; update t1 set id=id+1000;
-- error 1062,1022 -- error ER_DUP_ENTRY_WITH_KEY_NAME,1022
update t1 set id=1024 where id=1009; update t1 set id=1024 where id=1009;
select * from t1; select * from t1;
update ignore t1 set id=id+1; # This will change all rows update ignore t1 set id=id+1; # This will change all rows
...@@ -133,13 +133,13 @@ commit; ...@@ -133,13 +133,13 @@ commit;
select n, "after commit" from t1; select n, "after commit" from t1;
commit; commit;
insert into t1 values (5); insert into t1 values (5);
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 values (4); insert into t1 values (4);
commit; commit;
select n, "after commit" from t1; select n, "after commit" from t1;
set autocommit=1; set autocommit=1;
insert into t1 values (6); insert into t1 values (6);
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 values (4); insert into t1 values (4);
select n from t1; select n from t1;
set autocommit=0; set autocommit=0;
...@@ -213,7 +213,7 @@ drop table t1; ...@@ -213,7 +213,7 @@ drop table t1;
CREATE TABLE t1 (id char(8) not null primary key, val int not null) engine=innodb; CREATE TABLE t1 (id char(8) not null primary key, val int not null) engine=innodb;
insert into t1 values ('pippo', 12); insert into t1 values ('pippo', 12);
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 values ('pippo', 12); # Gives error insert into t1 values ('pippo', 12); # Gives error
delete from t1; delete from t1;
delete from t1 where id = 'pippo'; delete from t1 where id = 'pippo';
...@@ -341,9 +341,9 @@ CREATE TABLE t1 ( ...@@ -341,9 +341,9 @@ CREATE TABLE t1 (
insert into t1 (ggid,passwd) values ('test1','xxx'); insert into t1 (ggid,passwd) values ('test1','xxx');
insert into t1 (ggid,passwd) values ('test2','yyy'); insert into t1 (ggid,passwd) values ('test2','yyy');
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 (ggid,passwd) values ('test2','this will fail'); insert into t1 (ggid,passwd) values ('test2','this will fail');
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 (ggid,id) values ('this will fail',1); insert into t1 (ggid,id) values ('this will fail',1);
select * from t1 where ggid='test1'; select * from t1 where ggid='test1';
...@@ -352,7 +352,7 @@ select * from t1 where id=2; ...@@ -352,7 +352,7 @@ select * from t1 where id=2;
replace into t1 (ggid,id) values ('this will work',1); replace into t1 (ggid,id) values ('this will work',1);
replace into t1 (ggid,passwd) values ('test2','this will work'); replace into t1 (ggid,passwd) values ('test2','this will work');
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
update t1 set id=100,ggid='test2' where id=1; update t1 set id=100,ggid='test2' where id=1;
select * from t1; select * from t1;
select * from t1 where id=1; select * from t1 where id=1;
...@@ -523,7 +523,7 @@ drop table t1; ...@@ -523,7 +523,7 @@ drop table t1;
create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb; create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb;
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
LOCK TABLES t1 WRITE; LOCK TABLES t1 WRITE;
--error 1062 --error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 values (99,1,2,'D'),(1,1,2,'D'); insert into t1 values (99,1,2,'D'),(1,1,2,'D');
select id from t1; select id from t1;
select id from t1; select id from t1;
...@@ -534,7 +534,7 @@ create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(3 ...@@ -534,7 +534,7 @@ create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(3
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
LOCK TABLES t1 WRITE; LOCK TABLES t1 WRITE;
begin; begin;
--error 1062 --error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 values (99,1,2,'D'),(1,1,2,'D'); insert into t1 values (99,1,2,'D'),(1,1,2,'D');
select id from t1; select id from t1;
insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D'); insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
...@@ -1407,7 +1407,7 @@ create table t1 (rowid int not null auto_increment, val int not null,primary ...@@ -1407,7 +1407,7 @@ create table t1 (rowid int not null auto_increment, val int not null,primary
key (rowid), unique(val)) engine=innodb; key (rowid), unique(val)) engine=innodb;
replace into t1 (val) values ('1'),('2'); replace into t1 (val) values ('1'),('2');
replace into t1 (val) values ('1'),('2'); replace into t1 (val) values ('1'),('2');
--error 1062 --error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 (val) values ('1'),('2'); insert into t1 (val) values ('1'),('2');
select * from t1; select * from t1;
drop table t1; drop table t1;
...@@ -1420,7 +1420,7 @@ create table t1 (a int not null auto_increment primary key, val int) engine=Inno ...@@ -1420,7 +1420,7 @@ create table t1 (a int not null auto_increment primary key, val int) engine=Inno
insert into t1 (val) values (1); insert into t1 (val) values (1);
update t1 set a=2 where a=1; update t1 set a=2 where a=1;
# We should get the following error because InnoDB does not update the counter # We should get the following error because InnoDB does not update the counter
--error 1062 --error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t1 (val) values (1); insert into t1 (val) values (1);
select * from t1; select * from t1;
drop table t1; drop table t1;
...@@ -1876,13 +1876,13 @@ create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb; ...@@ -1876,13 +1876,13 @@ create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb; create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
insert into t1 values (0x41),(0x4120),(0x4100); insert into t1 values (0x41),(0x4120),(0x4100);
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t2 values (0x41),(0x4120),(0x4100); insert into t2 values (0x41),(0x4120),(0x4100);
insert into t2 values (0x41),(0x4120); insert into t2 values (0x41),(0x4120);
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t3 values (0x41),(0x4120),(0x4100); insert into t3 values (0x41),(0x4120),(0x4100);
insert into t3 values (0x41),(0x4100); insert into t3 values (0x41),(0x4100);
-- error 1062 -- error ER_DUP_ENTRY_WITH_KEY_NAME
insert into t4 values (0x41),(0x4120),(0x4100); insert into t4 values (0x41),(0x4120),(0x4100);
insert into t4 values (0x41),(0x4100); insert into t4 values (0x41),(0x4100);
select hex(s1) from t1; select hex(s1) from t1;
...@@ -2487,12 +2487,6 @@ SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over'; ...@@ -2487,12 +2487,6 @@ SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
drop table t2, t1; drop table t2, t1;
#
# Bug #15680 (SPATIAL key in innodb)
#
--error ER_TABLE_CANT_HANDLE_SPKEYS
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
# #
# Test optimize on table with open transaction # Test optimize on table with open transaction
# #
...@@ -2519,6 +2513,22 @@ DELETE CASCADE ON UPDATE CASCADE; ...@@ -2519,6 +2513,22 @@ DELETE CASCADE ON UPDATE CASCADE;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
DROP TABLE t2, t1; DROP TABLE t2, t1;
#
# Bug #25927: Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns
# for which there is a foreign key constraint ON ... SET NULL.
#
CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
--replace_regex /'\.\/test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
--error 1025
ALTER TABLE t2 MODIFY a INT NOT NULL;
DELETE FROM t1;
DROP TABLE t2,t1;
####################################################################### #######################################################################
# # # #
# Please, DO NOT TOUCH this file as well as the innodb.result file. # # Please, DO NOT TOUCH this file as well as the innodb.result file. #
......
...@@ -460,3 +460,5 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field ...@@ -460,3 +460,5 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
insert into t1 (fl) values (pointfromtext('point(1,1)')); insert into t1 (fl) values (pointfromtext('point(1,1)'));
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
drop table t1; drop table t1;
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
ERROR HY000: The used table type doesn't support SPATIAL indexes
--source include/have_innodb.inc --source include/have_innodb.inc
SET storage_engine=innodb; SET storage_engine=innodb;
--source include/gis_generic.inc --source include/gis_generic.inc
#
# Bug #15680 (SPATIAL key in innodb)
#
--error ER_TABLE_CANT_HANDLE_SPKEYS
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment