diff options
author | unknown <mkindahl@dl145k.mysql.com> | 2006-07-11 12:17:19 +0200 |
---|---|---|
committer | unknown <mkindahl@dl145k.mysql.com> | 2006-07-11 12:17:19 +0200 |
commit | c22a89819916b66753d266376650c53c1c991811 (patch) | |
tree | a7de1f862d3573e58eb4ee35c13d673028cafbf0 /sql/sql_insert.cc | |
parent | a6edf110bcd6b393c801624181e5b20b6557b8c1 (diff) | |
parent | e8f1a99a7d27d4326541804b918cbdd4f70ebcd4 (diff) | |
download | mariadb-git-c22a89819916b66753d266376650c53c1c991811.tar.gz |
Merge dl145k.mysql.com:/data0/mkindahl/bkroot/mysql-5.1-new-rpl
into dl145k.mysql.com:/data0/mkindahl/bk/MERGE/mysql-5.1-merge
include/my_sys.h:
Auto merged
mysql-test/mysql-test-run.pl:
Auto merged
mysql-test/r/rpl_row_create_table.result:
Auto merged
mysql-test/t/disabled.def:
Auto merged
mysql-test/t/rpl_row_create_table.test:
Auto merged
mysys/my_malloc.c:
Auto merged
server-tools/instance-manager/parse.h:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/handler.h:
Auto merged
sql/log.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/set_var.h:
Auto merged
sql/sp.cc:
Auto merged
sql/sp_head.cc:
Auto merged
sql/sp_head.h:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_update.cc:
Auto merged
sql/sql_view.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
mysys/safemalloc.c:
Merge of mysql-5.1-new-rpl into mysql-5.1
sql/ha_federated.cc:
d
Merge of mysql-5.1-new-rpl into mysql-5.1
sql/set_var.cc:
Merge of mysql-5.1-new-rpl with mysql-5.1
sql/slave.cc:
Merge of mysql-5.1-new-rpl into mysql-5.1
sql/sql_class.h:
Merge of mysql-5.1-new-rpl into mysql-5.1
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 292 |
1 files changed, 168 insertions, 124 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1f93bc99483..09d7d251b42 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -64,8 +64,8 @@ static int check_null_fields(THD *thd,TABLE *entry); #ifndef EMBEDDED_LIBRARY static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list); -static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, bool ignore, - char *query, uint query_length, bool log_on); +static int write_delayed(THD *thd, TABLE *table, enum_duplicates dup, + LEX_STRING query, bool ignore, bool log_on); static void end_delayed_insert(THD *thd); pthread_handler_t handle_delayed_insert(void *arg); static void unlink_blobs(register TABLE *table); @@ -448,7 +448,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table->next_number_field=table->found_next_number_field; error=0; - id=0; thd->proc_info="update"; if (duplic != DUP_ERROR || ignore) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -548,22 +547,13 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) { - error=write_delayed(thd, table, duplic, ignore, query, thd->query_length, log_on); + LEX_STRING const st_query = { query, thd->query_length }; + error=write_delayed(thd, table, duplic, st_query, ignore, log_on); query=0; } else #endif error=write_record(thd, table ,&info); - /* - If auto_increment values are used, save the first one - for LAST_INSERT_ID() and for the update log. - We can't use insert_id() as we don't want to touch the - last_insert_id_used flag. - */ - if (! id && thd->insert_id_used) - { // Get auto increment value - id= thd->last_insert_id; - } if (error) break; thd->row_count++; @@ -571,6 +561,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, free_underlaid_joins(thd, &thd->lex->select_lex); joins_freed= TRUE; + table->file->ha_release_auto_increment(); /* Now all rows are inserted. Time to update logs and sends response to @@ -581,7 +572,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, { if (!error) { - id=0; // No auto_increment id info.copied=values_list.elements; end_delayed_insert(thd); } @@ -595,11 +585,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table->file->print_error(my_errno,MYF(0)); error=1; } - if (id && values_list.elements != 1) - thd->insert_id(id); // For update log - else if (table->next_number_field && info.copied) - id=table->next_number_field->val_int(); // Return auto_increment value - transactional_table= table->file->has_transactions(); if ((changed= (info.copied || info.deleted || info.updated))) @@ -648,18 +633,27 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } } thd->proc_info="end"; + /* + We'll report to the client this id: + - if the table contains an autoincrement column and we successfully + inserted an autogenerated value, the autogenerated value. + - if the table contains no autoincrement column and LAST_INSERT_ID(X) was + called, X. + - if the table contains an autoincrement column, and some rows were + inserted, the id of the last "inserted" row (if IGNORE, that value may not + have been really inserted but ignored). + */ + id= (thd->first_successful_insert_id_in_cur_stmt > 0) ? + thd->first_successful_insert_id_in_cur_stmt : + (thd->arg_of_last_insert_id_function ? + thd->first_successful_insert_id_in_prev_stmt : + ((table->next_number_field && info.copied) ? + table->next_number_field->val_int() : 0)); table->next_number_field=0; thd->count_cuted_fields= CHECK_FIELD_IGNORE; - thd->next_insert_id=0; // Reset this if wrongly used if (duplic != DUP_ERROR || ignore) table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - /* Reset value of LAST_INSERT_ID if no rows where inserted */ - if (!info.copied && thd->insert_id_used) - { - thd->insert_id(0); - id=0; - } if (error) goto abort; if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) || @@ -681,8 +675,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->row_count_func= info.copied+info.deleted+info.updated; ::send_ok(thd, (ulong) thd->row_count_func, id, buff); } - if (table != NULL) - table->file->release_auto_increment(); thd->abort_on_warning= 0; DBUG_RETURN(FALSE); @@ -692,7 +684,7 @@ abort: end_delayed_insert(thd); #endif if (table != NULL) - table->file->release_auto_increment(); + table->file->ha_release_auto_increment(); if (!joins_freed) free_underlaid_joins(thd, &thd->lex->select_lex); thd->abort_on_warning= 0; @@ -1001,6 +993,8 @@ 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; + ulonglong prev_insert_id= table->file->next_insert_id; + ulonglong insert_id_for_cur_row= 0; DBUG_ENTER("write_record"); info->records++; @@ -1013,10 +1007,20 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) while ((error=table->file->ha_write_row(table->record[0]))) { uint key_nr; + /* + If we do more than one iteration of this loop, from the second one the + row will have an explicit value in the autoinc field, which was set at + the first call of handler::update_auto_increment(). So we must save + the autogenerated value to avoid thd->insert_id_for_cur_row to become + 0. + */ + if (table->file->insert_id_for_cur_row > 0) + insert_id_for_cur_row= table->file->insert_id_for_cur_row; + else + table->file->insert_id_for_cur_row= insert_id_for_cur_row; bool is_duplicate_key_error; if (table->file->is_fatal_error(error, HA_CHECK_DUP)) goto err; - table->file->restore_auto_increment(); // it's too early here! BUG#20188 is_duplicate_key_error= table->file->is_fatal_error(error, 0); if (!is_duplicate_key_error) { @@ -1044,7 +1048,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (info->handle_duplicates == DUP_REPLACE && table->next_number_field && key_nr == table->s->next_number_index && - table->file->auto_increment_column_changed) + (insert_id_for_cur_row > 0)) goto err; if (table->file->ha_table_flags() & HA_DUPLICATE_POS) { @@ -1103,22 +1107,29 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (res == VIEW_CHECK_ERROR) goto before_trg_err; - if (thd->clear_next_insert_id) - { - /* Reset auto-increment cacheing if we do an update */ - 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 (info->ignore && !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + { + table->file->restore_auto_increment(prev_insert_id); goto ok_or_after_trg_err; + } goto err; } info->updated++; - + /* + If ON DUP KEY UPDATE updates a row instead of inserting one, and + there is an auto_increment column, then SELECT LAST_INSERT_ID() + returns the id of the updated row: + */ + if (table->next_number_field) + { + longlong field_val= table->next_number_field->val_int(); + thd->record_first_successful_insert_id_in_cur_stmt(field_val); + table->file->adjust_next_insert_id_after_explicit_value(field_val); + } trg_error= (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE)); @@ -1147,16 +1158,11 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) && (!table->triggers || !table->triggers->has_delete_triggers())) { - if (thd->clear_next_insert_id) - { - /* Reset auto-increment cacheing if we do an update */ - thd->clear_next_insert_id= 0; - thd->next_insert_id= 0; - } if ((error=table->file->ha_update_row(table->record[1], table->record[0]))) goto err; info->deleted++; + thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row); /* Since we pretend that we have done insert we should call its after triggers. @@ -1185,6 +1191,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) } } } + thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row); /* Restore column maps if they where replaced during an duplicate key problem. @@ -1198,12 +1205,13 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (!info->ignore || table->file->is_fatal_error(error, HA_CHECK_DUP)) goto err; - table->file->restore_auto_increment(); + table->file->restore_auto_increment(prev_insert_id); goto ok_or_after_trg_err; } after_trg_n_copied_inc: info->copied++; + thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row); trg_error= (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_INSERT, TRG_ACTION_AFTER, TRUE)); @@ -1223,6 +1231,7 @@ err: table->file->print_error(error,MYF(0)); before_trg_err: + table->file->restore_auto_increment(prev_insert_id); if (key) my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH); table->column_bitmaps_set(save_read_set, save_write_set); @@ -1285,14 +1294,20 @@ public: char *record; enum_duplicates dup; time_t start_time; - bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query; - ulonglong last_insert_id; + bool query_start_used, ignore, log_query; + bool stmt_depends_on_first_successful_insert_id_in_prev_stmt; + ulonglong first_successful_insert_id_in_prev_stmt; timestamp_auto_set_type timestamp_field_type; + LEX_STRING query; - delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool log_query_arg) - :record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {} + delayed_row(LEX_STRING const query_arg, enum_duplicates dup_arg, + bool ignore_arg, bool log_query_arg) + : record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg), + query(query_arg) + {} ~delayed_row() { + x_free(query.str); x_free(record); } }; @@ -1300,9 +1315,6 @@ public: class delayed_insert :public ilink { uint locks_in_memory; - char *query; - ulong query_length; - ulong query_allocated; public: THD thd; TABLE *table; @@ -1316,7 +1328,7 @@ public: TABLE_LIST table_list; // Argument delayed_insert() - :locks_in_memory(0), query(0), query_length(0), query_allocated(0), + :locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0), group_count(0) { @@ -1327,6 +1339,11 @@ public: thd.command=COM_DELAYED_INSERT; thd.lex->current_select= 0; // for my_message_sql thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() + /* + Statement-based replication of INSERT DELAYED has problems with RAND() + and user vars, so in mixed mode we go to row-based. + */ + thd.set_current_stmt_binlog_row_based_if_mixed(); bzero((char*) &thd.net, sizeof(thd.net)); // Safety bzero((char*) &table_list, sizeof(table_list)); // Safety @@ -1342,7 +1359,6 @@ public: } ~delayed_insert() { - my_free(query, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); /* The following is not really needed, but just for safety */ delayed_row *row; while ((row=rows.get())) @@ -1362,25 +1378,6 @@ public: VOID(pthread_cond_broadcast(&COND_thread_count)); /* Tell main we are ready */ } - int set_query(char const *q, ulong qlen) { - if (q && qlen > 0) - { - if (query_allocated < qlen + 1) - { - ulong const flags(MY_WME|MY_FREE_ON_ERROR|MY_ALLOW_ZERO_PTR); - query= my_realloc(query, qlen + 1, MYF(flags)); - if (query == 0) - return HA_ERR_OUT_OF_MEM; - query_allocated= qlen; - } - query_length= qlen; - memcpy(query, q, qlen + 1); - } - else - query_length= 0; - return 0; - } - /* The following is for checking when we can delete ourselves */ inline void lock() { @@ -1658,13 +1655,14 @@ TABLE *delayed_insert::get_local_table(THD* client_thd) /* Put a question in queue */ -static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, - bool ignore, char *query, uint query_length, - bool log_on) +static int +write_delayed(THD *thd,TABLE *table, enum_duplicates duplic, + LEX_STRING query, bool ignore, bool log_on) { - delayed_row *row=0; + delayed_row *row; delayed_insert *di=thd->di; DBUG_ENTER("write_delayed"); + DBUG_PRINT("enter", ("query = '%s' length %u", query.str, query.length)); thd->proc_info="waiting for handler insert"; pthread_mutex_lock(&di->mutex); @@ -1672,18 +1670,44 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, pthread_cond_wait(&di->cond_client,&di->mutex); thd->proc_info="storing row into queue"; - if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on))) + if (thd->killed) + goto err; + + /* + Take a copy of the query string, if there is any. The string will + be free'ed when the row is destroyed. If there is no query string, + we don't do anything special. + */ + + if (query.str) + { + char *str; + if (!(str= my_strndup(query.str, query.length, MYF(MY_WME)))) + goto err; + query.str= str; + } + row= new delayed_row(query, duplic, ignore, log_on); + if (row == NULL) + { + my_free(query.str, MYF(MY_WME)); goto err; + } if (!(row->record= (char*) my_malloc(table->s->reclength, MYF(MY_WME)))) goto err; memcpy(row->record, table->record[0], table->s->reclength); - di->set_query(query, query_length); row->start_time= thd->start_time; row->query_start_used= thd->query_start_used; - row->last_insert_id_used= thd->last_insert_id_used; - row->insert_id_used= thd->insert_id_used; - row->last_insert_id= thd->last_insert_id; + /* + those are for the binlog: LAST_INSERT_ID() has been evaluated at this + time, so record does not need it, but statement-based binlogging of the + INSERT will need when the row is actually inserted. + As for SET INSERT_ID, DELAYED does not honour it (BUG#20830). + */ + row->stmt_depends_on_first_successful_insert_id_in_prev_stmt= + thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt; + row->first_successful_insert_id_in_prev_stmt= + thd->first_successful_insert_id_in_prev_stmt; row->timestamp_field_type= table->timestamp_field_type; di->rows.push_back(row); @@ -1937,6 +1961,7 @@ pthread_handler_t handle_delayed_insert(void *arg) MYSQL_LOCK *lock=thd->lock; thd->lock=0; pthread_mutex_unlock(&di->mutex); + di->table->file->ha_release_auto_increment(); mysql_unlock_tables(thd, lock); di->group_count=0; pthread_mutex_lock(&di->mutex); @@ -2037,7 +2062,7 @@ bool delayed_insert::handle_inserts(void) if (thd.killed || table->s->version != refresh_version) { thd.killed= THD::KILL_CONNECTION; - max_rows= ~(ulong)0; // Do as much as possible + max_rows= ULONG_MAX; // Do as much as possible } /* @@ -2049,13 +2074,6 @@ bool delayed_insert::handle_inserts(void) table->file->extra(HA_EXTRA_WRITE_CACHE); pthread_mutex_lock(&mutex); - /* Reset auto-increment cacheing */ - if (thd.clear_next_insert_id) - { - thd.next_insert_id= 0; - thd.clear_next_insert_id= 0; - } - while ((row=rows.get())) { stacked_inserts--; @@ -2064,9 +2082,12 @@ bool delayed_insert::handle_inserts(void) thd.start_time=row->start_time; thd.query_start_used=row->query_start_used; - thd.last_insert_id=row->last_insert_id; - thd.last_insert_id_used=row->last_insert_id_used; - thd.insert_id_used=row->insert_id_used; + /* for the binlog, forget auto_increment ids generated by previous rows */ +// thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty(); + thd.first_successful_insert_id_in_prev_stmt= + row->first_successful_insert_id_in_prev_stmt; + thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt= + row->stmt_depends_on_first_successful_insert_id_in_prev_stmt; table->timestamp_field_type= row->timestamp_field_type; info.ignore= row->ignore; @@ -2084,11 +2105,28 @@ bool delayed_insert::handle_inserts(void) thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status); row->log_query = 0; } + if (using_ignore) { using_ignore=0; table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); } + + if (row->log_query && row->query.str != NULL && mysql_bin_log.is_open()) + { + /* + If the query has several rows to insert, only the first row will come + here. In row-based binlogging, this means that the first row will be + written to binlog as one Table_map event and one Rows event (due to an + event flush done in binlog_query()), then all other rows of this query + will be binlogged together as one single Table_map event and one + single Rows event. + */ + thd.binlog_query(THD::ROW_QUERY_TYPE, + row->query.str, row->query.length, + FALSE, FALSE); + } + if (table->s->blob_fields) free_delayed_insert_blobs(table); thread_safe_sub(delayed_rows_in_use,1,&LOCK_delayed_status); @@ -2135,13 +2173,25 @@ bool delayed_insert::handle_inserts(void) pthread_cond_broadcast(&cond_client); // If waiting clients } } - thd.proc_info=0; pthread_mutex_unlock(&mutex); - /* After releasing the mutex, to prevent deadlocks. */ - if (mysql_bin_log.is_open()) - thd.binlog_query(THD::ROW_QUERY_TYPE, query, query_length, FALSE, FALSE); +#ifdef HAVE_ROW_BASED_REPLICATION + /* + We need to flush the pending event when using row-based + replication since the flushing normally done in binlog_query() is + not done last in the statement: for delayed inserts, the insert + statement is logged *before* all rows are inserted. + + We can flush the pending event without checking the thd->lock + since the delayed insert *thread* is not inside a stored function + or trigger. + + TODO: Move the logging to last in the sequence of rows. + */ + if (thd.current_stmt_binlog_row_based) + thd.binlog_flush_pending_rows_event(TRUE); +#endif /* HAVE_ROW_BASED_REPLICATION */ if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) { // This shouldn't happen @@ -2229,7 +2279,7 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, enum_duplicates duplic, bool ignore_check_option_errors) :table_list(table_list_par), table(table_par), fields(fields_par), - last_insert_id(0), + autoinc_value_of_last_inserted_row(0), insert_into_view(table_list_par && table_list_par->view != 0) { bzero((char*) &info,sizeof(info)); @@ -2438,15 +2488,20 @@ bool select_insert::send_data(List<Item> &values) if (table->next_number_field) { /* + If no value has been autogenerated so far, we need to remember the + value we just saw, we may need to send it to client in the end. + */ + if (thd->first_successful_insert_id_in_cur_stmt == 0) // optimization + autoinc_value_of_last_inserted_row= + table->next_number_field->val_int(); + /* Clear auto-increment field for the next record, if triggers are used we will clear it twice, but this should be cheap. */ table->next_number_field->reset(); - if (!last_insert_id && thd->insert_id_used) - last_insert_id= thd->insert_id(); } } - table->file->release_auto_increment(); + table->file->ha_release_auto_increment(); DBUG_RETURN(error); } @@ -2508,8 +2563,6 @@ void select_insert::send_error(uint errcode,const char *err) { 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, @@ -2529,6 +2582,7 @@ void select_insert::send_error(uint errcode,const char *err) bool select_insert::send_eof() { int error,error2; + ulonglong id; DBUG_ENTER("select_insert::send_eof"); error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0; @@ -2554,8 +2608,6 @@ bool select_insert::send_eof() thd->options|= OPTION_STATUS_NO_TRANS_UPDATE; } - if (last_insert_id) - thd->insert_id(last_insert_id); // For binary log /* Write to binlog before commiting transaction. No statement will be written by the binlog_query() below in RBR mode. All the @@ -2585,7 +2637,13 @@ bool select_insert::send_eof() sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); thd->row_count_func= info.copied+info.deleted+info.updated; - ::send_ok(thd, (ulong) thd->row_count_func, last_insert_id, buff); + + id= (thd->first_successful_insert_id_in_cur_stmt > 0) ? + thd->first_successful_insert_id_in_cur_stmt : + (thd->arg_of_last_insert_id_function ? + thd->first_successful_insert_id_in_prev_stmt : + (info.copied ? autoinc_value_of_last_inserted_row : 0)); + ::send_ok(thd, (ulong) thd->row_count_func, id, buff); DBUG_RETURN(0); } @@ -2751,21 +2809,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } -class MY_HOOKS : public TABLEOP_HOOKS -{ -public: - MY_HOOKS(select_create *x) : ptr(x) { } - virtual void do_prelock(TABLE **tables, uint count) - { - if (ptr->get_thd()->current_stmt_binlog_row_based) - ptr->binlog_show_create_table(tables, count); - } - -private: - select_create *ptr; -}; - - int select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) { @@ -2778,8 +2821,9 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) MY_HOOKS(select_create *x) : ptr(x) { } virtual void do_prelock(TABLE **tables, uint count) { - if (ptr->get_thd()->current_stmt_binlog_row_based) - ptr->binlog_show_create_table(tables, count); + if (ptr->get_thd()->current_stmt_binlog_row_based && + !(ptr->get_create_info()->options & HA_LEX_CREATE_TMP_TABLE)) + ptr->binlog_show_create_table(tables, count); } private: |