1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  mysql.com:/home/my/mysql-5.1


BitKeeper/etc/ignore:
  auto-union
include/heap.h:
  Auto merged
include/my_base.h:
  Auto merged
include/mysql_com.h:
  Auto merged
mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/mysql-test-run.sh:
  Auto merged
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test:
  Auto merged
mysql-test/r/binlog_stm_mix_innodb_myisam.result:
  Auto merged
mysql-test/r/func_time.result:
  Auto merged
mysql-test/r/ndb_index_unique.result:
  Auto merged
mysql-test/t/func_time.test:
  Auto merged
mysql-test/t/view_grant.test:
  Auto merged
sql/field.cc:
  Auto merged
sql/field.h:
  Auto merged
sql/ha_berkeley.cc:
  Auto merged
sql/ha_berkeley.h:
  Auto merged
mysql-test/r/view_grant.result:
  Auto merged
sql/ha_federated.cc:
  Auto merged
sql/ha_federated.h:
  Auto merged
sql/ha_heap.h:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/ha_innodb.h:
  Auto merged
sql/ha_myisam.h:
  Auto merged
sql/ha_myisammrg.cc:
  Auto merged
sql/ha_ndbcluster.h:
  Auto merged
sql/ha_partition.h:
  Auto merged
sql/item.cc:
  Auto merged
sql/item_cmpfunc.h:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_func.h:
  Auto merged
sql/item_strfunc.h:
  Auto merged
sql/item_subselect.cc:
  Auto merged
sql/item_subselect.h:
  Auto merged
sql/log.cc:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sp.cc:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/spatial.cc:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_bitmap.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_partition.cc:
  Auto merged
sql/sql_plugin.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/share/errmsg.txt:
  Auto merged
sql/sql_handler.cc:
  Auto merged
sql/sql_view.cc:
  Auto merged
sql/table.h:
  Auto merged
storage/archive/ha_archive.cc:
  Auto merged
storage/archive/ha_archive.h:
  Auto merged
storage/example/ha_example.cc:
  Auto merged
storage/myisam/ft_boolean_search.c:
  Auto merged
unittest/mysys/base64-t.c:
  Auto merged
mysql-test/r/innodb_mysql.result:
  manual merge
mysql-test/t/innodb_mysql.test:
  manual merge
mysql-test/valgrind.supp:
  manual merge
sql/event.cc:
  manual merge
sql/ha_heap.cc:
  manual merge
sql/ha_myisam.cc:
  manual merge
sql/ha_ndbcluster.cc:
  manual merge
sql/ha_ndbcluster_binlog.cc:
  manual merge
sql/ha_partition.cc:
  manual merge
sql/handler.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/handler.h:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/item.h:
  automatic merge
sql/item_cmpfunc.cc:
  automatic merge
sql/log_event.cc:
  manual merge
  Trivial cleanup
sql/mysql_priv.h:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/opt_range.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/sql_delete.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/sql_insert.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/sql_load.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/sql_select.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/sql_show.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/sql_table.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/sql_update.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
sql/table.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
storage/blackhole/ha_blackhole.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
storage/csv/ha_tina.cc:
  manual merge
  renamed print_key_dupp_error to print_key_dup_error
mysql-test/valgrind.supp.orig:
  Manual merge
This commit is contained in:
unknown
2006-06-04 21:05:22 +03:00
137 changed files with 4249 additions and 2341 deletions

View File

@ -108,7 +108,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
No fields are provided so all fields must be provided in the values.
Thus we set all bits in the write set.
*/
table->file->ha_set_all_bits_in_write_set();
bitmap_set_all(table->write_set);
}
else
{ // Part field list
@ -123,7 +123,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
return -1;
}
thd->dupp_field=0;
thd->dup_field= 0;
select_lex->no_wrap_view_item= TRUE;
/* Save the state of the current name resolution context. */
@ -135,11 +135,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
*/
table_list->next_local= 0;
context->resolve_in_table_list_only(table_list);
/*
Indicate fields in list is to be updated by setting set_query_id
parameter to 2. This sets the bit in the write_set for each field.
*/
res= setup_fields(thd, 0, fields, 2, 0, 0);
res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0);
/* Restore the current context. */
ctx_state.restore_state(context, table_list);
@ -167,16 +163,27 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
table_list->table= table= tbl->table;
}
if (check_unique && thd->dupp_field)
if (check_unique && thd->dup_field)
{
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name);
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dup_field->field_name);
return -1;
}
if (table->timestamp_field && // Don't set timestamp if used
table->timestamp_field->query_id == thd->query_id)
clear_timestamp_auto_bits(table->timestamp_field_type,
TIMESTAMP_AUTO_SET_ON_INSERT);
if (table->timestamp_field) // Don't automaticly set timestamp if used
{
if (bitmap_is_set(table->write_set,
table->timestamp_field->field_index))
clear_timestamp_auto_bits(table->timestamp_field_type,
TIMESTAMP_AUTO_SET_ON_INSERT);
else
{
bitmap_set_bit(table->write_set,
table->timestamp_field->field_index);
}
}
}
if (table->found_next_number_field)
table->mark_auto_increment_column();
table->mark_columns_needed_for_insert();
// For the values we need select_priv
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
@ -217,40 +224,33 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
List<Item> &update_fields)
{
TABLE *table= insert_table_list->table;
query_id_t timestamp_query_id;
LINT_INIT(timestamp_query_id);
my_bool timestamp_mark;
/*
Change the query_id for the timestamp column so that we can
check if this is modified directly.
*/
if (table->timestamp_field)
{
timestamp_query_id= table->timestamp_field->query_id;
table->timestamp_field->query_id= thd->query_id - 1;
/*
Unmark the timestamp field so that we can check if this is modified
by update_fields
*/
timestamp_mark= bitmap_test_and_clear(table->write_set,
table->timestamp_field->field_index);
}
/*
Check the fields we are going to modify. This will set the query_id
of all used fields to the threads query_id. It will also set all
fields into the write set of this table.
*/
if (setup_fields(thd, 0, update_fields, 2, 0, 0))
/* Check the fields we are going to modify */
if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0))
return -1;
if (table->timestamp_field)
{
/* Don't set timestamp column if this is modified. */
if (table->timestamp_field->query_id == thd->query_id)
if (bitmap_is_set(table->write_set,
table->timestamp_field->field_index))
clear_timestamp_auto_bits(table->timestamp_field_type,
TIMESTAMP_AUTO_SET_ON_UPDATE);
else
{
table->timestamp_field->query_id= timestamp_query_id;
table->file->ha_set_bit_in_write_set(table->timestamp_field->fieldnr);
}
if (timestamp_mark)
bitmap_set_bit(table->write_set,
table->timestamp_field->field_index);
}
return 0;
}
@ -269,8 +269,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
By default, both logs are enabled (this won't cause problems if the server
runs without --log-update or --log-bin).
*/
bool log_on= (thd->options & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL));
bool log_on= ((thd->options & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL)));
bool transactional_table, joins_freed= FALSE;
bool changed;
uint value_count;
@ -380,7 +380,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
goto abort;
}
if (setup_fields(thd, 0, *values, 0, 0, 0))
if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0))
goto abort;
}
its.rewind ();
@ -757,7 +757,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
*/
static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
List<Item> &fields, COND **where,
List<Item> &fields,
bool select_insert)
{
bool insert_into_view= (table_list->view != 0);
@ -765,7 +765,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
table_list, where,
table_list,
&thd->lex->select_lex.leaf_tables,
select_insert, INSERT_ACL))
DBUG_RETURN(TRUE);
@ -856,8 +856,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
}
if (mysql_prepare_insert_check_table(thd, table_list, fields, where,
select_insert))
if (mysql_prepare_insert_check_table(thd, table_list, fields, select_insert))
DBUG_RETURN(TRUE);
/* Save the state of the current name resolution context. */
@ -874,7 +873,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
if (values &&
!(res= check_insert_fields(thd, context->table_list, fields, *values,
!insert_into_view) ||
setup_fields(thd, 0, *values, 0, 0, 0)) &&
setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0)) &&
duplic == DUP_UPDATE)
{
select_lex->no_wrap_view_item= TRUE;
@ -892,7 +891,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
next_name_resolution_table= ctx_state.save_next_local;
}
if (!res)
res= setup_fields(thd, 0, update_values, 1, 0, 0);
res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
}
/* Restore the current context. */
@ -917,7 +916,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
select_lex->first_execution= 0;
}
if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
table->file->ha_retrieve_all_pk();
table->prepare_for_position();
DBUG_RETURN(FALSE);
}
@ -964,9 +963,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
{
int error, trg_error= 0;
char *key=0;
MY_BITMAP *save_read_set, *save_write_set;
DBUG_ENTER("write_record");
info->records++;
save_read_set= table->read_set;
save_write_set= table->write_set;
if (info->handle_duplicates == DUP_REPLACE ||
info->handle_duplicates == DUP_UPDATE)
@ -982,6 +984,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
error=HA_WRITE_SKIP; /* Database can't find key */
goto err;
}
/* Read all columns for the row we are going to replace */
table->use_all_columns();
/*
Don't allow REPLACE to replace a row when a auto_increment column
was used. This ensures that we don't get a problem when the
@ -992,9 +996,9 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
key_nr == table->s->next_number_index &&
table->file->auto_increment_column_changed)
goto err;
if (table->file->table_flags() & HA_DUPP_POS)
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{
if (table->file->rnd_pos(table->record[1],table->file->dupp_ref))
if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
goto err;
}
else
@ -1055,7 +1059,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
thd->clear_next_insert_id= 0;
thd->next_insert_id= 0;
}
if ((error=table->file->ha_update_row(table->record[1],table->record[0])))
if ((error=table->file->ha_update_row(table->record[1],
table->record[0])))
{
if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
goto ok_or_after_trg_err;
@ -1132,6 +1137,13 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
trg_error= (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_AFTER, TRUE));
/*
Restore column maps if they where replaced during an duplicate key
problem.
*/
if (table->read_set != save_read_set ||
table->write_set != save_write_set)
table->column_bitmaps_set(save_read_set, save_write_set);
}
else if ((error=table->file->ha_write_row(table->record[0])))
{
@ -1165,6 +1177,7 @@ err:
before_trg_err:
if (key)
my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH);
table->column_bitmaps_set(save_read_set, save_write_set);
DBUG_RETURN(1);
}
@ -1177,9 +1190,11 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
TABLE_LIST *table_list)
{
int err= 0;
MY_BITMAP *write_set= entry->write_set;
for (Field **field=entry->field ; *field ; field++)
{
if ((*field)->query_id != thd->query_id &&
if (!bitmap_is_set(write_set, (*field)->field_index) &&
((*field)->flags & NO_DEFAULT_VALUE_FLAG) &&
((*field)->real_type() != FIELD_TYPE_ENUM))
{
@ -1511,6 +1526,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
Field **field,**org_field, *found_next_number_field;
TABLE *copy;
TABLE_SHARE *share= table->s;
byte *bitmap;
/* First request insert thread to get a lock */
status=1;
@ -1537,14 +1553,16 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
client_thd->proc_info="allocating local table";
copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
(share->fields+1)*sizeof(Field**)+
share->reclength);
share->reclength +
share->column_bitmap_size*2);
if (!copy)
goto error;
*copy= *table;
/* We don't need to change the file handler here */
field=copy->field=(Field**) (copy+1);
copy->record[0]=(byte*) (field+share->fields+1);
field= copy->field= (Field**) (copy+1);
bitmap= (byte*) (field+share->fields+1);
copy->record[0]= (bitmap+ share->column_bitmap_size*2);
memcpy((char*) copy->record[0],(char*) table->record[0],share->reclength);
/* Make a copy of all fields */
@ -1573,13 +1591,21 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
copy->timestamp_field_type= copy->timestamp_field->get_auto_set_type();
}
/* Adjust in_use for pointing to client thread */
copy->in_use= client_thd;
/* Adjust lock_count. This table object is not part of a lock. */
copy->lock_count= 0;
/* Adjust bitmaps */
copy->def_read_set.bitmap= (my_bitmap_map*) bitmap;
copy->def_write_set.bitmap= ((my_bitmap_map*)
(bitmap + share->column_bitmap_size));
copy->tmp_set.bitmap= 0; // To catch errors
bzero((char*) bitmap, share->column_bitmap_size*2);
copy->read_set= &copy->def_read_set;
copy->write_set= &copy->def_write_set;
return copy;
/* Got fatal error */
@ -1747,7 +1773,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->fatal_error(); // Abort waiting inserts
goto err;
}
if (!(di->table->file->table_flags() & HA_CAN_INSERT_DELAYED))
if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED))
{
thd->fatal_error();
my_error(ER_ILLEGAL_HA, MYF(0), di->table_list.table_name);
@ -1957,6 +1983,7 @@ bool delayed_insert::handle_inserts(void)
pthread_mutex_unlock(&mutex);
table->next_number_field=table->found_next_number_field;
table->use_all_columns();
thd.proc_info="upgrading lock";
if (thr_upgrade_write_delay_lock(*thd.lock->locks))
@ -2063,7 +2090,6 @@ bool delayed_insert::handle_inserts(void)
}
thd.proc_info=0;
table->next_number_field=0;
pthread_mutex_unlock(&mutex);
/* After releasing the mutex, to prevent deadlocks. */
@ -2186,7 +2212,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
lex->current_select= &lex->select_lex;
res= check_insert_fields(thd, table_list, *fields, values,
!insert_into_view) ||
setup_fields(thd, 0, values, 0, 0, 0);
setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0);
if (info.handle_duplicates == DUP_UPDATE)
{
@ -2216,7 +2242,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
context->first_name_resolution_table->
next_name_resolution_table= ctx_state.save_next_local;
}
res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
res= res || setup_fields(thd, 0, *info.update_values, MARK_COLUMNS_READ,
0, 0);
/* Restore the current context. */
ctx_state.restore_state(context, table_list);
@ -2269,16 +2296,6 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
check_that_all_fields_are_given_values(thd, table, table_list)) ||
table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd));
/*
For non-transactional non-temporary tables, we set the
OPTION_STATUS_NO_TRANS_UPDATE flag here. The send_eof() function
is used by both the select_insert and the select_create classes,
so setting it there would clash.
*/
if (!(table->file->has_transactions() || table->s->tmp_table))
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
DBUG_RETURN(res);
}
@ -2397,7 +2414,9 @@ void select_insert::send_error(uint errcode,const char *err)
{
DBUG_ENTER("select_insert::send_error");
my_message(errcode, err, MYF(0));
/* Avoid an extra 'unknown error' message if we already reported an error */
if (errcode != ER_UNKNOWN_ERROR && !thd->net.report_error)
my_message(errcode, err, MYF(0));
if (!table)
{
@ -2425,11 +2444,8 @@ void select_insert::send_error(uint errcode,const char *err)
INSERT-SELECT.
When replicating a CREATE-SELECT statement, we shall not write the
events to the binary log. To prevent the ha_rollback_stmt() below
from writing to the binary log, we have to pretend that the table
is transactional, even if it actually is not. Therefore, the
OPTION_STATUS_NO_TRANS_UPDATE is cleared in
select_create::prepare() and will remain cleared here.
events to the binary log and should thus not set
OPTION_STATUS_NO_TRANS_UPDATE.
When replicating INSERT-SELECT, we shall not write the events to
the binary log for transactional table, but shall write all events
@ -2437,22 +2453,22 @@ void select_insert::send_error(uint errcode,const char *err)
this case, the OPTION_STATUS_NO_TRANS_UPDATE is set if there is a
write to a non-transactional table, otherwise it is cleared.
*/
if ((info.copied || info.deleted || info.updated) &&
!table->file->has_transactions())
{
if (last_insert_id)
thd->insert_id(last_insert_id); // For binary log
if (mysql_bin_log.is_open())
{
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
table->file->has_transactions(), FALSE);
}
if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
if (info.copied || info.deleted || info.updated)
{
query_cache_invalidate3(thd, table, 1);
if (!table->file->has_transactions())
{
if (last_insert_id)
thd->insert_id(last_insert_id); // For binary log
if (mysql_bin_log.is_open())
{
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
table->file->has_transactions(), FALSE);
}
if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table &&
!can_rollback_data())
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
query_cache_invalidate3(thd, table, 1);
}
}
ha_rollback_stmt(thd);
DBUG_VOID_RETURN;
@ -2467,22 +2483,25 @@ bool select_insert::send_eof()
error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
/*
We must invalidate the table in the query cache before binlog writing
and ha_autocommit_or_rollback.
If nothing was inserted in the table, there is no need to emit a
ROLLBACK statement to the binary log, so in that case we clear
OPTION_STATUS_NO_TRANS_UPDATE.
Observe that select_insert::send_eof() is used by both
select_insert and select_create and that they set the flag in
different manners. See Note 1 below for more info.
*/
if (info.copied || info.deleted || info.updated)
{
/*
We must invalidate the table in the query cache before binlog writing
and ha_autocommit_or_rollback.
*/
query_cache_invalidate3(thd, table, 1);
else
thd->options&= ~OPTION_STATUS_NO_TRANS_UPDATE;
/*
Mark that we have done permanent changes if all of the below is true
- Table doesn't support transactions
- It's a normal (not temporary) table. (Changes to temporary tables
are not logged in RBR)
- We are using statement based replication
*/
if (!table->file->has_transactions() &&
(!table->s->tmp_table ||
!thd->current_stmt_binlog_row_based))
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
}
if (last_insert_id)
thd->insert_id(last_insert_id); // For binary log
@ -2621,9 +2640,9 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
don't want to delete from it) 2) it would be written before the CREATE
TABLE, which is a wrong order. So we keep binary logging disabled when we
open_table().
NOTE: By locking table which we just have created (or for which we just have
have found that it already exists) separately from other tables used by the
statement we create potential window for deadlock.
NOTE: By locking table which we just have created (or for which we just
have have found that it already exists) separately from other tables used
by the statement we create potential window for deadlock.
TODO: create and open should be done atomic !
*/
{
@ -2681,7 +2700,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
}
class MY_HOOKS : public TABLEOP_HOOKS {
class MY_HOOKS : public TABLEOP_HOOKS
{
public:
MY_HOOKS(select_create *x) : ptr(x) { }
virtual void do_prelock(TABLE **tables, uint count)
@ -2694,18 +2714,16 @@ private:
select_create *ptr;
};
int
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
int select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
MY_HOOKS hooks(this);
DBUG_ENTER("select_create::prepare");
MY_HOOKS hooks(this);
unit= u;
table= create_table_from_items(thd, create_info, create_table,
extra_fields, keys, &values, &lock,
&hooks);
if (!table)
if (!(table= create_table_from_items(thd, create_info, create_table,
extra_fields, keys, &values, &lock,
&hooks)))
DBUG_RETURN(-1); // abort() deletes table
if (table->s->fields < values.elements)
@ -2714,16 +2732,15 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_RETURN(-1);
}
/* First field to copy */
/* First field to copy */
field= table->field+table->s->fields - values.elements;
/* Mark all fields that are given values */
for (Field **f= field ; *f ; f++)
(*f)->query_id= thd->query_id;
bitmap_set_bit(table->write_set, (*f)->field_index);
/* Don't set timestamp if used */
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
table->next_number_field=table->found_next_number_field;
restore_record(table,s->default_values); // Get empty record
@ -2742,8 +2759,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
}
void
select_create::binlog_show_create_table(TABLE **tables, uint count)
void select_create::binlog_show_create_table(TABLE **tables, uint count)
{
/*
Note 1: In RBR mode, we generate a CREATE TABLE statement for the
@ -2761,25 +2777,22 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
since there potentially are sub-selects or accesses to information
schema that will do a close_thread_tables(), destroying the
statement transaction cache.
To ensure that the event kaboodle is not written to the binary log
on rollback, we clear the OPTION_STATUS_NO_TRANS_UPDATE bit of
thd->options.
*/
*/
DBUG_ASSERT(thd->current_stmt_binlog_row_based);
DBUG_ASSERT(tables && *tables && count > 0);
thd->options&= ~OPTION_STATUS_NO_TRANS_UPDATE;
char buf[2048];
String query(buf, sizeof(buf), system_charset_info);
query.length(0); // Have to zero it since constructor doesn't
int result;
TABLE_LIST table_list;
memset(&table_list, 0, sizeof(table_list));
table_list.table = *tables;
query.length(0); // Have to zero it since constructor doesn't
int result= store_create_info(thd, &table_list, &query, create_info);
result= store_create_info(thd, &table_list, &query, create_info);
DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */
thd->binlog_query(THD::STMT_QUERY_TYPE,
query.ptr(), query.length(),
/* is_trans */ TRUE,
@ -2816,17 +2829,9 @@ bool select_create::send_eof()
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
VOID(pthread_mutex_lock(&LOCK_open));
mysql_unlock_tables(thd, lock);
/*
TODO:
Check if we can remove the following two rows.
We should be able to just keep the table in the table cache.
*/
if (!table->s->tmp_table)
{
ulong version= table->s->version;
hash_delete(&open_cache,(byte*) table);
/* Tell threads waiting for refresh that something has happened */
if (version != refresh_version)
if (close_thread_table(thd, &table))
VOID(pthread_cond_broadcast(&COND_refresh));
}
lock=0;