diff options
author | Jacob Mathew <jacob.mathew@mariadb.com> | 2017-10-14 15:24:24 -0700 |
---|---|---|
committer | Jacob Mathew <jacob.mathew@mariadb.com> | 2017-11-10 13:38:09 -0800 |
commit | 26211d5567d72e502f6edaaab7bdefbafd92cdd8 (patch) | |
tree | 045dfe3b51d5b1a02c24b0ae1bd2accc8a6c1800 | |
parent | 6e2e040432b7ade5c42f3feb0902d0286a2d3466 (diff) | |
download | mariadb-git-bb-10.2-spider-extra-jacob.tar.gz |
Adding direct update/delete to the server and to the partition engine.bb-10.2-spider-extra-jacob
Contains Spiral patches:
- Spiral Patch 006: 006_mariadb-10.2.0.direct_update_rows.diff MDEV-7704
- Spiral Patch 008: 008_mariadb-10.2.0.partition_direct_update.diff MDEV-7706
- Spiral Patch 010: 010_mariadb-10.2.0.direct_update_rows2.diff MDEV-7708
- Spiral Patch 011: 011_mariadb-10.2.0.aggregate.diff MDEV-7709
- Spiral Patch 027: 027_mariadb-10.2.0.force_bulk_update.diff MDEV-7724
- Spiral Patch 061: 061_mariadb-10.2.0.mariadb-10.1.8.diff MDEV-12870
- Add support for direct update and direct delete requests. A direct
update/delete request handles all qualified rows in a single operation,
rather than one row at a time.
- This commit has the following differences compared to the original patches:
- Most of the parameters of the new functions are unnecessary. The
unnecessary parameters have been removed.
- Changed bit positions for new handler flags upon consideration of
handler flags not needed by other Spiral patches and handler flags
merged from MySQL.
23 files changed, 1221 insertions, 110 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 16dca66dd06..ab825504121 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -7231,6 +7231,7 @@ FT_INFO *ha_partition::ft_init_ext(uint flags, uint inx, String *key) DBUG_RETURN((FT_INFO*)ft_target); } + /** Return the next record from the FT result set during an ordered index pre-scan @@ -7245,7 +7246,7 @@ int ha_partition::pre_ft_read(bool use_parallel) { int error; DBUG_ENTER("ha_partition::pre_ft_read"); - DBUG_PRINT("info", ("partition this=%p", this)); + DBUG_PRINT("info", ("partition this: %p", this)); m_pre_calling= TRUE; m_pre_call_use_parallel= use_parallel; error= ft_read(table->record[0]); @@ -11224,6 +11225,659 @@ void ha_partition::cond_pop() /** + Perform bulk update preparation on each partition. + + SYNOPSIS + start_bulk_update() + + RETURN VALUE + TRUE Error + FALSE Success +*/ + +bool ha_partition::start_bulk_update() +{ + handler **file= m_file; + DBUG_ENTER("ha_partition::start_bulk_update"); + + if (bitmap_is_overlapping(&m_part_info->full_part_field_set, + table->write_set)) + DBUG_RETURN(TRUE); + + do + { + if ((*file)->start_bulk_update()) + DBUG_RETURN(TRUE); + } while (*(++file)); + DBUG_RETURN(FALSE); +} + + +/** + Perform bulk update execution on each partition. A bulk update allows + a handler to batch the updated rows instead of performing the updates + one row at a time. + + SYNOPSIS + exec_bulk_update() + + RETURN VALUE + TRUE Error + FALSE Success +*/ + +int ha_partition::exec_bulk_update(ha_rows *dup_key_found) +{ + int error; + handler **file= m_file; + DBUG_ENTER("ha_partition::exec_bulk_update"); + + do + { + if ((error= (*file)->exec_bulk_update(dup_key_found))) + DBUG_RETURN(error); + } while (*(++file)); + DBUG_RETURN(0); +} + + +/** + Perform bulk update cleanup on each partition. + + SYNOPSIS + end_bulk_update() + + RETURN VALUE + NONE +*/ + +int ha_partition::end_bulk_update() +{ + int error= 0; + handler **file= m_file; + DBUG_ENTER("ha_partition::end_bulk_update"); + + do + { + int tmp; + if ((tmp= (*file)->end_bulk_update())) + error= tmp; + } while (*(++file)); + DBUG_RETURN(error); +} + + +/** + Add the row to the bulk update on the partition on which the row is stored. + A bulk update allows a handler to batch the updated rows instead of + performing the updates one row at a time. + + SYNOPSIS + bulk_update_row() + old_data Old record + new_data New record + dup_key_found Number of duplicate keys found + + RETURN VALUE + >1 Error + 1 Bulk update not used, normal operation used + 0 Bulk update used by handler +*/ + +int ha_partition::bulk_update_row(const uchar *old_data, uchar *new_data, + ha_rows *dup_key_found) +{ + int error= 0; + uint32 part_id; + longlong func_value; + my_bitmap_map *old_map; + DBUG_ENTER("ha_partition::bulk_update_row"); + + old_map= dbug_tmp_use_all_columns(table, table->read_set); + error= m_part_info->get_partition_id(m_part_info, &part_id, + &func_value); + dbug_tmp_restore_column_map(table->read_set, old_map); + if (unlikely(error)) + { + m_part_info->err_value= func_value; + goto end; + } + + error= m_file[part_id]->ha_bulk_update_row(old_data, new_data, + dup_key_found); + +end: + DBUG_RETURN(error); +} + + +/** + Perform bulk delete preparation on each partition. + + SYNOPSIS + start_bulk_delete() + + RETURN VALUE + TRUE Error + FALSE Success +*/ + +bool ha_partition::start_bulk_delete() +{ + handler **file= m_file; + DBUG_ENTER("ha_partition::start_bulk_delete"); + + do + { + if ((*file)->start_bulk_delete()) + DBUG_RETURN(TRUE); + } while (*(++file)); + DBUG_RETURN(FALSE); +} + + +/** + Perform bulk delete cleanup on each partition. + + SYNOPSIS + end_bulk_delete() + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::end_bulk_delete() +{ + int error= 0; + handler **file= m_file; + DBUG_ENTER("ha_partition::end_bulk_delete"); + + do + { + int tmp; + if ((tmp= (*file)->end_bulk_delete())) + error= tmp; + } while (*(++file)); + DBUG_RETURN(error); +} + + +/** + Perform initialization for a direct update request. + + SYNOPSIS + direct_update_rows_init() + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::direct_update_rows_init() +{ + int error; + uint i, j; + handler *file; + DBUG_ENTER("ha_partition::direct_update_rows_init"); + + if (bitmap_is_overlapping(&m_part_info->full_part_field_set, + table->write_set) +#if defined(HS_HAS_SQLCOM) + && (thd_sql_command(ha_thd()) != SQLCOM_HS_UPDATE || + check_hs_update_overlapping(&ranges->start_key)) +#endif + ) + { + DBUG_PRINT("info", ("partition FALSE by updating part_key")); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + + m_part_spec.start_part= 0; + m_part_spec.end_part= m_tot_parts - 1; + m_direct_update_part_spec= m_part_spec; + + j= 0; + for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++) + { + if (bitmap_is_set(&(m_part_info->read_partitions), i) && + bitmap_is_set(&(m_part_info->lock_partitions), i)) + { + file= m_file[i]; + if ((error= (m_pre_calling ? + file->pre_direct_update_rows_init() : + file->direct_update_rows_init()))) + { + DBUG_PRINT("info", ("partition FALSE by storage engine")); + DBUG_RETURN(error); + } + j++; + } + } + + TABLE_LIST *table_list= table->pos_in_table_list; + if (j != 1 && table_list) + { + while (table_list->parent_l) + table_list= table_list->parent_l; + st_select_lex *select_lex= table_list->select_lex; + DBUG_PRINT("info", ("partition select_lex=%p", select_lex)); + if (select_lex && select_lex->explicit_limit) + { + DBUG_PRINT("info", ("partition explicit_limit=TRUE")); + DBUG_PRINT("info", ("partition offset_limit=%p", + select_lex->offset_limit)); + DBUG_PRINT("info", ("partition select_limit=%p", + select_lex->select_limit)); + DBUG_PRINT("info", ("partition FALSE by select_lex")); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + } + DBUG_PRINT("info", ("partition OK")); + DBUG_RETURN(0); +} + + +/** + Do initialization for performing parallel direct update + for a handlersocket update request. + + SYNOPSIS + pre_direct_update_rows_init() + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::pre_direct_update_rows_init() +{ + int error; + DBUG_ENTER("ha_partition::pre_direct_update_rows_init"); + m_pre_calling= TRUE; + error= direct_update_rows_init(); + m_pre_calling= FALSE; + if (!error && bulk_access_started) + bulk_access_info_current->called= TRUE; + DBUG_RETURN(error); +} + + +/** + Execute a direct update request. A direct update request updates all + qualified rows in a single operation, rather than one row at a time. + The direct update operation is pushed down to each individual + partition. + + SYNOPSIS + direct_update_rows() + update_rows Number of updated rows + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::direct_update_rows(ha_rows *update_rows_result) +{ + int error; + bool rnd_seq= FALSE; + ha_rows update_rows= 0; + uint32 i; + handler *file; + DBUG_ENTER("ha_partition::direct_update_rows"); + + /* If first call to direct_update_rows with RND scan */ + if ((m_pre_calling ? pre_inited : inited) == RND && m_scan_value == 1) + { + rnd_seq= TRUE; + m_scan_value= 2; + } + + *update_rows_result= 0; + for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++) + { + file= m_file[i]; + if (bitmap_is_set(&(m_part_info->read_partitions), i) && + bitmap_is_set(&(m_part_info->lock_partitions), i)) + { + if (rnd_seq && (m_pre_calling ? file->pre_inited : file->inited) == NONE) + { + if ((error= (m_pre_calling ? + file->ha_pre_rnd_init(TRUE) : + file->ha_rnd_init(TRUE)))) + DBUG_RETURN(error); + } + if ((error= (m_pre_calling ? + (file)->ha_pre_direct_update_rows() : + (file)->ha_direct_update_rows(&update_rows)))) + { + if (rnd_seq) + { + if (m_pre_calling) + file->ha_pre_rnd_end(); + else + file->ha_rnd_end(); + } + DBUG_RETURN(error); + } + *update_rows_result+= update_rows; + if (m_pre_calling) + bitmap_set_bit(&bulk_access_exec_bitmap, i); + } + if (rnd_seq) + { + if ((error= (m_pre_calling ? + file->ha_pre_index_or_rnd_end() : + file->ha_index_or_rnd_end()))) + DBUG_RETURN(error); + } + } + DBUG_RETURN(0); +} + + +/** + Start parallel execution of a direct update for a handlersocket update + request. A direct update request updates all qualified rows in a single + operation, rather than one row at a time. The direct update operation + is pushed down to each individual partition. + + SYNOPSIS + pre_direct_update_rows() + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::pre_direct_update_rows() +{ + int error; + ha_rows not_used= 0; + DBUG_ENTER("ha_partition::pre_direct_update_rows"); + m_pre_calling= TRUE; + error= direct_update_rows(¬_used); + m_pre_calling= FALSE; + DBUG_RETURN(error); +} + + +#if defined(HS_HAS_SQLCOM) +/** + Determine whether a key value being updated includes partition columns + when using handlersocket + + SYNOPSIS + check_hs_update_overlapping() + key Key value + + RETURN VALUE + TRUE The key value being updated does not include + partition columns + FALSE The key value being updated does include + partition columns +*/ + +bool ha_partition::check_hs_update_overlapping(key_range *key) +{ + Field *field; + uint store_length, length, var_len, field_index; + const uchar *ptr; + bool key_eq; + KEY *key_info; + KEY_PART_INFO *key_part; + key_part_map tgt_key_part_map= key->keypart_map; + char buf[MAX_FIELD_WIDTH], buf2[MAX_FIELD_WIDTH]; + String tmp_str(buf, MAX_FIELD_WIDTH, &my_charset_bin), *str, + tmp_str2(buf2, MAX_FIELD_WIDTH, &my_charset_bin), *str2; + DBUG_ENTER("ha_partition::check_hs_update_overlapping"); + + key_info= &table->key_info[active_index]; + for (key_part= key_info->key_part, + store_length= key_part->store_length, length= 0; + tgt_key_part_map; + length += store_length, tgt_key_part_map >>= 1, key_part++, + store_length= key_part->store_length) + { + field= key_part->field; + field_index= field->field_index; + if (bitmap_is_set(&m_part_info->full_part_field_set, field_index) && + bitmap_is_set(table->write_set, field_index)) + { + ptr= key->key + length; + key_eq= (tgt_key_part_map > 1); + if (key_part->null_bit && *ptr++) + { + if (key->flag != HA_READ_KEY_EXACT || !field->is_null()) + { + DBUG_PRINT("info", ("spider flag=%u is_null=%s", + key->flag, + field->is_null() ? "TRUE" : "FALSE")); + DBUG_RETURN(TRUE); + } + } + else + { + if (field->type() == MYSQL_TYPE_BLOB || + field->real_type() == MYSQL_TYPE_VARCHAR || + field->type() == MYSQL_TYPE_GEOMETRY) + { + var_len= uint2korr(ptr); + tmp_str.set_quick((char *)ptr + HA_KEY_BLOB_LENGTH, var_len, + &my_charset_bin); + str= &tmp_str; + } + else + str= field->val_str(&tmp_str, ptr); + str2= field->val_str(&tmp_str2); + if (str->length() != str2->length() || + memcmp(str->ptr(), str2->ptr(), str->length())) + { + DBUG_PRINT("info", ("spider length=%u %u", + str->length(), str2->length())); + DBUG_PRINT("info", ("spider length=%s %s", + str->c_ptr_safe(), str2->c_ptr_safe())); + DBUG_RETURN(TRUE); + } + } + } + } + + DBUG_PRINT("info", ("partition return FALSE")); + DBUG_RETURN(FALSE); +} +#endif + + +/** + Perform initialization for a direct delete request. + + SYNOPSIS + direct_delete_rows_init() + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::direct_delete_rows_init() +{ + int error; + uint i, j; + handler *file; + DBUG_ENTER("ha_partition::direct_delete_rows_init"); + + m_part_spec.start_part= 0; + m_part_spec.end_part= m_tot_parts - 1; + m_direct_update_part_spec= m_part_spec; + + j= 0; + for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++) + { + if (bitmap_is_set(&(m_part_info->read_partitions), i) && + bitmap_is_set(&(m_part_info->lock_partitions), i)) + { + file= m_file[i]; + if ((error= (m_pre_calling ? + file->pre_direct_delete_rows_init() : + file->direct_delete_rows_init()))) + { + DBUG_PRINT("info", ("partition FALSE by storage engine")); + DBUG_RETURN(error); + } + j++; + } + } + + TABLE_LIST *table_list= table->pos_in_table_list; + if (j != 1 && table_list) + { + while (table_list->parent_l) + table_list= table_list->parent_l; + st_select_lex *select_lex= table_list->select_lex; + DBUG_PRINT("info", ("partition select_lex=%p", select_lex)); + if (select_lex && select_lex->explicit_limit) + { + DBUG_PRINT("info", ("partition explicit_limit=TRUE")); + DBUG_PRINT("info", ("partition offset_limit=%p", + select_lex->offset_limit)); + DBUG_PRINT("info", ("partition select_limit=%p", + select_lex->select_limit)); + DBUG_PRINT("info", ("partition FALSE by select_lex")); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + } + DBUG_PRINT("info", ("partition OK")); + DBUG_RETURN(0); +} + + +/** + Do initialization for performing parallel direct delete + for a handlersocket delete request. + + SYNOPSIS + pre_direct_delete_rows_init() + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::pre_direct_delete_rows_init() +{ + int error; + DBUG_ENTER("ha_partition::pre_direct_delete_rows_init"); + m_pre_calling= TRUE; + error= direct_delete_rows_init(); + m_pre_calling= FALSE; + if (bulk_access_started) + bulk_access_info_current->called= TRUE; + DBUG_RETURN(error); +} + + +/** + Execute a direct delete request. A direct delete request deletes all + qualified rows in a single operation, rather than one row at a time. + The direct delete operation is pushed down to each individual + partition. + + SYNOPSIS + direct_delete_rows() + delete_rows Number of deleted rows + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::direct_delete_rows(ha_rows *delete_rows_result) +{ + int error; + bool rnd_seq= FALSE; + ha_rows delete_rows= 0; + uint32 i; + handler *file; + DBUG_ENTER("ha_partition::direct_delete_rows"); + + if ((m_pre_calling ? pre_inited : inited) == RND && m_scan_value == 1) + { + rnd_seq= TRUE; + m_scan_value= 2; + } + + *delete_rows_result= 0; + m_part_spec= m_direct_update_part_spec; + for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++) + { + file= m_file[i]; + if (bitmap_is_set(&(m_part_info->read_partitions), i) && + bitmap_is_set(&(m_part_info->lock_partitions), i)) + { + if (rnd_seq && (m_pre_calling ? file->pre_inited : file->inited) == NONE) + { + if ((error= (m_pre_calling ? + file->ha_pre_rnd_init(TRUE) : + file->ha_rnd_init(TRUE)))) + DBUG_RETURN(error); + } + if ((error= (m_pre_calling ? + file->ha_pre_direct_delete_rows() : + file->ha_direct_delete_rows(&delete_rows)))) + { + if (m_pre_calling) + file->ha_pre_rnd_end(); + else + file->ha_rnd_end(); + DBUG_RETURN(error); + } + delete_rows_result+= delete_rows; + if (m_pre_calling) + bitmap_set_bit(&bulk_access_exec_bitmap, i); + } + if (rnd_seq) + { + if ((error= (m_pre_calling ? + file->ha_pre_index_or_rnd_end() : + file->ha_index_or_rnd_end()))) + DBUG_RETURN(error); + } + } + DBUG_RETURN(0); +} + + +/** + Start parallel execution of a direct delete for a handlersocket delete + request. A direct delete request deletes all qualified rows in a single + operation, rather than one row at a time. The direct delete operation + is pushed down to each individual partition. + + SYNOPSIS + pre_direct_delete_rows() + + RETURN VALUE + >0 Error + 0 Success +*/ + +int ha_partition::pre_direct_delete_rows() +{ + int error; + ha_rows not_used; + DBUG_ENTER("ha_partition::pre_direct_delete_rows"); + m_pre_calling= TRUE; + error= direct_delete_rows(¬_used); + m_pre_calling= FALSE; + if (!error && bulk_access_started) + bulk_access_info_current->called= TRUE; + DBUG_RETURN(error); +} + + +/** Push metadata for the current operation down to each partition. SYNOPSIS diff --git a/sql/ha_partition.h b/sql/ha_partition.h index db268a89aea..7bce64cf3a2 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -308,9 +308,11 @@ private: bool auto_increment_safe_stmt_log_lock; /** For optimizing ha_start_bulk_insert calls */ MY_BITMAP m_bulk_insert_started; + MY_BITMAP bulk_access_exec_bitmap; ha_rows m_bulk_inserted_rows; /** used for prediction of start_bulk_insert rows */ enum_monotonicity_info m_part_func_monotonicity_info; + part_id_range m_direct_update_part_spec; bool m_pre_calling; bool m_pre_call_use_parallel; /* Keep track of bulk access requests */ @@ -320,7 +322,6 @@ private: PARTITION_BULK_ACCESS_INFO *bulk_access_info_first; PARTITION_BULK_ACCESS_INFO *bulk_access_info_current; PARTITION_BULK_ACCESS_INFO *bulk_access_info_exec_tgt; - MY_BITMAP bulk_access_exec_bitmap; /** keep track of locked partitions */ MY_BITMAP m_locked_partitions; @@ -551,8 +552,26 @@ public: */ virtual int pre_write_row(uchar *buf); virtual int write_row(uchar * buf); + virtual bool start_bulk_update(); + virtual int exec_bulk_update(ha_rows *dup_key_found); + virtual int end_bulk_update(); + virtual int bulk_update_row(const uchar *old_data, uchar *new_data, + ha_rows *dup_key_found); virtual int update_row(const uchar * old_data, uchar * new_data); + virtual int direct_update_rows_init(); + virtual int pre_direct_update_rows_init(); + virtual int direct_update_rows(ha_rows *update_rows); + virtual int pre_direct_update_rows(); +#if defined(HS_HAS_SQLCOM) + virtual bool check_hs_update_overlapping(key_range *key); +#endif + virtual bool start_bulk_delete(); + virtual int end_bulk_delete(); virtual int delete_row(const uchar * buf); + virtual int direct_delete_rows_init(); + virtual int pre_direct_delete_rows_init(); + virtual int direct_delete_rows(ha_rows *delete_rows); + virtual int pre_direct_delete_rows(); virtual int delete_all_rows(void); virtual int truncate(); virtual void start_bulk_insert(ha_rows rows, uint flags); diff --git a/sql/handler.cc b/sql/handler.cc index c4dce3caf78..977dff0b6f4 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4035,7 +4035,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt) int handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data, - uint *dup_key_found) + ha_rows *dup_key_found) { DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || m_lock_type == F_WRLCK); @@ -6085,6 +6085,95 @@ int handler::ha_delete_row(const uchar *buf) } +/** + Execute a direct update request. A direct update request updates all + qualified rows in a single operation, rather than one row at a time. + In a Spider cluster the direct update operation is pushed down to the + child levels of the cluster. + + @param update_rows Number of updated rows. + + @retval 0 Success. + @retval != 0 Failure. +*/ + +int handler::ha_direct_update_rows(ha_rows *update_rows) +{ + int error; + + MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str); + mark_trx_read_write(); + + error = direct_update_rows(update_rows); + MYSQL_UPDATE_ROW_DONE(error); + return error; +} + + +/** + Log to the binary log the changes for a single row + in a direct update request. + + @retval 0 Success. + @retval != 0 Failure. +*/ + +int handler::ha_direct_update_row_binlog(const uchar *old_data, + uchar *new_data) +{ + Log_func *log_func= Update_rows_log_event::binlog_row_logging_function; + + /* + Some storage engines require that the new record is in record[0] + (and the old record is in record[1]). + */ + DBUG_ASSERT(new_data == table->record[0]); + + return binlog_log_row(table, old_data, new_data, log_func); +} + + +/** + Execute a direct delete request. A direct delete request deletes all + qualified rows in a single operation, rather than one row at a time. + In a Spider cluster the direct delete operation is pushed down to the + child levels of the cluster. + + @param delete_rows Number of deleted rows. + + @retval 0 Success. + @retval != 0 Failure. +*/ + +int handler::ha_direct_delete_rows(ha_rows *delete_rows) +{ + int error; + + MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str); + mark_trx_read_write(); + + error = direct_delete_rows(delete_rows); + MYSQL_DELETE_ROW_DONE(error); + return error; +} + + +/** + Log to the binary log the deletion of a single row + in a direct delete request. + + @retval 0 Success. + @retval != 0 Failure. +*/ + +int handler::ha_direct_delete_row_binlog(const uchar *buf) +{ + Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function; + + return binlog_log_row(table, buf, 0, log_func); +} + + /** @brief use_hidden_primary_key() is called in case of an update/delete when diff --git a/sql/handler.h b/sql/handler.h index 2818431cb64..88ee9e20b4d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -277,6 +277,10 @@ enum enum_alter_inplace_result { /* The following is for bulk access by the partition handler */ #define HA_CAN_BULK_ACCESS (1ULL << 49) +/* The following are used by Spider */ +#define HA_CAN_FORCE_BULK_UPDATE (1ULL << 50) +#define HA_CAN_FORCE_BULK_DELETE (1ULL << 51) + /* bits in index_flags(index_number) for what you can do with index */ #define HA_READ_NEXT 1 /* TODO really use this flag */ #define HA_READ_PREV 2 /* supports ::index_prev */ @@ -426,6 +430,10 @@ static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4; #define HA_CHECK_ALL (~0U) /* Options for info_push() */ +#define INFO_KIND_UPDATE_FIELDS 101 +#define INFO_KIND_UPDATE_VALUES 102 +#define INFO_KIND_FORCE_LIMIT_BEGIN 103 +#define INFO_KIND_FORCE_LIMIT_END 104 #define INFO_KIND_BULK_ACCESS_BEGIN 105 #define INFO_KIND_BULK_ACCESS_CURRENT 106 #define INFO_KIND_BULK_ACCESS_END 107 @@ -1405,9 +1413,6 @@ handlerton *ha_default_tmp_handlerton(THD *thd); #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported #define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables #define HTON_NO_PARTITION (1 << 8) //Not partition of these tables -#define HTON_CAN_MULTISTEP_MERGE (1 << 9) //You can merge mearged tables -// Engine needs to access the main connect string in partitions -#define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 << 10) /* This flag should be set when deciding that the engine does not allow @@ -1428,6 +1433,10 @@ handlerton *ha_default_tmp_handlerton(THD *thd); // MySQL compatibility. Unused. #define HTON_SUPPORTS_FOREIGN_KEYS (1 << 0) //Foreign key constraint supported. +#define HTON_CAN_MERGE (1 <<11) //Merge type table +// Engine needs to access the main connect string in partitions +#define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 <<12) + class Ha_trx_info; struct THD_TRANS @@ -2834,15 +2843,6 @@ public: } DBUG_RETURN(result); } - int ha_pre_index_init(uint idx, bool sorted) - { - int result; - DBUG_ENTER("ha_pre_index_init"); - DBUG_ASSERT(pre_inited==NONE); - if (!(result= pre_index_init(idx, sorted))) - pre_inited=INDEX; - DBUG_RETURN(result); - } int ha_index_end() { DBUG_ENTER("ha_index_end"); @@ -2852,13 +2852,6 @@ public: end_range= NULL; DBUG_RETURN(index_end()); } - int ha_pre_index_end() - { - DBUG_ENTER("ha_pre_index_end"); - DBUG_ASSERT(pre_inited==INDEX); - pre_inited=NONE; - DBUG_RETURN(pre_index_end()); - } /* This is called after index_init() if we need to do a index scan */ virtual int prepare_index_scan() { return 0; } virtual int prepare_index_key_scan_map(const uchar * key, key_part_map keypart_map) @@ -2881,14 +2874,6 @@ public: end_range= NULL; DBUG_RETURN(result); } - int ha_pre_rnd_init(bool scan) - { - int result; - DBUG_ENTER("ha_pre_rnd_init"); - DBUG_ASSERT(pre_inited==NONE || (pre_inited==RND && scan)); - pre_inited= (result= pre_rnd_init(scan)) ? NONE: RND; - DBUG_RETURN(result); - } int ha_rnd_end() { DBUG_ENTER("ha_rnd_end"); @@ -2897,13 +2882,6 @@ public: end_range= NULL; DBUG_RETURN(rnd_end()); } - int ha_pre_rnd_end() - { - DBUG_ENTER("ha_pre_rnd_end"); - DBUG_ASSERT(pre_inited==RND); - pre_inited=NONE; - DBUG_RETURN(pre_rnd_end()); - } int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result)); int ha_reset(); /* this is necessary in many places, e.g. in HANDLER command */ @@ -2911,12 +2889,6 @@ public: { return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0; } - int ha_pre_index_or_rnd_end() - { - return pre_inited == INDEX ? ha_pre_index_end() - : pre_inited == RND ? - ha_pre_rnd_end() : 0; - } /** The cached_table_flags is set at ha_open and ha_external_lock */ @@ -2969,7 +2941,7 @@ public: DBUG_RETURN(ret); } int ha_bulk_update_row(const uchar *old_data, uchar *new_data, - uint *dup_key_found); + ha_rows *dup_key_found); int ha_delete_all_rows(); int ha_truncate(); int ha_reset_auto_increment(ulonglong value); @@ -3151,7 +3123,7 @@ public: @retval 0 Success @retval >0 Error code */ - virtual int exec_bulk_update(uint *dup_key_found) + virtual int exec_bulk_update(ha_rows *dup_key_found) { DBUG_ASSERT(FALSE); return HA_ERR_WRONG_COMMAND; @@ -3160,7 +3132,7 @@ public: Perform any needed clean-up, no outstanding updates are there at the moment. */ - virtual void end_bulk_update() { return; } + virtual int end_bulk_update() { return 0; } /** Execute all outstanding deletes and close down the bulk delete. @@ -3192,6 +3164,48 @@ public: { return 0; } virtual int pre_rnd_next(bool use_parallel) { return 0; } + int ha_pre_rnd_init(bool scan) + { + int result; + DBUG_ENTER("ha_pre_rnd_init"); + DBUG_ASSERT(pre_inited==NONE || (pre_inited==RND && scan)); + pre_inited= (result= pre_rnd_init(scan)) ? NONE: RND; + DBUG_RETURN(result); + } + int ha_pre_rnd_end() + { + DBUG_ENTER("ha_pre_rnd_end"); + DBUG_ASSERT(pre_inited==RND); + pre_inited=NONE; + DBUG_RETURN(pre_rnd_end()); + } + virtual int pre_rnd_init(bool scan) { return 0; } + virtual int pre_rnd_end() { return 0; } + virtual int pre_index_init(uint idx, bool sorted) { return 0; } + virtual int pre_index_end() { return 0; } + int ha_pre_index_init(uint idx, bool sorted) + { + int result; + DBUG_ENTER("ha_pre_index_init"); + DBUG_ASSERT(pre_inited==NONE); + if (!(result= pre_index_init(idx, sorted))) + pre_inited=INDEX; + DBUG_RETURN(result); + } + int ha_pre_index_end() + { + DBUG_ENTER("ha_pre_index_end"); + DBUG_ASSERT(pre_inited==INDEX); + pre_inited=NONE; + DBUG_RETURN(pre_index_end()); + } + int ha_pre_index_or_rnd_end() + { + return (pre_inited == INDEX ? + ha_pre_index_end() : + pre_inited == RND ? ha_pre_rnd_end() : 0 ); + } + /** @brief Positions an index cursor to the index specified in the @@ -4112,9 +4126,7 @@ private: virtual int open(const char *name, int mode, uint test_if_locked)=0; /* Note: ha_index_read_idx_map() may bypass index_init() */ virtual int index_init(uint idx, bool sorted) { return 0; } - virtual int pre_index_init(uint idx, bool sorted) { return 0; } virtual int index_end() { return 0; } - virtual int pre_index_end() { return 0; } /** rnd_init() can be called two times without rnd_end() in between (it only makes sense if scan=1). @@ -4123,9 +4135,7 @@ private: to the start of the table, no need to deallocate and allocate it again */ virtual int rnd_init(bool scan)= 0; - virtual int pre_rnd_init(bool scan) { return 0; } virtual int rnd_end() { return 0; } - virtual int pre_rnd_end() { return 0; } virtual int write_row(uchar *buf __attribute__((unused))) { return HA_ERR_WRONG_COMMAND; @@ -4153,6 +4163,60 @@ private: { return HA_ERR_WRONG_COMMAND; } + + /* Perform initialization for a direct update request */ +public: + int ha_direct_update_rows(ha_rows *update_rows); + int ha_pre_direct_update_rows() + { + return pre_direct_update_rows(); + } + int ha_direct_update_row_binlog(const uchar *old_data, + uchar *new_data); + virtual int direct_update_rows_init() + { + return HA_ERR_WRONG_COMMAND; + } +private: + virtual int pre_direct_update_rows_init() + { + return HA_ERR_WRONG_COMMAND; + } + virtual int direct_update_rows(ha_rows *update_rows __attribute__((unused))) + { + return HA_ERR_WRONG_COMMAND; + } + virtual int pre_direct_update_rows() + { + return HA_ERR_WRONG_COMMAND; + } + + /* Perform initialization for a direct delete request */ +public: + int ha_direct_delete_rows(ha_rows *delete_rows); + int ha_pre_direct_delete_rows() + { + return pre_direct_delete_rows(); + } + int ha_direct_delete_row_binlog(const uchar *buf); + virtual int direct_delete_rows_init() + { + return HA_ERR_WRONG_COMMAND; + } +private: + virtual int pre_direct_delete_rows_init() + { + return HA_ERR_WRONG_COMMAND; + } + virtual int direct_delete_rows(ha_rows *delete_rows __attribute__((unused))) + { + return HA_ERR_WRONG_COMMAND; + } + virtual int pre_direct_delete_rows() + { + return HA_ERR_WRONG_COMMAND; + } + /** Reset state of file to after 'open'. This function is called after every statement for all tables used @@ -4226,7 +4290,7 @@ public: @retval 1 Bulk delete not used, normal operation used */ virtual int bulk_update_row(const uchar *old_data, uchar *new_data, - uint *dup_key_found) + ha_rows *dup_key_found) { DBUG_ASSERT(FALSE); return HA_ERR_WRONG_COMMAND; diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index ab587b8b279..3c5a4da874b 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -398,6 +398,8 @@ int opt_sum_query(THD *thd, const_result= 0; break; } + longlong info_limit = 1; + table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit); if (!(error= table->file->ha_index_init((uint) ref.key, 1))) error= (is_max ? get_index_max_value(table, &ref, range_fl) : @@ -408,9 +410,10 @@ int opt_sum_query(THD *thd, if (!error && reckey_in_range(is_max, &ref, item_field->field, conds, range_fl, prefix_len)) error= HA_ERR_KEY_NOT_FOUND; - table->file->ha_end_keyread(); - table->file->ha_index_end(); - if (error) + table->file->ha_end_keyread(); + table->file->ha_index_end(); + table->file->info_push(INFO_KIND_FORCE_LIMIT_END, NULL); + if (error) { if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) DBUG_RETURN(HA_ERR_KEY_NOT_FOUND); // No rows matching WHERE diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index eb5f0d7a477..c051ffcc13a 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -224,7 +224,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_I_List<ORDER> *order_list, ha_rows limit, ulonglong options, select_result *result) { - bool will_batch; + bool will_batch= FALSE; int error, loc_error; TABLE *table; SQL_SELECT *select=0; @@ -236,11 +236,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, bool return_error= 0; ha_rows deleted= 0; bool reverse= FALSE; + bool has_triggers; ORDER *order= (ORDER *) ((order_list && order_list->elements) ? order_list->first : NULL); SELECT_LEX *select_lex= &thd->lex->select_lex; killed_state killed_status= NOT_KILLED; THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE; + bool binlog_is_row= FALSE; bool with_select= !select_lex->item_list.is_empty(); Explain_delete *explain; Delete_plan query_plan(thd->mem_root); @@ -341,9 +343,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - We should not be binlogging this statement in row-based, and - there should be no delete triggers associated with the table. */ + + has_triggers= (table->triggers && + table->triggers->has_delete_triggers()); if (!with_select && !using_limit && const_cond_result && (!thd->is_current_stmt_binlog_format_row() && - !(table->triggers && table->triggers->has_delete_triggers()))) + !has_triggers)) { /* Update the table->file->stats.records number */ table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); @@ -490,14 +495,58 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (!(select && select->quick)) status_var_increment(thd->status_var.delete_scan_count); - if (query_plan.using_filesort) + table->mark_columns_needed_for_delete(); + + binlog_is_row= (mysql_bin_log.is_open() && + thd->is_current_stmt_binlog_format_row()); + DBUG_PRINT("info", ("binlog_is_row: %s", binlog_is_row ? "TRUE" : "FALSE")); + + /* + We can use direct delete (delete that is done silently in the handler) + if none of the following conditions are true: + - There are triggers + - There is binlog row logging + - There is a virtual not stored column in the WHERE clause + - ORDER BY or LIMIT + - As this requires the rows to be deleted in a specific order + - Note that Spider can handle ORDER BY and LIMIT in a cluster with + one data node. These conditions are therefore checked in + direct_delete_rows_init(). + + Direct delete does not require a WHERE clause + + Later we also ensure that we are only using one table (no sub queries) + */ + if (!has_triggers && !binlog_is_row && !with_select && + !table->check_virtual_columns_marked_for_read()) { + DBUG_PRINT("info", ("Trying direct delete")); + if (select && select->cond && + (select->cond->used_tables() == table->map)) + { + DBUG_ASSERT(!table->file->pushed_cond); + if (!table->file->cond_push(select->cond)) + table->file->pushed_cond= select->cond; + } + if (!table->file->direct_delete_rows_init()) + { + /* Direct deleting is supported */ + DBUG_PRINT("info", ("Using direct delete")); + THD_STAGE_INFO(thd, stage_updating); + if (!(error= table->file->ha_direct_delete_rows(&deleted))) + error= -1; + goto delete_end; + } + } + + if (query_plan.using_filesort) + { { Filesort fsort(order, HA_POS_ERROR, true, select); DBUG_ASSERT(query_plan.index == MAX_KEY); - Filesort_tracker *fs_tracker= + Filesort_tracker *fs_tracker= thd->lex->explain->get_upd_del_plan()->filesort_tracker; if (!(file_sort= filesort(thd, table, &fsort, fs_tracker))) @@ -536,15 +585,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, init_ftfuncs(thd, select_lex, 1); THD_STAGE_INFO(thd, stage_updating); - if (table->prepare_triggers_for_delete_stmt_or_event()) - { - will_batch= FALSE; - } - else + if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_DELETE) || + !table->prepare_triggers_for_delete_stmt_or_event()) will_batch= !table->file->start_bulk_delete(); - table->mark_columns_needed_for_delete(); - if (with_select) { if (result->send_result_set_metadata(select_lex->item_list, @@ -616,6 +660,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, else break; } + +delete_end: killed_status= thd->killed; if (killed_status != NOT_KILLED || thd->is_error()) error= 1; // Aborted @@ -699,6 +745,8 @@ cleanup: } delete file_sort; free_underlaid_joins(thd, select_lex); + if (table->file->pushed_cond) + table->file->cond_pop(); DBUG_RETURN(error >= 0 || thd->is_error()); /* Special exits */ @@ -719,6 +767,8 @@ send_nothing_and_leave: delete select; delete file_sort; free_underlaid_joins(thd, select_lex); + if (table->file->pushed_cond) + table->file->cond_pop(); //table->set_keyread(false); DBUG_ASSERT(!return_error || thd->is_error() || thd->killed); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 0d55003a50f..b8051e0e45d 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -255,11 +255,12 @@ int mysql_update(THD *thd, { bool using_limit= limit != HA_POS_ERROR; bool safe_update= thd->variables.option_bits & OPTION_SAFE_UPDATES; - bool used_key_is_modified= FALSE, transactional_table, will_batch; + bool used_key_is_modified= FALSE, transactional_table; + bool will_batch= FALSE; bool can_compare_record; int res; int error, loc_error; - uint dup_key_found; + ha_rows dup_key_found; bool need_sort= TRUE; bool reverse= FALSE; #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -276,6 +277,7 @@ int mysql_update(THD *thd, ulonglong id; List<Item> all_fields; killed_state killed_status= NOT_KILLED; + bool has_triggers, binlog_is_row, do_direct_update= FALSE; Update_plan query_plan(thd->mem_root); Explain_update *explain; query_plan.index= MAX_KEY; @@ -286,7 +288,7 @@ int mysql_update(THD *thd, if (open_tables(thd, &table_list, &table_count, 0)) DBUG_RETURN(1); - //Prepare views so they are handled correctly. + /* Prepare views so they are handled correctly */ if (mysql_handle_derived(thd->lex, DT_INIT)) DBUG_RETURN(1); @@ -511,7 +513,6 @@ int mysql_update(THD *thd, query_plan.using_io_buffer= true; } - /* Ok, we have generated a query plan for the UPDATE. - if we're running EXPLAIN UPDATE, goto produce explain output @@ -525,10 +526,68 @@ int mysql_update(THD *thd, DBUG_EXECUTE_IF("show_explain_probe_update_exec_start", dbug_serve_apcs(thd, 1);); - + + has_triggers= (table->triggers && + (table->triggers->has_triggers(TRG_EVENT_UPDATE, + TRG_ACTION_BEFORE) || + table->triggers->has_triggers(TRG_EVENT_UPDATE, + TRG_ACTION_AFTER))); + DBUG_PRINT("info", ("has_triggers: %s", has_triggers ? "TRUE" : "FALSE")); + binlog_is_row = (mysql_bin_log.is_open() && + thd->is_current_stmt_binlog_format_row()); + DBUG_PRINT("info", ("binlog_is_row: %s", binlog_is_row ? "TRUE" : "FALSE")); + if (!(select && select->quick)) status_var_increment(thd->status_var.update_scan_count); + /* + We can use direct update (update that is done silently in the handler) + if none of the following conditions are true: + - There are triggers + - There is binlog row logging + - using_io_buffer + - This means that the partition changed or the key we want + to use for scanning the table is changed + - ignore is set + - Direct updates don't return the number of ignored rows + - There is a virtual not stored column in the WHERE clause + - Changing a field used by a stored virtual column, which + would require the column to be recalculated. + - ORDER BY or LIMIT + - As this requires the rows to be updated in a specific order + - Note that Spider can handle ORDER BY and LIMIT in a cluster with + one data node. These conditions are therefore checked in + direct_update_rows_init(). + + Direct update does not require a WHERE clause + + Later we also ensure that we are only using one table (no sub queries) + */ + if (!has_triggers && !binlog_is_row && + !query_plan.using_io_buffer && !ignore && + !table->check_virtual_columns_marked_for_read() && + !table->check_virtual_columns_marked_for_write()) + { + DBUG_PRINT("info", ("Trying direct update")); + if (select && select->cond && + (select->cond->used_tables() == table->map)) + { + DBUG_ASSERT(!table->file->pushed_cond); + if (!table->file->cond_push(select->cond)) + table->file->pushed_cond= select->cond; + } + + if (!table->file->info_push(INFO_KIND_UPDATE_FIELDS, &fields) && + !table->file->info_push(INFO_KIND_UPDATE_VALUES, &values) && + !table->file->direct_update_rows_init()) + { + do_direct_update= TRUE; + + /* Direct update is not using_filesort and is not using_io_buffer */ + goto update_begin; + } + } + if (query_plan.using_filesort || query_plan.using_io_buffer) { /* @@ -688,6 +747,7 @@ int mysql_update(THD *thd, } } +update_begin: if (ignore) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -708,11 +768,20 @@ int mysql_update(THD *thd, transactional_table= table->file->has_transactions(); thd->abort_on_warning= !ignore && thd->is_strict_mode(); - if (table->prepare_triggers_for_update_stmt_or_event()) + + if (do_direct_update) { - will_batch= FALSE; + /* Direct updating is supported */ + DBUG_PRINT("info", ("Using direct update")); + table->reset_default_fields(); + if (!(error= table->file->ha_direct_update_rows(&updated))) + error= -1; + found= updated; + goto update_end; } - else + + if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_UPDATE) || + !table->prepare_triggers_for_update_stmt_or_event()) will_batch= !table->file->start_bulk_update(); /* @@ -796,6 +865,7 @@ int mysql_update(THD *thd, call then it should be included in the count of dup_key_found and error should be set to 0 (only if these errors are ignored). */ + DBUG_PRINT("info", ("Batched update")); error= table->file->ha_bulk_update_row(table->record[1], table->record[0], &dup_key_found); @@ -944,6 +1014,8 @@ int mysql_update(THD *thd, updated-= dup_key_found; if (will_batch) table->file->end_bulk_update(); + +update_end: table->file->try_semi_consistent_read(0); if (!transactional_table && updated > 0) @@ -999,6 +1071,8 @@ int mysql_update(THD *thd, DBUG_ASSERT(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table); free_underlaid_joins(thd, select_lex); delete file_sort; + if (table->file->pushed_cond) + table->file->cond_pop(); /* If LAST_INSERT_ID(X) was used, report X */ id= thd->arg_of_last_insert_id_function ? @@ -1024,7 +1098,6 @@ int mysql_update(THD *thd, *found_return= found; *updated_return= updated; - if (thd->lex->analyze_stmt) goto emit_explain_and_leave; @@ -1035,6 +1108,8 @@ err: delete file_sort; free_underlaid_joins(thd, select_lex); table->file->ha_end_keyread(); + if (table->file->pushed_cond) + table->file->cond_pop(); thd->abort_on_warning= 0; DBUG_RETURN(1); diff --git a/sql/table.cc b/sql/table.cc index 450e116080a..96fa09823a9 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6628,6 +6628,58 @@ bool TABLE::mark_virtual_columns_for_write(bool insert_fl) DBUG_RETURN(bitmap_updated); } + +/** + Check if a virtual not stored column field is in read set + + @retval FALSE No virtual not stored column is used + @retval TRUE At least one virtual not stored column is used +*/ + +bool TABLE::check_virtual_columns_marked_for_read() +{ + if (vfield) + { + Field **vfield_ptr; + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) + { + Field *tmp_vfield= *vfield_ptr; + if (bitmap_is_set(read_set, tmp_vfield->field_index) && + !tmp_vfield->vcol_info->stored_in_db) + return TRUE; + } + } + return FALSE; +} + + +/** + Check if a stored virtual column field is marked for write + + This can be used to check if any column that is part of a virtual + stored column is changed + + @retval FALSE No stored virtual column is used + @retval TRUE At least one stored virtual column is used +*/ + +bool TABLE::check_virtual_columns_marked_for_write() +{ + if (vfield) + { + Field **vfield_ptr; + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) + { + Field *tmp_vfield= *vfield_ptr; + if (bitmap_is_set(write_set, tmp_vfield->field_index) && + tmp_vfield->vcol_info->stored_in_db) + return TRUE; + } + } + return FALSE; +} + + /* Mark fields used by check constraints. This is done once for the TABLE_SHARE the first time the table is opened. @@ -6685,6 +6737,7 @@ void TABLE::mark_default_fields_for_write(bool is_insert) DBUG_VOID_RETURN; } + void TABLE::move_fields(Field **ptr, const uchar *to, const uchar *from) { my_ptrdiff_t diff= to - from; diff --git a/sql/table.h b/sql/table.h index 22846e05bde..ba6e13dd4c5 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1319,6 +1319,8 @@ public: void mark_columns_per_binlog_row_image(void); bool mark_virtual_col(Field *field); bool mark_virtual_columns_for_write(bool insert_fl); + bool check_virtual_columns_marked_for_read(); + bool check_virtual_columns_marked_for_write(); void mark_default_fields_for_write(bool insert_fl); void mark_columns_used_by_check_constraints(void); void mark_check_constraint_columns_for_read(void); diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index c2aafb68de8..1278148a789 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -9726,7 +9726,7 @@ bool ha_spider::start_bulk_update( } int ha_spider::exec_bulk_update( - uint *dup_key_found + ha_rows *dup_key_found ) { int error_num; backup_error_status(); @@ -9738,7 +9738,7 @@ int ha_spider::exec_bulk_update( DBUG_RETURN(0); } -void ha_spider::end_bulk_update( +int ha_spider::end_bulk_update( ) { int error_num; backup_error_status(); @@ -9747,15 +9747,17 @@ void ha_spider::end_bulk_update( if ((error_num = check_and_end_bulk_update(SPD_BU_START_BY_BULK_INIT))) { if (check_error_mode(error_num)) - my_errno = error_num; + my_errno= error_num; + else + error_num= 0; } - DBUG_VOID_RETURN; + DBUG_RETURN(error_num); } int ha_spider::bulk_update_row( const uchar *old_data, uchar *new_data, - uint *dup_key_found + ha_rows *dup_key_found ) { DBUG_ENTER("ha_spider::bulk_update_row"); DBUG_PRINT("info",("spider this=%p", this)); @@ -10005,7 +10007,7 @@ int ha_spider::pre_direct_update_rows_init( if (bulk_access_started) { error_num = bulk_access_link_current->spider-> - ha_pre_direct_update_rows_init( + pre_direct_update_rows_init( mode, ranges, range_count, sorted, new_data); bulk_access_link_current->spider->bulk_access_pre_called = TRUE; bulk_access_link_current->called = TRUE; @@ -10022,7 +10024,7 @@ int ha_spider::direct_update_rows( uint range_count, bool sorted, uchar *new_data, - uint *update_rows + ha_rows *update_rows ) { int error_num; THD *thd = ha_thd(); @@ -10079,7 +10081,7 @@ int ha_spider::pre_direct_update_rows( uint range_count, bool sorted, uchar *new_data, - uint *update_rows + ha_rows *update_rows ) { DBUG_ENTER("ha_spider::pre_direct_update_rows"); DBUG_PRINT("info",("spider this=%p", this)); @@ -10277,7 +10279,7 @@ int ha_spider::pre_direct_delete_rows_init( if (bulk_access_started) { error_num = bulk_access_link_current->spider-> - ha_pre_direct_delete_rows_init( + pre_direct_delete_rows_init( mode, ranges, range_count, sorted); bulk_access_link_current->spider->bulk_access_pre_called = TRUE; bulk_access_link_current->called = TRUE; @@ -10293,7 +10295,7 @@ int ha_spider::direct_delete_rows( KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, - uint *delete_rows + ha_rows *delete_rows ) { int error_num; THD *thd = ha_thd(); @@ -10349,7 +10351,7 @@ int ha_spider::pre_direct_delete_rows( KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, - uint *delete_rows + ha_rows *delete_rows ) { DBUG_ENTER("ha_spider::pre_direct_delete_rows"); DBUG_PRINT("info",("spider this=%p", this)); @@ -12027,7 +12029,7 @@ int ha_spider::check_and_end_bulk_update( spider_bulk_upd_start bulk_upd_start ) { int error_num = 0; - uint dup_key_found = 0; + ha_rows dup_key_found = 0; DBUG_ENTER("ha_spider::check_and_end_bulk_update"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_PRINT("info",("spider bulk_update_start=%d", diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index d539946d89b..d40bc376a4c 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -562,19 +562,23 @@ public: #endif bool start_bulk_update(); int exec_bulk_update( - uint *dup_key_found + ha_rows *dup_key_found ); - void end_bulk_update(); + int end_bulk_update(); int bulk_update_row( const uchar *old_data, uchar *new_data, - uint *dup_key_found + ha_rows *dup_key_found ); int update_row( const uchar *old_data, uchar *new_data ); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS + inline int direct_update_rows_init() + { + return direct_update_rows_init(2, NULL, 0, FALSE, NULL); + } int direct_update_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -583,6 +587,10 @@ public: uchar *new_data ); #ifdef HA_CAN_BULK_ACCESS + inline int pre_direct_update_rows_init() + { + return pre_direct_update_rows_init(2, NULL, 0, FALSE, NULL); + } int pre_direct_update_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -591,20 +599,36 @@ public: uchar *new_data ); #endif + inline int ha_direct_update_rows(KEY_MULTI_RANGE *ranges, + uint range_count, bool sorted, + uchar *new_data, ha_rows *update_rows) + { + return handler::ha_direct_update_rows(update_rows); + } + inline int direct_update_rows(ha_rows *update_rows) + { + return direct_update_rows(NULL, 0, FALSE, NULL, update_rows); + } int direct_update_rows( KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, uchar *new_data, - uint *update_rows + ha_rows *update_rows ); #ifdef HA_CAN_BULK_ACCESS + inline int pre_direct_update_rows() + { + ha_rows update_rows; + + return pre_direct_update_rows(NULL, 0, FALSE, NULL, &update_rows); + } int pre_direct_update_rows( KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, uchar *new_data, - uint *update_rows + ha_rows *update_rows ); #endif #endif @@ -614,6 +638,10 @@ public: const uchar *buf ); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS + inline int direct_delete_rows_init() + { + return direct_delete_rows_init(2, NULL, 0, FALSE); + } int direct_delete_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -621,6 +649,10 @@ public: bool sorted ); #ifdef HA_CAN_BULK_ACCESS + inline int pre_direct_delete_rows_init() + { + return pre_direct_delete_rows_init(2, NULL, 0, FALSE); + } int pre_direct_delete_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -628,18 +660,34 @@ public: bool sorted ); #endif + inline int ha_direct_delete_rows(KEY_MULTI_RANGE *ranges, + uint range_count, bool sorted, + ha_rows *delete_rows) + { + return handler::ha_direct_delete_rows(delete_rows); + } + inline int direct_delete_rows(ha_rows *delete_rows) + { + return direct_delete_rows(NULL, 0, FALSE, delete_rows); + } int direct_delete_rows( KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, - uint *delete_rows + ha_rows *delete_rows ); #ifdef HA_CAN_BULK_ACCESS + inline int pre_direct_delete_rows() + { + ha_rows delete_rows; + + return pre_direct_delete_rows(NULL, 0, FALSE, &delete_rows); + } int pre_direct_delete_rows( KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, - uint *delete_rows + ha_rows *delete_rows ); #endif #endif diff --git a/storage/spider/mysql-test/spider/bg/r/direct_update.result b/storage/spider/mysql-test/spider/bg/r/direct_update.result index 74dae7aec2e..0e536d48617 100644 --- a/storage/spider/mysql-test/spider/bg/r/direct_update.result +++ b/storage/spider/mysql-test/spider/bg/r/direct_update.result @@ -48,6 +48,7 @@ direct_updating test connection master_1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 0 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-01 10:21:39 @@ -59,6 +60,7 @@ update all rows with function UPDATE ta_l SET c = ADDDATE(c, 1); SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -70,6 +72,7 @@ update by primary key UPDATE ta_l SET b = 'x' WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -81,6 +84,7 @@ update by a column without index UPDATE ta_l SET c = '2011-10-17' WHERE b = 'x'; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -92,6 +96,7 @@ update by primary key with order and limit UPDATE ta_l SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 4 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -103,6 +108,7 @@ delete by primary key with order and limit DELETE FROM ta_l WHERE a < 4 ORDER BY c LIMIT 1; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -113,6 +119,7 @@ delete by a column without index DELETE FROM ta_l WHERE b = 'c'; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -122,6 +129,7 @@ delete by primary key DELETE FROM ta_l WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 diff --git a/storage/spider/mysql-test/spider/bg/r/direct_update_part.result b/storage/spider/mysql-test/spider/bg/r/direct_update_part.result index 6db7c01f563..7069cd72fda 100644 --- a/storage/spider/mysql-test/spider/bg/r/direct_update_part.result +++ b/storage/spider/mysql-test/spider/bg/r/direct_update_part.result @@ -38,6 +38,7 @@ PRIMARY KEY(a) ) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1 SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 0 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-01 10:21:39 @@ -49,6 +50,7 @@ update all rows with function UPDATE ta_l2 SET c = ADDDATE(c, 1); SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -60,6 +62,7 @@ update by primary key UPDATE ta_l2 SET b = 'x' WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -71,6 +74,7 @@ update by a column without index UPDATE ta_l2 SET c = '2011-10-17' WHERE b = 'x'; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 5 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -82,6 +86,7 @@ update by primary key with order and limit UPDATE ta_l2 SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 6 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -93,6 +98,7 @@ delete by primary key with order and limit DELETE FROM ta_l2 WHERE a < 4 ORDER BY c LIMIT 1; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -103,6 +109,7 @@ delete by a column without index DELETE FROM ta_l2 WHERE b = 'c'; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -112,6 +119,7 @@ delete by primary key DELETE FROM ta_l2 WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 4 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 diff --git a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result index f50c9822534..1db31ca9f95 100644 --- a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result @@ -461,6 +461,7 @@ Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist DELETE FROM t1; Warnings: Error 12702 Remote table 'auto_test_remote.ter1_1' is not found +Error 12702 Remote table 'auto_test_remote.ter1_1' is not found Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist TRUNCATE t1; Warnings: diff --git a/storage/spider/mysql-test/spider/handler/r/direct_update.result b/storage/spider/mysql-test/spider/handler/r/direct_update.result index 74dae7aec2e..0e536d48617 100644 --- a/storage/spider/mysql-test/spider/handler/r/direct_update.result +++ b/storage/spider/mysql-test/spider/handler/r/direct_update.result @@ -48,6 +48,7 @@ direct_updating test connection master_1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 0 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-01 10:21:39 @@ -59,6 +60,7 @@ update all rows with function UPDATE ta_l SET c = ADDDATE(c, 1); SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -70,6 +72,7 @@ update by primary key UPDATE ta_l SET b = 'x' WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -81,6 +84,7 @@ update by a column without index UPDATE ta_l SET c = '2011-10-17' WHERE b = 'x'; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -92,6 +96,7 @@ update by primary key with order and limit UPDATE ta_l SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 4 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -103,6 +108,7 @@ delete by primary key with order and limit DELETE FROM ta_l WHERE a < 4 ORDER BY c LIMIT 1; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -113,6 +119,7 @@ delete by a column without index DELETE FROM ta_l WHERE b = 'c'; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -122,6 +129,7 @@ delete by primary key DELETE FROM ta_l WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 diff --git a/storage/spider/mysql-test/spider/handler/r/direct_update_part.result b/storage/spider/mysql-test/spider/handler/r/direct_update_part.result index 6db7c01f563..7069cd72fda 100644 --- a/storage/spider/mysql-test/spider/handler/r/direct_update_part.result +++ b/storage/spider/mysql-test/spider/handler/r/direct_update_part.result @@ -38,6 +38,7 @@ PRIMARY KEY(a) ) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1 SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 0 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-01 10:21:39 @@ -49,6 +50,7 @@ update all rows with function UPDATE ta_l2 SET c = ADDDATE(c, 1); SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -60,6 +62,7 @@ update by primary key UPDATE ta_l2 SET b = 'x' WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -71,6 +74,7 @@ update by a column without index UPDATE ta_l2 SET c = '2011-10-17' WHERE b = 'x'; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 5 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -82,6 +86,7 @@ update by primary key with order and limit UPDATE ta_l2 SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 6 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -93,6 +98,7 @@ delete by primary key with order and limit DELETE FROM ta_l2 WHERE a < 4 ORDER BY c LIMIT 1; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -103,6 +109,7 @@ delete by a column without index DELETE FROM ta_l2 WHERE b = 'c'; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -112,6 +119,7 @@ delete by primary key DELETE FROM ta_l2 WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 4 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 diff --git a/storage/spider/mysql-test/spider/handler/r/spider_fixes.result b/storage/spider/mysql-test/spider/handler/r/spider_fixes.result index 9b14817eee4..c171167a1b7 100644 --- a/storage/spider/mysql-test/spider/handler/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/handler/r/spider_fixes.result @@ -465,6 +465,7 @@ Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist DELETE FROM t1; Warnings: Error 12702 Remote table 'auto_test_remote.ter1_1' is not found +Error 12702 Remote table 'auto_test_remote.ter1_1' is not found Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist TRUNCATE t1; Warnings: diff --git a/storage/spider/mysql-test/spider/r/direct_update.result b/storage/spider/mysql-test/spider/r/direct_update.result index 74dae7aec2e..0e536d48617 100644 --- a/storage/spider/mysql-test/spider/r/direct_update.result +++ b/storage/spider/mysql-test/spider/r/direct_update.result @@ -48,6 +48,7 @@ direct_updating test connection master_1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 0 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-01 10:21:39 @@ -59,6 +60,7 @@ update all rows with function UPDATE ta_l SET c = ADDDATE(c, 1); SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -70,6 +72,7 @@ update by primary key UPDATE ta_l SET b = 'x' WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -81,6 +84,7 @@ update by a column without index UPDATE ta_l SET c = '2011-10-17' WHERE b = 'x'; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -92,6 +96,7 @@ update by primary key with order and limit UPDATE ta_l SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 4 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -103,6 +108,7 @@ delete by primary key with order and limit DELETE FROM ta_l WHERE a < 4 ORDER BY c LIMIT 1; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -113,6 +119,7 @@ delete by a column without index DELETE FROM ta_l WHERE b = 'c'; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -122,6 +129,7 @@ delete by primary key DELETE FROM ta_l WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 diff --git a/storage/spider/mysql-test/spider/r/direct_update_part.result b/storage/spider/mysql-test/spider/r/direct_update_part.result index 6db7c01f563..7069cd72fda 100644 --- a/storage/spider/mysql-test/spider/r/direct_update_part.result +++ b/storage/spider/mysql-test/spider/r/direct_update_part.result @@ -38,6 +38,7 @@ PRIMARY KEY(a) ) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1 SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 0 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-01 10:21:39 @@ -49,6 +50,7 @@ update all rows with function UPDATE ta_l2 SET c = ADDDATE(c, 1); SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 2 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -60,6 +62,7 @@ update by primary key UPDATE ta_l2 SET b = 'x' WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -71,6 +74,7 @@ update by a column without index UPDATE ta_l2 SET c = '2011-10-17' WHERE b = 'x'; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 5 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -82,6 +86,7 @@ update by primary key with order and limit UPDATE ta_l2 SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1; SHOW STATUS LIKE 'Spider_direct_update'; Variable_name Value +Spider_direct_update 6 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -93,6 +98,7 @@ delete by primary key with order and limit DELETE FROM ta_l2 WHERE a < 4 ORDER BY c LIMIT 1; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 1 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -103,6 +109,7 @@ delete by a column without index DELETE FROM ta_l2 WHERE b = 'c'; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 3 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 @@ -112,6 +119,7 @@ delete by primary key DELETE FROM ta_l2 WHERE a = 3; SHOW STATUS LIKE 'Spider_direct_delete'; Variable_name Value +Spider_direct_delete 4 SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') 1 a 2008-08-02 10:21:39 diff --git a/storage/spider/mysql-test/spider/r/spider_fixes.result b/storage/spider/mysql-test/spider/r/spider_fixes.result index f50c9822534..1db31ca9f95 100644 --- a/storage/spider/mysql-test/spider/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/r/spider_fixes.result @@ -461,6 +461,7 @@ Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist DELETE FROM t1; Warnings: Error 12702 Remote table 'auto_test_remote.ter1_1' is not found +Error 12702 Remote table 'auto_test_remote.ter1_1' is not found Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist TRUNCATE t1; Warnings: diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index c6bf4db3075..10332dc8709 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -1011,7 +1011,7 @@ int spider_db_query_for_bulk_update( ha_spider *spider, SPIDER_CONN *conn, int link_idx, - uint *dup_key_found + ha_rows *dup_key_found ) { int error_num; SPIDER_SHARE *share = spider->share; @@ -6096,7 +6096,7 @@ int spider_db_bulk_update_size_limit( SPIDER_SHARE *share = spider->share; SPIDER_RESULT_LIST *result_list = &spider->result_list; SPIDER_CONN *conn; - uint dup_key_found = 0; + ha_rows dup_key_found = 0; DBUG_ENTER("spider_db_bulk_update_size_limit"); if (result_list->bulk_update_mode == 1) @@ -6159,7 +6159,7 @@ error_mk_table: int spider_db_bulk_update_end( ha_spider *spider, - uint *dup_key_found + ha_rows *dup_key_found ) { int error_num = 0, error_num2, roop_count; THD *thd = spider->trx->thd; @@ -6492,7 +6492,7 @@ int spider_db_direct_update( TABLE *table, KEY_MULTI_RANGE *ranges, uint range_count, - uint *update_rows + ha_rows *update_rows ) { int error_num, roop_count; SPIDER_SHARE *share = spider->share; @@ -6762,7 +6762,7 @@ int spider_db_direct_update( if (!counted) { *update_rows = spider->conns[roop_count]->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider update_rows = %u", *update_rows)); + DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows)); counted = TRUE; } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) @@ -6783,7 +6783,7 @@ int spider_db_direct_update( if (!counted) { *update_rows = conn->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider update_rows = %u", *update_rows)); + DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows)); counted = TRUE; } result->free_result(); @@ -6822,7 +6822,7 @@ int spider_db_direct_update( #ifdef HA_CAN_BULK_ACCESS int spider_db_bulk_direct_update( ha_spider *spider, - uint *update_rows + ha_rows *update_rows ) { int error_num = 0, roop_count, tmp_error_num; SPIDER_SHARE *share = spider->share; @@ -6866,7 +6866,7 @@ int spider_db_bulk_direct_update( if (!counted) { *update_rows = spider->conns[roop_count]->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider update_rows = %u", *update_rows)); + DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows)); counted = TRUE; } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) @@ -6887,7 +6887,7 @@ int spider_db_bulk_direct_update( if (!counted) { *update_rows = conn->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider update_rows = %u", *update_rows)); + DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows)); counted = TRUE; } result->free_result(); @@ -6996,7 +6996,7 @@ int spider_db_direct_delete( TABLE *table, KEY_MULTI_RANGE *ranges, uint range_count, - uint *delete_rows + ha_rows *delete_rows ) { int error_num, roop_count; SPIDER_SHARE *share = spider->share; @@ -7186,7 +7186,7 @@ int spider_db_direct_delete( if (!counted) { *delete_rows = spider->conns[roop_count]->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider delete_rows = %u", *delete_rows)); + DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows)); counted = TRUE; } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) diff --git a/storage/spider/spd_db_conn.h b/storage/spider/spd_db_conn.h index 6d149f6d4a0..ab6826d0157 100644 --- a/storage/spider/spd_db_conn.h +++ b/storage/spider/spd_db_conn.h @@ -325,7 +325,7 @@ int spider_db_query_for_bulk_update( ha_spider *spider, SPIDER_CONN *conn, int link_idx, - uint *dup_key_found + ha_rows *dup_key_found ); size_t spider_db_real_escape_string( @@ -713,7 +713,7 @@ int spider_db_bulk_update_size_limit( int spider_db_bulk_update_end( ha_spider *spider, - uint *dup_key_found + ha_rows *dup_key_found ); int spider_db_bulk_update( @@ -734,14 +734,14 @@ int spider_db_direct_update( TABLE *table, KEY_MULTI_RANGE *ranges, uint range_count, - uint *update_rows + ha_rows *update_rows ); #endif #ifdef HA_CAN_BULK_ACCESS int spider_db_bulk_direct_update( ha_spider *spider, - uint *update_rows + ha_rows *update_rows ); #endif @@ -763,7 +763,7 @@ int spider_db_direct_delete( TABLE *table, KEY_MULTI_RANGE *ranges, uint range_count, - uint *delete_rows + ha_rows *delete_rows ); #endif diff --git a/storage/spider/spd_environ.h b/storage/spider/spd_environ.h index 1ca40f3f8cd..fa462c75230 100644 --- a/storage/spider/spd_environ.h +++ b/storage/spider/spd_environ.h @@ -14,7 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* - Define functinolity offered by MySQL or MariaDB + Define functionality offered by MySQL or MariaDB */ #ifndef SPD_ENVIRON_INCLUDED @@ -25,6 +25,7 @@ #if MYSQL_VERSION_ID >= 100204 #define HANDLER_HAS_TOP_TABLE_FIELDS +#define HANDLER_HAS_DIRECT_UPDATE_ROWS #define HANDLER_HAS_DIRECT_AGGREGATE #define PARTITION_HAS_EXTRA_ATTACH_CHILDREN #define PARTITION_HAS_GET_CHILD_HANDLERS |