diff options
Diffstat (limited to 'storage')
52 files changed, 12158 insertions, 1422 deletions
diff --git a/storage/spider/CMakeLists.txt b/storage/spider/CMakeLists.txt index 14c50f35bd9..499b4948485 100644 --- a/storage/spider/CMakeLists.txt +++ b/storage/spider/CMakeLists.txt @@ -1,13 +1,17 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_HANDLERSOCKET") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_HANDLERSOCKET") -MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG) +IF(HAVE_WVLA) + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-vla") + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wno-vla") +ENDIF() SET(SPIDER_SOURCES spd_param.cc spd_sys_table.cc spd_trx.cc spd_db_conn.cc spd_conn.cc spd_table.cc spd_direct_sql.cc spd_udf.cc spd_ping_table.cc spd_copy_tables.cc spd_i_s.cc spd_malloc.cc ha_spider.cc spd_udf.def spd_db_mysql.cc spd_db_handlersocket.cc spd_db_oracle.cc + spd_group_by_handler.cc hs_client/config.cpp hs_client/escape.cpp hs_client/fatal.cpp hs_client/hstcpcli.cpp hs_client/socket.cpp hs_client/string_util.cpp ) @@ -21,11 +25,11 @@ IF(DEFINED ENV{ORACLE_HOME}) ENDIF() IF(EXISTS ${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake) - SET(CMAKE_CXX_FLAGS_DEBUG + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi") - SET(CMAKE_C_FLAGS_DEBUG + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi") - SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS") + SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS") INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") INCLUDE_DIRECTORIES( @@ -53,3 +57,12 @@ IF(ORACLE_INCLUDE_DIR AND ORACLE_OCI_LIBRARY) TARGET_LINK_LIBRARIES (spider ${ORACLE_OCI_LIBRARY}) ENDIF() ENDIF() + +IF(MSVC) + IF (CMAKE_BUILD_TYPE STREQUAL "Debug") + ADD_CUSTOM_COMMAND(TARGET spider + POST_BUILD + COMMAND if not exist ..\\..\\sql\\lib mkdir ..\\..\\sql\\lib\\plugin + COMMAND copy Debug\\ha_spider.dll ..\\..\\sql\\lib\\plugin\\ha_spider.dll) + ENDIF() +ENDIF() diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 6c1f84337d9..67e27dd9b81 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation @@ -109,6 +109,9 @@ ha_spider::ha_spider( sql_kinds = 0; error_mode = 0; use_spatial_index = FALSE; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + use_fields = FALSE; +#endif use_pre_call = FALSE; use_pre_records = FALSE; #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS @@ -153,6 +156,7 @@ ha_spider::ha_spider( result_list.tmp_tables_created = FALSE; result_list.bgs_working = FALSE; result_list.direct_order_limit = FALSE; + result_list.direct_limit_offset = FALSE; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) result_list.hs_has_result = FALSE; #endif @@ -217,6 +221,9 @@ ha_spider::ha_spider( sql_kinds = 0; error_mode = 0; use_spatial_index = FALSE; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + use_fields = FALSE; +#endif use_pre_call = FALSE; use_pre_records = FALSE; #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS @@ -261,6 +268,7 @@ ha_spider::ha_spider( result_list.tmp_tables_created = FALSE; result_list.bgs_working = FALSE; result_list.direct_order_limit = FALSE; + result_list.direct_limit_offset = FALSE; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) result_list.hs_has_result = FALSE; #endif @@ -416,6 +424,7 @@ int ha_spider::open( partition_handler_share->rnd_bitmap_is_set = FALSE; partition_handler_share->table_hash_value = hash_value; partition_handler_share->creator = this; + partition_handler_share->parallel_search_query_id = 0; pt_handler_share_creator = this; if (part_num) { @@ -483,6 +492,8 @@ int ha_spider::open( } } #endif + memset(ft_discard_bitmap, 0xFF, no_bytes_in_map(table->read_set)); + memset(searched_bitmap, 0, no_bytes_in_map(table->read_set)); init_sql_alloc_size = spider_param_init_sql_alloc_size(thd, share->init_sql_alloc_size); @@ -1309,6 +1320,7 @@ int ha_spider::external_lock( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -1362,6 +1374,7 @@ int ha_spider::external_lock( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -1394,6 +1407,7 @@ int ha_spider::external_lock( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -1429,6 +1443,7 @@ int ha_spider::external_lock( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -1454,6 +1469,7 @@ int ha_spider::external_lock( if (thd_test_options(trx->thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) trans_register_ha(trx->thd, TRUE, spider_hton_ptr); } + if ((conn_kinds & SPIDER_CONN_KIND_HS_READ)) { SPIDER_CONN *hs_conn; @@ -1535,6 +1551,43 @@ int ha_spider::external_lock( } } #endif + + DBUG_PRINT("info",("spider trx_start=%s", trx->trx_start ? "TRUE" : "FALSE")); + /* need to check after spider_internal_start_trx() */ + if (trx->trx_start) + { + switch (sql_command) + { + case SQLCOM_SELECT: + case SQLCOM_HA_READ: +#ifdef HS_HAS_SQLCOM + case SQLCOM_HS_READ: +#endif + /* nothing to do */ + break; + case SQLCOM_UPDATE: + case SQLCOM_UPDATE_MULTI: +#ifdef HS_HAS_SQLCOM + case SQLCOM_HS_UPDATE: +#endif + case SQLCOM_CREATE_TABLE: + case SQLCOM_INSERT: + case SQLCOM_INSERT_SELECT: + case SQLCOM_DELETE: + case SQLCOM_LOAD: + case SQLCOM_REPLACE: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_DELETE_MULTI: +#ifdef HS_HAS_SQLCOM + case SQLCOM_HS_INSERT: + case SQLCOM_HS_DELETE: +#endif + default: + trx->updated_in_this_trx = TRUE; + DBUG_PRINT("info",("spider trx->updated_in_this_trx=TRUE")); + break; + } + } DBUG_RETURN(0); } @@ -1622,7 +1675,11 @@ int ha_spider::reset() partition_handler_share->rnd_bitmap_is_set = FALSE; } #endif - memset(ft_discard_bitmap, 0xFF, no_bytes_in_map(table->read_set)); + if (!is_clone) + { + memset(ft_discard_bitmap, 0xFF, no_bytes_in_map(table->read_set)); + memset(searched_bitmap, 0, no_bytes_in_map(table->read_set)); + } if (!(tmp_trx = spider_get_trx(thd, TRUE, &error_num2))) { DBUG_PRINT("info",("spider get trx error")); @@ -1686,6 +1743,7 @@ int ha_spider::reset() trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -1792,6 +1850,7 @@ int ha_spider::reset() prev_index_rnd_init = SPD_NONE; result_list.have_sql_kind_backup = FALSE; result_list.direct_order_limit = FALSE; + result_list.direct_limit_offset = FALSE; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) if ((error_num2 = reset_hs_strs(SPIDER_SQL_TYPE_UPDATE_HS))) error_num = error_num2; @@ -1799,6 +1858,9 @@ int ha_spider::reset() result_list.set_split_read = FALSE; result_list.insert_dup_update_pushdown = FALSE; use_spatial_index = FALSE; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + use_fields = FALSE; +#endif error_mode = 0; #ifdef HA_CAN_BULK_ACCESS #ifndef DBUG_OFF @@ -1873,8 +1935,13 @@ int ha_spider::extra( DBUG_RETURN(error_num); break; #endif +#if defined(HA_EXTRA_HAS_STARTING_ORDERED_INDEX_SCAN) || defined(HA_EXTRA_HAS_HA_EXTRA_USE_CMP_REF) #ifdef HA_EXTRA_HAS_STARTING_ORDERED_INDEX_SCAN - case HA_EXTRA_STARTING_ORDERED_INDEX_SCAN: + case HA_EXTRA_STARTING_ORDERED_INDEX_SCAN: +#endif +#ifdef HA_EXTRA_HAS_HA_EXTRA_USE_CMP_REF + case HA_EXTRA_USE_CMP_REF: +#endif DBUG_PRINT("info",("spider HA_EXTRA_STARTING_ORDERED_INDEX_SCAN")); if (table_share->primary_key != MAX_KEY) { @@ -2222,6 +2289,7 @@ int ha_spider::index_read_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -2305,6 +2373,7 @@ int ha_spider::index_read_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -2338,6 +2407,7 @@ int ha_spider::index_read_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -2368,6 +2438,7 @@ int ha_spider::index_read_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -2714,6 +2785,7 @@ int ha_spider::index_read_last_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -2794,6 +2866,7 @@ int ha_spider::index_read_last_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -2827,6 +2900,7 @@ int ha_spider::index_read_last_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -2857,6 +2931,7 @@ int ha_spider::index_read_last_map_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3180,6 +3255,7 @@ int ha_spider::index_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3261,6 +3337,7 @@ int ha_spider::index_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3294,6 +3371,7 @@ int ha_spider::index_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3324,6 +3402,7 @@ int ha_spider::index_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3564,6 +3643,7 @@ int ha_spider::index_last_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3645,6 +3725,7 @@ int ha_spider::index_last_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3678,6 +3759,7 @@ int ha_spider::index_last_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3708,6 +3790,7 @@ int ha_spider::index_last_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4008,6 +4091,7 @@ int ha_spider::read_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4088,6 +4172,7 @@ int ha_spider::read_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4121,6 +4206,7 @@ int ha_spider::read_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4151,6 +4237,7 @@ int ha_spider::read_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4636,6 +4723,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4721,6 +4809,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4755,6 +4844,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4787,6 +4877,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5427,6 +5518,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5515,6 +5607,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5555,6 +5648,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5590,6 +5684,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5620,6 +5715,7 @@ int ha_spider::read_multi_range_first_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6076,6 +6172,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6161,6 +6258,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6195,6 +6293,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6227,6 +6326,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6871,6 +6971,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6959,6 +7060,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6999,6 +7101,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7034,6 +7137,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7064,6 +7168,7 @@ int ha_spider::read_multi_range_next( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7367,6 +7472,8 @@ int ha_spider::rnd_next_internal( uchar *buf ) { int error_num; + ha_spider *direct_limit_offset_spider = + (ha_spider *) partition_handler_share->creator; backup_error_status(); DBUG_ENTER("ha_spider::rnd_next_internal"); DBUG_PRINT("info",("spider this=%p", this)); @@ -7398,6 +7505,42 @@ int ha_spider::rnd_next_internal( #ifdef WITH_PARTITION_STORAGE_ENGINE check_select_column(TRUE); #endif + + if (this->result_list.direct_limit_offset) + { + if (direct_limit_offset_spider->direct_select_limit == 0) + { // mean has got all result + DBUG_RETURN(check_error_mode_eof(HA_ERR_END_OF_FILE)); + } + if ( + partition_handler_share->handlers && + direct_limit_offset_spider->direct_current_offset > 0 + ) { + longlong table_count = this->records(); + DBUG_PRINT("info",("spider table_count=%lld", table_count)); + if (table_count <= direct_limit_offset_spider->direct_current_offset) + { + // skip this spider(partition) + direct_limit_offset_spider->direct_current_offset -= table_count; + DBUG_PRINT("info",("spider direct_current_offset=%lld", + direct_limit_offset_spider->direct_current_offset)); + DBUG_RETURN(check_error_mode_eof(HA_ERR_END_OF_FILE)); + } + } + + // make the offset/limit statement + DBUG_PRINT("info",("spider direct_current_offset=%lld", + direct_limit_offset_spider->direct_current_offset)); + result_list.internal_offset = direct_limit_offset_spider->direct_current_offset; + DBUG_PRINT("info",("spider direct_select_limit=%lld", + direct_limit_offset_spider->direct_select_limit)); + result_list.internal_limit = direct_limit_offset_spider->direct_select_limit; + result_list.split_read = direct_limit_offset_spider->direct_select_limit; + + // start with this spider(partition) + direct_limit_offset_spider->direct_current_offset = 0; + } + DBUG_PRINT("info",("spider result_list.finish_flg = FALSE")); result_list.finish_flg = FALSE; result_list.record_num = 0; @@ -7501,6 +7644,7 @@ int ha_spider::rnd_next_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7560,6 +7704,7 @@ int ha_spider::rnd_next_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7593,6 +7738,7 @@ int ha_spider::rnd_next_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7623,6 +7769,7 @@ int ha_spider::rnd_next_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7648,7 +7795,25 @@ int ha_spider::rnd_next_internal( #endif } rnd_scan_and_first = FALSE; + + if (this->result_list.direct_limit_offset) + { + if (buf && (error_num = spider_db_seek_next(buf, this, search_link_idx, + table))) + DBUG_RETURN(check_error_mode_eof(error_num)); + DBUG_RETURN(0); + } } + + if ( + result_list.direct_limit_offset && + direct_limit_offset_spider->direct_select_offset > 0 + ) { + // limit-- for each got row + direct_limit_offset_spider->direct_select_offset--; + DBUG_RETURN(0); + } + if (buf && (error_num = spider_db_seek_next(buf, this, search_link_idx, table))) DBUG_RETURN(check_error_mode_eof(error_num)); @@ -7795,7 +7960,7 @@ int ha_spider::cmp_ref( *field; field++ ) { - if ((ret = (*field)->cmp_binary_offset((uint)ptr_diff))) + if ((ret = (*field)->cmp_binary_offset(ptr_diff))) { DBUG_PRINT("info",("spider different at %s", (*field)->field_name.str)); @@ -7901,6 +8066,7 @@ void ha_spider::ft_end() store_error_num = index_end(); } ft_init_without_index_init = FALSE; + handler::ft_end(); DBUG_VOID_RETURN; } @@ -8100,6 +8266,7 @@ int ha_spider::ft_read_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -8153,6 +8320,7 @@ int ha_spider::ft_read_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -8185,6 +8353,7 @@ int ha_spider::ft_read_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -8215,6 +8384,7 @@ int ha_spider::ft_read_internal( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -8475,6 +8645,7 @@ int ha_spider::info( trx, trx->thd, share, + search_link_idx, (uint32) share->monitoring_sid[search_link_idx], share->table_name, share->table_name_length, @@ -8522,7 +8693,7 @@ int ha_spider::info( } } #ifndef WITHOUT_SPIDER_BG_SEARCH - } else { + } else if (sts_bg_mode == 1) { /* background */ if (!share->bg_sts_init || share->bg_sts_thd_wait) { @@ -8552,6 +8723,14 @@ int ha_spider::info( } else pthread_cond_signal(&share->bg_sts_cond); } + } else { + share->bg_sts_try_time = tmp_time; + share->bg_sts_interval = sts_interval; + share->bg_sts_mode = sts_mode; +#ifdef WITH_PARTITION_STORAGE_ENGINE + share->bg_sts_sync = sts_sync; +#endif + spider_table_add_share_to_sts_thread(share); } #endif pthread_mutex_unlock(&share->sts_mutex); @@ -8745,6 +8924,7 @@ ha_rows ha_spider::records_in_range( trx, trx->thd, share, + search_link_idx, (uint32) share->monitoring_sid[search_link_idx], share->table_name, share->table_name_length, @@ -8785,7 +8965,7 @@ ha_rows ha_spider::records_in_range( } } #ifndef WITHOUT_SPIDER_BG_SEARCH - } else { + } else if (crd_bg_mode == 1) { /* background */ if (!share->bg_crd_init || share->bg_crd_thd_wait) { @@ -8807,6 +8987,14 @@ ha_rows ha_spider::records_in_range( } else pthread_cond_signal(&share->bg_crd_cond); } + } else { + share->bg_crd_try_time = tmp_time; + share->bg_crd_interval = crd_interval; + share->bg_crd_mode = crd_mode; +#ifdef WITH_PARTITION_STORAGE_ENGINE + share->bg_crd_sync = crd_sync; +#endif + spider_table_add_share_to_crd_thread(share); } #endif pthread_mutex_unlock(&share->crd_mutex); @@ -9036,6 +9224,7 @@ int ha_spider::check_crd() trx, trx->thd, share, + search_link_idx, (uint32) share->monitoring_sid[search_link_idx], share->table_name, share->table_name_length, @@ -9070,7 +9259,7 @@ int ha_spider::check_crd() } } #ifndef WITHOUT_SPIDER_BG_SEARCH - } else { + } else if (crd_bg_mode == 1) { /* background */ if (!share->bg_crd_init || share->bg_crd_thd_wait) { @@ -9091,6 +9280,14 @@ int ha_spider::check_crd() } else pthread_cond_signal(&share->bg_crd_cond); } + } else { + share->bg_crd_try_time = tmp_time; + share->bg_crd_interval = crd_interval; + share->bg_crd_mode = crd_mode; +#ifdef WITH_PARTITION_STORAGE_ENGINE + share->bg_crd_sync = crd_sync; +#endif + spider_table_add_share_to_crd_thread(share); } #endif pthread_mutex_unlock(&share->crd_mutex); @@ -9140,11 +9337,11 @@ ha_rows ha_spider::records() use_pre_records = FALSE; DBUG_RETURN(0); } - if (!(share->additional_table_flags & HA_HAS_RECORDS)) + if (!(share->additional_table_flags & HA_HAS_RECORDS) && !this->result_list.direct_limit_offset) { DBUG_RETURN(handler::records()); } - if (!use_pre_records) + if (!use_pre_records && !this->result_list.direct_limit_offset) { THD *thd = trx->thd; if ( @@ -9195,10 +9392,15 @@ ulonglong ha_spider::table_flags() const HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_PARTIAL_COLUMN_READ | +#ifdef HA_CMP_REF_IS_EXPENSIVE HA_CMP_REF_IS_EXPENSIVE | +#endif #ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON HA_CAN_TABLE_CONDITION_PUSHDOWN | #endif +#ifdef HA_SKIP_OPTIMIZE_CONST_TABLE + HA_SKIP_OPTIMIZE_CONST_TABLE | +#endif #ifdef HA_CAN_BULK_ACCESS #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) (support_bulk_access_hs() ? HA_CAN_BULK_ACCESS : 0) | @@ -9207,7 +9409,9 @@ ulonglong ha_spider::table_flags() const SPIDER_CAN_BG_SEARCH | SPIDER_CAN_BG_INSERT | SPIDER_CAN_BG_UPDATE | +#ifdef HA_CAN_DIRECT_UPDATE_AND_DELETE HA_CAN_DIRECT_UPDATE_AND_DELETE | +#endif #ifdef HA_CAN_FORCE_BULK_UPDATE (share && share->force_bulk_update ? HA_CAN_FORCE_BULK_UPDATE : 0) | #endif @@ -9569,6 +9773,9 @@ int ha_spider::write_row( DBUG_RETURN(error_num); } #endif +#ifndef SPIDER_WITHOUT_HA_STATISTIC_INCREMENT + ha_statistic_increment(&SSV::ha_write_count); +#endif #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 #else if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) @@ -9750,11 +9957,9 @@ int 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; - else - error_num= 0; + DBUG_RETURN(error_num); } - DBUG_RETURN(error_num); + DBUG_RETURN(0); } int ha_spider::bulk_update_row( @@ -9806,6 +10011,9 @@ int ha_spider::update_row( DBUG_RETURN(error_num); } #endif +#ifndef SPIDER_WITHOUT_HA_STATISTIC_INCREMENT + ha_statistic_increment(&SSV::ha_update_count); +#endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS do_direct_update = FALSE; #endif @@ -9858,6 +10066,7 @@ int ha_spider::update_row( } #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::direct_update_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -9995,8 +10204,103 @@ int ha_spider::direct_update_rows_init( do_direct_update = FALSE; DBUG_RETURN(HA_ERR_WRONG_COMMAND); } +#else +int ha_spider::direct_update_rows_init() +{ + st_select_lex *select_lex; + longlong select_limit; + longlong offset_limit; + THD *thd = trx->thd; + DBUG_ENTER("ha_spider::direct_update_rows_init"); + DBUG_PRINT("info",("spider this=%p", this)); +#ifdef HA_CAN_BULK_ACCESS + if ( + bulk_access_executing && + ( + ( + !is_bulk_access_clone && + bulk_access_link_exec_tgt->called + ) || + bulk_access_pre_called + ) + ) { + if (is_bulk_access_clone) + { + DBUG_PRINT("info",("spider return pre_direct_init_result %d", + pre_direct_init_result)); + DBUG_RETURN(pre_direct_init_result); + } + DBUG_RETURN(bulk_access_link_exec_tgt->spider->direct_update_rows_init()); + } +#endif + direct_update_init( + thd, + FALSE + ); + if (!condition) + cond_check = FALSE; + spider_get_select_limit(this, &select_lex, &select_limit, &offset_limit); + if (direct_update_fields) + { + if ( +#if MYSQL_VERSION_ID < 50500 + !thd->variables.engine_condition_pushdown || +#else +#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON +#else + !(thd->variables.optimizer_switch & + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) || +#endif +#endif + !select_lex || + select_lex->table_list.elements != 1 || + check_update_columns_sql_part() || + spider_db_append_condition(this, NULL, 0, TRUE) + ) { + DBUG_PRINT("info",("spider FALSE by condition")); + do_direct_update = FALSE; + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + if (select_lex->order_list.elements) + { + ORDER *order; + for (order = (ORDER *) select_lex->order_list.first; order; + order = order->next) + { + if (check_item_type_sql((*order->item))) + { + DBUG_PRINT("info",("spider FALSE by order")); + do_direct_update = FALSE; + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + } + result_list.direct_order_limit = TRUE; + } + trx->direct_update_count++; + DBUG_PRINT("info",("spider OK")); + DBUG_RETURN(0); + } + + DBUG_PRINT("info",("spider offset_limit=%lld", offset_limit)); + DBUG_PRINT("info",("spider sql_command=%u", sql_command)); + DBUG_PRINT("info",("spider do_direct_update=%s", + do_direct_update ? "TRUE" : "FALSE")); + if ( + !offset_limit && + do_direct_update + ) { + trx->direct_update_count++; + DBUG_PRINT("info",("spider OK")); + DBUG_RETURN(0); + } + DBUG_PRINT("info",("spider FALSE by default")); + do_direct_update = FALSE; + DBUG_RETURN(HA_ERR_WRONG_COMMAND); +} +#endif #ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::pre_direct_update_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -10020,8 +10324,27 @@ int ha_spider::pre_direct_update_rows_init( mode, ranges, range_count, sorted, new_data); DBUG_RETURN(pre_direct_init_result); } +#else +int ha_spider::pre_direct_update_rows_init() +{ + int error_num; + DBUG_ENTER("ha_spider::pre_direct_update_rows_init"); + DBUG_PRINT("info",("spider this=%p", this)); + if (bulk_access_started) + { + error_num = bulk_access_link_current->spider-> + pre_direct_update_rows_init(); + bulk_access_link_current->spider->bulk_access_pre_called = TRUE; + bulk_access_link_current->called = TRUE; + DBUG_RETURN(error_num); + } + pre_direct_init_result = direct_update_rows_init(); + DBUG_RETURN(pre_direct_init_result); +} +#endif #endif +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::direct_update_rows( KEY_MULTI_RANGE *ranges, uint range_count, @@ -10077,8 +10400,61 @@ int ha_spider::direct_update_rows( #endif DBUG_RETURN(0); } +#else +int ha_spider::direct_update_rows( + ha_rows *update_rows +) { + int error_num; + THD *thd = ha_thd(); + backup_error_status(); + DBUG_ENTER("ha_spider::direct_update_rows"); + DBUG_PRINT("info",("spider this=%p", this)); + if (spider_param_read_only_mode(thd, share->read_only_mode)) + { + my_printf_error(ER_SPIDER_READ_ONLY_NUM, ER_SPIDER_READ_ONLY_STR, MYF(0), + table_share->db.str, table_share->table_name.str); + DBUG_RETURN(ER_SPIDER_READ_ONLY_NUM); + } +#ifdef HA_CAN_BULK_ACCESS + if ( + bulk_access_executing && + ( + ( + !is_bulk_access_clone && + bulk_access_link_exec_tgt->called + ) || + bulk_access_pre_called + ) + ) { + if (is_bulk_access_clone) + { + bulk_access_pre_called = FALSE; + DBUG_RETURN(spider_db_bulk_direct_update(this, update_rows)); + } + DBUG_RETURN(bulk_access_link_exec_tgt->spider->ha_direct_update_rows( + update_rows)); + } +#endif + if ( + (active_index != MAX_KEY && (error_num = index_handler_init())) || + (active_index == MAX_KEY && (error_num = rnd_handler_init())) || + (error_num = spider_db_direct_update(this, table, update_rows)) + ) + DBUG_RETURN(check_error_mode(error_num)); #ifdef HA_CAN_BULK_ACCESS + if (bulk_access_executing && is_bulk_access_clone) + { + bulk_req_exec(); + DBUG_RETURN(spider_db_bulk_direct_update(this, update_rows)); + } +#endif + DBUG_RETURN(0); +} +#endif + +#ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::pre_direct_update_rows( KEY_MULTI_RANGE *ranges, uint range_count, @@ -10091,6 +10467,16 @@ int ha_spider::pre_direct_update_rows( DBUG_RETURN(bulk_access_link_current->spider->ha_direct_update_rows(ranges, range_count, sorted, new_data, update_rows)); } +#else +int ha_spider::pre_direct_update_rows() +{ + uint update_rows; + DBUG_ENTER("ha_spider::pre_direct_update_rows"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN(bulk_access_link_current->spider->ha_direct_update_rows( + &update_rows)); +} +#endif #endif #endif @@ -10148,6 +10534,9 @@ int ha_spider::delete_row( DBUG_RETURN(error_num); } #endif +#ifndef SPIDER_WITHOUT_HA_STATISTIC_INCREMENT + ha_statistic_increment(&SSV::ha_delete_count); +#endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS do_direct_update = FALSE; #endif @@ -10157,6 +10546,7 @@ int ha_spider::delete_row( } #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::direct_delete_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -10268,8 +10658,81 @@ int ha_spider::direct_delete_rows_init( do_direct_update = FALSE; DBUG_RETURN(HA_ERR_WRONG_COMMAND); } +#else +int ha_spider::direct_delete_rows_init() +{ + st_select_lex *select_lex; + longlong select_limit; + longlong offset_limit; + THD *thd = trx->thd; + DBUG_ENTER("ha_spider::direct_delete_rows_init"); + DBUG_PRINT("info",("spider this=%p", this)); +#ifdef HA_CAN_BULK_ACCESS + if ( + bulk_access_executing && + ( + ( + !is_bulk_access_clone && + bulk_access_link_exec_tgt->called + ) || + bulk_access_pre_called + ) + ) { + if (is_bulk_access_clone) + { + DBUG_RETURN(pre_direct_init_result); + } + DBUG_RETURN(bulk_access_link_exec_tgt->spider->direct_delete_rows_init()); + } +#endif + direct_update_init( + thd, + FALSE + ); + if (!condition) + cond_check = FALSE; + spider_get_select_limit(this, &select_lex, &select_limit, &offset_limit); + if ( +#if MYSQL_VERSION_ID < 50500 + !thd->variables.engine_condition_pushdown || +#else +#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON +#else + !(thd->variables.optimizer_switch & + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) || +#endif +#endif + !select_lex || + select_lex->table_list.elements != 1 || + spider_db_append_condition(this, NULL, 0, TRUE) + ) { + DBUG_PRINT("info",("spider FALSE by condition")); + do_direct_update = FALSE; + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + if (select_lex->order_list.elements) + { + ORDER *order; + for (order = (ORDER *) select_lex->order_list.first; order; + order = order->next) + { + if (check_item_type_sql((*order->item))) + { + DBUG_PRINT("info",("spider FALSE by order")); + do_direct_update = FALSE; + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + } + result_list.direct_order_limit = TRUE; + } + trx->direct_delete_count++; + DBUG_PRINT("info",("spider OK")); + DBUG_RETURN(0); +} +#endif #ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::pre_direct_delete_rows_init( uint mode, KEY_MULTI_RANGE *ranges, @@ -10292,8 +10755,27 @@ int ha_spider::pre_direct_delete_rows_init( mode, ranges, range_count, sorted); DBUG_RETURN(pre_direct_init_result); } +#else +int ha_spider::pre_direct_delete_rows_init() +{ + int error_num; + DBUG_ENTER("ha_spider::pre_direct_delete_rows_init"); + DBUG_PRINT("info",("spider this=%p", this)); + if (bulk_access_started) + { + error_num = bulk_access_link_current->spider-> + pre_direct_delete_rows_init(); + bulk_access_link_current->spider->bulk_access_pre_called = TRUE; + bulk_access_link_current->called = TRUE; + DBUG_RETURN(error_num); + } + pre_direct_init_result = direct_delete_rows_init(); + DBUG_RETURN(pre_direct_init_result); +} +#endif #endif +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::direct_delete_rows( KEY_MULTI_RANGE *ranges, uint range_count, @@ -10348,8 +10830,61 @@ int ha_spider::direct_delete_rows( #endif DBUG_RETURN(0); } +#else +int ha_spider::direct_delete_rows( + ha_rows *delete_rows +) { + int error_num; + THD *thd = ha_thd(); + backup_error_status(); + DBUG_ENTER("ha_spider::direct_delete_rows"); + DBUG_PRINT("info",("spider this=%p", this)); + if (spider_param_read_only_mode(thd, share->read_only_mode)) + { + my_printf_error(ER_SPIDER_READ_ONLY_NUM, ER_SPIDER_READ_ONLY_STR, MYF(0), + table_share->db.str, table_share->table_name.str); + DBUG_RETURN(ER_SPIDER_READ_ONLY_NUM); + } +#ifdef HA_CAN_BULK_ACCESS + if ( + bulk_access_executing && + ( + ( + !is_bulk_access_clone && + bulk_access_link_exec_tgt->called + ) || + bulk_access_pre_called + ) + ) { + if (is_bulk_access_clone) + { + bulk_access_pre_called = FALSE; + DBUG_RETURN(spider_db_bulk_direct_update(this, delete_rows)); + } + DBUG_RETURN(bulk_access_link_exec_tgt->spider->ha_direct_delete_rows( + delete_rows)); + } +#endif + if ( + (active_index != MAX_KEY && (error_num = index_handler_init())) || + (active_index == MAX_KEY && (error_num = rnd_handler_init())) || + (error_num = spider_db_direct_delete(this, table, delete_rows)) + ) + DBUG_RETURN(check_error_mode(error_num)); + +#ifdef HA_CAN_BULK_ACCESS + if (bulk_access_executing && is_bulk_access_clone) + { + bulk_req_exec(); + DBUG_RETURN(spider_db_bulk_direct_update(this, delete_rows)); + } +#endif + DBUG_RETURN(0); +} +#endif #ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int ha_spider::pre_direct_delete_rows( KEY_MULTI_RANGE *ranges, uint range_count, @@ -10361,6 +10896,16 @@ int ha_spider::pre_direct_delete_rows( DBUG_RETURN(bulk_access_link_current->spider->ha_direct_delete_rows( ranges, range_count, sorted, delete_rows)); } +#else +int ha_spider::pre_direct_delete_rows() +{ + uint delete_rows; + DBUG_ENTER("ha_spider::pre_direct_delete_rows"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN(bulk_access_link_current->spider->ha_direct_delete_rows( + &delete_rows)); +} +#endif #endif #endif @@ -10545,7 +11090,17 @@ void ha_spider::print_error( DBUG_ENTER("ha_spider::print_error"); DBUG_PRINT("info",("spider this=%p", this)); if (!current_thd->is_error()) - handler::print_error(error, errflag); + { + switch (error) + { + case ER_SPIDER_CON_COUNT_ERROR: + my_message(error, ER_SPIDER_CON_COUNT_ERROR_STR, MYF(0)); + break; + default: + handler::print_error(error, errflag); + break; + } + } DBUG_VOID_RETURN; } @@ -10577,7 +11132,7 @@ int ha_spider::create( TABLE *form, HA_CREATE_INFO *info ) { - int error_num; + int error_num, dummy; SPIDER_SHARE tmp_share; THD *thd = ha_thd(); uint sql_command = thd_sql_command(thd), roop_count; @@ -10668,6 +11223,15 @@ int ha_spider::create( ) { goto error; } +#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE + if ( + thd->lex->create_info.or_replace() && + (error_num = spider_delete_tables( + table_tables, tmp_share.table_name, &dummy)) + ) { + goto error; + } +#endif if ( (error_num = spider_insert_tables(table_tables, &tmp_share)) ) { @@ -10863,7 +11427,13 @@ int ha_spider::rename_table( /* release table mon list */ for (roop_count = 0; roop_count < old_link_count; roop_count++) - spider_release_ping_table_mon_list(from, from_len, roop_count); + { + if ((error_num = + spider_release_ping_table_mon_list(from, from_len, roop_count))) + { + goto error; + } + } } else if (sql_command == SQLCOM_ALTER_TABLE) { DBUG_PRINT("info",("spider alter_table_from=%p", alter_table_from)); @@ -10945,9 +11515,21 @@ int ha_spider::rename_table( /* release table mon list */ for (roop_count = 0; roop_count < (int) alter_table_from->all_link_count; roop_count++) - spider_release_ping_table_mon_list(from, from_len, roop_count); + { + if ((error_num = + spider_release_ping_table_mon_list(from, from_len, roop_count))) + { + goto error; + } + } for (roop_count = 0; roop_count < old_link_count; roop_count++) - spider_release_ping_table_mon_list(to, to_len, roop_count); + { + if ((error_num = + spider_release_ping_table_mon_list(to, to_len, roop_count))) + { + goto error; + } + } } /* spider_free_trx_alter_table_alloc(trx, alter_table_from); @@ -11088,6 +11670,12 @@ int ha_spider::delete_table( ) need_lock = TRUE; + if ((error_num = spider_sys_delete_table_sts( + current_thd, name, name_len, need_lock))) + goto error; + if ((error_num = spider_sys_delete_table_crd( + current_thd, name, name_len, need_lock))) + goto error; if ( !(table_tables = spider_open_sys_table( current_thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, @@ -11108,7 +11696,11 @@ int ha_spider::delete_table( /* release table mon list */ for (roop_count = 0; roop_count < old_link_count; roop_count++) - spider_release_ping_table_mon_list(name, name_len, roop_count); + { + if ((error_num = + spider_release_ping_table_mon_list(name, name_len, roop_count))) + goto error; + } pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex); #ifdef SPIDER_HAS_HASH_VALUE_TYPE @@ -11299,15 +11891,18 @@ Field *ha_spider::field_exchange( } #endif DBUG_PRINT("info",("spider in field=%p", field)); + DBUG_PRINT("info",("spider in field->table=%p", field->table)); #ifdef HANDLER_HAS_TOP_TABLE_FIELDS if (set_top_table_fields) { + DBUG_PRINT("info",("spider top_table=%p", top_table)); if (field->table != top_table) DBUG_RETURN(NULL); if (!(field = top_table_field[field->field_index])) DBUG_RETURN(NULL); } else { #endif + DBUG_PRINT("info",("spider table=%p", table)); if (field->table != table) DBUG_RETURN(NULL); #ifdef HANDLER_HAS_TOP_TABLE_FIELDS @@ -11487,6 +12082,7 @@ int ha_spider::info_push( hs_decrement = FALSE; break; #endif +#ifdef INFO_KIND_UPDATE_FIELDS case INFO_KIND_UPDATE_FIELDS: DBUG_PRINT("info",("spider INFO_KIND_UPDATE_FIELDS")); direct_update_fields = (List<Item> *) info; @@ -11496,10 +12092,13 @@ int ha_spider::info_push( keyread = FALSE; #endif break; +#endif +#ifdef INFO_KIND_UPDATE_VALUES case INFO_KIND_UPDATE_VALUES: DBUG_PRINT("info",("spider INFO_KIND_UPDATE_VALUES")); direct_update_values = (List<Item> *) info; break; +#endif #ifdef INFO_KIND_FORCE_LIMIT_BEGIN case INFO_KIND_FORCE_LIMIT_BEGIN: DBUG_PRINT("info",("spider INFO_KIND_FORCE_LIMIT_BEGIN")); @@ -11778,8 +12377,22 @@ void ha_spider::set_searched_bitmap() void ha_spider::set_clone_searched_bitmap() { DBUG_ENTER("ha_spider::set_clone_searched_bitmap"); + DBUG_PRINT("info",("spider searched_bitmap=%p", searched_bitmap)); +#ifndef DBUG_OFF + int roop_count; + for (roop_count = 0; roop_count < (int) ((table_share->fields + 7) / 8); + roop_count++) + DBUG_PRINT("info", ("spider before searched_bitmap is %x", + ((uchar *) searched_bitmap)[roop_count])); +#endif memcpy(searched_bitmap, pt_clone_source_handler->searched_bitmap, (table_share->fields + 7) / 8); +#ifndef DBUG_OFF + for (roop_count = 0; roop_count < (int) ((table_share->fields + 7) / 8); + roop_count++) + DBUG_PRINT("info", ("spider after searched_bitmap is %x", + ((uchar *) searched_bitmap)[roop_count])); +#endif memcpy(ft_discard_bitmap, pt_clone_source_handler->ft_discard_bitmap, (table_share->fields + 7) / 8); DBUG_VOID_RETURN; @@ -12084,6 +12697,8 @@ void ha_spider::check_direct_order_limit() sql_kind[roop_count] = SPIDER_SQL_KIND_SQL; } else result_list.direct_order_limit = FALSE; + + spider_set_direct_limit_offset(this); result_list.check_direct_order_limit = TRUE; } DBUG_VOID_RETURN; @@ -12102,27 +12717,27 @@ void ha_spider::check_direct_order_limit() ********************************************************************/ void ha_spider::check_distinct_key_query() { - DBUG_ENTER( "ha_spider::check_distinct_key_query" ); + DBUG_ENTER( "ha_spider::check_distinct_key_query" ); - if ( result_list.direct_distinct && !partition_handler_share->handlers && - result_list.keyread && result_list.check_direct_order_limit ) - { - // SELECT DISTINCT query using an index in a non-partitioned configuration - KEY_PART_INFO* key_part = result_list.key_info->key_part; - Field* key_field = key_part->field; + if ( result_list.direct_distinct && !partition_handler_share->handlers && + result_list.keyread && result_list.check_direct_order_limit ) + { + // SELECT DISTINCT query using an index in a non-partitioned configuration + KEY_PART_INFO* key_part = result_list.key_info->key_part; + Field* key_field = key_part->field; - if ( is_sole_projection_field( key_field->field_index ) ) - { - // Projection list consists solely of the first key prefix column + if ( is_sole_projection_field( key_field->field_index ) ) + { + // Projection list consists solely of the first key prefix column - // Set the internal row retrieval limit to avoid visiting each row - // multiple times. This fixes a Spider performance bug that - // caused each row to be visited multiple times. - result_list.internal_limit = 1; - } + // Set the internal row retrieval limit to avoid visiting each row + // multiple times. This fixes a Spider performance bug that + // caused each row to be visited multiple times. + result_list.internal_limit = 1; } + } - DBUG_VOID_RETURN; + DBUG_VOID_RETURN; } /******************************************************************** @@ -12137,31 +12752,32 @@ void ha_spider::check_distinct_key_query() * solely of the specified column. * FALSE - otherwise. ********************************************************************/ -bool ha_spider::is_sole_projection_field( uint16 field_index ) -{ - // NOTE: It is assumed that spider_db_append_select_columns() has already been called - // to build the bitmap of projection fields - bool is_ha_sole_projection_field; - uint loop_index, dbton_id; - spider_db_handler* dbton_hdl; - DBUG_ENTER( "ha_spider::is_sole_projection_field" ); +bool ha_spider::is_sole_projection_field( + uint16 field_index +) { + // NOTE: It is assumed that spider_db_append_select_columns() has already been called + // to build the bitmap of projection fields + bool is_ha_sole_projection_field; + uint loop_index, dbton_id; + spider_db_handler* dbton_hdl; + DBUG_ENTER( "ha_spider::is_sole_projection_field" ); - for ( loop_index = 0; loop_index < share->use_sql_dbton_count; loop_index++ ) - { - dbton_id = share->use_sql_dbton_ids[ loop_index ]; - dbton_hdl = dbton_handler[ dbton_id ]; + for ( loop_index = 0; loop_index < share->use_sql_dbton_count; loop_index++ ) + { + dbton_id = share->use_sql_dbton_ids[ loop_index ]; + dbton_hdl = dbton_handler[ dbton_id ]; - if ( dbton_hdl->first_link_idx >= 0 ) - { - is_ha_sole_projection_field = dbton_hdl->is_sole_projection_field( field_index ); - if ( !is_ha_sole_projection_field ) - { - DBUG_RETURN( FALSE ); - } - } + if ( dbton_hdl->first_link_idx >= 0 ) + { + is_ha_sole_projection_field = dbton_hdl->is_sole_projection_field( field_index ); + if ( !is_ha_sole_projection_field ) + { + DBUG_RETURN( FALSE ); + } } + } - DBUG_RETURN( TRUE ); + DBUG_RETURN( TRUE ); } int ha_spider::check_ha_range_eof() @@ -12258,6 +12874,7 @@ int ha_spider::drop_tmp_tables() trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -12293,6 +12910,7 @@ int ha_spider::drop_tmp_tables() trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -12412,6 +13030,7 @@ int ha_spider::close_opened_handler( trx, trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -12447,6 +13066,7 @@ int ha_spider::close_opened_handler( trx, trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -12488,6 +13108,7 @@ int ha_spider::close_opened_handler( trx, trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -12589,6 +13210,7 @@ int ha_spider::index_handler_init() trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -12695,6 +13317,7 @@ int ha_spider::rnd_handler_init() trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -12850,15 +13473,39 @@ int ha_spider::check_error_mode_eof( void ha_spider::check_pre_call( bool use_parallel ) { + THD* thd = ha_thd(); + st_select_lex *select_lex = spider_get_select_lex(this); + int skip_parallel_search = + spider_param_skip_parallel_search(thd, share->skip_parallel_search); DBUG_ENTER("ha_spider::check_pre_call"); DBUG_PRINT("info",("spider this=%p", this)); + if ( + ( + (skip_parallel_search & 1) && + thd->lex && thd->lex->sql_command != SQLCOM_SELECT // such like insert .. select .. + ) || + ( + (skip_parallel_search & 2) && + select_lex && select_lex->sql_cache == SELECT_LEX::SQL_NO_CACHE // for mysqldump + ) + ) { + use_pre_call = FALSE; + DBUG_VOID_RETURN; + } + if ( + use_parallel && + thd->query_id != partition_handler_share->parallel_search_query_id + ) { + partition_handler_share->parallel_search_query_id = thd->query_id; + ++trx->parallel_search_count; + } use_pre_call = use_parallel; if (!use_pre_call) { - st_select_lex *select_lex; longlong select_limit; longlong offset_limit; - spider_get_select_limit(this, &select_lex, &select_limit, &offset_limit); + spider_get_select_limit_from_select_lex( + select_lex, &select_limit, &offset_limit); if ( select_lex && (!select_lex->explicit_limit || !select_limit) @@ -15088,7 +15735,7 @@ int ha_spider::print_item_type( if ( dbton_hdl->first_link_idx >= 0 && (error_num = spider_db_print_item_type(item, this, str, - alias, alias_length, dbton_id)) + alias, alias_length, dbton_id, FALSE, NULL)) ) { DBUG_RETURN(error_num); } diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index a9cdf07b296..b79e1b89fbf 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,14 +11,12 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef USE_PRAGMA_INTERFACE #pragma interface #endif -#include "spd_environ.h" - #define SPIDER_CONNECT_INFO_MAX_LEN 64 #define SPIDER_CONNECT_INFO_PATH_MAX_LEN FN_REFLEN #define SPIDER_LONGLONG_LEN 20 @@ -131,6 +129,14 @@ public: bool da_status; bool use_spatial_index; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + uint idx_for_direct_join; + bool use_fields; + spider_fields *fields; + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + SPIDER_LINK_IDX_CHAIN *result_link_idx_chain; +#endif + /* for mrr */ bool mrr_with_cnt; uint multi_range_cnt; @@ -249,6 +255,11 @@ public: /* for dbton */ spider_db_handler **dbton_handler; + /* for direct limit offset */ + longlong direct_select_offset; + longlong direct_current_offset; + longlong direct_select_limit; + ha_spider(); ha_spider( handlerton *hton, @@ -575,6 +586,7 @@ public: const uchar *new_data ); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int direct_update_rows_init() { return direct_update_rows_init(2, NULL, 0, FALSE, NULL); @@ -586,7 +598,11 @@ public: bool sorted, const uchar *new_data ); +#else + int direct_update_rows_init(); +#endif #ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int pre_direct_update_rows_init() { return pre_direct_update_rows_init(2, NULL, 0, FALSE, NULL); @@ -598,13 +614,11 @@ public: bool sorted, uchar *new_data ); +#else + int pre_direct_update_rows_init(); #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); - } +#endif +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int direct_update_rows(ha_rows *update_rows) { return direct_update_rows(NULL, 0, FALSE, NULL, update_rows); @@ -616,7 +630,13 @@ public: uchar *new_data, ha_rows *update_rows ); +#else + int direct_update_rows( + ha_rows *update_rows + ); +#endif #ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int pre_direct_update_rows() { ha_rows update_rows; @@ -630,6 +650,9 @@ public: uchar *new_data, ha_rows *update_rows ); +#else + int pre_direct_update_rows(); +#endif #endif #endif bool start_bulk_delete(); @@ -638,6 +661,7 @@ public: const uchar *buf ); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int direct_delete_rows_init() { return direct_delete_rows_init(2, NULL, 0, FALSE); @@ -648,7 +672,11 @@ public: uint range_count, bool sorted ); +#else + int direct_delete_rows_init(); +#endif #ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int pre_direct_delete_rows_init() { return pre_direct_delete_rows_init(2, NULL, 0, FALSE); @@ -659,13 +687,11 @@ public: uint range_count, bool sorted ); +#else + int pre_direct_delete_rows_init(); #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); - } +#endif +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int direct_delete_rows(ha_rows *delete_rows) { return direct_delete_rows(NULL, 0, FALSE, delete_rows); @@ -676,7 +702,13 @@ public: bool sorted, ha_rows *delete_rows ); +#else + int direct_delete_rows( + ha_rows *delete_rows + ); +#endif #ifdef HA_CAN_BULK_ACCESS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS inline int pre_direct_delete_rows() { ha_rows delete_rows; @@ -689,6 +721,9 @@ public: bool sorted, ha_rows *delete_rows ); +#else + int pre_direct_delete_rows(); +#endif #endif #endif int delete_all_rows(); @@ -798,7 +833,9 @@ public: uint check_partitioned(); void check_direct_order_limit(); void check_distinct_key_query(); - bool is_sole_projection_field( uint16 field_index ); + bool is_sole_projection_field( + uint16 field_index + ); int check_ha_range_eof(); int drop_tmp_tables(); bool handler_opened( diff --git a/storage/spider/hs_client/allocator.hpp b/storage/spider/hs_client/allocator.hpp index a29015e6886..c302e07804e 100644 --- a/storage/spider/hs_client/allocator.hpp +++ b/storage/spider/hs_client/allocator.hpp @@ -3,7 +3,7 @@ /* * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ @@ -31,11 +31,11 @@ extern "C" { #if 1 #define DENA_ALLOCA_ALLOCATE(typ, len) \ - (typ *) alloca((len) * sizeof(typ)) + (typ *) (alloca((len) * sizeof(typ))) #define DENA_ALLOCA_FREE(x) #else #define DENA_ALLOCA_ALLOCATE(typ, len) \ - static_cast<typ *>(malloc((len) * sizeof(typ))) + (typ *) (malloc((len) * sizeof(typ))) #define DENA_ALLOCA_FREE(x) free(x) #endif diff --git a/storage/spider/hs_client/config.cpp b/storage/spider/hs_client/config.cpp index 3bf0f3e5bdf..030571f9d85 100644 --- a/storage/spider/hs_client/config.cpp +++ b/storage/spider/hs_client/config.cpp @@ -3,7 +3,7 @@ /* * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ @@ -263,8 +263,8 @@ parse_args(int argc, char **argv, config& conf) } if (!(param = new conf_param())) continue; - uint32 key_len = (uint32)(eq - arg); - uint32 val_len = (uint32)(strlen(eq + 1)); + uint32 key_len = eq - arg; + uint32 val_len = strlen(eq + 1); if ( param->key.reserve(key_len + 1) || param->val.reserve(val_len + 1) diff --git a/storage/spider/hs_client/escape.cpp b/storage/spider/hs_client/escape.cpp index c3194e1d111..f3e60afc387 100644 --- a/storage/spider/hs_client/escape.cpp +++ b/storage/spider/hs_client/escape.cpp @@ -3,6 +3,7 @@ /* * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved. + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ diff --git a/storage/spider/hs_client/fatal.cpp b/storage/spider/hs_client/fatal.cpp index 260a2e75372..cfbc14df64a 100644 --- a/storage/spider/hs_client/fatal.cpp +++ b/storage/spider/hs_client/fatal.cpp @@ -3,7 +3,7 @@ /* * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ diff --git a/storage/spider/hs_client/fatal.hpp b/storage/spider/hs_client/fatal.hpp index e1190ae49c1..38fc149e98e 100644 --- a/storage/spider/hs_client/fatal.hpp +++ b/storage/spider/hs_client/fatal.hpp @@ -3,7 +3,7 @@ /* * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ diff --git a/storage/spider/hs_client/hs_compat.h b/storage/spider/hs_client/hs_compat.h index a26dd18e481..920b4efa508 100644 --- a/storage/spider/hs_client/hs_compat.h +++ b/storage/spider/hs_client/hs_compat.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef HS_COMPAT_H #define HS_COMPAT_H diff --git a/storage/spider/hs_client/hstcpcli.cpp b/storage/spider/hs_client/hstcpcli.cpp index 60da87b9f20..d6bdc098438 100644 --- a/storage/spider/hs_client/hstcpcli.cpp +++ b/storage/spider/hs_client/hstcpcli.cpp @@ -3,7 +3,7 @@ /* * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ @@ -497,7 +497,7 @@ hstcpcli::response_recv(size_t& num_flds_r) char *const err_begin = start; read_token(start, finish); char *const err_end = start; - String e = String(err_begin, (uint32)(err_end - err_begin), &my_charset_bin); + String e = String(err_begin, err_end - err_begin, &my_charset_bin); if (!e.length()) { e = String("unknown_error", &my_charset_bin); } diff --git a/storage/spider/hs_client/socket.cpp b/storage/spider/hs_client/socket.cpp index 0717acf0da1..7530bb12239 100644 --- a/storage/spider/hs_client/socket.cpp +++ b/storage/spider/hs_client/socket.cpp @@ -3,11 +3,12 @@ /* * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ #include <my_global.h> +#include <my_config.h> #ifndef __WIN__ #include <sys/types.h> #include <sys/un.h> @@ -223,7 +224,7 @@ socket_set_options(auto_file& fd, const socket_args& args, String& err_r) int socket_open(auto_file& fd, const socket_args& args, String& err_r) { - fd.reset((int)socket(args.family, args.socktype, args.protocol)); + fd.reset(socket(args.family, args.socktype, args.protocol)); if (fd.get() < 0) { return errno_string("socket", errno, err_r); } @@ -253,7 +254,7 @@ socket_connect(auto_file& fd, const socket_args& args, String& err_r) int socket_bind(auto_file& fd, const socket_args& args, String& err_r) { - fd.reset((int)socket(args.family, args.socktype, args.protocol)); + fd.reset(socket(args.family, args.socktype, args.protocol)); if (fd.get() < 0) { return errno_string("socket", errno, err_r); } @@ -300,7 +301,7 @@ int socket_accept(int listen_fd, auto_file& fd, const socket_args& args, sockaddr_storage& addr_r, socklen_t& addrlen_r, String& err_r) { - fd.reset((int)accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r), + fd.reset(accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r), &addrlen_r)); if (fd.get() < 0) { return errno_string("accept", errno, err_r); diff --git a/storage/spider/hs_client/string_util.cpp b/storage/spider/hs_client/string_util.cpp index 9cf2f04d5b6..39934148cb8 100644 --- a/storage/spider/hs_client/string_util.cpp +++ b/storage/spider/hs_client/string_util.cpp @@ -3,7 +3,7 @@ /* * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA + * Copyright (C) 2011-2017 Kentoku SHIBA * See COPYRIGHT.txt for details. */ diff --git a/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result b/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result index af06349c65a..ede48906a84 100644 --- a/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result +++ b/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result @@ -54,31 +54,31 @@ COUNT(*) 5 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 1 +Spider_direct_aggregate 0 SELECT MAX(a) FROM ta_l; MAX(a) 5 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 2 +Spider_direct_aggregate 1 SELECT MIN(a) FROM ta_l; MIN(a) 1 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 3 +Spider_direct_aggregate 2 SELECT MAX(a) FROM ta_l WHERE a < 5; MAX(a) 4 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 4 +Spider_direct_aggregate 3 SELECT MIN(a) FROM ta_l WHERE a > 1; MIN(a) 2 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 5 +Spider_direct_aggregate 4 deinit connection master_1; diff --git a/storage/spider/mysql-test/spider/include/deinit_spider.inc b/storage/spider/mysql-test/spider/include/deinit_spider.inc index c9c414eb56e..3609551e169 100644 --- a/storage/spider/mysql-test/spider/include/deinit_spider.inc +++ b/storage/spider/mysql-test/spider/include/deinit_spider.inc @@ -6,9 +6,13 @@ DROP FUNCTION spider_flush_table_mon_cache; UNINSTALL PLUGIN spider; DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa_member; +DROP TABLE IF EXISTS mysql.spider_xa_failed_log; DROP TABLE IF EXISTS mysql.spider_tables; DROP TABLE IF EXISTS mysql.spider_link_mon_servers; DROP TABLE IF EXISTS mysql.spider_link_failed_log; +DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery; +DROP TABLE IF EXISTS mysql.spider_table_sts; +DROP TABLE IF EXISTS mysql.spider_table_crd; DROP SERVER s_2_1; DROP SERVER s_2_2; DROP SERVER s_2_3; diff --git a/storage/spider/mysql-test/spider/include/init_spider.inc b/storage/spider/mysql-test/spider/include/init_spider.inc index 90c4b7d7084..f94bd51edd7 100644 --- a/storage/spider/mysql-test/spider/include/init_spider.inc +++ b/storage/spider/mysql-test/spider/include/init_spider.inc @@ -277,10 +277,35 @@ if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`) default_group char(64) default null, KEY idx1 (data, format_id, gtrid_length, host) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + DROP TABLE IF EXISTS mysql.spider_xa_failed_log; + CREATE TABLE mysql.spider_xa_failed_log( + format_id int not null default 0, + gtrid_length int not null default 0, + bqual_length int not null default 0, + data char(128) charset binary not null default '', + scheme char(64) not null default '', + host char(64) not null default '', + port char(5) not null default '', + socket text not null, + username char(64) not null default '', + password char(64) not null default '', + ssl_ca text, + ssl_capath text, + ssl_cert text, + ssl_cipher char(64) default null, + ssl_key text, + ssl_verify_server_cert tinyint not null default 0, + default_file text, + default_group char(64) default null, + thread_id int default null, + status char(8) not null default '', + failed_time timestamp not null default current_timestamp, + key idx1 (data, format_id, gtrid_length, host) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; DROP TABLE IF EXISTS mysql.spider_tables; CREATE TABLE mysql.spider_tables( db_name char(64) not null default '', - table_name char(64) not null default '', + table_name char(199) not null default '', link_id int not null default 0, priority bigint not null default 0, server char(64) default null, @@ -296,18 +321,22 @@ if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`) ssl_cipher char(64) default null, ssl_key text default null, ssl_verify_server_cert tinyint not null default 0, + monitoring_binlog_pos_at_failing tinyint not null default 0, default_file text default null, default_group char(64) default null, tgt_db_name char(64) default null, tgt_table_name char(64) default null, link_status tinyint not null default 1, + block_status tinyint not null default 0, + static_link_id char(64) default null, PRIMARY KEY (db_name, table_name, link_id), - KEY idx1 (priority) + KEY idx1 (priority), + UNIQUE KEY uidx1 (db_name, table_name, static_link_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; DROP TABLE IF EXISTS mysql.spider_link_mon_servers; CREATE TABLE mysql.spider_link_mon_servers( db_name char(64) not null default '', - table_name char(64) not null default '', + table_name char(199) not null default '', link_id char(5) not null default '', sid int not null default 0, server char(64) default null, @@ -330,10 +359,43 @@ if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`) DROP TABLE IF EXISTS mysql.spider_link_failed_log; CREATE TABLE mysql.spider_link_failed_log( db_name char(64) not null default '', - table_name char(64) not null default '', + table_name char(199) not null default '', link_id int not null default 0, failed_time timestamp not null default current_timestamp ) ENGINE=MYISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery; + CREATE TABLE mysql.spider_table_position_for_recovery( + db_name char(64) not null default '', + table_name char(199) not null default '', + failed_link_id int not null default 0, + source_link_id int not null default 0, + file text, + position text, + gtid text, + primary key (db_name, table_name, failed_link_id, source_link_id) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + DROP TABLE IF EXISTS mysql.spider_table_sts; + CREATE TABLE mysql.spider_table_sts( + db_name char(64) not null default '', + table_name char(199) not null default '', + data_file_length bigint unsigned not null default 0, + max_data_file_length bigint unsigned not null default 0, + index_file_length bigint unsigned not null default 0, + records bigint unsigned not null default 0, + mean_rec_length bigint unsigned not null default 0, + check_time datetime not null default '0000-00-00 00:00:00', + create_time datetime not null default '0000-00-00 00:00:00', + update_time datetime not null default '0000-00-00 00:00:00', + primary key (db_name, table_name) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + DROP TABLE IF EXISTS mysql.spider_table_crd; + CREATE TABLE mysql.spider_table_crd( + db_name char(64) not null default '', + table_name char(199) not null default '', + key_seq int unsigned not null default 0, + cardinality bigint not null default 0, + primary key (db_name, table_name, key_seq) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; } SET spider_internal_sql_log_off= 0; diff --git a/storage/spider/mysql-test/spider/r/direct_aggregate.result b/storage/spider/mysql-test/spider/r/direct_aggregate.result index af06349c65a..ede48906a84 100644 --- a/storage/spider/mysql-test/spider/r/direct_aggregate.result +++ b/storage/spider/mysql-test/spider/r/direct_aggregate.result @@ -54,31 +54,31 @@ COUNT(*) 5 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 1 +Spider_direct_aggregate 0 SELECT MAX(a) FROM ta_l; MAX(a) 5 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 2 +Spider_direct_aggregate 1 SELECT MIN(a) FROM ta_l; MIN(a) 1 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 3 +Spider_direct_aggregate 2 SELECT MAX(a) FROM ta_l WHERE a < 5; MAX(a) 4 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 4 +Spider_direct_aggregate 3 SELECT MIN(a) FROM ta_l WHERE a > 1; MIN(a) 2 SHOW STATUS LIKE 'Spider_direct_aggregate'; Variable_name Value -Spider_direct_aggregate 5 +Spider_direct_aggregate 4 deinit connection master_1; diff --git a/storage/spider/scripts/install_spider.sql b/storage/spider/scripts/install_spider.sql index 328541a550b..3fd9a6c8a37 100644 --- a/storage/spider/scripts/install_spider.sql +++ b/storage/spider/scripts/install_spider.sql @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 Kentoku Shiba +# Copyright (C) 2010-2016 Kentoku Shiba # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -73,7 +73,7 @@ create table if not exists mysql.spider_xa_failed_log( ) engine=MyISAM default charset=utf8 collate=utf8_bin; create table if not exists mysql.spider_tables( db_name char(64) not null default '', - table_name char(64) not null default '', + table_name char(199) not null default '', link_id int not null default 0, priority bigint not null default 0, server char(64) default null, @@ -89,18 +89,22 @@ create table if not exists mysql.spider_tables( ssl_cipher char(64) default null, ssl_key text, ssl_verify_server_cert tinyint not null default 0, + monitoring_binlog_pos_at_failing tinyint not null default 0, default_file text, default_group char(64) default null, tgt_db_name char(64) default null, tgt_table_name char(64) default null, link_status tinyint not null default 1, + block_status tinyint not null default 0, + static_link_id char(64) default null, primary key (db_name, table_name, link_id), - key idx1 (priority) + key idx1 (priority), + unique key uidx1 (db_name, table_name, static_link_id) ) engine=MyISAM default charset=utf8 collate=utf8_bin; create table if not exists mysql.spider_link_mon_servers( db_name char(64) not null default '', - table_name char(64) not null default '', - link_id char(5) not null default '', + table_name char(199) not null default '', + link_id char(64) not null default '', sid int unsigned not null default 0, server char(64) default null, scheme char(64) default null, @@ -121,10 +125,40 @@ create table if not exists mysql.spider_link_mon_servers( ) engine=MyISAM default charset=utf8 collate=utf8_bin; create table if not exists mysql.spider_link_failed_log( db_name char(64) not null default '', - table_name char(64) not null default '', - link_id int not null default 0, + table_name char(199) not null default '', + link_id char(64) not null default '', failed_time timestamp not null default current_timestamp ) engine=MyISAM default charset=utf8 collate=utf8_bin; +create table if not exists mysql.spider_table_position_for_recovery( + db_name char(64) not null default '', + table_name char(199) not null default '', + failed_link_id int not null default 0, + source_link_id int not null default 0, + file text, + position text, + gtid text, + primary key (db_name, table_name, failed_link_id, source_link_id) +) engine=MyISAM default charset=utf8 collate=utf8_bin; +create table if not exists mysql.spider_table_sts( + db_name char(64) not null default '', + table_name char(199) not null default '', + data_file_length bigint unsigned not null default 0, + max_data_file_length bigint unsigned not null default 0, + index_file_length bigint unsigned not null default 0, + records bigint unsigned not null default 0, + mean_rec_length bigint unsigned not null default 0, + check_time datetime not null default '0000-00-00 00:00:00', + create_time datetime not null default '0000-00-00 00:00:00', + update_time datetime not null default '0000-00-00 00:00:00', + primary key (db_name, table_name) +) engine=MyISAM default charset=utf8 collate=utf8_bin; +create table if not exists mysql.spider_table_crd( + db_name char(64) not null default '', + table_name char(199) not null default '', + key_seq int unsigned not null default 0, + cardinality bigint not null default 0, + primary key (db_name, table_name, key_seq) +) engine=MyISAM default charset=utf8 collate=utf8_bin; -- If tables already exist and their definition differ from the latest ones, -- we fix them here. @@ -222,14 +256,14 @@ begin add column default_group char(64) default null after default_file'); -- Fix for version 2.25 - select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS - where TABLE_SCHEMA = 'mysql' - AND TABLE_NAME = 'spider_link_mon_servers' - AND COLUMN_NAME = 'link_id'; - if @col_type != 'char(5)' then - alter table mysql.spider_link_mon_servers - modify link_id char(5) not null default ''; - end if; + -- select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + -- where TABLE_SCHEMA = 'mysql' + -- AND TABLE_NAME = 'spider_link_mon_servers' + -- AND COLUMN_NAME = 'link_id'; + -- if @col_type != 'char(5)' then + -- alter table mysql.spider_link_mon_servers + -- modify link_id char(5) not null default ''; + -- end if; -- Fix for version 2.28 select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS @@ -283,6 +317,87 @@ begin modify ssl_key text, modify default_file text; end if; + + -- Fix for version 3.3.0 + call mysql.spider_fix_one_table('spider_tables', + 'monitoring_binlog_pos_at_failing', + 'alter table mysql.spider_tables + add monitoring_binlog_pos_at_failing tinyint not null default 0 after ssl_verify_server_cert'); + + -- Fix for version 3.3.6 + call mysql.spider_fix_one_table('spider_tables', 'block_status', + 'alter table mysql.spider_tables + add column block_status tinyint not null default 0 after link_status'); + call mysql.spider_fix_one_table('spider_tables', 'static_link_id', + 'alter table mysql.spider_tables + add column static_link_id char(64) default null after block_status, + add unique index uidx1 (db_name, table_name, static_link_id)'); + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_link_mon_servers' + AND COLUMN_NAME = 'link_id'; + if @col_type != 'char(64)' then + alter table mysql.spider_link_mon_servers + modify link_id char(64) not null default ''; + end if; + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_link_failed_log' + AND COLUMN_NAME = 'link_id'; + if @col_type != 'char(64)' then + alter table mysql.spider_link_failed_log + modify link_id char(64) not null default ''; + end if; + + -- Fix for version 3.3.10 + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_tables' + AND COLUMN_NAME = 'table_name'; + if @col_type != 'char(199)' then + alter table mysql.spider_tables + modify table_name char(199) not null default ''; + end if; + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_link_mon_servers' + AND COLUMN_NAME = 'table_name'; + if @col_type != 'char(199)' then + alter table mysql.spider_link_mon_servers + modify table_name char(199) not null default ''; + end if; + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_link_failed_log' + AND COLUMN_NAME = 'table_name'; + if @col_type != 'char(199)' then + alter table mysql.spider_link_failed_log + modify table_name char(199) not null default ''; + end if; + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_table_position_for_recovery' + AND COLUMN_NAME = 'table_name'; + if @col_type != 'char(199)' then + alter table mysql.spider_table_position_for_recovery + modify table_name char(199) not null default ''; + end if; + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_table_sts' + AND COLUMN_NAME = 'table_name'; + if @col_type != 'char(199)' then + alter table mysql.spider_table_sts + modify table_name char(199) not null default ''; + end if; + select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS + where TABLE_SCHEMA = 'mysql' + AND TABLE_NAME = 'spider_table_crd' + AND COLUMN_NAME = 'table_name'; + if @col_type != 'char(199)' then + alter table mysql.spider_table_crd + modify table_name char(199) not null default ''; + end if; end;// delimiter ; call mysql.spider_fix_system_tables; diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index e41fb33af5d..3fa825a9d88 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -27,6 +27,7 @@ #include "sql_partition.h" #include "tztime.h" #endif +#include "spd_err.h" #include "spd_param.h" #include "spd_db_include.h" #include "spd_include.h" @@ -38,10 +39,24 @@ #include "spd_direct_sql.h" #include "spd_ping_table.h" #include "spd_malloc.h" +#include "spd_err.h" + +#ifdef SPIDER_HAS_NEXT_THREAD_ID +#define SPIDER_set_next_thread_id(A) +#else +extern ulong *spd_db_att_thread_id; +inline void SPIDER_set_next_thread_id(THD *A) +{ + pthread_mutex_lock(&LOCK_thread_count); + A->thread_id = (*spd_db_att_thread_id)++; + pthread_mutex_unlock(&LOCK_thread_count); +} +#endif extern handlerton *spider_hton_ptr; extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; pthread_mutex_t spider_conn_id_mutex; +pthread_mutex_t spider_ipport_conn_mutex; ulonglong spider_conn_id = 1; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -49,6 +64,8 @@ extern pthread_attr_t spider_pt_attr; #ifdef HAVE_PSI_INTERFACE extern PSI_mutex_key spd_key_mutex_mta_conn; +extern PSI_mutex_key spd_key_mutex_conn_i; +extern PSI_cond_key spd_key_cond_conn_i; #ifndef WITHOUT_SPIDER_BG_SEARCH extern PSI_mutex_key spd_key_mutex_bg_conn_chain; extern PSI_mutex_key spd_key_mutex_bg_conn_sync; @@ -76,6 +93,9 @@ extern SPIDER_TRX *spider_global_trx; HASH spider_open_connections; uint spider_open_connections_id; +HASH spider_ipport_conns; +long spider_conn_mutex_id = 0; + const char *spider_open_connections_func_name; const char *spider_open_connections_file_name; ulong spider_open_connections_line_no; @@ -110,6 +130,17 @@ uchar *spider_conn_get_key( DBUG_RETURN((uchar*) conn->conn_key); } +uchar *spider_ipport_conn_get_key( + SPIDER_IP_PORT_CONN *ip_port, + size_t *length, + my_bool not_used __attribute__ ((unused)) +) +{ + DBUG_ENTER("spider_ipport_conn_get_key"); + *length = ip_port->key_len; + DBUG_RETURN((uchar*) ip_port->key); +} + int spider_reset_conn_setted_parameter( SPIDER_CONN *conn, THD *thd @@ -153,10 +184,10 @@ int spider_free_conn_alloc( SPIDER_CONN *conn ) { DBUG_ENTER("spider_free_conn_alloc"); - spider_db_disconnect(conn); #ifndef WITHOUT_SPIDER_BG_SEARCH spider_free_conn_thread(conn); #endif + spider_db_disconnect(conn); if (conn->db_conn) { delete conn->db_conn; @@ -176,6 +207,7 @@ void spider_free_conn_from_trx( int *roop_count ) { ha_spider *spider; + SPIDER_IP_PORT_CONN *ip_port_conn = conn->ip_port_conn; DBUG_ENTER("spider_free_conn_from_trx"); spider_conn_clear_queue(conn); conn->use_for_active_standby = FALSE; @@ -253,6 +285,15 @@ void spider_free_conn_from_trx( pthread_mutex_unlock(&spider_conn_mutex); spider_free_conn(conn); } else { + if (ip_port_conn) + { /* exists */ + if (ip_port_conn->waiting_count) + { + pthread_mutex_lock(&ip_port_conn->mutex); + pthread_cond_signal(&ip_port_conn->cond); + pthread_mutex_unlock(&ip_port_conn->mutex); + } + } if (spider_open_connections.array.max_element > old_elements) { spider_alloc_calc_mem(spider_current_trx, @@ -410,6 +451,7 @@ SPIDER_CONN *spider_create_conn( ) { int *need_mon; SPIDER_CONN *conn; + SPIDER_IP_PORT_CONN *ip_port_conn; char *tmp_name, *tmp_host, *tmp_username, *tmp_password, *tmp_socket; char *tmp_wrapper, *tmp_ssl_ca, *tmp_ssl_capath, *tmp_ssl_cert; char *tmp_ssl_cipher, *tmp_ssl_key, *tmp_default_file, *tmp_default_group; @@ -626,6 +668,28 @@ SPIDER_CONN *spider_create_conn( conn->dbton_id = share->hs_dbton_ids[link_idx]; } #endif + if (conn->dbton_id == SPIDER_DBTON_SIZE) + { +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) + { +#endif + my_printf_error( + ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM, + ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR, + MYF(0), conn->tgt_wrapper); + *error_num = ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM; +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + } else { + my_printf_error( + ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM, + ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR, + MYF(0), conn->tgt_wrapper); + *error_num = ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM; + } +#endif + goto error_invalid_wrapper; + } if (!(conn->db_conn = spider_dbton[conn->dbton_id].create_db_conn(conn))) { *error_num = HA_ERR_OUT_OF_MEM; @@ -668,6 +732,47 @@ SPIDER_CONN *spider_create_conn( ++spider_conn_id; pthread_mutex_unlock(&spider_conn_id_mutex); + pthread_mutex_lock(&spider_ipport_conn_mutex); +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search_using_hash_value( + &spider_ipport_conns, conn->conn_key_hash_value, + (uchar*)conn->conn_key, conn->conn_key_length))) +#else + if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search( + &spider_ipport_conns, (uchar*)conn->conn_key, conn->conn_key_length))) +#endif + { /* exists, +1 */ + pthread_mutex_unlock(&spider_ipport_conn_mutex); + pthread_mutex_lock(&ip_port_conn->mutex); + if (spider_param_max_connections()) + { /* enable conncetion pool */ + if (ip_port_conn->ip_port_count >= spider_param_max_connections()) + { /* bigger than the max num of connections, free conn and return NULL */ + pthread_mutex_unlock(&ip_port_conn->mutex); + *error_num = ER_SPIDER_CON_COUNT_ERROR; + goto error_too_many_ipport_count; + } + } + ip_port_conn->ip_port_count++; + pthread_mutex_unlock(&ip_port_conn->mutex); + } + else + {// do not exist + ip_port_conn = spider_create_ipport_conn(conn); + if (!ip_port_conn) { + /* failed, always do not effect 'create conn' */ + pthread_mutex_unlock(&spider_ipport_conn_mutex); + DBUG_RETURN(conn); + } + if (my_hash_insert(&spider_ipport_conns, (uchar *)ip_port_conn)) { + /* insert failed, always do not effect 'create conn' */ + pthread_mutex_unlock(&spider_ipport_conn_mutex); + DBUG_RETURN(conn); + } + pthread_mutex_unlock(&spider_ipport_conn_mutex); + } + conn->ip_port_conn = ip_port_conn; + DBUG_RETURN(conn); /* @@ -675,10 +780,12 @@ error_init_lock_table_hash: DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name); pthread_mutex_destroy(&conn->mta_conn_mutex); */ +error_too_many_ipport_count: error_mta_conn_mutex_init: error_db_conn_init: delete conn->db_conn; error_db_conn_create: +error_invalid_wrapper: spider_free(spider_current_trx, conn, MYF(0)); error_alloc_conn: DBUG_RETURN(NULL); @@ -828,16 +935,27 @@ SPIDER_CONN *spider_get_conn( #endif { pthread_mutex_unlock(&spider_conn_mutex); - DBUG_PRINT("info",("spider create new conn")); - if (!(conn = spider_create_conn(share, spider, link_idx, - base_link_idx, conn_kind, error_num))) - goto error; - *conn->conn_key = *conn_key; - if (spider) - { - spider->conns[base_link_idx] = conn; - if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) - conn->use_for_active_standby = TRUE; + if (spider_param_max_connections()) + { /* enable connection pool */ + conn = spider_get_conn_from_idle_connection(share, link_idx, conn_key, spider, conn_kind, base_link_idx, error_num); + /* failed get conn, goto error */ + if (!conn) + goto error; + + } + else + { /* did not enable conncetion pool , create_conn */ + DBUG_PRINT("info",("spider create new conn")); + if (!(conn = spider_create_conn(share, spider, link_idx, + base_link_idx, conn_kind, error_num))) + goto error; + *conn->conn_key = *conn_key; + if (spider) + { + spider->conns[base_link_idx] = conn; + if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) + conn->use_for_active_standby = TRUE; + } } } else { #ifdef HASH_UPDATE_WITH_HASH_VALUE @@ -1109,6 +1227,14 @@ int spider_free_conn( ) { DBUG_ENTER("spider_free_conn"); DBUG_PRINT("info", ("spider conn=%p", conn)); + SPIDER_IP_PORT_CONN* ip_port_conn = conn->ip_port_conn; + if (ip_port_conn) + { /* free conn, ip_port_count-- */ + pthread_mutex_lock(&ip_port_conn->mutex); + if (ip_port_conn->ip_port_count > 0) + ip_port_conn->ip_port_count--; + pthread_mutex_unlock(&ip_port_conn->mutex); + } spider_free_conn_alloc(conn); spider_free(spider_current_trx, conn, MYF(0)); DBUG_RETURN(0); @@ -1571,6 +1697,7 @@ int spider_set_conn_bg_param( SPIDER_RESULT_LIST *result_list = &spider->result_list; THD *thd = spider->trx->thd; DBUG_ENTER("spider_set_conn_bg_param"); + DBUG_PRINT("info",("spider spider=%p", spider)); bgs_mode = spider_param_bgs_mode(thd, share->bgs_mode); if (bgs_mode == 0) @@ -1611,28 +1738,44 @@ int spider_set_conn_bg_param( if (result_list->bgs_phase > 0) { - for ( - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - spider->lock_mode ? - SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK); - roop_count < (int) share->link_count; - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count, share->link_count, - spider->lock_mode ? - SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK) - ) { - if ((error_num = spider_create_conn_thread(spider->conns[roop_count]))) - DBUG_RETURN(error_num); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + if (spider->use_fields) + { + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + spider_fields *fields = spider->fields; + fields->set_pos_to_first_link_idx_chain(); + while ((link_idx_chain = fields->get_next_link_idx_chain())) + { + if ((error_num = spider_create_conn_thread(link_idx_chain->conn))) + DBUG_RETURN(error_num); + } + } else { +#endif + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + spider->lock_mode ? + SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK); + roop_count < (int) share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + spider->lock_mode ? + SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK) + ) { + if ((error_num = spider_create_conn_thread(spider->conns[roop_count]))) + DBUG_RETURN(error_num); #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = spider_create_conn_thread( - spider->hs_r_conns[roop_count]))) - DBUG_RETURN(error_num); - if ((error_num = spider_create_conn_thread( - spider->hs_w_conns[roop_count]))) - DBUG_RETURN(error_num); + if ((error_num = spider_create_conn_thread( + spider->hs_r_conns[roop_count]))) + DBUG_RETURN(error_num); + if ((error_num = spider_create_conn_thread( + spider->hs_w_conns[roop_count]))) + DBUG_RETURN(error_num); #endif + } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER } +#endif } DBUG_RETURN(0); } @@ -1977,6 +2120,7 @@ int spider_bg_conn_search( SPIDER_RESULT_LIST *result_list = &spider->result_list; bool with_lock = FALSE; DBUG_ENTER("spider_bg_conn_search"); + DBUG_PRINT("info",("spider spider=%p", spider)); #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL) { @@ -2018,7 +2162,7 @@ int spider_bg_conn_search( DBUG_RETURN(result_list->bgs_error); } } - if (!result_list->finish_flg) + if (result_list->bgs_working || !result_list->finish_flg) { pthread_mutex_lock(&conn->bg_conn_mutex); if (!result_list->finish_flg) @@ -2042,10 +2186,18 @@ int spider_bg_conn_search( result_list->bgs_error_msg, MYF(0)); DBUG_RETURN(result_list->bgs_error); } + DBUG_PRINT("info",("spider result_list->quick_mode=%d", + result_list->quick_mode)); + DBUG_PRINT("info",("spider result_list->bgs_current->result=%p", + result_list->bgs_current->result)); if ( result_list->quick_mode == 0 || !result_list->bgs_current->result ) { + DBUG_PRINT("info",("spider result_list->bgs_second_read=%lld", + result_list->bgs_second_read)); + DBUG_PRINT("info",("spider result_list->bgs_split_read=%lld", + result_list->bgs_split_read)); result_list->split_read = result_list->bgs_second_read > 0 ? result_list->bgs_second_read : @@ -2055,6 +2207,7 @@ int spider_bg_conn_search( result_list->split_read ? result_list->split_read : result_list->internal_limit - result_list->record_num; + DBUG_PRINT("info",("spider sql_kinds=%u", spider->sql_kinds)); if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) { if ((error_num = spider->reappend_limit_sql_part( @@ -2096,6 +2249,9 @@ int spider_bg_conn_search( conn->bg_target = spider; conn->link_idx = link_idx; conn->bg_discard_result = discard_result; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + conn->link_idx_chain = spider->link_idx_chain; +#endif pthread_mutex_lock(&conn->bg_conn_sync_mutex); pthread_cond_signal(&conn->bg_conn_cond); pthread_mutex_unlock(&conn->bg_conn_mutex); @@ -2107,11 +2263,33 @@ int spider_bg_conn_search( DBUG_PRINT("info",("spider bg current->finish_flg=%s", result_list->current ? (result_list->current->finish_flg ? "TRUE" : "FALSE") : "NULL")); + if (result_list->bgs_error) + { + DBUG_PRINT("info",("spider bg error")); + if (result_list->bgs_error != HA_ERR_END_OF_FILE) + { + if (result_list->bgs_error_with_message) + my_message(result_list->bgs_error, + result_list->bgs_error_msg, MYF(0)); + DBUG_RETURN(result_list->bgs_error); + } + } } } else { DBUG_PRINT("info",("spider bg current->finish_flg=%s", result_list->current ? (result_list->current->finish_flg ? "TRUE" : "FALSE") : "NULL")); + if (result_list->bgs_error) + { + DBUG_PRINT("info",("spider bg error")); + if (result_list->bgs_error != HA_ERR_END_OF_FILE) + { + if (result_list->bgs_error_with_message) + my_message(result_list->bgs_error, + result_list->bgs_error_msg, MYF(0)); + DBUG_RETURN(result_list->bgs_error); + } + } } } else { DBUG_PRINT("info",("spider bg search")); @@ -2149,6 +2327,10 @@ int spider_bg_conn_search( DBUG_PRINT("info",("spider bg next search")); if (!result_list->current->finish_flg) { + DBUG_PRINT("info",("spider result_list->quick_mode=%d", + result_list->quick_mode)); + DBUG_PRINT("info",("spider result_list->bgs_current->result=%p", + result_list->bgs_current->result)); pthread_mutex_lock(&conn->bg_conn_mutex); result_list->bgs_phase = 3; if ( @@ -2161,6 +2343,7 @@ int spider_bg_conn_search( result_list->split_read ? result_list->split_read : result_list->internal_limit - result_list->record_num; + DBUG_PRINT("info",("spider sql_kinds=%u", spider->sql_kinds)); if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) { if ((error_num = spider->reappend_limit_sql_part( @@ -2195,6 +2378,9 @@ int spider_bg_conn_search( conn->bg_target = spider; conn->link_idx = link_idx; conn->bg_discard_result = discard_result; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + conn->link_idx_chain = spider->link_idx_chain; +#endif result_list->bgs_working = TRUE; conn->bg_search = TRUE; if (with_lock) @@ -2261,7 +2447,7 @@ void *spider_bg_conn_action( my_thread_init(); DBUG_ENTER("spider_bg_conn_action"); /* init start */ - if (!(thd = new THD(next_thread_id()))) + if (!(thd = SPIDER_new_THD(next_thread_id()))) { pthread_mutex_lock(&conn->bg_conn_sync_mutex); pthread_cond_signal(&conn->bg_conn_sync_cond); @@ -2269,6 +2455,7 @@ void *spider_bg_conn_action( my_thread_end(); DBUG_RETURN(NULL); } + SPIDER_set_next_thread_id(thd); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif @@ -2395,12 +2582,23 @@ void *spider_bg_conn_action( pthread_mutex_lock(&conn->mta_conn_mutex); SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); } - if ((error_num = dbton_handler->set_sql_for_exec(sql_type, - conn->link_idx))) + if (spider->use_fields) { - result_list->bgs_error = error_num; - if ((result_list->bgs_error_with_message = thd->is_error())) - strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd)); + if ((error_num = dbton_handler->set_sql_for_exec(sql_type, + conn->link_idx, conn->link_idx_chain))) + { + result_list->bgs_error = error_num; + if ((result_list->bgs_error_with_message = thd->is_error())) + strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd)); + } + } else { + if ((error_num = dbton_handler->set_sql_for_exec(sql_type, + conn->link_idx))) + { + result_list->bgs_error = error_num; + if ((result_list->bgs_error_with_message = thd->is_error())) + strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd)); + } } if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) { @@ -2703,7 +2901,6 @@ void *spider_bg_sts_action( SPIDER_TRX *trx; int error_num = 0, roop_count; ha_spider spider; -#if defined(_MSC_VER) || defined(__SUNPRO_CC) int *need_mons; SPIDER_CONN **conns; uint *conn_link_idx; @@ -2714,48 +2911,31 @@ void *spider_bg_sts_action( char **hs_w_conn_keys; #endif spider_db_handler **dbton_hdl; -#else - int need_mons[share->link_count]; - SPIDER_CONN *conns[share->link_count]; - uint conn_link_idx[share->link_count]; - uchar conn_can_fo[share->link_bitmap_size]; - char *conn_keys[share->link_count]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char *hs_r_conn_keys[share->link_count]; - char *hs_w_conn_keys[share->link_count]; -#endif - spider_db_handler *dbton_hdl[SPIDER_DBTON_SIZE]; -#endif THD *thd; my_thread_init(); DBUG_ENTER("spider_bg_sts_action"); /* init start */ -#if defined(_MSC_VER) || defined(__SUNPRO_CC) + char *ptr; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!(need_mons = (int *) - spider_bulk_malloc(spider_current_trx, 21, MYF(MY_WME), - &need_mons, sizeof(int) * share->link_count, - &conns, sizeof(SPIDER_CONN *) * share->link_count, - &conn_link_idx, sizeof(uint) * share->link_count, - &conn_can_fo, sizeof(uchar) * share->link_bitmap_size, - &conn_keys, sizeof(char *) * share->link_count, - &hs_r_conn_keys, sizeof(char *) * share->link_count, - &hs_w_conn_keys, sizeof(char *) * share->link_count, - &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, - NullS)) - ) + ptr = (char *) my_alloca( + (sizeof(int) * share->link_count) + + (sizeof(SPIDER_CONN *) * share->link_count) + + (sizeof(uint) * share->link_count) + + (sizeof(uchar) * share->link_bitmap_size) + + (sizeof(char *) * share->link_count) + + (sizeof(char *) * share->link_count) + + (sizeof(char *) * share->link_count) + + (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); #else - if (!(need_mons = (int *) - spider_bulk_malloc(spider_current_trx, 21, MYF(MY_WME), - &need_mons, sizeof(int) * share->link_count, - &conns, sizeof(SPIDER_CONN *) * share->link_count, - &conn_link_idx, sizeof(uint) * share->link_count, - &conn_can_fo, sizeof(uchar) * share->link_bitmap_size, - &conn_keys, sizeof(char *) * share->link_count, - &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, - NullS)) - ) -#endif + ptr = (char *) my_alloca( + (sizeof(int) * share->link_count) + + (sizeof(SPIDER_CONN *) * share->link_count) + + (sizeof(uint) * share->link_count) + + (sizeof(uchar) * share->link_bitmap_size) + + (sizeof(char *) * share->link_count) + + (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); +#endif + if (!ptr) { pthread_mutex_lock(&share->sts_mutex); share->bg_sts_thd_wait = FALSE; @@ -2765,20 +2945,35 @@ void *spider_bg_sts_action( my_thread_end(); DBUG_RETURN(NULL); } + need_mons = (int *) ptr; + ptr += (sizeof(int) * share->link_count); + conns = (SPIDER_CONN **) ptr; + ptr += (sizeof(SPIDER_CONN *) * share->link_count); + conn_link_idx = (uint *) ptr; + ptr += (sizeof(uint) * share->link_count); + conn_can_fo = (uchar *) ptr; + ptr += (sizeof(uchar) * share->link_bitmap_size); + conn_keys = (char **) ptr; + ptr += (sizeof(char *) * share->link_count); +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + hs_r_conn_keys = (char **) ptr; + ptr += (sizeof(char *) * share->link_count); + hs_w_conn_keys = (char **) ptr; + ptr += (sizeof(char *) * share->link_count); #endif + dbton_hdl = (spider_db_handler **) ptr; pthread_mutex_lock(&share->sts_mutex); - if (!(thd = new THD(next_thread_id()))) + if (!(thd = SPIDER_new_THD(next_thread_id()))) { share->bg_sts_thd_wait = FALSE; share->bg_sts_kill = FALSE; share->bg_sts_init = FALSE; pthread_mutex_unlock(&share->sts_mutex); my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } + SPIDER_set_next_thread_id(thd); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif @@ -2795,9 +2990,7 @@ void *spider_bg_sts_action( my_pthread_setspecific_ptr(THR_THD, NULL); #endif my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } share->bg_sts_thd = thd; @@ -2830,14 +3023,14 @@ void *spider_bg_sts_action( spider_bit_is_set(share->dbton_bitmap, roop_count) && spider_dbton[roop_count].create_db_handler ) { - if ((dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler( + if (!(dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler( &spider, share->dbton_share[roop_count]))) break; if (dbton_hdl[roop_count]->init()) break; } } - if (roop_count == SPIDER_DBTON_SIZE) + if (roop_count < SPIDER_DBTON_SIZE) { DBUG_PRINT("info",("spider handler init error")); for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count) @@ -2860,9 +3053,7 @@ void *spider_bg_sts_action( my_pthread_setspecific_ptr(THR_THD, NULL); #endif my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } /* init end */ @@ -2891,12 +3082,10 @@ void *spider_bg_sts_action( my_pthread_setspecific_ptr(THR_THD, NULL); #endif my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } - if (spider.search_link_idx == -1) + if (spider.search_link_idx < 0) { spider_trx_set_link_idx_for_all(&spider); /* @@ -2934,6 +3123,7 @@ void *spider_bg_sts_action( spider_global_trx, thd, share, + spider.search_link_idx, (uint32) share->monitoring_sid[spider.search_link_idx], share->table_name, share->table_name_length, @@ -2976,6 +3166,7 @@ void *spider_bg_sts_action( spider_global_trx, thd, share, + spider.search_link_idx, (uint32) share->monitoring_sid[spider.search_link_idx], share->table_name, share->table_name_length, @@ -3082,7 +3273,6 @@ void *spider_bg_crd_action( int error_num = 0, roop_count; ha_spider spider; TABLE table; -#if defined(_MSC_VER) || defined(__SUNPRO_CC) int *need_mons; SPIDER_CONN **conns; uint *conn_link_idx; @@ -3093,48 +3283,31 @@ void *spider_bg_crd_action( char **hs_w_conn_keys; #endif spider_db_handler **dbton_hdl; -#else - int need_mons[share->link_count]; - SPIDER_CONN *conns[share->link_count]; - uint conn_link_idx[share->link_count]; - uchar conn_can_fo[share->link_bitmap_size]; - char *conn_keys[share->link_count]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char *hs_r_conn_keys[share->link_count]; - char *hs_w_conn_keys[share->link_count]; -#endif - spider_db_handler *dbton_hdl[SPIDER_DBTON_SIZE]; -#endif THD *thd; my_thread_init(); DBUG_ENTER("spider_bg_crd_action"); /* init start */ -#if defined(_MSC_VER) || defined(__SUNPRO_CC) + char *ptr; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!(need_mons = (int *) - spider_bulk_malloc(spider_current_trx, 22, MYF(MY_WME), - &need_mons, sizeof(int) * share->link_count, - &conns, sizeof(SPIDER_CONN *) * share->link_count, - &conn_link_idx, sizeof(uint) * share->link_count, - &conn_can_fo, sizeof(uchar) * share->link_bitmap_size, - &conn_keys, sizeof(char *) * share->link_count, - &hs_r_conn_keys, sizeof(char *) * share->link_count, - &hs_w_conn_keys, sizeof(char *) * share->link_count, - &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, - NullS)) - ) + ptr = (char *) my_alloca( + (sizeof(int) * share->link_count) + + (sizeof(SPIDER_CONN *) * share->link_count) + + (sizeof(uint) * share->link_count) + + (sizeof(uchar) * share->link_bitmap_size) + + (sizeof(char *) * share->link_count) + + (sizeof(char *) * share->link_count) + + (sizeof(char *) * share->link_count) + + (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); #else - if (!(need_mons = (int *) - spider_bulk_malloc(spider_current_trx, 22, MYF(MY_WME), - &need_mons, sizeof(int) * share->link_count, - &conns, sizeof(SPIDER_CONN *) * share->link_count, - &conn_link_idx, sizeof(uint) * share->link_count, - &conn_can_fo, sizeof(uchar) * share->link_bitmap_size, - &conn_keys, sizeof(char *) * share->link_count, - &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, - NullS)) - ) -#endif + ptr = (char *) my_alloca( + (sizeof(int) * share->link_count) + + (sizeof(SPIDER_CONN *) * share->link_count) + + (sizeof(uint) * share->link_count) + + (sizeof(uchar) * share->link_bitmap_size) + + (sizeof(char *) * share->link_count) + + (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); +#endif + if (!ptr) { pthread_mutex_lock(&share->crd_mutex); share->bg_crd_thd_wait = FALSE; @@ -3144,20 +3317,35 @@ void *spider_bg_crd_action( my_thread_end(); DBUG_RETURN(NULL); } + need_mons = (int *) ptr; + ptr += (sizeof(int) * share->link_count); + conns = (SPIDER_CONN **) ptr; + ptr += (sizeof(SPIDER_CONN *) * share->link_count); + conn_link_idx = (uint *) ptr; + ptr += (sizeof(uint) * share->link_count); + conn_can_fo = (uchar *) ptr; + ptr += (sizeof(uchar) * share->link_bitmap_size); + conn_keys = (char **) ptr; + ptr += (sizeof(char *) * share->link_count); +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + hs_r_conn_keys = (char **) ptr; + ptr += (sizeof(char *) * share->link_count); + hs_w_conn_keys = (char **) ptr; + ptr += (sizeof(char *) * share->link_count); #endif + dbton_hdl = (spider_db_handler **) ptr; pthread_mutex_lock(&share->crd_mutex); - if (!(thd = new THD(next_thread_id()))) + if (!(thd = SPIDER_new_THD(next_thread_id()))) { share->bg_crd_thd_wait = FALSE; share->bg_crd_kill = FALSE; share->bg_crd_init = FALSE; pthread_mutex_unlock(&share->crd_mutex); my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } + SPIDER_set_next_thread_id(thd); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif @@ -3174,9 +3362,7 @@ void *spider_bg_crd_action( my_pthread_setspecific_ptr(THR_THD, NULL); #endif my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } share->bg_crd_thd = thd; @@ -3213,14 +3399,14 @@ void *spider_bg_crd_action( spider_bit_is_set(share->dbton_bitmap, roop_count) && spider_dbton[roop_count].create_db_handler ) { - if ((dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler( + if (!(dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler( &spider, share->dbton_share[roop_count]))) break; if (dbton_hdl[roop_count]->init()) break; } } - if (roop_count == SPIDER_DBTON_SIZE) + if (roop_count < SPIDER_DBTON_SIZE) { DBUG_PRINT("info",("spider handler init error")); for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count) @@ -3243,9 +3429,7 @@ void *spider_bg_crd_action( my_pthread_setspecific_ptr(THR_THD, NULL); #endif my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } /* init end */ @@ -3274,12 +3458,10 @@ void *spider_bg_crd_action( my_pthread_setspecific_ptr(THR_THD, NULL); #endif my_thread_end(); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(NULL, need_mons, MYF(MY_WME)); -#endif + my_afree(need_mons); DBUG_RETURN(NULL); } - if (spider.search_link_idx == -1) + if (spider.search_link_idx < 0) { spider_trx_set_link_idx_for_all(&spider); /* @@ -3317,6 +3499,7 @@ void *spider_bg_crd_action( spider_global_trx, thd, share, + spider.search_link_idx, (uint32) share->monitoring_sid[spider.search_link_idx], share->table_name, share->table_name_length, @@ -3359,6 +3542,7 @@ void *spider_bg_crd_action( spider_global_trx, thd, share, + spider.search_link_idx, (uint32) share->monitoring_sid[spider.search_link_idx], share->table_name, share->table_name_length, @@ -3408,15 +3592,9 @@ int spider_create_mon_threads( { char link_idx_str[SPIDER_SQL_INT_LEN]; int link_idx_str_length; -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_string conv_name_str(share->table_name_length + - SPIDER_SQL_INT_LEN + 1); - conv_name_str.set_charset(system_charset_info); -#else - char buf[share->table_name_length + SPIDER_SQL_INT_LEN + 1]; + char *buf = (char *) my_alloca(share->table_name_length + SPIDER_SQL_INT_LEN + 1); spider_string conv_name_str(buf, share->table_name_length + SPIDER_SQL_INT_LEN + 1, system_charset_info); -#endif conv_name_str.init_calc_mem(105); conv_name_str.length(0); conv_name_str.q_append(share->table_name, share->table_name_length); @@ -3426,14 +3604,26 @@ int spider_create_mon_threads( if (share->monitoring_bg_kind[roop_count]) { conv_name_str.length(share->table_name_length); - link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, - "%010d", roop_count)); + if (share->static_link_ids[roop_count]) + { + memcpy(link_idx_str, share->static_link_ids[roop_count], + share->static_link_ids_lengths[roop_count] + 1); + link_idx_str_length = share->static_link_ids_lengths[roop_count]; + } else { + link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, + "%010d", roop_count)); + } conv_name_str.q_append(link_idx_str, link_idx_str_length + 1); conv_name_str.length(conv_name_str.length() - 1); if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd, &conv_name_str, share->table_name_length, roop_count, + share->static_link_ids[roop_count], + share->static_link_ids_lengths[roop_count], (uint32) share->monitoring_sid[roop_count], FALSE, &error_num))) + { + my_afree(buf); goto error_get_ping_table_mon_list; + } spider_free_ping_table_mon_list(table_mon_list); } } @@ -3449,6 +3639,7 @@ int spider_create_mon_threads( NullS)) ) { error_num = HA_ERR_OUT_OF_MEM; + my_afree(buf); goto error_alloc_base; } for (roop_count = 0; roop_count < (int) share->all_link_count; @@ -3465,6 +3656,7 @@ int spider_create_mon_threads( #endif ) { error_num = HA_ERR_OUT_OF_MEM; + my_afree(buf); goto error_mutex_init; } } @@ -3481,6 +3673,7 @@ int spider_create_mon_threads( #endif ) { error_num = HA_ERR_OUT_OF_MEM; + my_afree(buf); goto error_cond_init; } } @@ -3497,6 +3690,7 @@ int spider_create_mon_threads( #endif ) { error_num = HA_ERR_OUT_OF_MEM; + my_afree(buf); goto error_sleep_cond_init; } } @@ -3520,6 +3714,7 @@ int spider_create_mon_threads( #endif { error_num = HA_ERR_OUT_OF_MEM; + my_afree(buf); goto error_thread_create; } pthread_cond_wait(&share->bg_mon_conds[roop_count], @@ -3528,6 +3723,7 @@ int spider_create_mon_threads( } } share->bg_mon_init = TRUE; + my_afree(buf); } } DBUG_RETURN(0); @@ -3635,7 +3831,7 @@ void *spider_bg_mon_action( DBUG_ENTER("spider_bg_mon_action"); /* init start */ pthread_mutex_lock(&share->bg_mon_mutexes[link_idx]); - if (!(thd = new THD(next_thread_id()))) + if (!(thd = SPIDER_new_THD(next_thread_id()))) { share->bg_mon_kill = FALSE; share->bg_mon_init = FALSE; @@ -3644,6 +3840,7 @@ void *spider_bg_mon_action( my_thread_end(); DBUG_RETURN(NULL); } + SPIDER_set_next_thread_id(thd); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif @@ -3708,6 +3905,7 @@ void *spider_bg_mon_action( spider_global_trx, thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -3736,25 +3934,19 @@ int spider_conn_first_link_idx( int roop_count, active_links = 0; longlong balance_total = 0, balance_val; double rand_val; -#if defined(_MSC_VER) || defined(__SUNPRO_CC) int *link_idxs, link_idx; long *balances; -#else - int link_idxs[link_count]; - long balances[link_count]; -#endif DBUG_ENTER("spider_conn_first_link_idx"); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - if (!(link_idxs = (int *) - spider_bulk_malloc(spider_current_trx, 24, MYF(MY_WME), - &link_idxs, sizeof(int) * link_count, - &balances, sizeof(long) * link_count, - NullS)) - ) { + char *ptr; + ptr = (char *) my_alloca((sizeof(int) * link_count) + (sizeof(long) * link_count)); + if (!ptr) + { DBUG_PRINT("info",("spider out of memory")); - DBUG_RETURN(-1); + DBUG_RETURN(-2); } -#endif + link_idxs = (int *) ptr; + ptr += sizeof(int) * link_count; + balances = (long *) ptr; for (roop_count = 0; roop_count < link_count; roop_count++) { DBUG_ASSERT((conn_link_idx[roop_count] - roop_count) % link_count == 0); @@ -3770,9 +3962,7 @@ int spider_conn_first_link_idx( if (active_links == 0) { DBUG_PRINT("info",("spider all links are failed")); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(spider_current_trx, link_idxs, MYF(MY_WME)); -#endif + my_afree(link_idxs); DBUG_RETURN(-1); } #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002 @@ -3799,13 +3989,9 @@ int spider_conn_first_link_idx( } DBUG_PRINT("info",("spider first link_idx=%d", link_idxs[roop_count])); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) link_idx = link_idxs[roop_count]; - spider_free(spider_current_trx, link_idxs, MYF(MY_WME)); + my_afree(link_idxs); DBUG_RETURN(link_idx); -#else - DBUG_RETURN(link_idxs[roop_count]); -#endif } int spider_conn_next_link_idx( @@ -3858,6 +4044,17 @@ int spider_conn_link_idx_next( DBUG_RETURN(link_idx); } +int spider_conn_get_link_status( + long *link_statuses, + uint *conn_link_idx, + int link_idx +) { + DBUG_ENTER("spider_conn_get_link_status"); + DBUG_PRINT("info",("spider link_status=%d", + (int) link_statuses[conn_link_idx[link_idx]])); + DBUG_RETURN((int) link_statuses[conn_link_idx[link_idx]]); +} + int spider_conn_lock_mode( ha_spider *spider ) { @@ -4167,3 +4364,208 @@ bool spider_conn_need_open_handler( } DBUG_RETURN(TRUE); } + +SPIDER_CONN* spider_get_conn_from_idle_connection( + SPIDER_SHARE *share, + int link_idx, + char *conn_key, + ha_spider *spider, + uint conn_kind, + int base_link_idx, + int *error_num + ) +{ + DBUG_ENTER("spider_get_conn_from_idle_connection"); + SPIDER_IP_PORT_CONN *ip_port_conn; + SPIDER_CONN *conn = NULL; + uint spider_max_connections = spider_param_max_connections(); + struct timespec abstime; + ulonglong start, inter_val = 0; + longlong last_ntime = 0; + ulonglong wait_time = (ulonglong)spider_param_conn_wait_timeout()*1000*1000*1000; // default 10s + + unsigned long ip_port_count = 0; // init 0 + + set_timespec(abstime, 0); + + pthread_mutex_lock(&spider_ipport_conn_mutex); +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search_using_hash_value( + &spider_ipport_conns, share->conn_keys_hash_value[link_idx], + (uchar*) share->conn_keys[link_idx], share->conn_keys_lengths[link_idx]))) +#else + if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search( + &spider_ipport_conns, + (uchar*) share->conn_keys[link_idx], share->conn_keys_lengths[link_idx]))) +#endif + { /* exists */ + pthread_mutex_unlock(&spider_ipport_conn_mutex); + pthread_mutex_lock(&ip_port_conn->mutex); + ip_port_count = ip_port_conn->ip_port_count; + } else { + pthread_mutex_unlock(&spider_ipport_conn_mutex); + } + + if ( + ip_port_conn && + ip_port_count >= spider_max_connections && + spider_max_connections > 0 + ) { /* no idle conn && enable connection pool, wait */ + pthread_mutex_unlock(&ip_port_conn->mutex); + start = my_hrtime().val; + while(1) + { + int error; + inter_val = my_hrtime().val - start; // us + last_ntime = wait_time - inter_val*1000; // *1000, to ns + if(last_ntime <= 0) + {/* wait timeout */ + *error_num = ER_SPIDER_CON_COUNT_ERROR; + DBUG_RETURN(NULL); + } + set_timespec_nsec(abstime, last_ntime); + pthread_mutex_lock(&ip_port_conn->mutex); + ++ip_port_conn->waiting_count; + error = pthread_cond_timedwait(&ip_port_conn->cond, &ip_port_conn->mutex, &abstime); + --ip_port_conn->waiting_count; + pthread_mutex_unlock(&ip_port_conn->mutex); + if (error == ETIMEDOUT || error == ETIME || error != 0 ) + { + *error_num = ER_SPIDER_CON_COUNT_ERROR; + DBUG_RETURN(NULL); + } + + pthread_mutex_lock(&spider_conn_mutex); +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + if ((conn = (SPIDER_CONN*) my_hash_search_using_hash_value( + &spider_open_connections, share->conn_keys_hash_value[link_idx], + (uchar*) share->conn_keys[link_idx], + share->conn_keys_lengths[link_idx]))) +#else + if ((conn = (SPIDER_CONN*) my_hash_search(&spider_open_connections, + (uchar*) share->conn_keys[link_idx], + share->conn_keys_lengths[link_idx]))) +#endif + { + /* get conn from spider_open_connections, then delete conn in spider_open_connections */ +#ifdef HASH_UPDATE_WITH_HASH_VALUE + my_hash_delete_with_hash_value(&spider_open_connections, + conn->conn_key_hash_value, (uchar*) conn); +#else + my_hash_delete(&spider_open_connections, (uchar*) conn); +#endif + pthread_mutex_unlock(&spider_conn_mutex); + DBUG_PRINT("info",("spider get global conn")); + if (spider) + { + spider->conns[base_link_idx] = conn; + if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) + conn->use_for_active_standby = TRUE; + } + DBUG_RETURN(conn); + } + else + { + pthread_mutex_unlock(&spider_conn_mutex); + } + } + } + else + { /* create conn */ + if (ip_port_conn) + pthread_mutex_unlock(&ip_port_conn->mutex); + DBUG_PRINT("info",("spider create new conn")); + if (!(conn = spider_create_conn(share, spider, link_idx, base_link_idx, conn_kind, error_num))) + DBUG_RETURN(conn); + *conn->conn_key = *conn_key; + if (spider) + { + spider->conns[base_link_idx] = conn; + if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) + conn->use_for_active_standby = TRUE; + } + } + + DBUG_RETURN(conn); +} + + +SPIDER_IP_PORT_CONN* spider_create_ipport_conn(SPIDER_CONN *conn) +{ + DBUG_ENTER("spider_create_ipport_conn"); + if (conn) + { + SPIDER_IP_PORT_CONN *ret = (SPIDER_IP_PORT_CONN *) my_malloc(sizeof(*ret), MY_ZEROFILL | MY_WME); + if (!ret) + { + goto err_return_direct; + } + +#if MYSQL_VERSION_ID < 50500 + if (pthread_mutex_init(&ret->mutex, MY_MUTEX_INIT_FAST)) +#else + if (mysql_mutex_init(spd_key_mutex_conn_i, &ret->mutex, MY_MUTEX_INIT_FAST)) +#endif + { + //error + goto err_malloc_key; + } + +#if MYSQL_VERSION_ID < 50500 + if (pthread_cond_init(&ret->cond, NULL)) +#else + if (mysql_cond_init(spd_key_cond_conn_i, &ret->cond, NULL)) +#endif + { + pthread_mutex_destroy(&ret->mutex); + goto err_malloc_key; + //error + } + + ret->key_len = conn->conn_key_length; + if (ret->key_len <= 0) { + pthread_cond_destroy(&ret->cond); + pthread_mutex_destroy(&ret->mutex); + goto err_malloc_key; + } + + ret->key = (char *) my_malloc(ret->key_len, MY_ZEROFILL | MY_WME); + if (!ret->key) { + pthread_cond_destroy(&ret->cond); + pthread_mutex_destroy(&ret->mutex); + goto err_malloc_key; + } + + memcpy(ret->key, conn->conn_key, ret->key_len); + + strncpy(ret->remote_ip_str, conn->tgt_host, sizeof(ret->remote_ip_str)); + ret->remote_port = conn->tgt_port; + ret->conn_id = conn->conn_id; + ret->ip_port_count = 1; // init + +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + ret->key_hash_value = conn->conn_key_hash_value; +#endif + DBUG_RETURN(ret); +err_malloc_key: + spider_my_free(ret, MYF(0)); +err_return_direct: + DBUG_RETURN(NULL); + } + DBUG_RETURN(NULL); +} + + +void spider_free_ipport_conn(void *info) +{ + DBUG_ENTER("spider_free_ipport_conn"); + if (info) + { + SPIDER_IP_PORT_CONN *p = (SPIDER_IP_PORT_CONN *)info; + pthread_cond_destroy(&p->cond); + pthread_mutex_destroy(&p->mutex); + spider_my_free(p->key, MYF(0)); + spider_my_free(p, MYF(0)); + } + DBUG_VOID_RETURN; +} diff --git a/storage/spider/spd_conn.h b/storage/spider/spd_conn.h index cdcb6543a35..91c692cc309 100644 --- a/storage/spider/spd_conn.h +++ b/storage/spider/spd_conn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2014 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define SPIDER_LOCK_MODE_NO_LOCK 0 #define SPIDER_LOCK_MODE_SHARED 1 @@ -28,6 +28,12 @@ uchar *spider_conn_get_key( my_bool not_used __attribute__ ((unused)) ); +uchar *spider_ipport_conn_get_key( + SPIDER_IP_PORT_CONN *ip_port, + size_t *length, + my_bool not_used __attribute__ ((unused)) +); + int spider_reset_conn_setted_parameter( SPIDER_CONN *conn, THD *thd @@ -315,6 +321,12 @@ int spider_conn_link_idx_next( int link_status ); +int spider_conn_get_link_status( + long *link_statuses, + uint *conn_link_idx, + int link_idx +); + int spider_conn_lock_mode( ha_spider *spider ); @@ -334,3 +346,16 @@ bool spider_conn_need_open_handler( uint idx, int link_idx ); + +SPIDER_IP_PORT_CONN *spider_create_ipport_conn(SPIDER_CONN *conn) ; +SPIDER_CONN* spider_get_conn_from_idle_connection +( + SPIDER_SHARE *share, + int link_idx, + char *conn_key, + ha_spider *spider, + uint conn_kind, + int base_link_idx, + int *error_num + ); +void spider_free_ipport_conn(void *info); diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc index 36db8a9f7af..8a527015958 100644 --- a/storage/spider/spd_copy_tables.cc +++ b/storage/spider/spd_copy_tables.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2014 Kentoku Shiba +/* Copyright (C) 2009-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -993,6 +993,8 @@ long long spider_copy_tables_body( reprepare_observer_backup = thd->m_reprepare_observer; thd->m_reprepare_observer = NULL; copy_tables->trx->trx_start = TRUE; + copy_tables->trx->updated_in_this_trx = FALSE; + DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE")); #if MYSQL_VERSION_ID < 50500 if (open_and_lock_tables(thd, table_list)) #else @@ -1008,6 +1010,8 @@ long long spider_copy_tables_body( { thd->m_reprepare_observer = reprepare_observer_backup; copy_tables->trx->trx_start = FALSE; + copy_tables->trx->updated_in_this_trx = FALSE; + DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE")); my_printf_error(ER_SPIDER_UDF_CANT_OPEN_TABLE_NUM, ER_SPIDER_UDF_CANT_OPEN_TABLE_STR, MYF(0), table_list->db, table_list->table_name); @@ -1015,6 +1019,8 @@ long long spider_copy_tables_body( } thd->m_reprepare_observer = reprepare_observer_backup; copy_tables->trx->trx_start = FALSE; + copy_tables->trx->updated_in_this_trx = FALSE; + DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE")); table = table_list->table; table_share = table->s; diff --git a/storage/spider/spd_copy_tables.h b/storage/spider/spd_copy_tables.h index bac9b5d202c..bda7a051bc6 100644 --- a/storage/spider/spd_copy_tables.h +++ b/storage/spider/spd_copy_tables.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ int spider_udf_set_copy_tables_param_default( SPIDER_COPY_TABLES *copy_tables diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 817fac34efe..6d8c8f6aad1 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -195,29 +195,24 @@ int spider_db_connect( DBUG_RETURN(0); } -int spider_db_ping( - ha_spider *spider, +int spider_db_ping_internal( + SPIDER_SHARE *share, SPIDER_CONN *conn, - int link_idx + int all_link_idx, + int *need_mon ) { int error_num; - DBUG_ENTER("spider_db_ping"); -#ifndef DBUG_OFF - if (spider->trx->thd) - DBUG_PRINT("info", ("spider thd->query_id is %lld", - spider->trx->thd->query_id)); -#endif + DBUG_ENTER("spider_db_ping_internal"); if (!conn->mta_conn_mutex_lock_already) { pthread_mutex_lock(&conn->mta_conn_mutex); SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - conn->need_mon = &spider->need_mons[link_idx]; + conn->need_mon = need_mon; } DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name); if (conn->server_lost || conn->queued_connect) { - if ((error_num = spider_db_connect(spider->share, conn, - spider->conn_link_idx[link_idx]))) + if ((error_num = spider_db_connect(share, conn, all_link_idx))) { if (!conn->mta_conn_mutex_unlock_later) { @@ -232,8 +227,7 @@ int spider_db_ping( if ((error_num = conn->db_conn->ping())) { spider_db_disconnect(conn); - if ((error_num = spider_db_connect(spider->share, conn, - spider->conn_link_idx[link_idx]))) + if ((error_num = spider_db_connect(share, conn, all_link_idx))) { DBUG_PRINT("info", ("spider conn=%p SERVER_LOST", conn)); conn->server_lost = TRUE; @@ -266,6 +260,21 @@ int spider_db_ping( DBUG_RETURN(0); } +int spider_db_ping( + ha_spider *spider, + SPIDER_CONN *conn, + int link_idx +) { + DBUG_ENTER("spider_db_ping"); +#ifndef DBUG_OFF + if (spider->trx->thd) + DBUG_PRINT("info", ("spider thd->query_id is %lld", + spider->trx->thd->query_id)); +#endif + DBUG_RETURN(spider_db_ping_internal(spider->share, conn, + spider->conn_link_idx[link_idx], &spider->need_mons[link_idx])); +} + void spider_db_disconnect( SPIDER_CONN *conn ) { @@ -736,11 +745,11 @@ int spider_db_errorno( struct tm lt; struct tm *l_time = localtime_r(&cur_time, <); fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] " - "to %ld: %d %s\n", + "to %lld: %d %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - (ulong) current_thd->thread_id, error_num, - conn->db_conn->get_error()); + (long long int) current_thd->thread_id, error_num, + conn->db_conn->get_error()); } if (!conn->mta_conn_mutex_unlock_later) { @@ -757,11 +766,11 @@ int spider_db_errorno( struct tm lt; struct tm *l_time = localtime_r(&cur_time, <); fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [ERROR SPIDER RESULT] " - "to %ld: %d %s\n", + "to %lld: %d %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - (ulong) current_thd->thread_id, error_num, - conn->db_conn->get_error()); + (long long int) current_thd->thread_id, error_num, + conn->db_conn->get_error()); } if (!conn->mta_conn_mutex_unlock_later) { @@ -806,7 +815,7 @@ int spider_db_errorno( "to %ld: %d %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - current_thd->thread_id, conn->db_conn->get_errno(), + (ulong) current_thd->thread_id, conn->db_conn->get_errno(), conn->db_conn->get_error()); } *conn->need_mon = ER_SPIDER_HS_NUM; @@ -954,6 +963,7 @@ int spider_db_query_with_set_names( spider->trx, spider->trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -987,6 +997,7 @@ int spider_db_query_with_set_names( spider->trx, spider->trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -1039,6 +1050,7 @@ int spider_db_query_for_bulk_update( spider->trx, spider->trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -1076,6 +1088,7 @@ int spider_db_query_for_bulk_update( spider->trx, spider->trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -1120,6 +1133,7 @@ int spider_db_query_for_bulk_update( spider->trx, spider->trx->thd, share, + link_idx, (uint32) share->monitoring_sid[link_idx], share->table_name, share->table_name_length, @@ -1372,7 +1386,11 @@ int spider_db_append_name_with_quote_str( for (name_end = name + length; name < name_end; name += length) { head_code = *name; - if ((length= my_charlen(system_charset_info, name, name_end)) < 1) +#ifdef SPIDER_HAS_MY_CHARLEN + if ((length = my_charlen(system_charset_info, name, name_end)) < 1) +#else + if (!(length = my_mbcharlen(system_charset_info, (uchar) head_code))) +#endif { my_message(ER_SPIDER_WRONG_CHARACTER_IN_NAME_NUM, ER_SPIDER_WRONG_CHARACTER_IN_NAME_STR, MYF(0)); @@ -1848,8 +1866,8 @@ int spider_db_append_key_where_internal( #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 case HA_READ_PREFIX_LAST: result_list->desc_flg = TRUE; -#endif /* fall through */ +#endif case HA_READ_KEY_EXACT: if (sql_kind == SPIDER_SQL_KIND_SQL) { @@ -2938,9 +2956,16 @@ int spider_db_fetch_table( } #endif - if ((error_num = spider_db_append_match_fetch(spider, - spider->ft_first, spider->ft_current, row))) - DBUG_RETURN(error_num); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + if (!spider->use_fields) + { +#endif + if ((error_num = spider_db_append_match_fetch(spider, + spider->ft_first, spider->ft_current, row))) + DBUG_RETURN(error_num); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + } +#endif #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) } else { if (!(row = result_list->hs_result->fetch_row_from_result_buffer( @@ -3180,6 +3205,10 @@ int spider_db_fetch_minimum_columns( } else { if (result_list->current_row_num < result_list->quick_page_size) { + DBUG_PRINT("info", ("spider current=%p", current)); + DBUG_PRINT("info", ("spider first_position=%p", current->first_position)); + DBUG_PRINT("info", ("spider current_row_num=%lld", result_list->current_row_num)); + DBUG_PRINT("info", ("spider first_position[]=%p", ¤t->first_position[result_list->current_row_num])); row = current->first_position[result_list->current_row_num].row; } else { if ((error_num = spider_db_get_row_from_tmp_tbl( @@ -3894,6 +3923,7 @@ int spider_db_store_result( SPIDER_DB_ROW *row; if (!(row = current->result->fetch_row())) { + error_num = current->result->get_errno(); DBUG_PRINT("info",("spider set finish_flg point 3")); DBUG_PRINT("info",("spider current->finish_flg = TRUE")); DBUG_PRINT("info",("spider result_list->finish_flg = TRUE")); @@ -3913,7 +3943,10 @@ int spider_db_store_result( ) { result_list->current_row_num = 0; table->status = STATUS_NOT_FOUND; - } else if (result_list->quick_phase > 0) + } + if (error_num) + DBUG_RETURN(error_num); + else if (result_list->quick_phase > 0) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_END_OF_FILE); } @@ -4018,6 +4051,10 @@ int spider_db_store_result( conn->quick_target = NULL; spider->quick_targets[link_idx] = NULL; } +#ifndef WITHOUT_SPIDER_BG_SEARCH + DBUG_PRINT("info", ("spider bgs_phase=%d", result_list->bgs_phase)); +#endif + DBUG_PRINT("info", ("spider quick_phase=%d", result_list->quick_phase)); if ( #ifndef WITHOUT_SPIDER_BG_SEARCH result_list->bgs_phase <= 1 && @@ -4026,6 +4063,12 @@ int spider_db_store_result( ) { result_list->current_row_num = 0; } + DBUG_PRINT("info", ("spider result_list->current=%p", result_list->current)); + DBUG_PRINT("info", ("spider current=%p", current)); + DBUG_PRINT("info", ("spider first_position=%p", current->first_position)); + DBUG_PRINT("info", ("spider current_row_num=%lld", result_list->current_row_num)); + DBUG_PRINT("info", ("spider first_position[]=%p", ¤t->first_position[result_list->current_row_num])); + DBUG_PRINT("info", ("spider row=%p", current->first_position[result_list->current_row_num].row)); } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) } else { @@ -4266,39 +4309,74 @@ int spider_db_seek_next( spider_db_free_one_result(result_list, (SPIDER_RESULT*) result_list->current); - int roop_start, roop_end, roop_count, lock_mode, link_ok; - lock_mode = spider_conn_lock_mode(spider); - if (lock_mode) + int roop_start = 0, roop_end = 1, roop_count, lock_mode, link_ok = 0; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + if (!spider->use_fields) { - /* "for update" or "lock in share mode" */ - link_ok = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_OK); - roop_start = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_end = spider->share->link_count; - } else { - link_ok = link_idx; - roop_start = link_idx; - roop_end = link_idx + 1; +#endif + lock_mode = spider_conn_lock_mode(spider); + if (lock_mode) + { + /* "for update" or "lock in share mode" */ + link_ok = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + SPIDER_LINK_STATUS_OK); + roop_start = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + SPIDER_LINK_STATUS_RECOVERY); + roop_end = spider->share->link_count; + } else { + link_ok = link_idx; + roop_start = link_idx; + roop_end = link_idx + 1; + } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER } +#endif #ifndef WITHOUT_SPIDER_BG_SEARCH if (result_list->bgs_phase > 0) { - for (roop_count = roop_start; roop_count < roop_end; - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - if ((error_num = spider_bg_conn_search(spider, roop_count, roop_start, - FALSE, FALSE, (roop_count != link_ok)))) +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + if (spider->use_fields) + { + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + spider_fields *fields = spider->fields; + fields->set_pos_to_first_link_idx_chain(); + while ((link_idx_chain = fields->get_next_link_idx_chain())) { - DBUG_PRINT("info",("spider error_num 1=%d", error_num)); - DBUG_RETURN(error_num); + conn = link_idx_chain->conn; + link_idx_holder = link_idx_chain->link_idx_holder; + spider_db_handler *dbton_hdl = + spider->dbton_handler[conn->dbton_id]; + spider->link_idx_chain = link_idx_chain; + if ((error_num = spider_bg_conn_search(spider, + link_idx_holder->link_idx, dbton_hdl->first_link_idx, + FALSE, FALSE, + !fields->is_first_link_ok_chain(link_idx_chain)))) + { + DBUG_PRINT("info",("spider error_num 1=%d", error_num)); + DBUG_RETURN(error_num); + } } + } else { +#endif + for (roop_count = roop_start; roop_count < roop_end; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + SPIDER_LINK_STATUS_RECOVERY) + ) { + if ((error_num = spider_bg_conn_search(spider, roop_count, roop_start, + FALSE, FALSE, (roop_count != link_ok)))) + { + DBUG_PRINT("info",("spider error_num 1=%d", error_num)); + DBUG_RETURN(error_num); + } + } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER } +#endif } else { #endif if (result_list->current == result_list->bgs_current) @@ -4350,113 +4428,142 @@ int spider_db_seek_next( } } - for (roop_count = roop_start; roop_count < roop_end; - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - ulong sql_type; - conn = spider->conns[roop_count]; - if (spider->sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + if (spider->use_fields) + { + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + spider_fields *fields = spider->fields; + fields->set_pos_to_first_link_idx_chain(); + while ((link_idx_chain = fields->get_next_link_idx_chain())) { + ulong sql_type; + conn = link_idx_chain->conn; sql_type = SPIDER_SQL_TYPE_SELECT_SQL; - } else { - sql_type = SPIDER_SQL_TYPE_HANDLER; - } - spider_db_handler *dbton_handler = - spider->dbton_handler[conn->dbton_id]; - if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) - { - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - } - if ((error_num = dbton_handler->set_sql_for_exec(sql_type, - roop_count))) - { - DBUG_PRINT("info",("spider error_num 6=%d", error_num)); - DBUG_RETURN(error_num); - } - if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) - { - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - } - conn->need_mon = &spider->need_mons[roop_count]; - conn->mta_conn_mutex_lock_already = TRUE; - conn->mta_conn_mutex_unlock_later = TRUE; - if ((error_num = spider_db_set_names(spider, conn, roop_count))) - { - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] + link_idx_holder = link_idx_chain->link_idx_holder; + link_idx = link_idx_holder->link_idx; + spider_db_handler *dbton_handler = + spider->dbton_handler[conn->dbton_id]; + if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + if ((error_num = dbton_handler->set_sql_for_exec(sql_type, + link_idx))) + { + DBUG_PRINT("info",("spider error_num 6=%d", error_num)); + DBUG_RETURN(error_num); + } + if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + conn->need_mon = &spider->need_mons[link_idx]; + conn->mta_conn_mutex_lock_already = TRUE; + conn->mta_conn_mutex_unlock_later = TRUE; + if ((error_num = spider_db_set_names(spider, conn, link_idx))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + if ( + spider->need_mons[link_idx] + ) { + error_num = fields->ping_table_mon_from_table(link_idx_chain); + } + DBUG_PRINT("info",("spider error_num 7a=%d", error_num)); + DBUG_RETURN(error_num); + } + spider_conn_set_timeout_from_share(conn, link_idx, + spider->trx->thd, share); + if (dbton_handler->execute_sql( + sql_type, + conn, + result_list->quick_mode, + &spider->need_mons[link_idx]) ) { - error_num = spider_ping_table_mon_from_table( - spider->trx, - spider->trx->thd, - share, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - TRUE - ); + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + error_num = spider_db_errorno(conn); + if ( + spider->need_mons[link_idx] + ) { + error_num = fields->ping_table_mon_from_table(link_idx_chain); + } + DBUG_PRINT("info",("spider error_num 8a=%d", error_num)); + DBUG_RETURN(error_num); } - DBUG_PRINT("info",("spider error_num 7=%d", error_num)); - DBUG_RETURN(error_num); - } - spider_conn_set_timeout_from_share(conn, roop_count, - spider->trx->thd, share); - if (dbton_handler->execute_sql( - sql_type, - conn, - result_list->quick_mode, - &spider->need_mons[roop_count]) - ) { + spider->connection_ids[link_idx] = conn->connection_id; conn->mta_conn_mutex_lock_already = FALSE; conn->mta_conn_mutex_unlock_later = FALSE; - error_num = spider_db_errorno(conn); - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - error_num = spider_ping_table_mon_from_table( - spider->trx, - spider->trx->thd, - share, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - TRUE - ); + if (fields->is_first_link_ok_chain(link_idx_chain)) + { + if ((error_num = spider_db_store_result(spider, link_idx, + table))) + { + if ( + error_num != HA_ERR_END_OF_FILE && + spider->need_mons[link_idx] + ) { + error_num = + fields->ping_table_mon_from_table(link_idx_chain); + } + DBUG_PRINT("info",("spider error_num 9a=%d", error_num)); + DBUG_RETURN(error_num); + } + spider->result_link_idx = link_ok; + } else { + spider_db_discard_result(spider, link_idx, conn); + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); } - DBUG_PRINT("info",("spider error_num 8=%d", error_num)); - DBUG_RETURN(error_num); } - spider->connection_ids[roop_count] = conn->connection_id; - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - if (roop_count == link_ok) - { - if ((error_num = spider_db_store_result(spider, roop_count, - table))) + } else { +#endif + for (roop_count = roop_start; roop_count < roop_end; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + SPIDER_LINK_STATUS_RECOVERY) + ) { + ulong sql_type; + conn = spider->conns[roop_count]; + if (spider->sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) + { + sql_type = SPIDER_SQL_TYPE_SELECT_SQL; + } else { + sql_type = SPIDER_SQL_TYPE_HANDLER; + } + spider_db_handler *dbton_handler = + spider->dbton_handler[conn->dbton_id]; + if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + if ((error_num = dbton_handler->set_sql_for_exec(sql_type, + roop_count))) + { + DBUG_PRINT("info",("spider error_num 6=%d", error_num)); + DBUG_RETURN(error_num); + } + if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + conn->need_mon = &spider->need_mons[roop_count]; + conn->mta_conn_mutex_lock_already = TRUE; + conn->mta_conn_mutex_unlock_later = TRUE; + if ((error_num = spider_db_set_names(spider, conn, roop_count))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); if ( - error_num != HA_ERR_END_OF_FILE && share->monitoring_kind[roop_count] && spider->need_mons[roop_count] ) { @@ -4464,6 +4571,7 @@ int spider_db_seek_next( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4476,16 +4584,87 @@ int spider_db_seek_next( TRUE ); } - DBUG_PRINT("info",("spider error_num 9=%d", error_num)); + DBUG_PRINT("info",("spider error_num 7=%d", error_num)); DBUG_RETURN(error_num); } - spider->result_link_idx = link_ok; - } else { - spider_db_discard_result(spider, roop_count, conn); - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); + spider_conn_set_timeout_from_share(conn, roop_count, + spider->trx->thd, share); + if (dbton_handler->execute_sql( + sql_type, + conn, + result_list->quick_mode, + &spider->need_mons[roop_count]) + ) { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + error_num = spider_db_errorno(conn); + if ( + share->monitoring_kind[roop_count] && + spider->need_mons[roop_count] + ) { + error_num = spider_ping_table_mon_from_table( + spider->trx, + spider->trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + TRUE + ); + } + DBUG_PRINT("info",("spider error_num 8=%d", error_num)); + DBUG_RETURN(error_num); + } + spider->connection_ids[roop_count] = conn->connection_id; + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + if (roop_count == link_ok) + { + if ((error_num = spider_db_store_result(spider, roop_count, + table))) + { + if ( + error_num != HA_ERR_END_OF_FILE && + share->monitoring_kind[roop_count] && + spider->need_mons[roop_count] + ) { + error_num = spider_ping_table_mon_from_table( + spider->trx, + spider->trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + TRUE + ); + } + DBUG_PRINT("info",("spider error_num 9=%d", error_num)); + DBUG_RETURN(error_num); + } + spider->result_link_idx = link_ok; + } else { + spider_db_discard_result(spider, roop_count, conn); + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + } } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER } +#endif } else { spider->connection_ids[link_idx] = conn->connection_id; conn->mta_conn_mutex_unlock_later = TRUE; @@ -4646,6 +4825,7 @@ int spider_db_seek_last( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4679,6 +4859,7 @@ int spider_db_seek_last( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4709,6 +4890,7 @@ int spider_db_seek_last( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4846,6 +5028,7 @@ int spider_db_seek_last( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4879,6 +5062,7 @@ int spider_db_seek_last( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4909,6 +5093,7 @@ int spider_db_seek_last( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5513,6 +5698,7 @@ int spider_db_bulk_insert_init( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5683,6 +5869,7 @@ int spider_db_bulk_insert( spider->trx, spider->trx->thd, share, + roop_count2, (uint32) share->monitoring_sid[roop_count2], share->table_name, share->table_name_length, @@ -5732,6 +5919,7 @@ int spider_db_bulk_insert( spider->trx, spider->trx->thd, share, + roop_count2, (uint32) share->monitoring_sid[roop_count2], share->table_name, share->table_name_length, @@ -6378,6 +6566,7 @@ int spider_db_update( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6414,6 +6603,7 @@ int spider_db_update( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6466,6 +6656,7 @@ int spider_db_update( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6492,6 +6683,7 @@ int spider_db_update( } #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int spider_db_direct_update( ha_spider *spider, TABLE *table, @@ -6707,6 +6899,7 @@ int spider_db_direct_update( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6746,6 +6939,7 @@ int spider_db_direct_update( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -6822,6 +7016,217 @@ int spider_db_direct_update( #endif DBUG_RETURN(0); } +#else +int spider_db_direct_update( + ha_spider *spider, + TABLE *table, + ha_rows *update_rows +) { + int error_num, roop_count; + SPIDER_SHARE *share = spider->share; + SPIDER_CONN *conn; + SPIDER_RESULT_LIST *result_list = &spider->result_list; + bool counted = FALSE; + st_select_lex *select_lex; + longlong select_limit; + longlong offset_limit; + DBUG_ENTER("spider_db_direct_update"); + + spider_set_result_list_param(spider); + result_list->finish_flg = FALSE; + DBUG_PRINT("info", ("spider do_direct_update=%s", + spider->do_direct_update ? "TRUE" : "FALSE")); + DBUG_PRINT("info", ("spider direct_update_kinds=%u", + spider->direct_update_kinds)); + if ((error_num = spider->append_update_sql_part())) + DBUG_RETURN(error_num); + +/* + SQL access -> SQL remote access + !spider->do_direct_update && + (spider->sql_kinds & SPIDER_SQL_KIND_SQL) + + SQL access -> SQL remote access with dirct_update + spider->do_direct_update && + spider->direct_update_kinds == SPIDER_SQL_KIND_SQL && + spider->direct_update_fields +*/ + +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS + if (!spider->do_direct_update) + { +#endif + if ( + (spider->sql_kinds & SPIDER_SQL_KIND_SQL) && + (error_num = spider->append_update_set_sql_part()) + ) { + DBUG_RETURN(error_num); + } +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS + } else { + if ( + (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) && + (error_num = spider->append_direct_update_set_sql_part()) + ) { + DBUG_RETURN(error_num); + } + } +#endif + + result_list->desc_flg = FALSE; + result_list->sorted = TRUE; + if (spider->active_index == MAX_KEY) + result_list->key_info = NULL; + else + result_list->key_info = &table->key_info[spider->active_index]; + spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit); + result_list->limit_num = + result_list->internal_limit >= select_limit ? + select_limit : result_list->internal_limit; + result_list->internal_offset += offset_limit; + if (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) + { + if ( + (error_num = spider->append_key_where_sql_part( + NULL, + NULL, + SPIDER_SQL_TYPE_UPDATE_SQL)) || + (error_num = spider-> + append_key_order_for_direct_order_limit_with_alias_sql_part( + NULL, 0, SPIDER_SQL_TYPE_UPDATE_SQL)) || + (error_num = spider->append_limit_sql_part( + result_list->internal_offset, result_list->limit_num, + SPIDER_SQL_TYPE_UPDATE_SQL)) + ) { + DBUG_RETURN(error_num); + } + } + + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + SPIDER_LINK_STATUS_RECOVERY); + roop_count < (int) share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + SPIDER_LINK_STATUS_RECOVERY) + ) { + ulong sql_type; + DBUG_PRINT("info", ("spider exec sql")); + conn = spider->conns[roop_count]; + sql_type = SPIDER_SQL_TYPE_UPDATE_SQL; + spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id]; + if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count))) + { + DBUG_RETURN(error_num); + } + if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } +#ifdef HA_CAN_BULK_ACCESS + if (spider->is_bulk_access_clone) + { + spider->connection_ids[roop_count] = conn->connection_id; + spider_trx_add_bulk_access_conn(spider->trx, conn); + } else { +#endif + conn->need_mon = &spider->need_mons[roop_count]; + conn->mta_conn_mutex_lock_already = TRUE; + conn->mta_conn_mutex_unlock_later = TRUE; + if ((error_num = spider_db_set_names(spider, conn, roop_count))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + if ( + share->monitoring_kind[roop_count] && + spider->need_mons[roop_count] + ) { + error_num = spider_ping_table_mon_from_table( + spider->trx, + spider->trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + TRUE + ); + } + DBUG_RETURN(error_num); + } + spider_conn_set_timeout_from_share(conn, roop_count, spider->trx->thd, + share); + if ( + (error_num = dbton_hdl->execute_sql( + sql_type, + conn, + -1, + &spider->need_mons[roop_count]) + ) && + (error_num != HA_ERR_FOUND_DUPP_KEY || !spider->ignore_dup_key) + ) { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + error_num = spider_db_errorno(conn); + if ( + error_num != ER_DUP_ENTRY && + error_num != ER_DUP_KEY && + error_num != HA_ERR_FOUND_DUPP_KEY && + share->monitoring_kind[roop_count] && + spider->need_mons[roop_count] + ) { + error_num = spider_ping_table_mon_from_table( + spider->trx, + spider->trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + TRUE + ); + } + DBUG_RETURN(error_num); + } + if (!counted) + { + *update_rows = spider->conns[roop_count]->db_conn->affected_rows(); + DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows)); + counted = TRUE; + } +#ifdef HA_CAN_BULK_ACCESS + } +#endif + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + } + spider->reset_sql_sql(SPIDER_SQL_TYPE_UPDATE_SQL); + DBUG_RETURN(0); +} +#endif #endif #ifdef HA_CAN_BULK_ACCESS @@ -6996,6 +7401,7 @@ int spider_db_delete( } #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int spider_db_direct_delete( ha_spider *spider, TABLE *table, @@ -7135,6 +7541,7 @@ int spider_db_direct_delete( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7168,6 +7575,7 @@ int spider_db_direct_delete( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7212,7 +7620,7 @@ int spider_db_direct_delete( if (!counted) { *delete_rows = conn->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider delete_rows = %u", *delete_rows)); + DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows)); counted = TRUE; } result->free_result(); @@ -7249,6 +7657,184 @@ int spider_db_direct_delete( #endif DBUG_RETURN(error_num2); } +#else +int spider_db_direct_delete( + ha_spider *spider, + TABLE *table, + ha_rows *delete_rows +) { + int error_num, roop_count; + SPIDER_SHARE *share = spider->share; + SPIDER_CONN *conn; + SPIDER_RESULT_LIST *result_list = &spider->result_list; + bool counted = FALSE; + st_select_lex *select_lex; + longlong select_limit; + longlong offset_limit; + DBUG_ENTER("spider_db_direct_delete"); + + spider_set_result_list_param(spider); + result_list->finish_flg = FALSE; + result_list->desc_flg = FALSE; + result_list->sorted = TRUE; + if (spider->active_index == MAX_KEY) + result_list->key_info = NULL; + else + result_list->key_info = &table->key_info[spider->active_index]; + spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit); + result_list->limit_num = + result_list->internal_limit >= select_limit ? + select_limit : result_list->internal_limit; + result_list->internal_offset += offset_limit; + if (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) + { + if ( + (error_num = spider->append_delete_sql_part()) || + (error_num = spider->append_from_sql_part(SPIDER_SQL_TYPE_DELETE_SQL)) + ) { + DBUG_RETURN(error_num); + } + spider->set_where_pos_sql(SPIDER_SQL_TYPE_DELETE_SQL); + if ( + (error_num = spider->append_key_where_sql_part( + NULL, + NULL, + SPIDER_SQL_TYPE_DELETE_SQL)) || + (error_num = spider-> + append_key_order_for_direct_order_limit_with_alias_sql_part( + NULL, 0, SPIDER_SQL_TYPE_DELETE_SQL)) || + (error_num = spider->append_limit_sql_part( + result_list->internal_offset, result_list->limit_num, + SPIDER_SQL_TYPE_DELETE_SQL)) + ) { + DBUG_RETURN(error_num); + } + } + + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + SPIDER_LINK_STATUS_RECOVERY); + roop_count < (int) share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + SPIDER_LINK_STATUS_RECOVERY) + ) { + ulong sql_type; + DBUG_PRINT("info", ("spider exec sql")); + conn = spider->conns[roop_count]; + sql_type = SPIDER_SQL_TYPE_DELETE_SQL; + spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id]; + if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count))) + { + DBUG_RETURN(error_num); + } + if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } +#ifdef HA_CAN_BULK_ACCESS + if (spider->is_bulk_access_clone) + { + spider->connection_ids[roop_count] = conn->connection_id; + spider_trx_add_bulk_access_conn(spider->trx, conn); + } else { +#endif + conn->need_mon = &spider->need_mons[roop_count]; + conn->mta_conn_mutex_lock_already = TRUE; + conn->mta_conn_mutex_unlock_later = TRUE; + if ((error_num = spider_db_set_names(spider, conn, roop_count))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + if ( + share->monitoring_kind[roop_count] && + spider->need_mons[roop_count] + ) { + error_num = spider_ping_table_mon_from_table( + spider->trx, + spider->trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + TRUE + ); + } + DBUG_RETURN(error_num); + } + spider_conn_set_timeout_from_share(conn, roop_count, spider->trx->thd, + share); + if (dbton_hdl->execute_sql( + sql_type, + conn, + -1, + &spider->need_mons[roop_count]) + ) { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + error_num = spider_db_errorno(conn); + if ( + share->monitoring_kind[roop_count] && + spider->need_mons[roop_count] + ) { + error_num = spider_ping_table_mon_from_table( + spider->trx, + spider->trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + TRUE + ); + } + DBUG_RETURN(error_num); + } + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + if (!counted) + { + *delete_rows = spider->conns[roop_count]->db_conn->affected_rows(); + DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows)); + counted = TRUE; + } +#ifdef HA_CAN_BULK_ACCESS + } +#endif + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + } + int error_num2 = 0; + if (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) + { + if ((error_num = spider->reset_sql_sql(SPIDER_SQL_TYPE_DELETE_SQL))) + error_num2 = error_num; + } + DBUG_RETURN(error_num2); +} +#endif #endif int spider_db_delete_all_rows( @@ -7326,6 +7912,7 @@ int spider_db_delete_all_rows( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7354,6 +7941,7 @@ int spider_db_delete_all_rows( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7387,6 +7975,7 @@ int spider_db_delete_all_rows( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7414,6 +8003,7 @@ int spider_db_delete_all_rows( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7472,6 +8062,7 @@ int spider_db_disable_keys( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7524,6 +8115,7 @@ int spider_db_enable_keys( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7577,6 +8169,7 @@ int spider_db_check_table( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7630,6 +8223,7 @@ int spider_db_repair_table( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7682,6 +8276,7 @@ int spider_db_analyze_table( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7734,6 +8329,7 @@ int spider_db_optimize_table( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7783,6 +8379,7 @@ int spider_db_flush_tables( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7830,6 +8427,7 @@ int spider_db_flush_logs( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -7854,7 +8452,9 @@ int spider_db_print_item_type( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { DBUG_ENTER("spider_db_print_item_type"); DBUG_PRINT("info",("spider COND type=%d", item->type())); @@ -7862,38 +8462,38 @@ int spider_db_print_item_type( { case Item::FUNC_ITEM: DBUG_RETURN(spider_db_open_item_func((Item_func *) item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); #ifdef HANDLER_HAS_DIRECT_AGGREGATE case Item::SUM_FUNC_ITEM: DBUG_RETURN(spider_db_open_item_sum_func((Item_sum *)item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); #endif case Item::COND_ITEM: DBUG_RETURN(spider_db_open_item_cond((Item_cond *) item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item::FIELD_ITEM: DBUG_RETURN(spider_db_open_item_field((Item_field *) item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item::REF_ITEM: DBUG_RETURN(spider_db_open_item_ref((Item_ref *) item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item::ROW_ITEM: DBUG_RETURN(spider_db_open_item_row((Item_row *) item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item::STRING_ITEM: DBUG_RETURN(spider_db_open_item_string(item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item::INT_ITEM: case Item::REAL_ITEM: case Item::DECIMAL_ITEM: DBUG_RETURN(spider_db_open_item_int(item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item::CACHE_ITEM: DBUG_RETURN(spider_db_open_item_cache((Item_cache *)item, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item::INSERT_VALUE_ITEM: - DBUG_RETURN(spider_db_open_item_insert_value((Item_insert_value *)item, spider, str, - alias, alias_length, dbton_id)); + DBUG_RETURN(spider_db_open_item_insert_value((Item_insert_value *)item, + spider, str, alias, alias_length, dbton_id, use_fields, fields)); case Item::SUBSELECT_ITEM: case Item::TRIGGER_FIELD_ITEM: #ifdef SPIDER_HAS_EXPR_CACHE_ITEM @@ -7931,7 +8531,9 @@ int spider_db_open_item_cond( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { int error_num = 0; List_iterator_fast<Item> lif(*(item_cond->argument_list())); @@ -7952,7 +8554,7 @@ restart_first: if (str) restart_pos = str->length(); if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) { if ( str && @@ -7986,7 +8588,7 @@ restart_first: } if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) { if ( str && @@ -8014,11 +8616,13 @@ int spider_db_open_item_func( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { DBUG_ENTER("spider_db_open_item_func"); DBUG_RETURN(spider_dbton[dbton_id].db_util->open_item_func( - item_func, spider, str, alias, alias_length)); + item_func, spider, str, alias, alias_length, use_fields, fields)); } #ifdef HANDLER_HAS_DIRECT_AGGREGATE @@ -8028,11 +8632,13 @@ int spider_db_open_item_sum_func( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { DBUG_ENTER("spider_db_open_item_func"); DBUG_RETURN(spider_dbton[dbton_id].db_util->open_item_sum_func( - item_sum, spider, str, alias, alias_length)); + item_sum, spider, str, alias, alias_length, use_fields, fields)); } #endif @@ -8042,7 +8648,9 @@ int spider_db_open_item_ident( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { int error_num, field_name_length; SPIDER_SHARE *share = spider->share; @@ -8053,15 +8661,37 @@ int spider_db_open_item_ident( ) { Field *field = item_ident->cached_table->table->field[ item_ident->cached_field_index]; - if (!(field = spider->field_exchange(field))) - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); DBUG_PRINT("info",("spider use cached_field_index")); - if (str) + if (!use_fields) { - if ((error_num = share->dbton_share[dbton_id]-> - append_column_name_with_alias(str, field->field_index, - alias, alias_length))) - DBUG_RETURN(error_num); + if (!(field = spider->field_exchange(field))) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + if (str) + { + if ((error_num = share->dbton_share[dbton_id]-> + append_column_name_with_alias(str, field->field_index, + alias, alias_length))) + DBUG_RETURN(error_num); + } + } else { + if (str) + { + SPIDER_FIELD_CHAIN *field_chain = fields->get_next_field_chain(); + SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder; + spider = field_holder->spider; + share = spider->share; + field = spider->field_exchange(field); + DBUG_ASSERT(field); + if ((error_num = share->dbton_share[dbton_id]-> + append_column_name_with_alias(str, field->field_index, + field_holder->alias->ptr(), field_holder->alias->length()))) + DBUG_RETURN(error_num); + } else { + if ((error_num = fields->add_field(field))) + { + DBUG_RETURN(error_num); + } + } } DBUG_RETURN(0); } @@ -8102,7 +8732,9 @@ int spider_db_open_item_field( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { int error_num; Field *field = item_field->field; @@ -8111,22 +8743,52 @@ int spider_db_open_item_field( if (field) { DBUG_PRINT("info",("spider field=%p", field)); - if (!(field = spider->field_exchange(field))) - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + DBUG_PRINT("info",("spider db=%s", field->table->s->db.str)); + DBUG_PRINT("info",("spider table_name=%s", field->table->s->table_name.str)); + DBUG_PRINT("info",("spider tmp_table=%u", field->table->s->tmp_table)); +/* if (field->table->const_table) +*/ + if (field->table->s->tmp_table != INTERNAL_TMP_TABLE) { - if (str) + if (!use_fields) { - if ((error_num = share->dbton_share[dbton_id]-> - append_column_name_with_alias(str, field->field_index, - alias, alias_length))) - DBUG_RETURN(error_num); + if (!(field = spider->field_exchange(field))) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + if (str) + { + if ((error_num = share->dbton_share[dbton_id]-> + append_column_name_with_alias(str, field->field_index, + alias, alias_length))) + DBUG_RETURN(error_num); + } + DBUG_RETURN(0); + } else { + if (str) + { + SPIDER_FIELD_CHAIN *field_chain = fields->get_next_field_chain(); + SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder; + spider = field_holder->spider; + share = spider->share; + field = spider->field_exchange(field); + DBUG_ASSERT(field); + if ((error_num = share->dbton_share[dbton_id]-> + append_column_name_with_alias(str, field->field_index, + field_holder->alias->ptr(), field_holder->alias->length()))) + DBUG_RETURN(error_num); + } else { + if ((error_num = fields->add_field(field))) + { + DBUG_RETURN(error_num); + } + } + DBUG_RETURN(0); } - DBUG_RETURN(0); } } DBUG_RETURN(spider_db_open_item_ident( - (Item_ident *) item_field, spider, str, alias, alias_length, dbton_id)); + (Item_ident *) item_field, spider, str, alias, alias_length, dbton_id, + use_fields, fields)); } int spider_db_open_item_ref( @@ -8135,7 +8797,9 @@ int spider_db_open_item_ref( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { int error_num; DBUG_ENTER("spider_db_open_item_ref"); @@ -8164,10 +8828,10 @@ int spider_db_open_item_ref( DBUG_RETURN(0); } DBUG_RETURN(spider_db_print_item_type(*(item_ref->ref), spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } DBUG_RETURN(spider_db_open_item_ident((Item_ident *) item_ref, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } int spider_db_open_item_row( @@ -8176,7 +8840,9 @@ int spider_db_open_item_row( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { int error_num; uint roop_count, cols = item_row->cols() - 1; @@ -8192,7 +8858,7 @@ int spider_db_open_item_row( { item = item_row->element_index(roop_count); if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -8203,7 +8869,7 @@ int spider_db_open_item_row( } item = item_row->element_index(roop_count); if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -8221,7 +8887,9 @@ int spider_db_open_item_string( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { DBUG_ENTER("spider_db_open_item_string"); if (str) @@ -8258,7 +8926,9 @@ int spider_db_open_item_int( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { DBUG_ENTER("spider_db_open_item_int"); if (str) @@ -8296,7 +8966,9 @@ int spider_db_open_item_cache( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { DBUG_ENTER("spider_db_open_item_cache"); if (!item_cache->const_item()) @@ -8306,7 +8978,7 @@ int spider_db_open_item_cache( { case STRING_RESULT: DBUG_RETURN(spider_db_open_item_string(item_cache, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case ROW_RESULT: { int error_num; @@ -8322,7 +8994,7 @@ int spider_db_open_item_cache( { if ((error_num = spider_db_open_item_cache( (Item_cache *) item_cache_row->element_index(roop_count), - spider, str, alias, alias_length, dbton_id + spider, str, alias, alias_length, dbton_id, use_fields, fields ))) { DBUG_RETURN(error_num); } @@ -8335,7 +9007,7 @@ int spider_db_open_item_cache( } if ((error_num = spider_db_open_item_cache( (Item_cache *) item_cache_row->element_index(roop_count), - spider, str, alias, alias_length, dbton_id + spider, str, alias, alias_length, dbton_id, use_fields, fields ))) { DBUG_RETURN(error_num); } @@ -8355,7 +9027,7 @@ int spider_db_open_item_cache( break; } DBUG_RETURN(spider_db_open_item_int(item_cache, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } int spider_db_open_item_insert_value( @@ -8364,7 +9036,9 @@ int spider_db_open_item_insert_value( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { int error_num; DBUG_ENTER("spider_db_open_item_insert_value"); @@ -8378,7 +9052,7 @@ int spider_db_open_item_insert_value( str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); } if ((error_num = spider_db_print_item_type(item_insert_value->arg, spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -8429,7 +9103,9 @@ int spider_db_append_update_columns( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ) { int error_num; bool add_comma = FALSE; @@ -8441,7 +9117,8 @@ int spider_db_append_update_columns( { value = vi++; if ((error_num = spider_db_print_item_type( - (Item *) field, spider, str, alias, alias_length, dbton_id))) + (Item *) field, spider, str, alias, alias_length, dbton_id, + use_fields, fields))) { if ( error_num == ER_SPIDER_COND_SKIP_NUM && @@ -8460,7 +9137,8 @@ int spider_db_append_update_columns( str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); } if ((error_num = spider_db_print_item_type( - (Item *) value, spider, str, alias, alias_length, dbton_id))) + (Item *) value, spider, str, alias, alias_length, dbton_id, + use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -9301,18 +9979,19 @@ int spider_db_udf_ping_table( { int init_sql_alloc_size = spider_param_init_sql_alloc_size(trx->thd, share->init_sql_alloc_size); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_string sql_str(init_sql_alloc_size); - sql_str.set_charset(system_charset_info); - spider_string where_str(init_sql_alloc_size); - where_str.set_charset(system_charset_info); -#else - char sql_buf[init_sql_alloc_size], where_buf[init_sql_alloc_size]; + char *sql_buf = (char *) my_alloca(init_sql_alloc_size * 2); + if (!sql_buf) + { + table_mon_list->last_mon_result = HA_ERR_OUT_OF_MEM; + pthread_mutex_unlock(&table_mon_list->monitor_mutex); + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + char *where_buf = sql_buf + init_sql_alloc_size; spider_string sql_str(sql_buf, sizeof(sql_buf), system_charset_info); spider_string where_str(where_buf, sizeof(where_buf), system_charset_info); -#endif sql_str.init_calc_mem(128); where_str.init_calc_mem(129); sql_str.length(0); @@ -9325,6 +10004,7 @@ int spider_db_udf_ping_table( table_mon_list->last_mon_result = HA_ERR_OUT_OF_MEM; pthread_mutex_unlock(&table_mon_list->monitor_mutex); my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + my_afree(sql_buf); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } share->access_charset = system_charset_info; @@ -9334,6 +10014,7 @@ int spider_db_udf_ping_table( table_mon_list->last_mon_result = error_num; pthread_mutex_unlock(&table_mon_list->monitor_mutex); my_error(error_num, MYF(0)); + my_afree(sql_buf); DBUG_RETURN(error_num); } pthread_mutex_lock(&conn->mta_conn_mutex); @@ -9350,6 +10031,7 @@ int spider_db_udf_ping_table( table_mon_list->last_mon_result = error_num; pthread_mutex_unlock(&table_mon_list->monitor_mutex); DBUG_PRINT("info",("spider error_num=%d", error_num)); + my_afree(sql_buf); DBUG_RETURN(error_num); } spider_conn_set_timeout_from_share(conn, 0, trx->thd, share); @@ -9366,6 +10048,7 @@ int spider_db_udf_ping_table( table_mon_list->last_mon_result = error_num; pthread_mutex_unlock(&table_mon_list->monitor_mutex); DBUG_PRINT("info",("spider error_num=%d", error_num)); + my_afree(sql_buf); DBUG_RETURN(error_num); } conn->mta_conn_mutex_lock_already = FALSE; @@ -9373,6 +10056,7 @@ int spider_db_udf_ping_table( spider_db_discard_result(&spider, 0, conn); SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); pthread_mutex_unlock(&conn->mta_conn_mutex); + my_afree(sql_buf); } table_mon_list->last_mon_result = 0; pthread_mutex_unlock(&table_mon_list->monitor_mutex); @@ -9391,6 +10075,8 @@ int spider_db_udf_ping_table_append_mon_next( char *child_table_name, uint child_table_name_length, int link_id, + char *static_link_id, + uint static_link_id_length, char *where_clause, uint where_clause_length, longlong first_sid, @@ -9418,7 +10104,13 @@ int spider_db_udf_ping_table_append_mon_next( SPIDER_SQL_SELECT_LEN + SPIDER_SQL_PING_TABLE_LEN + (child_table_name_length * 2) + - (SPIDER_SQL_INT_LEN * 6) + + ( + static_link_id ? + (SPIDER_SQL_INT_LEN * 5) + + (SPIDER_SQL_VALUE_QUOTE_LEN * 2) + + (static_link_id_length * 2) : + (SPIDER_SQL_INT_LEN * 6) + ) + sid_str_length + limit_str_length + (where_clause_length * 2) + @@ -9433,7 +10125,14 @@ int spider_db_udf_ping_table_append_mon_next( str->append_escape_string(child_table_name_str.ptr(), child_table_name_str.length()); str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - str->qs_append(link_id); + if (static_link_id) + { + str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); + str->append_for_single_quote(static_link_id, static_link_id_length); + str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); + } else { + str->qs_append(link_id); + } str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); str->qs_append(flags); str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); @@ -9524,17 +10223,17 @@ int spider_db_udf_ping_table_mon_next( SPIDER_SHARE *share = table_mon->share; int init_sql_alloc_size = spider_param_init_sql_alloc_size(thd, share->init_sql_alloc_size); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_string sql_str(init_sql_alloc_size); - sql_str.set_charset(thd->variables.character_set_client); -#else - char sql_buf[init_sql_alloc_size]; - spider_string sql_str(sql_buf, sizeof(sql_buf), - thd->variables.character_set_client); -#endif ha_spider spider; SPIDER_TRX trx; DBUG_ENTER("spider_db_udf_ping_table_mon_next"); + char *sql_buf = (char *) my_alloca(init_sql_alloc_size); + if (!sql_buf) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + spider_string sql_str(sql_buf, sizeof(sql_buf), + thd->variables.character_set_client); sql_str.init_calc_mem(132); sql_str.length(0); trx.thd = thd; @@ -9545,11 +10244,15 @@ int spider_db_udf_ping_table_mon_next( share->access_charset = thd->variables.character_set_client; if ((error_num = spider_db_udf_ping_table_append_mon_next(&sql_str, - child_table_name, child_table_name_length, link_id, where_clause, + child_table_name, child_table_name_length, link_id, + table_mon->parent->share->static_link_ids[0], + table_mon->parent->share->static_link_ids_lengths[0], + where_clause, where_clause_length, first_sid, full_mon_count, current_mon_count, success_count, fault_count, flags, limit))) { my_error(error_num, MYF(0)); + my_afree(sql_buf); DBUG_RETURN(error_num); } @@ -9566,6 +10269,7 @@ int spider_db_udf_ping_table_mon_next( pthread_mutex_unlock(&conn->mta_conn_mutex); my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), share->server_names[0]); + my_afree(sql_buf); DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE); } if ((error_num = spider_db_set_names(&spider, conn, 0))) @@ -9574,6 +10278,7 @@ int spider_db_udf_ping_table_mon_next( conn->mta_conn_mutex_unlock_later = FALSE; SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); pthread_mutex_unlock(&conn->mta_conn_mutex); + my_afree(sql_buf); DBUG_RETURN(error_num); } spider_conn_set_timeout_from_share(conn, 0, thd, share); @@ -9586,6 +10291,7 @@ int spider_db_udf_ping_table_mon_next( ) { conn->mta_conn_mutex_lock_already = FALSE; conn->mta_conn_mutex_unlock_later = FALSE; + my_afree(sql_buf); DBUG_RETURN(spider_db_errorno(conn)); } st_spider_db_request_key request_key; @@ -9599,14 +10305,19 @@ int spider_db_udf_ping_table_mon_next( conn->mta_conn_mutex_lock_already = FALSE; conn->mta_conn_mutex_unlock_later = FALSE; if (error_num || (error_num = spider_db_errorno(conn))) + { + my_afree(sql_buf); DBUG_RETURN(error_num); + } my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + my_afree(sql_buf); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } conn->mta_conn_mutex_lock_already = FALSE; conn->mta_conn_mutex_unlock_later = FALSE; SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); pthread_mutex_unlock(&conn->mta_conn_mutex); + my_afree(sql_buf); error_num = res->fetch_table_mon_status(mon_table_result->result_status); res->free_result(); delete res; diff --git a/storage/spider/spd_db_conn.h b/storage/spider/spd_db_conn.h index ab6826d0157..7977e61da58 100644 --- a/storage/spider/spd_db_conn.h +++ b/storage/spider/spd_db_conn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define SPIDER_DB_WRAPPER_STR "mysql" #define SPIDER_DB_WRAPPER_LEN (sizeof(SPIDER_DB_WRAPPER_STR) - 1) @@ -192,6 +192,8 @@ #define SPIDER_SQL_PF_EQUAL_LEN (sizeof(SPIDER_SQL_PF_EQUAL_STR) - 1) #define SPIDER_SQL_GROUP_STR " group by " #define SPIDER_SQL_GROUP_LEN (sizeof(SPIDER_SQL_GROUP_STR) - 1) +#define SPIDER_SQL_HAVING_STR " having " +#define SPIDER_SQL_HAVING_LEN (sizeof(SPIDER_SQL_HAVING_STR) - 1) #define SPIDER_SQL_PLUS_STR " + " #define SPIDER_SQL_PLUS_LEN (sizeof(SPIDER_SQL_PLUS_STR) - 1) #define SPIDER_SQL_MINUS_STR " - " @@ -250,6 +252,13 @@ #define SPIDER_SQL_B_STR "b" #define SPIDER_SQL_B_LEN (sizeof(SPIDER_SQL_B_STR) - 1) +#define SPIDER_SQL_INDEX_IGNORE_STR " IGNORE INDEX " +#define SPIDER_SQL_INDEX_IGNORE_LEN (sizeof(SPIDER_SQL_INDEX_IGNORE_STR) - 1) +#define SPIDER_SQL_INDEX_USE_STR " USE INDEX " +#define SPIDER_SQL_INDEX_USE_LEN (sizeof(SPIDER_SQL_INDEX_USE_STR) - 1) +#define SPIDER_SQL_INDEX_FORCE_STR " FORCE INDEX " +#define SPIDER_SQL_INDEX_FORCE_LEN (sizeof(SPIDER_SQL_INDEX_FORCE_STR) - 1) + #define SPIDER_SQL_INT_LEN 20 #define SPIDER_SQL_HANDLER_CID_LEN 6 #define SPIDER_SQL_HANDLER_CID_FORMAT "t%05u" @@ -263,6 +272,13 @@ int spider_db_connect( int link_idx ); +int spider_db_ping_internal( + SPIDER_SHARE *share, + SPIDER_CONN *conn, + int all_link_idx, + int *need_mon +); + int spider_db_ping( ha_spider *spider, SPIDER_CONN *conn, @@ -729,6 +745,7 @@ int spider_db_update( ); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int spider_db_direct_update( ha_spider *spider, TABLE *table, @@ -736,6 +753,13 @@ int spider_db_direct_update( uint range_count, ha_rows *update_rows ); +#else +int spider_db_direct_update( + ha_spider *spider, + TABLE *table, + ha_rows *update_rows +); +#endif #endif #ifdef HA_CAN_BULK_ACCESS @@ -758,6 +782,7 @@ int spider_db_delete( ); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS int spider_db_direct_delete( ha_spider *spider, TABLE *table, @@ -765,6 +790,13 @@ int spider_db_direct_delete( uint range_count, ha_rows *delete_rows ); +#else +int spider_db_direct_delete( + ha_spider *spider, + TABLE *table, + ha_rows *delete_rows +); +#endif #endif int spider_db_delete_all_rows( @@ -812,7 +844,9 @@ int spider_db_print_item_type( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_cond( @@ -821,7 +855,9 @@ int spider_db_open_item_cond( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_func( @@ -830,7 +866,9 @@ int spider_db_open_item_func( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); #ifdef HANDLER_HAS_DIRECT_AGGREGATE @@ -840,7 +878,9 @@ int spider_db_open_item_sum_func( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); #endif @@ -850,7 +890,9 @@ int spider_db_open_item_ident( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_field( @@ -859,7 +901,9 @@ int spider_db_open_item_field( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_ref( @@ -868,7 +912,9 @@ int spider_db_open_item_ref( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_row( @@ -877,7 +923,9 @@ int spider_db_open_item_row( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_string( @@ -886,7 +934,9 @@ int spider_db_open_item_string( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_int( @@ -895,7 +945,9 @@ int spider_db_open_item_int( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_cache( @@ -904,7 +956,9 @@ int spider_db_open_item_cache( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_open_item_insert_value( @@ -913,7 +967,9 @@ int spider_db_open_item_insert_value( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); int spider_db_append_condition( @@ -929,7 +985,9 @@ int spider_db_append_update_columns( spider_string *str, const char *alias, uint alias_length, - uint dbton_id + uint dbton_id, + bool use_fields, + spider_fields *fields ); #endif diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc index 6e4a5dcc5ec..dc4b9dd25ec 100644 --- a/storage/spider/spd_db_handlersocket.cc +++ b/storage/spider/spd_db_handlersocket.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2014 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -40,6 +40,7 @@ extern handlerton *spider_hton_ptr; extern HASH spider_open_connections; +extern HASH spider_ipport_conns; extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; extern const char spider_dig_upper[]; @@ -107,6 +108,12 @@ SPIDER_DB_CONN *spider_handlersocket_create_conn( DBUG_RETURN(new spider_db_handlersocket(conn)); } +bool spider_handlersocket_support_direct_join( +) { + DBUG_ENTER("spider_handlersocket_support_direct_join"); + DBUG_RETURN(FALSE); +} + spider_db_handlersocket_util spider_db_handlersocket_utility; SPIDER_DBTON spider_dbton_handlersocket = { @@ -119,6 +126,7 @@ SPIDER_DBTON spider_dbton_handlersocket = { spider_handlersocket_create_handler, NULL, spider_handlersocket_create_conn, + spider_handlersocket_support_direct_join, &spider_db_handlersocket_utility }; @@ -591,7 +599,8 @@ bool spider_db_handlersocket_result_buffer::check_size( } spider_db_handlersocket_result::spider_db_handlersocket_result( -) : spider_db_result(spider_dbton_handlersocket.dbton_id) + SPIDER_DB_CONN *in_db_conn +) : spider_db_result(in_db_conn, spider_dbton_handlersocket.dbton_id) { DBUG_ENTER("spider_db_handlersocket_result::spider_db_handlersocket_result"); DBUG_PRINT("info",("spider this=%p", this)); @@ -1228,7 +1237,7 @@ spider_db_result *spider_db_handlersocket::store_result( *spider_res_buf = (spider_db_result_buffer *) hs_res_buf; } hs_res_buf->clear(); - if (!(result = new spider_db_handlersocket_result())) + if (!(result = new spider_db_handlersocket_result(this))) { *error_num = HA_ERR_OUT_OF_MEM; DBUG_RETURN(NULL); @@ -1438,7 +1447,7 @@ spider_db_result *spider_db_handlersocket::use_result( spider_db_handlersocket_result *result; DBUG_ENTER("spider_db_handlersocket::use_result"); DBUG_PRINT("info",("spider this=%p", this)); - if (!(result = new spider_db_handlersocket_result())) + if (!(result = new spider_db_handlersocket_result(this))) { *error_num = HA_ERR_OUT_OF_MEM; DBUG_RETURN(NULL); @@ -1841,6 +1850,22 @@ int spider_db_handlersocket::set_time_zone( DBUG_RETURN(0); } +int spider_db_handlersocket::show_master_status( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + int mode, + SPIDER_DB_RESULT **res1, + SPIDER_DB_RESULT **res2 +) { + DBUG_ENTER("spider_db_handlersocket::show_master_status"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN(0); +} + int spider_db_handlersocket::append_sql( char *sql, ulong sql_length, @@ -2721,7 +2746,9 @@ int spider_db_handlersocket_util::open_item_func( ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) { uint dbton_id = spider_dbton_handlersocket.dbton_id; int error_num; @@ -2734,6 +2761,7 @@ int spider_db_handlersocket_util::open_item_func( separete_str_length = SPIDER_SQL_NULL_CHAR_LEN, last_str_length = SPIDER_SQL_NULL_CHAR_LEN; int use_pushdown_udf; + bool merge_func = FALSE; DBUG_ENTER("spider_db_handlersocket_util::open_item_func"); if (str) { @@ -2797,7 +2825,7 @@ int spider_db_handlersocket_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_int(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if ( !strncasecmp("case", func_name, func_name_length) ) { @@ -2813,7 +2841,7 @@ int spider_db_handlersocket_util::open_item_func( { if ((error_num = spider_db_print_item_type( item_list[item_func_case->first_expr_num], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } for (roop_count = 0; roop_count < item_func_case->ncases; @@ -2827,7 +2855,7 @@ int spider_db_handlersocket_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[roop_count], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -2837,7 +2865,7 @@ int spider_db_handlersocket_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[roop_count + 1], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (item_func_case->else_expr_num != -1) @@ -2850,7 +2878,7 @@ int spider_db_handlersocket_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[item_func_case->else_expr_num], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (str) @@ -2887,7 +2915,7 @@ int spider_db_handlersocket_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if ( !strncasecmp("convert", func_name, func_name_length) ) { @@ -2912,41 +2940,110 @@ int spider_db_handlersocket_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if (func_name_length == 9 && !strncasecmp("isnottrue", func_name, func_name_length) ) { last_str = SPIDER_SQL_IS_NOT_TRUE_STR; last_str_length = SPIDER_SQL_IS_NOT_TRUE_LEN; break; - } else if (func_name_length == 10 && - !strncasecmp("isnotfalse", func_name, func_name_length) - ) { - last_str = SPIDER_SQL_IS_NOT_FALSE_STR; - last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN; - break; + } else if (func_name_length == 10) + { + if (!strncasecmp("isnotfalse", func_name, func_name_length)) + { + last_str = SPIDER_SQL_IS_NOT_FALSE_STR; + last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN; + break; + } else if (!strncasecmp("column_get", func_name, func_name_length)) + { + if (str) + { + str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); + if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(func_name, func_name_length); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); + } + func_name = SPIDER_SQL_COMMA_STR; + func_name_length = SPIDER_SQL_COMMA_LEN; + separete_str = SPIDER_SQL_COMMA_STR; + separete_str_length = SPIDER_SQL_COMMA_LEN; + break; + } } else if (func_name_length == 12) { if (!strncasecmp("cast_as_date", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_DATE_STR; last_str_length = SPIDER_SQL_AS_DATE_LEN; break; } else if (!strncasecmp("cast_as_time", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_TIME_STR; last_str_length = SPIDER_SQL_AS_TIME_LEN; @@ -2959,7 +3056,7 @@ int spider_db_handlersocket_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if (!strncasecmp("timestampdiff", func_name, func_name_length)) { #ifdef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC @@ -3022,7 +3119,7 @@ int spider_db_handlersocket_util::open_item_func( str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } if ((error_num = spider_db_print_item_type(item_list[0], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3031,7 +3128,7 @@ int spider_db_handlersocket_util::open_item_func( str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } if ((error_num = spider_db_print_item_type(item_list[1], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3049,6 +3146,29 @@ int spider_db_handlersocket_util::open_item_func( { if (!strncasecmp("cast_as_binary", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3056,9 +3176,12 @@ int spider_db_handlersocket_util::open_item_func( tmp_str.init_calc_mem(123); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3077,12 +3200,38 @@ int spider_db_handlersocket_util::open_item_func( break; } else if (!strncasecmp("cast_as_signed", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_SIGNED_STR; last_str_length = SPIDER_SQL_AS_SIGNED_LEN; @@ -3092,12 +3241,38 @@ int spider_db_handlersocket_util::open_item_func( { if (!strncasecmp("cast_as_unsigned", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_UNSIGNED_STR; last_str_length = SPIDER_SQL_AS_UNSIGNED_LEN; @@ -3105,6 +3280,29 @@ int spider_db_handlersocket_util::open_item_func( } else if (!strncasecmp("decimal_typecast", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3112,9 +3310,12 @@ int spider_db_handlersocket_util::open_item_func( tmp_str.init_calc_mem(124); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3134,12 +3335,38 @@ int spider_db_handlersocket_util::open_item_func( } else if (!strncasecmp("cast_as_datetime", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_DATETIME_STR; last_str_length = SPIDER_SQL_AS_DATETIME_LEN; @@ -3155,7 +3382,7 @@ int spider_db_handlersocket_util::open_item_func( item_date_add_interval->int_type]; func_name_length = strlen(func_name); if ((error_num = spider_db_print_item_type(item_list[0], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3172,7 +3399,7 @@ int spider_db_handlersocket_util::open_item_func( } } if ((error_num = spider_db_print_item_type(item_list[1], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3203,9 +3430,33 @@ int spider_db_handlersocket_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::CHAR_TYPECAST_FUNC: + DBUG_PRINT("info",("spider CHAR_TYPECAST_FUNC")); { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3213,9 +3464,12 @@ int spider_db_handlersocket_util::open_item_func( tmp_str.init_calc_mem(125); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3248,12 +3502,15 @@ int spider_db_handlersocket_util::open_item_func( bool has_other_item = FALSE; while((item = lif++)) { +#ifdef SPIDER_HAS_EXPR_CACHE_ITEM if ( item->type() == Item::EXPR_CACHE_ITEM ) { DBUG_PRINT("info",("spider EXPR_CACHE_ITEM")); has_expr_cache_item = TRUE; - } else if ( + } else +#endif + if ( item->type() == Item::FUNC_ITEM && ((Item_func *) item)->functype() == Item_func::ISNOTNULL_FUNC ) { @@ -3357,7 +3614,7 @@ int spider_db_handlersocket_util::open_item_func( str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN( spider_db_open_item_cond((Item_cond *) item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::TRIG_COND_FUNC: DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); case Item_func::GUSERVAR_FUNC: @@ -3365,10 +3622,10 @@ int spider_db_handlersocket_util::open_item_func( str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (item_func->result_type() == STRING_RESULT) DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); else DBUG_RETURN(spider_db_open_item_int(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::FT_FUNC: if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY) DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); @@ -3474,7 +3731,7 @@ int spider_db_handlersocket_util::open_item_func( { item = item_list[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (roop_count == 1) { @@ -3492,7 +3749,7 @@ int spider_db_handlersocket_util::open_item_func( } item = item_list[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (item_func->functype() == Item_func::FT_FUNC) @@ -3506,7 +3763,7 @@ int spider_db_handlersocket_util::open_item_func( } item = item_list[0]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3534,7 +3791,8 @@ int spider_db_handlersocket_util::open_item_func( { Item_func_conv_charset *item_func_conv_charset = (Item_func_conv_charset *)item_func; - CHARSET_INFO *conv_charset = item_func_conv_charset->conv_charset; + CHARSET_INFO *conv_charset = + item_func_conv_charset->SPIDER_Item_func_conv_charset_conv_charset; uint cset_length = strlen(conv_charset->csname); if (str->reserve(SPIDER_SQL_USING_LEN + cset_length)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -3545,6 +3803,8 @@ int spider_db_handlersocket_util::open_item_func( } if (str) { + if (merge_func) + str->length(str->length() - SPIDER_SQL_CLOSE_PAREN_LEN); if (str->reserve(last_str_length + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(last_str, last_str_length); @@ -3559,7 +3819,9 @@ int spider_db_handlersocket_util::open_item_sum_func( ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) { uint dbton_id = spider_dbton_handlersocket.dbton_id; uint roop_count, item_count = item_sum->get_arg_count(); @@ -3589,7 +3851,7 @@ int spider_db_handlersocket_util::open_item_sum_func( { item = args[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3600,7 +3862,7 @@ int spider_db_handlersocket_util::open_item_sum_func( } item = args[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (str) @@ -3638,6 +3900,47 @@ int spider_db_handlersocket_util::append_escaped_util( DBUG_RETURN(0); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_db_handlersocket_util::append_from_and_tables( + spider_fields *fields, + spider_string *str +) { + DBUG_ENTER("spider_db_handlersocket_util::append_from_and_tables"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_db_handlersocket_util::reappend_tables( + spider_fields *fields, + SPIDER_LINK_IDX_CHAIN *link_idx_chain, + spider_string *str +) { + DBUG_ENTER("spider_db_handlersocket_util::reappend_tables"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_db_handlersocket_util::append_where( + spider_string *str +) { + DBUG_ENTER("spider_db_handlersocket_util::append_where"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_db_handlersocket_util::append_having( + spider_string *str +) { + DBUG_ENTER("spider_db_handlersocket_util::append_having"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} +#endif + spider_handlersocket_share::spider_handlersocket_share( st_spider_share *share ) : spider_db_share( @@ -4053,6 +4356,16 @@ int spider_handlersocket_handler::init() DBUG_RETURN(0); } +int spider_handlersocket_handler::append_index_hint( + spider_string *str, + int link_idx, + ulong sql_type + ) +{ + DBUG_ENTER("spider_handlersocket_handler::append_index_hint"); + DBUG_RETURN(0); +} + int spider_handlersocket_handler::append_table_name_with_adjusting( spider_string *str, int link_idx, @@ -5000,7 +5313,7 @@ int spider_handlersocket_handler::is_sole_projection_field( uint16 field_index ) { DBUG_ENTER("spider_handlersocket_handler::is_sole_projection_field"); - DBUG_PRINT("info", ("spider this=%p", this)); + DBUG_PRINT("info",("spider this=%p", this)); DBUG_ASSERT(0); DBUG_RETURN(0); } @@ -5367,6 +5680,19 @@ bool spider_handlersocket_handler::need_lock_before_set_sql_for_exec( DBUG_RETURN(TRUE); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_handlersocket_handler::set_sql_for_exec( + ulong sql_type, + int link_idx, + SPIDER_LINK_IDX_CHAIN *link_idx_chain +) { + DBUG_ENTER("spider_handlersocket_handler::set_sql_for_exec"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} +#endif + int spider_handlersocket_handler::set_sql_for_exec( ulong sql_type, int link_idx @@ -5444,7 +5770,7 @@ int spider_handlersocket_handler::show_table_status( int sts_mode, uint flag ) { - spider_db_handlersocket_result res; + spider_db_handlersocket_result res(NULL); SPIDER_SHARE *share = spider->share; ulonglong auto_increment_value = 0; DBUG_ENTER("spider_handlersocket_show_table_status"); @@ -5792,4 +6118,100 @@ int spider_handlersocket_handler::reset_union_table_name( DBUG_ASSERT(0); DBUG_RETURN(0); } + +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_handlersocket_handler::append_list_item_select_part( + List<Item> *select, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::append_list_item_select_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_handlersocket_handler::append_from_and_tables_part( + spider_fields *fields, + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::append_from_and_tables_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_handlersocket_handler::reappend_tables_part( + spider_fields *fields, + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::reappend_tables_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_handlersocket_handler::append_where_part( + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::append_where_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_handlersocket_handler::append_having_part( + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::append_having_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_handlersocket_handler::append_item_type_part( + Item *item, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::append_item_type_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_handlersocket_handler::append_group_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::append_group_by_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + +int spider_handlersocket_handler::append_order_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + DBUG_ENTER("spider_handlersocket_handler::append_order_by_part"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} +#endif #endif diff --git a/storage/spider/spd_db_handlersocket.h b/storage/spider/spd_db_handlersocket.h index a3955aea044..19138b22e1a 100644 --- a/storage/spider/spd_db_handlersocket.h +++ b/storage/spider/spd_db_handlersocket.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2014 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define SPIDER_HS_CONN dena::hstcpcli_ptr #define SPIDER_HS_CONN_CREATE dena::hstcpcli_i::create @@ -94,7 +94,9 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ); #ifdef HANDLER_HAS_DIRECT_AGGREGATE int open_item_sum_func( @@ -102,13 +104,36 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ); #endif int append_escaped_util( spider_string *to, String *from ); + int append_escaped_util( + spider_string *to, + String *from + ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int append_from_and_tables( + spider_fields *fields, + spider_string *str + ); + int reappend_tables( + spider_fields *fields, + SPIDER_LINK_IDX_CHAIN *link_idx_chain, + spider_string *str + ); + int append_where( + spider_string *str + ); + int append_having( + spider_string *str + ); +#endif }; class spider_db_handlersocket_row: public spider_db_row @@ -167,7 +192,7 @@ public: SPIDER_HS_STRING_REF hs_row; uint field_count; int store_error_num; - spider_db_handlersocket_result(); + spider_db_handlersocket_result(SPIDER_DB_CONN *in_db_conn); ~spider_db_handlersocket_result(); bool has_result(); void free_result(); @@ -355,6 +380,17 @@ public: Time_zone *time_zone, int *need_mon ); + int show_master_status( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + int mode, + SPIDER_DB_RESULT **res1, + SPIDER_DB_RESULT **res2 + ); int append_sql( char *sql, ulong sql_length, @@ -505,6 +541,11 @@ public: ); ~spider_handlersocket_handler(); int init(); + int append_index_hint( + spider_string *str, + int link_idx, + ulong sql_type + ); int append_table_name_with_adjusting( spider_string *str, int link_idx, @@ -849,6 +890,13 @@ public: bool need_lock_before_set_sql_for_exec( ulong sql_type ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int set_sql_for_exec( + ulong sql_type, + int link_idx, + SPIDER_LINK_IDX_CHAIN *link_idx_chain + ); +#endif int set_sql_for_exec( ulong sql_type, int link_idx @@ -960,4 +1008,52 @@ public: int link_idx, ulong sql_type ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int append_from_and_tables_part( + spider_fields *fields, + ulong sql_type + ); + int reappend_tables_part( + spider_fields *fields, + ulong sql_type + ); + int append_where_part( + ulong sql_type + ); + int append_having_part( + ulong sql_type + ); + int append_item_type_part( + Item *item, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_list_item_select_part( + List<Item> *select, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_group_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_order_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); +#endif }; diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index 56bc2ccad42..2913f911587 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2014 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,15 +11,29 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hs_compat.h" #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) #include "hstcpcli.hpp" #endif +#define SPIDER_DBTON_SIZE 15 + #define SPIDER_DB_WRAPPER_MYSQL "mysql" +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100204 +#define PLUGIN_VAR_CAN_MEMALLOC +/* +#define ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC +#define HASH_UPDATE_WITH_HASH_VALUE +*/ +#else +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS +#define HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS +#endif +#endif + #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002 #define SPIDER_HAS_DISCOVER_TABLE_STRUCTURE #define SPIDER_HAS_APPEND_FOR_SINGLE_QUOTE @@ -31,7 +45,6 @@ #endif #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100007 -#define SPIDER_HAS_DISCOVER_TABLE_STRUCTURE_COMMENT #define SPIDER_ITEM_HAS_CMP_TYPE #endif @@ -47,6 +60,14 @@ #endif #endif +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108 +#define SPIDER_HAS_GROUP_BY_HANDLER +#endif + +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100200 +#define SPIDER_ORDER_HAS_ENUM_ORDER +#endif + #if defined(MARIADB_BASE_VERSION) #define SPIDER_ITEM_GEOFUNC_NAME_HAS_MBR #define SPIDER_HANDLER_AUTO_REPAIR_HAS_ERROR @@ -182,32 +203,32 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_LCL_NAME_QUOTE_STR "`" #define SPIDER_SQL_LCL_NAME_QUOTE_LEN (sizeof(SPIDER_SQL_LCL_NAME_QUOTE_STR) - 1) -#define SPIDER_CONN_KIND_MYSQL (1U << 0) +#define SPIDER_CONN_KIND_MYSQL (1 << 0) #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#define SPIDER_CONN_KIND_HS_READ (1U << 2) -#define SPIDER_CONN_KIND_HS_WRITE (1U << 3) +#define SPIDER_CONN_KIND_HS_READ (1 << 2) +#define SPIDER_CONN_KIND_HS_WRITE (1 << 3) #endif -#define SPIDER_SQL_KIND_SQL (1U << 0) -#define SPIDER_SQL_KIND_HANDLER (1U << 1) +#define SPIDER_SQL_KIND_SQL (1 << 0) +#define SPIDER_SQL_KIND_HANDLER (1 << 1) #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#define SPIDER_SQL_KIND_HS (1U << 2) +#define SPIDER_SQL_KIND_HS (1 << 2) #endif -#define SPIDER_SQL_TYPE_SELECT_SQL (1U << 0) -#define SPIDER_SQL_TYPE_INSERT_SQL (1U << 1) -#define SPIDER_SQL_TYPE_UPDATE_SQL (1U << 2) -#define SPIDER_SQL_TYPE_DELETE_SQL (1U << 3) -#define SPIDER_SQL_TYPE_BULK_UPDATE_SQL (1U << 4) -#define SPIDER_SQL_TYPE_TMP_SQL (1U << 5) -#define SPIDER_SQL_TYPE_DROP_TMP_TABLE_SQL (1U << 6) -#define SPIDER_SQL_TYPE_OTHER_SQL (1U << 7) -#define SPIDER_SQL_TYPE_HANDLER (1U << 8) -#define SPIDER_SQL_TYPE_SELECT_HS (1U << 9) -#define SPIDER_SQL_TYPE_INSERT_HS (1U << 10) -#define SPIDER_SQL_TYPE_UPDATE_HS (1U << 11) -#define SPIDER_SQL_TYPE_DELETE_HS (1U << 12) -#define SPIDER_SQL_TYPE_OTHER_HS (1U << 13) +#define SPIDER_SQL_TYPE_SELECT_SQL (1 << 0) +#define SPIDER_SQL_TYPE_INSERT_SQL (1 << 1) +#define SPIDER_SQL_TYPE_UPDATE_SQL (1 << 2) +#define SPIDER_SQL_TYPE_DELETE_SQL (1 << 3) +#define SPIDER_SQL_TYPE_BULK_UPDATE_SQL (1 << 4) +#define SPIDER_SQL_TYPE_TMP_SQL (1 << 5) +#define SPIDER_SQL_TYPE_DROP_TMP_TABLE_SQL (1 << 6) +#define SPIDER_SQL_TYPE_OTHER_SQL (1 << 7) +#define SPIDER_SQL_TYPE_HANDLER (1 << 8) +#define SPIDER_SQL_TYPE_SELECT_HS (1 << 9) +#define SPIDER_SQL_TYPE_INSERT_HS (1 << 10) +#define SPIDER_SQL_TYPE_UPDATE_HS (1 << 11) +#define SPIDER_SQL_TYPE_DELETE_HS (1 << 12) +#define SPIDER_SQL_TYPE_OTHER_HS (1 << 13) enum spider_bulk_upd_start { SPD_BU_NOT_START, @@ -531,6 +552,169 @@ public: bool is_ascii() const; }; +typedef struct spider_table_link_idx_holder SPIDER_TABLE_LINK_IDX_HOLDER; +typedef struct spider_table_holder SPIDER_TABLE_HOLDER; + +typedef struct spider_link_idx_holder +{ + spider_table_link_idx_holder *table_link_idx_holder; + int link_idx; + int link_status; + spider_link_idx_holder *next_table; + spider_link_idx_holder *next; +} SPIDER_LINK_IDX_HOLDER; + +typedef struct spider_link_idx_chain +{ + SPIDER_CONN *conn; + spider_link_idx_holder *link_idx_holder; + spider_link_idx_holder *current_link_idx_holder; + int link_status; + spider_link_idx_chain *next; +} SPIDER_LINK_IDX_CHAIN; + +typedef struct spider_table_link_idx_holder +{ + spider_table_holder *table_holder; + spider_link_idx_holder *first_link_idx_holder; + spider_link_idx_holder *last_link_idx_holder; + spider_link_idx_holder *current_link_idx_holder; + uint link_idx_holder_count; +} SPIDER_TABLE_LINK_IDX_HOLDER; + +typedef struct spider_conn_holder +{ + SPIDER_CONN *conn; + spider_table_link_idx_holder *table_link_idx_holder; + uint link_idx_holder_count_max; + bool checked_for_same_conn; + long access_balance; + spider_conn_holder *prev; + spider_conn_holder *next; +} SPIDER_CONN_HOLDER; + +typedef struct spider_table_holder +{ + TABLE *table; + ha_spider *spider; + spider_string *alias; +} SPIDER_TABLE_HOLDER; + +typedef struct spider_field_holder +{ + Field *field; + ha_spider *spider; + spider_string *alias; + spider_field_holder *next; +} SPIDER_FIELD_HOLDER; + +typedef struct spider_field_chain +{ + spider_field_holder *field_holder; + spider_field_chain *next; +} SPIDER_FIELD_CHAIN; + +class spider_fields +{ + uint dbton_count; + uint current_dbton_num; + uint dbton_ids[SPIDER_DBTON_SIZE]; + uint table_count; + uint current_table_num; + SPIDER_TABLE_HOLDER *table_holder; + SPIDER_LINK_IDX_CHAIN *first_link_idx_chain; + SPIDER_LINK_IDX_CHAIN *last_link_idx_chain; + SPIDER_LINK_IDX_CHAIN *current_link_idx_chain; + SPIDER_LINK_IDX_CHAIN *first_ok_link_idx_chain; + SPIDER_CONN_HOLDER *first_conn_holder; + SPIDER_CONN_HOLDER *last_conn_holder; + SPIDER_CONN_HOLDER *current_conn_holder; + SPIDER_FIELD_HOLDER *first_field_holder; + SPIDER_FIELD_HOLDER *last_field_holder; + SPIDER_FIELD_HOLDER *current_field_holder; + SPIDER_FIELD_CHAIN *first_field_chain; + SPIDER_FIELD_CHAIN *last_field_chain; + SPIDER_FIELD_CHAIN *current_field_chain; + Field **first_field_ptr; + Field **current_field_ptr; +public: + spider_fields(); + virtual ~spider_fields(); + void add_dbton_id( + uint dbton_id_arg + ); + void set_pos_to_first_dbton_id(); + uint get_next_dbton_id(); + int make_link_idx_chain( + int link_status + ); + SPIDER_LINK_IDX_CHAIN *create_link_idx_chain(); + void set_pos_to_first_link_idx_chain(); + SPIDER_LINK_IDX_CHAIN *get_next_link_idx_chain(); + SPIDER_LINK_IDX_HOLDER *get_dup_link_idx_holder( + SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder, + SPIDER_LINK_IDX_HOLDER *current + ); + bool check_link_ok_chain(); + bool is_first_link_ok_chain( + SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg + ); + int get_ok_link_idx(); + void set_first_link_idx(); + int add_link_idx( + SPIDER_CONN_HOLDER *conn_holder_arg, + ha_spider *spider_arg, + int link_idx + ); + SPIDER_LINK_IDX_HOLDER *create_link_idx_holder(); + void set_pos_to_first_table_on_link_idx_chain( + SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg + ); + SPIDER_LINK_IDX_HOLDER *get_next_table_on_link_idx_chain( + SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg + ); + SPIDER_CONN_HOLDER *add_conn( + SPIDER_CONN *conn_arg, + long access_balance + ); + SPIDER_CONN_HOLDER *create_conn_holder(); + void set_pos_to_first_conn_holder(); + SPIDER_CONN_HOLDER *get_next_conn_holder(); + bool has_conn_holder(); + void clear_conn_holder_from_conn(); + bool check_conn_same_conn( + SPIDER_CONN *conn_arg + ); + bool remove_conn_if_not_checked(); + void check_support_dbton( + uchar *dbton_bitmap + ); + void choose_a_conn(); + void free_conn_holder( + SPIDER_CONN_HOLDER *conn_holder_arg + ); + SPIDER_TABLE_HOLDER *add_table( + ha_spider *spider_arg + ); + int create_table_holder( + uint table_count_arg + ); + void set_pos_to_first_table_holder(); + SPIDER_TABLE_HOLDER *get_next_table_holder(); + int add_field(Field *field_arg); + SPIDER_FIELD_HOLDER *create_field_holder(); + void set_pos_to_first_field_holder(); + SPIDER_FIELD_HOLDER *get_next_field_holder(); + SPIDER_FIELD_CHAIN *create_field_chain(); + void set_pos_to_first_field_chain(); + SPIDER_FIELD_CHAIN *get_next_field_chain(); + void set_field_ptr(Field **field_arg); + Field **get_next_field_ptr(); + int ping_table_mon_from_table( + SPIDER_LINK_IDX_CHAIN *link_idx_chain + ); +}; + #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) #define SPIDER_HS_UINT32_INFO dena::uint32_info #define SPIDER_HS_STRING_REF dena::string_ref @@ -681,7 +865,9 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) = 0; #ifdef HANDLER_HAS_DIRECT_AGGREGATE virtual int open_item_sum_func( @@ -689,13 +875,32 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) = 0; #endif virtual int append_escaped_util( spider_string *to, String *from ) = 0; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + virtual int append_from_and_tables( + spider_fields *fields, + spider_string *str + ) = 0; + virtual int reappend_tables( + spider_fields *fields, + SPIDER_LINK_IDX_CHAIN *link_idx_chain, + spider_string *str + ) = 0; + virtual int append_where( + spider_string *str + ) = 0; + virtual int append_having( + spider_string *str + ) = 0; +#endif }; class spider_db_row @@ -745,9 +950,12 @@ public: class spider_db_result { +protected: + SPIDER_DB_CONN *db_conn; public: uint dbton_id; - spider_db_result(uint in_dbton_id) : dbton_id(in_dbton_id) {} + spider_db_result(SPIDER_DB_CONN *in_db_conn, uint in_dbton_id) : + db_conn(in_db_conn), dbton_id(in_dbton_id) {} virtual ~spider_db_result() {} virtual bool has_result() = 0; virtual void free_result() = 0; @@ -922,6 +1130,17 @@ public: Time_zone *time_zone, int *need_mon ) = 0; + virtual int show_master_status( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + int mode, + SPIDER_DB_RESULT **res1, + SPIDER_DB_RESULT **res2 + ) = 0; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) virtual int append_sql( char *sql, @@ -1041,10 +1260,18 @@ public: ha_spider *spider; spider_db_share *db_share; int first_link_idx; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + SPIDER_LINK_IDX_CHAIN *link_idx_chain; +#endif spider_db_handler(ha_spider *spider, spider_db_share *db_share) : spider(spider), db_share(db_share), first_link_idx(-1) {} virtual ~spider_db_handler() {} virtual int init() = 0; + virtual int append_index_hint( + spider_string *str, + int link_idx, + ulong sql_type + ) = 0; virtual int append_table_name_with_adjusting( spider_string *str, int link_idx, @@ -1104,6 +1331,10 @@ public: virtual int append_select_part( ulong sql_type ) = 0; + virtual int append_select( + spider_string *str, + ulong sql_type + ) = 0; virtual int append_table_select_part( ulong sql_type ) = 0; @@ -1280,7 +1511,7 @@ public: int link_idx ) = 0; virtual bool is_sole_projection_field( - uint16 field_index + uint16 field_index ) = 0; virtual bool is_bulk_insert_exec_period( bool bulk_end @@ -1342,6 +1573,13 @@ public: virtual bool need_lock_before_set_sql_for_exec( ulong sql_type ) = 0; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + virtual int set_sql_for_exec( + ulong sql_type, + int link_idx, + SPIDER_LINK_IDX_CHAIN *link_idx_chain + ) = 0; +#endif virtual int set_sql_for_exec( ulong sql_type, int link_idx @@ -1452,6 +1690,54 @@ public: int link_idx, ulong sql_type ) = 0; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + virtual int append_from_and_tables_part( + spider_fields *fields, + ulong sql_type + ) = 0; + virtual int reappend_tables_part( + spider_fields *fields, + ulong sql_type + ) = 0; + virtual int append_where_part( + ulong sql_type + ) = 0; + virtual int append_having_part( + ulong sql_type + ) = 0; + virtual int append_item_type_part( + Item *item, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ) = 0; + virtual int append_list_item_select_part( + List<Item> *select, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ) = 0; + virtual int append_group_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ) = 0; + virtual int append_order_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ) = 0; +#endif }; class spider_db_copy_table @@ -1539,9 +1825,9 @@ typedef struct st_spider_dbton spider_db_copy_table *(*create_db_copy_table)( spider_db_share *db_share); SPIDER_DB_CONN *(*create_db_conn)(SPIDER_CONN *conn); + bool (*support_direct_join)(); spider_db_util *db_util; } SPIDER_DBTON; -#define SPIDER_DBTON_SIZE 15 typedef struct st_spider_position { @@ -1661,6 +1947,8 @@ typedef struct st_spider_result_list spider_bulk_upd_start bulk_update_start; bool check_direct_order_limit; bool direct_order_limit; + /* the limit_offeset, without where condition */ + bool direct_limit_offset; bool direct_distinct; #ifdef HANDLER_HAS_DIRECT_AGGREGATE bool direct_aggregate; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 6dee59a10a5..98dfb2f466b 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2015 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -53,6 +53,7 @@ extern bool volatile *spd_abort_loop; extern handlerton *spider_hton_ptr; extern pthread_mutex_t spider_open_conn_mutex; extern HASH spider_open_connections; +extern HASH spider_ipport_conns; extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; extern const char spider_dig_upper[]; @@ -115,6 +116,11 @@ static const char *name_quote_str = SPIDER_SQL_NAME_QUOTE_STR; #define SPIDER_SQL_SHOW_WARNINGS_STR "show warnings" #define SPIDER_SQL_SHOW_WARNINGS_LEN sizeof(SPIDER_SQL_SHOW_WARNINGS_STR) - 1 +#define SPIDER_SQL_SHOW_MASTER_STATUS_STR "show master status" +#define SPIDER_SQL_SHOW_MASTER_STATUS_LEN sizeof(SPIDER_SQL_SHOW_MASTER_STATUS_STR) - 1 +#define SPIDER_SQL_BINLOG_GTID_POS_STR "select binlog_gtid_pos" +#define SPIDER_SQL_BINLOG_GTID_POS_LEN sizeof(SPIDER_SQL_BINLOG_GTID_POS_STR) - 1 + #ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE #define SPIDER_SQL_SHOW_COLUMNS_STR "show columns from " #define SPIDER_SQL_SHOW_COLUMNS_LEN sizeof(SPIDER_SQL_SHOW_COLUMNS_STR) - 1 @@ -216,6 +222,12 @@ SPIDER_DB_CONN *spider_mysql_create_conn( DBUG_RETURN(new spider_db_mysql(conn)); } +bool spider_mysql_support_direct_join( +) { + DBUG_ENTER("spider_mysql_support_direct_join"); + DBUG_RETURN(TRUE); +} + spider_db_mysql_util spider_db_mysql_utility; SPIDER_DBTON spider_dbton_mysql = { @@ -228,6 +240,7 @@ SPIDER_DBTON spider_dbton_mysql = { spider_mysql_create_handler, spider_mysql_create_copy_table, spider_mysql_create_conn, + spider_mysql_support_direct_join, &spider_db_mysql_utility }; @@ -468,8 +481,8 @@ int spider_db_mysql_row::store_to_tmp_table( DBUG_RETURN(tmp_table->file->ha_write_row(tmp_table->record[0])); } -spider_db_mysql_result::spider_db_mysql_result() : - spider_db_result(spider_dbton_mysql.dbton_id), +spider_db_mysql_result::spider_db_mysql_result(SPIDER_DB_CONN *in_db_conn) : + spider_db_result(in_db_conn, spider_dbton_mysql.dbton_id), db_result(NULL) { DBUG_ENTER("spider_db_mysql_result::spider_db_mysql_result"); @@ -521,7 +534,13 @@ SPIDER_DB_ROW *spider_db_mysql_result::fetch_row() DBUG_PRINT("info",("spider this=%p", this)); if (!(row.row = mysql_fetch_row(db_result))) { - store_error_num = HA_ERR_END_OF_FILE; + if (mysql_errno(((spider_db_mysql *) db_conn)->db_conn)) + { + store_error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn); + my_message(store_error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + } else + store_error_num = HA_ERR_END_OF_FILE; DBUG_RETURN(NULL); } row.lengths = mysql_fetch_lengths(db_result); @@ -538,7 +557,13 @@ SPIDER_DB_ROW *spider_db_mysql_result::fetch_row_from_result_buffer( DBUG_PRINT("info",("spider this=%p", this)); if (!(row.row = mysql_fetch_row(db_result))) { - store_error_num = HA_ERR_END_OF_FILE; + if (mysql_errno(((spider_db_mysql *) db_conn)->db_conn)) + { + store_error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn); + my_message(store_error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + } else + store_error_num = HA_ERR_END_OF_FILE; DBUG_RETURN(NULL); } row.lengths = mysql_fetch_lengths(db_result); @@ -621,6 +646,12 @@ int spider_db_mysql_result::fetch_table_status( if (!(mysql_row = mysql_fetch_row(db_result))) { DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM); } if (mode == 1) @@ -881,6 +912,12 @@ int spider_db_mysql_result::fetch_table_records( if (!(mysql_row = mysql_fetch_row(db_result))) { DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); } if (mode == 1) @@ -925,6 +962,12 @@ int spider_db_mysql_result::fetch_table_cardinality( if (!(mysql_row = mysql_fetch_row(db_result))) { DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } /* no index */ DBUG_RETURN(0); } @@ -991,18 +1034,31 @@ int spider_db_mysql_result::fetch_table_cardinality( mysql_row = mysql_fetch_row(db_result); } } + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } DBUG_RETURN(0); } int spider_db_mysql_result::fetch_table_mon_status( int &status ) { + int error_num; MYSQL_ROW mysql_row; DBUG_ENTER("spider_db_mysql_result::fetch_table_mon_status"); DBUG_PRINT("info",("spider this=%p", this)); if (!(mysql_row = mysql_fetch_row(db_result))) { DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } DBUG_RETURN(HA_ERR_OUT_OF_MEM); } if (num_fields() != 1) @@ -1019,6 +1075,65 @@ int spider_db_mysql_result::fetch_table_mon_status( DBUG_RETURN(0); } +int spider_db_mysql_result::fetch_show_master_status( + const char **binlog_file_name, + const char **binlog_pos +) { + int error_num; + MYSQL_ROW mysql_row; + DBUG_ENTER("spider_db_mysql_result::fetch_show_master_status"); + DBUG_PRINT("info",("spider this=%p", this)); + if (!(mysql_row = mysql_fetch_row(db_result))) + { + DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } + DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); + } + if (num_fields() != 4) + { + DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); + } + + *binlog_file_name = mysql_row[0]; + DBUG_PRINT("info",("spider binlog_file_name=%s", *binlog_file_name)); + *binlog_pos = mysql_row[1]; + DBUG_PRINT("info",("spider binlog_pos=%s", *binlog_pos)); + DBUG_RETURN(0); +} + +int spider_db_mysql_result::fetch_select_binlog_gtid_pos( + const char **gtid_pos +) { + int error_num; + MYSQL_ROW mysql_row; + DBUG_ENTER("spider_db_mysql_result::fetch_select_binlog_gtid_pos"); + DBUG_PRINT("info",("spider this=%p", this)); + if (!(mysql_row = mysql_fetch_row(db_result))) + { + DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } + DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); + } + if (num_fields() != 1) + { + DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); + } + + *gtid_pos = mysql_row[0]; + DBUG_PRINT("info",("spider gtid_pos=%s", *gtid_pos)); + DBUG_RETURN(0); +} + longlong spider_db_mysql_result::num_rows() { DBUG_ENTER("spider_db_mysql_result::num_rows"); @@ -1059,12 +1174,20 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure( spider_string *str, CHARSET_INFO *access_charset ) { + int error_num; + uint length; MYSQL_ROW mysql_row; DBUG_ENTER("spider_db_mysql_result::fetch_columns_for_discover_table_structure"); DBUG_PRINT("info",("spider this=%p", this)); if (!(mysql_row = mysql_fetch_row(db_result))) { DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } DBUG_RETURN(HA_ERR_OUT_OF_MEM); } if (num_fields() != 7) @@ -1095,21 +1218,23 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure( } if (mysql_row[3]) { - if (str->reserve(SPIDER_SQL_CHARACTER_SET_LEN)) + length = strlen(mysql_row[3]); + if (str->reserve(SPIDER_SQL_CHARACTER_SET_LEN + length)) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } str->q_append(SPIDER_SQL_CHARACTER_SET_STR, SPIDER_SQL_CHARACTER_SET_LEN); - str->q_append(mysql_row[3], strlen(mysql_row[3])); + str->q_append(mysql_row[3], length); } if (mysql_row[4]) { - if (str->reserve(SPIDER_SQL_COLLATE_LEN)) + length = strlen(mysql_row[4]); + if (str->reserve(SPIDER_SQL_COLLATE_LEN + length)) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } str->q_append(SPIDER_SQL_COLLATE_STR, SPIDER_SQL_COLLATE_LEN); - str->q_append(mysql_row[4], strlen(mysql_row[4])); + str->q_append(mysql_row[4], length); } if (!strcmp(mysql_row[2], "NO")) { @@ -1125,16 +1250,10 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure( DBUG_RETURN(HA_ERR_OUT_OF_MEM); } str->q_append(SPIDER_SQL_DEFAULT_STR, SPIDER_SQL_DEFAULT_LEN); - if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); if (str->append(mysql_row[1], strlen(mysql_row[1]), access_charset)) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); } } else { if (str->reserve(SPIDER_SQL_DEFAULT_LEN)) @@ -1144,16 +1263,10 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure( str->q_append(SPIDER_SQL_DEFAULT_STR, SPIDER_SQL_DEFAULT_LEN); if (mysql_row[1]) { - if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); if (str->append(mysql_row[1], strlen(mysql_row[1]), access_charset)) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); } else { if (str->reserve(SPIDER_SQL_NULL_LEN)) { @@ -1174,6 +1287,12 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure( } str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } while ((mysql_row = mysql_fetch_row(db_result))); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } DBUG_RETURN(0); } @@ -1181,15 +1300,18 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure( spider_string *str, CHARSET_INFO *access_charset ) { + int error_num; MYSQL_ROW mysql_row; DBUG_ENTER("spider_db_mysql_result::fetch_index_for_discover_table_structure"); DBUG_PRINT("info",("spider this=%p", this)); if (!(mysql_row = mysql_fetch_row(db_result))) { DBUG_PRINT("info",("spider fetch row is null")); - if (mysql_errno(db_result->handle)) + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); } DBUG_RETURN(0); } @@ -1357,6 +1479,12 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure( else using_hash = FALSE; } while ((mysql_row = mysql_fetch_row(db_result))); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } if (!first) { if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_COMMA_LEN + @@ -1377,12 +1505,19 @@ int spider_db_mysql_result::fetch_table_for_discover_table_structure( SPIDER_SHARE *spider_share, CHARSET_INFO *access_charset ) { + int error_num; MYSQL_ROW mysql_row; DBUG_ENTER("spider_db_mysql_result::fetch_table_for_discover_table_structure"); DBUG_PRINT("info",("spider this=%p", this)); if (!(mysql_row = mysql_fetch_row(db_result))) { DBUG_PRINT("info",("spider fetch row is null")); + if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn))) + { + my_message(error_num, + mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0)); + DBUG_RETURN(error_num); + } DBUG_RETURN(HA_ERR_OUT_OF_MEM); } if (num_fields() != 18) @@ -1917,7 +2052,7 @@ spider_db_result *spider_db_mysql::store_result( DBUG_ENTER("spider_db_mysql::store_result"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_ASSERT(!spider_res_buf); - if ((result = new spider_db_mysql_result())) + if ((result = new spider_db_mysql_result(this))) { *error_num = 0; if ( @@ -1943,7 +2078,7 @@ spider_db_result *spider_db_mysql::use_result( spider_db_mysql_result *result; DBUG_ENTER("spider_db_mysql::use_result"); DBUG_PRINT("info",("spider this=%p", this)); - if ((result = new spider_db_mysql_result())) + if ((result = new spider_db_mysql_result(this))) { *error_num = 0; if ( @@ -2439,6 +2574,237 @@ int spider_db_mysql::set_time_zone( DBUG_RETURN(0); } +int spider_db_mysql::exec_simple_sql_with_result( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + const char *sql, + uint sql_length, + int all_link_idx, + int *need_mon, + SPIDER_DB_RESULT **res +) { + int error_num; + DBUG_ENTER("spider_db_mysql::exec_simple_sql_with_result"); + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + conn->need_mon = need_mon; + conn->mta_conn_mutex_lock_already = TRUE; + conn->mta_conn_mutex_unlock_later = TRUE; + spider_conn_set_timeout_from_share(conn, all_link_idx, trx->thd, + share); + if ( + (error_num = spider_db_set_names_internal(trx, share, conn, + all_link_idx, need_mon)) || + ( + spider_db_query( + conn, + sql, + sql_length, + -1, + need_mon) && + (error_num = spider_db_errorno(conn)) + ) + ) { + if ( + error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM && + !conn->disable_reconnect + ) { + /* retry */ + if ((error_num = spider_db_ping_internal(share, conn, + all_link_idx, need_mon))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + DBUG_PRINT("info", ("spider error_num=%d 1", error_num)); + DBUG_RETURN(error_num); + } + if ((error_num = spider_db_set_names_internal(trx, share, conn, + all_link_idx, need_mon))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + DBUG_PRINT("info", ("spider error_num=%d 2", error_num)); + DBUG_RETURN(error_num); + } + spider_conn_set_timeout_from_share(conn, all_link_idx, trx->thd, + share); + if (spider_db_query( + conn, + sql, + sql_length, + -1, + need_mon) + ) { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + DBUG_PRINT("info", ("spider error_num=%d 3", error_num)); + DBUG_RETURN(spider_db_errorno(conn)); + } + } else { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + DBUG_PRINT("info", ("spider error_num=%d 4", error_num)); + DBUG_RETURN(error_num); + } + } + if (!(*res = store_result(NULL, NULL, &error_num))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + if (error_num || (error_num = spider_db_errorno(conn))) + { + DBUG_PRINT("info", ("spider error_num=%d 5", error_num)); + DBUG_RETURN(error_num); + } else { + DBUG_PRINT("info", ("spider error_num=%d 6", + ER_QUERY_ON_FOREIGN_DATA_SOURCE)); + DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); + } + } + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + DBUG_RETURN(0); +} + +int spider_db_mysql::show_master_status( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + int mode, + SPIDER_DB_RESULT **res1, + SPIDER_DB_RESULT **res2 +) { + int error_num; + const char *binlog_file_name, *binlog_pos; + uint binlog_file_name_length, binlog_pos_length; + DBUG_ENTER("spider_db_mysql::show_master_status"); + if ((error_num = exec_simple_sql_with_result(trx, share, + SPIDER_SQL_SHOW_MASTER_STATUS_STR, SPIDER_SQL_SHOW_MASTER_STATUS_LEN, + all_link_idx, need_mon, res1)) + ) { + DBUG_PRINT("info", ("spider error_num=%d 1", error_num)); + DBUG_RETURN(error_num); + } + + if (!(error_num = ((spider_db_mysql_result *)*res1)->fetch_show_master_status( + &binlog_file_name, &binlog_pos)) + ) { + binlog_file_name_length = strlen(binlog_file_name); + binlog_pos_length = strlen(binlog_pos); + spider_store_binlog_pos_binlog_file(table, + binlog_file_name, binlog_file_name_length, + binlog_pos, binlog_pos_length, conn->access_charset); + if (mode > 0) + { + error_num = select_binlog_gtid_pos( + trx, + share, + all_link_idx, + need_mon, + table, + str, + binlog_file_name, + binlog_file_name_length, + binlog_pos, + binlog_pos_length, + res2 + ); + } else { + spider_store_binlog_pos_gtid(table, NULL, 0, conn->access_charset); + } + } +/* + res->free_result(); + delete res; +*/ + if (error_num) + { + DBUG_PRINT("info", ("spider error_num=%d 2", error_num)); + DBUG_RETURN(error_num); + } + DBUG_RETURN(0); +} + +int spider_db_mysql::select_binlog_gtid_pos( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + const char *binlog_file_name, + uint binlog_file_name_length, + const char *binlog_pos, + uint binlog_pos_length, + SPIDER_DB_RESULT **res +) { + int error_num; + size_t length; + const char *gtid_pos; + DBUG_ENTER("spider_db_mysql::select_binlog_gtid_pos"); + str->length(0); + if (str->reserve( + SPIDER_SQL_BINLOG_GTID_POS_LEN + + SPIDER_SQL_OPEN_PAREN_LEN + + SPIDER_SQL_VALUE_QUOTE_LEN + + binlog_file_name_length * 2 + + SPIDER_SQL_VALUE_QUOTE_LEN + + SPIDER_SQL_COMMA_LEN + + SPIDER_SQL_VALUE_QUOTE_LEN + + binlog_pos_length * 2 + + SPIDER_SQL_VALUE_QUOTE_LEN + + SPIDER_SQL_CLOSE_PAREN_LEN + )) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_BINLOG_GTID_POS_STR, + SPIDER_SQL_BINLOG_GTID_POS_LEN); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); + length = conn->db_conn->escape_string((char *)str->ptr() + str->length(), + binlog_file_name, binlog_file_name_length); + str->length(str->length() + length); + str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); + length = conn->db_conn->escape_string((char *)str->ptr() + str->length(), + binlog_pos, binlog_pos_length); + str->length(str->length() + length); + str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN); + + if ((error_num = exec_simple_sql_with_result(trx, share, + str->ptr(), str->length(), all_link_idx, need_mon, res))) + { + DBUG_PRINT("info", ("spider error_num=%d 1", error_num)); + DBUG_RETURN(error_num); + } + if (!(error_num = ((spider_db_mysql_result *)*res)->fetch_select_binlog_gtid_pos(>id_pos))) + { + spider_store_binlog_pos_gtid(table, gtid_pos, strlen(gtid_pos), conn->access_charset); + } +/* + res->free_result(); + delete res; +*/ + if (error_num) + { + DBUG_PRINT("info", ("spider error_num=%d 2", error_num)); + DBUG_RETURN(error_num); + } + DBUG_RETURN(0); +} + #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) int spider_db_mysql::append_sql( char *sql, @@ -3230,7 +3596,9 @@ int spider_db_mysql_util::open_item_func( ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) { uint dbton_id = spider_dbton_mysql.dbton_id; int error_num; @@ -3243,6 +3611,7 @@ int spider_db_mysql_util::open_item_func( separete_str_length = SPIDER_SQL_NULL_CHAR_LEN, last_str_length = SPIDER_SQL_NULL_CHAR_LEN; int use_pushdown_udf; + bool merge_func = FALSE; DBUG_ENTER("spider_db_mysql_util::open_item_func"); if (str) { @@ -3306,7 +3675,7 @@ int spider_db_mysql_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_int(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if ( !strncasecmp("case", func_name, func_name_length) ) { @@ -3322,7 +3691,7 @@ int spider_db_mysql_util::open_item_func( { if ((error_num = spider_db_print_item_type( item_list[item_func_case->first_expr_num], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } for (roop_count = 0; roop_count < item_func_case->ncases; @@ -3336,7 +3705,7 @@ int spider_db_mysql_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[roop_count], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3346,7 +3715,7 @@ int spider_db_mysql_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[roop_count + 1], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (item_func_case->else_expr_num != -1) @@ -3359,7 +3728,7 @@ int spider_db_mysql_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[item_func_case->else_expr_num], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (str) @@ -3396,7 +3765,7 @@ int spider_db_mysql_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if ( !strncasecmp("convert", func_name, func_name_length) ) { @@ -3421,41 +3790,110 @@ int spider_db_mysql_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if (func_name_length == 9 && !strncasecmp("isnottrue", func_name, func_name_length) ) { last_str = SPIDER_SQL_IS_NOT_TRUE_STR; last_str_length = SPIDER_SQL_IS_NOT_TRUE_LEN; break; - } else if (func_name_length == 10 && - !strncasecmp("isnotfalse", func_name, func_name_length) - ) { - last_str = SPIDER_SQL_IS_NOT_FALSE_STR; - last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN; - break; + } else if (func_name_length == 10) + { + if (!strncasecmp("isnotfalse", func_name, func_name_length)) + { + last_str = SPIDER_SQL_IS_NOT_FALSE_STR; + last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN; + break; + } else if (!strncasecmp("column_get", func_name, func_name_length)) + { + if (str) + { + str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); + if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(func_name, func_name_length); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); + } + func_name = SPIDER_SQL_COMMA_STR; + func_name_length = SPIDER_SQL_COMMA_LEN; + separete_str = SPIDER_SQL_COMMA_STR; + separete_str_length = SPIDER_SQL_COMMA_LEN; + break; + } } else if (func_name_length == 12) { if (!strncasecmp("cast_as_date", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_DATE_STR; last_str_length = SPIDER_SQL_AS_DATE_LEN; break; } else if (!strncasecmp("cast_as_time", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_TIME_STR; last_str_length = SPIDER_SQL_AS_TIME_LEN; @@ -3468,7 +3906,7 @@ int spider_db_mysql_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if (!strncasecmp("timestampdiff", func_name, func_name_length)) { #ifdef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC @@ -3531,7 +3969,7 @@ int spider_db_mysql_util::open_item_func( str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } if ((error_num = spider_db_print_item_type(item_list[0], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3540,7 +3978,7 @@ int spider_db_mysql_util::open_item_func( str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } if ((error_num = spider_db_print_item_type(item_list[1], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3558,6 +3996,29 @@ int spider_db_mysql_util::open_item_func( { if (!strncasecmp("cast_as_binary", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3565,9 +4026,12 @@ int spider_db_mysql_util::open_item_func( tmp_str.init_calc_mem(123); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3586,12 +4050,38 @@ int spider_db_mysql_util::open_item_func( break; } else if (!strncasecmp("cast_as_signed", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_SIGNED_STR; last_str_length = SPIDER_SQL_AS_SIGNED_LEN; @@ -3601,12 +4091,38 @@ int spider_db_mysql_util::open_item_func( { if (!strncasecmp("cast_as_unsigned", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_UNSIGNED_STR; last_str_length = SPIDER_SQL_AS_UNSIGNED_LEN; @@ -3614,6 +4130,29 @@ int spider_db_mysql_util::open_item_func( } else if (!strncasecmp("decimal_typecast", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3621,9 +4160,12 @@ int spider_db_mysql_util::open_item_func( tmp_str.init_calc_mem(124); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3643,12 +4185,38 @@ int spider_db_mysql_util::open_item_func( } else if (!strncasecmp("cast_as_datetime", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_DATETIME_STR; last_str_length = SPIDER_SQL_AS_DATETIME_LEN; @@ -3664,7 +4232,7 @@ int spider_db_mysql_util::open_item_func( item_date_add_interval->int_type]; func_name_length = strlen(func_name); if ((error_num = spider_db_print_item_type(item_list[0], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3681,7 +4249,7 @@ int spider_db_mysql_util::open_item_func( } } if ((error_num = spider_db_print_item_type(item_list[1], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3712,9 +4280,33 @@ int spider_db_mysql_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::CHAR_TYPECAST_FUNC: + DBUG_PRINT("info",("spider CHAR_TYPECAST_FUNC")); { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3722,9 +4314,12 @@ int spider_db_mysql_util::open_item_func( tmp_str.init_calc_mem(125); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3757,12 +4352,15 @@ int spider_db_mysql_util::open_item_func( bool has_other_item = FALSE; while((item = lif++)) { +#ifdef SPIDER_HAS_EXPR_CACHE_ITEM if ( item->type() == Item::EXPR_CACHE_ITEM ) { DBUG_PRINT("info",("spider EXPR_CACHE_ITEM")); has_expr_cache_item = TRUE; - } else if ( + } else +#endif + if ( item->type() == Item::FUNC_ITEM && ((Item_func *) item)->functype() == Item_func::ISNOTNULL_FUNC ) { @@ -3866,7 +4464,7 @@ int spider_db_mysql_util::open_item_func( str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN( spider_db_open_item_cond((Item_cond *) item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::TRIG_COND_FUNC: DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); case Item_func::GUSERVAR_FUNC: @@ -3874,10 +4472,10 @@ int spider_db_mysql_util::open_item_func( str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (item_func->result_type() == STRING_RESULT) DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); else DBUG_RETURN(spider_db_open_item_int(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::FT_FUNC: if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY) DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); @@ -3983,7 +4581,7 @@ int spider_db_mysql_util::open_item_func( { item = item_list[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (roop_count == 1) { @@ -4001,7 +4599,7 @@ int spider_db_mysql_util::open_item_func( } item = item_list[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (item_func->functype() == Item_func::FT_FUNC) @@ -4015,7 +4613,7 @@ int spider_db_mysql_util::open_item_func( } item = item_list[0]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -4043,7 +4641,8 @@ int spider_db_mysql_util::open_item_func( { Item_func_conv_charset *item_func_conv_charset = (Item_func_conv_charset *)item_func; - CHARSET_INFO *conv_charset = item_func_conv_charset->collation.collation; + CHARSET_INFO *conv_charset = + item_func_conv_charset->SPIDER_Item_func_conv_charset_conv_charset; uint cset_length = strlen(conv_charset->csname); if (str->reserve(SPIDER_SQL_USING_LEN + cset_length)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -4054,6 +4653,8 @@ int spider_db_mysql_util::open_item_func( } if (str) { + if (merge_func) + str->length(str->length() - SPIDER_SQL_CLOSE_PAREN_LEN); if (str->reserve(last_str_length + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(last_str, last_str_length); @@ -4068,7 +4669,9 @@ int spider_db_mysql_util::open_item_sum_func( ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) { uint dbton_id = spider_dbton_mysql.dbton_id; uint roop_count, item_count = item_sum->get_arg_count(); @@ -4098,7 +4701,7 @@ int spider_db_mysql_util::open_item_sum_func( { item = args[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -4109,7 +4712,7 @@ int spider_db_mysql_util::open_item_sum_func( } item = args[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (str) @@ -4149,6 +4752,125 @@ int spider_db_mysql_util::append_escaped_util( DBUG_RETURN(0); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_db_mysql_util::append_from_and_tables( + spider_fields *fields, + spider_string *str +) { + SPIDER_TABLE_HOLDER *table_holder; + int error_num; + uint dbton_id = spider_dbton_mysql.dbton_id, from_length; + spider_mysql_share *db_share; + spider_mysql_handler *dbton_hdl; + ha_spider *spider; + DBUG_ENTER("spider_db_mysql_util::append_from_and_tables"); + DBUG_PRINT("info",("spider this=%p", this)); + + /* calculate from size */ + from_length = SPIDER_SQL_FROM_LEN; + fields->set_pos_to_first_table_holder(); + while ((table_holder = fields->get_next_table_holder())) + { + spider = table_holder->spider; + db_share = (spider_mysql_share *) + spider->share->dbton_share[dbton_id]; + from_length += + db_share->db_nm_max_length + + SPIDER_SQL_DOT_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 4 + + db_share->table_nm_max_length + + SPIDER_SQL_SPACE_LEN + SPIDER_SQL_COMMA_LEN + + table_holder->alias->length() - SPIDER_SQL_DOT_LEN; + } + + if (str->reserve(from_length)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN); + + fields->set_pos_to_first_table_holder(); + while ((table_holder = fields->get_next_table_holder())) + { + spider = table_holder->spider; + db_share = (spider_mysql_share *) + spider->share->dbton_share[dbton_id]; + dbton_hdl = (spider_mysql_handler *) + spider->dbton_handler[dbton_id]; + dbton_hdl->table_name_pos = str->length(); + if ((error_num = db_share->append_table_name_with_adjusting(str, + spider->conn_link_idx[dbton_hdl->first_link_idx]))) + { + DBUG_RETURN(error_num); + } + str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); + str->q_append(table_holder->alias->ptr(), + table_holder->alias->length() - SPIDER_SQL_DOT_LEN); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + DBUG_RETURN(0); +} + +int spider_db_mysql_util::reappend_tables( + spider_fields *fields, + SPIDER_LINK_IDX_CHAIN *link_idx_chain, + spider_string *str +) { + int error_num; + uint dbton_id = spider_dbton_mysql.dbton_id, length; + ha_spider *spider; + spider_mysql_share *db_share; + spider_mysql_handler *dbton_hdl; + SPIDER_TABLE_HOLDER *table_holder; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + DBUG_ENTER("spider_db_mysql_util::reappend_tables"); + DBUG_PRINT("info",("spider this=%p", this)); + length = str->length(); + fields->set_pos_to_first_table_on_link_idx_chain(link_idx_chain); + fields->set_pos_to_first_table_holder(); + while ((table_holder = fields->get_next_table_holder())) + { + link_idx_holder = + fields->get_next_table_on_link_idx_chain(link_idx_chain); + spider = table_holder->spider; + db_share = (spider_mysql_share *) + spider->share->dbton_share[dbton_id]; + if (!db_share->same_db_table_name) + { + dbton_hdl = (spider_mysql_handler *) spider->dbton_handler[dbton_id]; + str->length(dbton_hdl->table_name_pos); + if ((error_num = db_share->append_table_name_with_adjusting(str, + spider->conn_link_idx[link_idx_holder->link_idx]))) + { + DBUG_RETURN(error_num); + } + } + } + str->length(length); + DBUG_RETURN(0); +} + +int spider_db_mysql_util::append_where( + spider_string *str +) { + DBUG_ENTER("spider_db_mysql_util::append_where"); + DBUG_PRINT("info",("spider this=%p", this)); + if (str->reserve(SPIDER_SQL_WHERE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_WHERE_STR, SPIDER_SQL_WHERE_LEN); + DBUG_RETURN(0); +} + +int spider_db_mysql_util::append_having( + spider_string *str +) { + DBUG_ENTER("spider_db_mysql_util::append_having"); + DBUG_PRINT("info",("spider this=%p", this)); + if (str->reserve(SPIDER_SQL_HAVING_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_HAVING_STR, SPIDER_SQL_HAVING_LEN); + DBUG_RETURN(0); +} +#endif + spider_mysql_share::spider_mysql_share( st_spider_share *share ) : spider_db_share( @@ -5263,6 +5985,61 @@ int spider_mysql_handler::init() DBUG_RETURN(0); } + +int spider_mysql_handler::append_index_hint( + spider_string *str, + int link_idx, + ulong sql_type + ) +{ + List<Index_hint> *index_hints = spider_get_index_hints(spider); + List_iterator <Index_hint> iter(*index_hints); + Index_hint *hint; +// THD *thd = current_thd; + int error_num = 0; + DBUG_ENTER("spider_mysql_handler::append_index_hint"); + DBUG_PRINT("info",("spider this=%p", this)); + + while(index_hints && (hint = iter++)) + { +// hint->print(thd, str); + if (sql_type != SPIDER_SQL_TYPE_HANDLER) + { + switch(hint->type) + { + case INDEX_HINT_IGNORE: + if (str->reserve(hint->key_name.length+ SPIDER_SQL_INDEX_IGNORE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_INDEX_IGNORE_STR,SPIDER_SQL_INDEX_IGNORE_LEN); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR,SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(hint->key_name.str, hint->key_name.length); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,SPIDER_SQL_CLOSE_PAREN_LEN); + break; + case INDEX_HINT_USE: + if (str->reserve(hint->key_name.length+ SPIDER_SQL_INDEX_USE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_INDEX_USE_STR,SPIDER_SQL_INDEX_USE_LEN); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR,SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(hint->key_name.str, hint->key_name.length); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,SPIDER_SQL_CLOSE_PAREN_LEN); + break; + case INDEX_HINT_FORCE: + if (str->reserve(hint->key_name.length+ SPIDER_SQL_INDEX_FORCE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_INDEX_FORCE_STR,SPIDER_SQL_INDEX_FORCE_LEN); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR,SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(hint->key_name.str, hint->key_name.length); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,SPIDER_SQL_CLOSE_PAREN_LEN); + break; + default: + // SPIDER_SQL_COMMA_STR + break; + } + } + } + DBUG_RETURN(error_num); +} + int spider_mysql_handler::append_table_name_with_adjusting( spider_string *str, int link_idx, @@ -6283,7 +7060,7 @@ int spider_mysql_handler::append_direct_update_set( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_SET_STR, SPIDER_SQL_SET_LEN); DBUG_RETURN(spider_db_append_update_columns(spider, str, NULL, 0, - spider_dbton_mysql.dbton_id)); + spider_dbton_mysql.dbton_id, FALSE, NULL)); } if ( @@ -6388,7 +7165,7 @@ int spider_mysql_handler::append_update_columns( int error_num; DBUG_ENTER("spider_mysql_handler::append_update_columns"); error_num = spider_db_append_update_columns(spider, str, - alias, alias_length, spider_dbton_mysql.dbton_id); + alias, alias_length, spider_dbton_mysql.dbton_id, FALSE, NULL); DBUG_RETURN(error_num); } #endif @@ -6815,7 +7592,7 @@ int spider_mysql_handler::check_item_type( DBUG_ENTER("spider_mysql_handler::check_item_type"); DBUG_PRINT("info",("spider this=%p", this)); error_num = spider_db_print_item_type(item, spider, NULL, NULL, 0, - spider_dbton_mysql.dbton_id); + spider_dbton_mysql.dbton_id, FALSE, NULL); DBUG_RETURN(error_num); } @@ -7615,7 +8392,7 @@ int spider_mysql_handler::append_condition( } if ((error_num = spider_db_print_item_type( (Item *) tmp_cond->cond, spider, str, alias, alias_length, - spider_dbton_mysql.dbton_id))) + spider_dbton_mysql.dbton_id, FALSE, NULL))) { if (str && error_num == ER_SPIDER_COND_SKIP_NUM) { @@ -7823,7 +8600,7 @@ int spider_mysql_handler::append_sum_select( for (item_sum_ptr = join->sum_funcs; *item_sum_ptr; ++item_sum_ptr) { if ((error_num = spider_db_mysql_utility.open_item_sum_func(*item_sum_ptr, - spider, str, alias, alias_length))) + spider, str, alias, alias_length, FALSE, NULL))) { DBUG_RETURN(error_num); } @@ -7938,7 +8715,7 @@ int spider_mysql_handler::append_group_by( for (; group; group = group->next) { if ((error_num = spider_db_print_item_type((*group->item), spider, str, - alias, alias_length, spider_dbton_mysql.dbton_id))) + alias, alias_length, spider_dbton_mysql.dbton_id, FALSE, NULL))) { DBUG_RETURN(error_num); } @@ -8131,12 +8908,12 @@ int spider_mysql_handler::append_key_order_for_direct_order_limit_with_alias( { if ((error_num = spider_db_print_item_type((*order->item), spider, str, alias, - alias_length, spider_dbton_mysql.dbton_id))) + alias_length, spider_dbton_mysql.dbton_id, FALSE, NULL))) { DBUG_PRINT("info",("spider error=%d", error_num)); DBUG_RETURN(error_num); } - if (order->direction == ORDER::ORDER_ASC) + if (SPIDER_order_direction_is_asc(order)) { if (str->reserve(SPIDER_SQL_COMMA_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -9044,6 +9821,7 @@ int spider_mysql_handler::append_from( DBUG_ENTER("spider_mysql_handler::append_from"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_PRINT("info",("spider link_idx=%d", link_idx)); + int error_num = 0; if (sql_type == SPIDER_SQL_TYPE_HANDLER) { ha_table_name_pos = str->length(); @@ -9063,6 +9841,13 @@ int spider_mysql_handler::append_from( str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN); table_name_pos = str->length(); append_table_name_with_adjusting(str, link_idx, sql_type); + if(spider_param_index_hint_pushdown(spider->trx->thd)) + { + if((error_num = append_index_hint(str, link_idx, sql_type))) + { + DBUG_RETURN(error_num); + } + } } DBUG_RETURN(0); } @@ -9530,51 +10315,52 @@ int spider_mysql_handler::append_explain_select( * solely of the specified column. * FALSE - otherwise. ********************************************************************/ -bool spider_mysql_handler::is_sole_projection_field( uint16 field_index ) -{ - // Determine whether the projection list consists solely of the field of interest - bool is_field_in_projection_list = FALSE; - TABLE* table = spider->get_table(); - uint16 projection_field_count = 0; - uint16 projection_field_index; - Field** field; - DBUG_ENTER( "spider_mysql_handler::is_sole_projection_field" ); - - for ( field = table->field; *field ; field++ ) - { - projection_field_index = ( *field )->field_index; +bool spider_mysql_handler::is_sole_projection_field( + uint16 field_index +) { + // Determine whether the projection list consists solely of the field of interest + bool is_field_in_projection_list = FALSE; + TABLE* table = spider->get_table(); + uint16 projection_field_count = 0; + uint16 projection_field_index; + Field** field; + DBUG_ENTER( "spider_mysql_handler::is_sole_projection_field" ); - if ( !( minimum_select_bit_is_set( projection_field_index ) ) ) - { - // Current field is not in the projection list - continue; - } + for ( field = table->field; *field ; field++ ) + { + projection_field_index = ( *field )->field_index; - projection_field_count++; + if ( !( minimum_select_bit_is_set( projection_field_index ) ) ) + { + // Current field is not in the projection list + continue; + } - if ( !is_field_in_projection_list ) - { - if ( field_index == projection_field_index ) - { - // Field of interest is in the projection list - is_field_in_projection_list = TRUE; - } - } + projection_field_count++; - if ( is_field_in_projection_list && ( projection_field_count != 1 ) ) - { - // Field of interest is not the sole column in the projection list - DBUG_RETURN( FALSE ); - } + if ( !is_field_in_projection_list ) + { + if ( field_index == projection_field_index ) + { + // Field of interest is in the projection list + is_field_in_projection_list = TRUE; + } } - if ( is_field_in_projection_list && ( projection_field_count == 1 ) ) + if ( is_field_in_projection_list && ( projection_field_count != 1 ) ) { - // Field of interest is the only column in the projection list - DBUG_RETURN( TRUE ); + // Field of interest is not the sole column in the projection list + DBUG_RETURN( FALSE ); } + } - DBUG_RETURN( FALSE ); + if ( is_field_in_projection_list && ( projection_field_count == 1 ) ) + { + // Field of interest is the only column in the projection list + DBUG_RETURN( TRUE ); + } + + DBUG_RETURN( FALSE ); } bool spider_mysql_handler::is_bulk_insert_exec_period( @@ -10040,6 +10826,26 @@ bool spider_mysql_handler::need_lock_before_set_sql_for_exec( DBUG_RETURN(FALSE); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_mysql_handler::set_sql_for_exec( + ulong sql_type, + int link_idx, + SPIDER_LINK_IDX_CHAIN *link_idx_chain +) { + int error_num; + DBUG_ENTER("spider_mysql_handler::set_sql_for_exec"); + DBUG_PRINT("info",("spider this=%p", this)); + if (sql_type & SPIDER_SQL_TYPE_SELECT_SQL) + { + if ((error_num = spider_db_mysql_utility.reappend_tables( + spider->fields, link_idx_chain, &sql))) + DBUG_RETURN(error_num); + exec_sql = &sql; + } + DBUG_RETURN(0); +} +#endif + int spider_mysql_handler::set_sql_for_exec( ulong sql_type, int link_idx @@ -11842,6 +12648,302 @@ int spider_mysql_handler::reset_union_table_name( DBUG_RETURN(0); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_mysql_handler::append_from_and_tables_part( + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::append_from_and_tables_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_mysql_utility.append_from_and_tables(fields, str); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::reappend_tables_part( + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::reappend_tables_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_mysql_utility.reappend_tables(fields, + link_idx_chain, str); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::append_where_part( + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::append_where_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_mysql_utility.append_where(str); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::append_having_part( + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::append_having_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_mysql_utility.append_having(str); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::append_item_type_part( + Item *item, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::append_item_type_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_print_item_type(item, spider, str, alias, alias_length, + spider_dbton_mysql.dbton_id, use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::append_list_item_select_part( + List<Item> *select, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::append_list_item_select_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = append_list_item_select(select, str, alias, alias_length, + use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::append_list_item_select( + List<Item> *select, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields +) { + int error_num; + uint dbton_id = spider_dbton_mysql.dbton_id, length; + List_iterator_fast<Item> it(*select); + Item *item; + Field **field_ptr; + DBUG_ENTER("spider_mysql_handler::append_list_item_select"); + DBUG_PRINT("info",("spider this=%p", this)); + while ((item = it++)) + { + if ((error_num = spider_db_print_item_type(item, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + { + DBUG_RETURN(error_num); + } + field_ptr = fields->get_next_field_ptr(); + length = (*field_ptr)->field_name.length; + if (str->reserve( + SPIDER_SQL_COMMA_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + + SPIDER_SQL_SPACE_LEN + length + )) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); + if ((error_num = spider_db_mysql_utility.append_name(str, + (*field_ptr)->field_name.str, length))) + { + DBUG_RETURN(error_num); + } + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + DBUG_RETURN(0); +} + +int spider_mysql_handler::append_group_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::append_group_by_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = append_group_by(order, str, alias, alias_length, + use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::append_group_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields +) { + int error_num; + uint dbton_id = spider_dbton_mysql.dbton_id; + DBUG_ENTER("spider_mysql_handler::append_group_by"); + DBUG_PRINT("info",("spider this=%p", this)); + if (order) + { + if (str->reserve(SPIDER_SQL_GROUP_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_GROUP_STR, SPIDER_SQL_GROUP_LEN); + for (; order; order = order->next) + { + if ((error_num = spider_db_print_item_type((*order->item), spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + { + DBUG_RETURN(error_num); + } + if (str->reserve(SPIDER_SQL_COMMA_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + } + DBUG_RETURN(0); +} + +int spider_mysql_handler::append_order_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_mysql_handler::append_order_by_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = append_order_by(order, str, alias, alias_length, + use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_mysql_handler::append_order_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields +) { + int error_num; + uint dbton_id = spider_dbton_mysql.dbton_id; + DBUG_ENTER("spider_mysql_handler::append_order_by"); + DBUG_PRINT("info",("spider this=%p", this)); + if (order) + { + if (str->reserve(SPIDER_SQL_ORDER_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_ORDER_STR, SPIDER_SQL_ORDER_LEN); + for (; order; order = order->next) + { + if ((error_num = spider_db_print_item_type((*order->item), spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + { + DBUG_RETURN(error_num); + } + if (SPIDER_order_direction_is_asc(order)) + { + if (str->reserve(SPIDER_SQL_COMMA_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } else { + if (str->reserve(SPIDER_SQL_COMMA_LEN + SPIDER_SQL_DESC_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_DESC_STR, SPIDER_SQL_DESC_LEN); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + } + DBUG_RETURN(0); +} +#endif + spider_mysql_copy_table::spider_mysql_copy_table( spider_mysql_share *db_share ) : spider_db_copy_table( diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index 482289d1d68..766c15971ec 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2014 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ class spider_db_mysql_util: public spider_db_util { @@ -99,7 +99,9 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ); #ifdef HANDLER_HAS_DIRECT_AGGREGATE int open_item_sum_func( @@ -107,13 +109,32 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ); #endif int append_escaped_util( spider_string *to, String *from ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int append_from_and_tables( + spider_fields *fields, + spider_string *str + ); + int reappend_tables( + spider_fields *fields, + SPIDER_LINK_IDX_CHAIN *link_idx_chain, + spider_string *str + ); + int append_where( + spider_string *str + ); + int append_having( + spider_string *str + ); +#endif }; class spider_db_mysql_row: public spider_db_row @@ -161,7 +182,7 @@ public: spider_db_mysql_row row; MYSQL_ROW_OFFSET first_row; int store_error_num; - spider_db_mysql_result(); + spider_db_mysql_result(SPIDER_DB_CONN *in_db_conn); ~spider_db_mysql_result(); bool has_result(); void free_result(); @@ -199,6 +220,13 @@ public: int fetch_table_mon_status( int &status ); + int fetch_show_master_status( + const char **binlog_file_name, + const char **binlog_pos + ); + int fetch_select_binlog_gtid_pos( + const char **gtid_pos + ); longlong num_rows(); uint num_fields(); void move_to_pos( @@ -224,9 +252,9 @@ public: class spider_db_mysql: public spider_db_conn { - MYSQL *db_conn; int stored_error; public: + MYSQL *db_conn; HASH lock_table_hash; bool lock_table_hash_inited; uint lock_table_hash_id; @@ -351,6 +379,39 @@ public: Time_zone *time_zone, int *need_mon ); + int exec_simple_sql_with_result( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + const char *sql, + uint sql_length, + int all_link_idx, + int *need_mon, + SPIDER_DB_RESULT **res + ); + int show_master_status( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + int mode, + SPIDER_DB_RESULT **res1, + SPIDER_DB_RESULT **res2 + ); + int select_binlog_gtid_pos( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + const char *binlog_file_name, + uint binlog_file_name_length, + const char *binlog_pos, + uint binlog_pos_length, + SPIDER_DB_RESULT **res + ); #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) int append_sql( char *sql, @@ -512,7 +573,9 @@ class spider_mysql_handler: public spider_db_handler int where_pos; int order_pos; int limit_pos; +public: int table_name_pos; +private: int ha_read_pos; int ha_next_pos; int ha_where_pos; @@ -554,6 +617,11 @@ public: ); ~spider_mysql_handler(); int init(); + int append_index_hint( + spider_string *str, + int link_idx, + ulong sql_type + ); int append_table_name_with_adjusting( spider_string *str, int link_idx, @@ -1129,7 +1197,7 @@ public: int link_idx ); bool is_sole_projection_field( - uint16 field_index + uint16 field_index ); bool is_bulk_insert_exec_period( bool bulk_end @@ -1199,6 +1267,13 @@ public: bool need_lock_before_set_sql_for_exec( ulong sql_type ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int set_sql_for_exec( + ulong sql_type, + int link_idx, + SPIDER_LINK_IDX_CHAIN *link_idx_chain + ); +#endif int set_sql_for_exec( ulong sql_type, int link_idx @@ -1310,6 +1385,78 @@ public: int link_idx, ulong sql_type ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int append_from_and_tables_part( + spider_fields *fields, + ulong sql_type + ); + int reappend_tables_part( + spider_fields *fields, + ulong sql_type + ); + int append_where_part( + ulong sql_type + ); + int append_having_part( + ulong sql_type + ); + int append_item_type_part( + Item *item, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_list_item_select_part( + List<Item> *select, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_list_item_select( + List<Item> *select, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields + ); + int append_group_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_group_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields + ); + int append_order_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_order_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields + ); +#endif }; class spider_mysql_copy_table: public spider_db_copy_table diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc index 45e40661760..f9eb305d258 100644 --- a/storage/spider/spd_db_oracle.cc +++ b/storage/spider/spd_db_oracle.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2015 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -49,6 +49,7 @@ extern struct charset_info_st *spd_charset_utf8_bin; extern handlerton *spider_hton_ptr; extern pthread_mutex_t spider_open_conn_mutex; extern HASH spider_open_connections; +extern HASH spider_ipport_conns; extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; extern const char spider_dig_upper[]; @@ -308,6 +309,12 @@ SPIDER_DB_CONN *spider_oracle_create_conn( DBUG_RETURN(new spider_db_oracle(conn)); } +bool spider_oracle_support_direct_join( +) { + DBUG_ENTER("spider_oracle_support_direct_join"); + DBUG_RETURN(FALSE); +} + spider_db_oracle_util spider_db_oracle_utility; SPIDER_DBTON spider_dbton_oracle = { @@ -320,6 +327,7 @@ SPIDER_DBTON spider_dbton_oracle = { spider_oracle_create_handler, spider_oracle_create_copy_table, spider_oracle_create_conn, + spider_oracle_support_direct_join, &spider_db_oracle_utility }; @@ -746,8 +754,8 @@ int spider_db_oracle_row::fetch() DBUG_RETURN(0); } -spider_db_oracle_result::spider_db_oracle_result() : - spider_db_result(spider_dbton_oracle.dbton_id), +spider_db_oracle_result::spider_db_oracle_result(SPIDER_DB_CONN *in_db_conn) : + spider_db_result(in_db_conn, spider_dbton_oracle.dbton_id), db_conn(NULL), stmtp(NULL), field_count(0), access_charset(NULL), fetched(FALSE) { @@ -1564,7 +1572,7 @@ int spider_db_oracle::exec_query( DBUG_RETURN(error_num); } - if ((result = new spider_db_oracle_result())) + if ((result = new spider_db_oracle_result(this))) { result->db_conn = this; result->stmtp = stmtp; @@ -2095,6 +2103,22 @@ int spider_db_oracle::set_time_zone( DBUG_RETURN(0); } +int spider_db_oracle::show_master_status( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + int mode, + SPIDER_DB_RESULT **res1, + SPIDER_DB_RESULT **res2 +) { + DBUG_ENTER("spider_db_oracle::show_master_status"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN(0); +} + #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) int spider_db_oracle::append_sql( char *sql, @@ -2874,7 +2898,9 @@ int spider_db_oracle_util::open_item_func( ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) { uint dbton_id = spider_dbton_oracle.dbton_id; int error_num; @@ -2887,6 +2913,7 @@ int spider_db_oracle_util::open_item_func( separete_str_length = SPIDER_SQL_NULL_CHAR_LEN, last_str_length = SPIDER_SQL_NULL_CHAR_LEN; int use_pushdown_udf; + bool merge_func = FALSE; DBUG_ENTER("spider_db_oracle_util::open_item_func"); if (str) { @@ -2950,7 +2977,7 @@ int spider_db_oracle_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_int(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if ( !strncasecmp("case", func_name, func_name_length) ) { @@ -2966,7 +2993,7 @@ int spider_db_oracle_util::open_item_func( { if ((error_num = spider_db_print_item_type( item_list[item_func_case->first_expr_num], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } for (roop_count = 0; roop_count < item_func_case->ncases; @@ -2980,7 +3007,7 @@ int spider_db_oracle_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[roop_count], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -2990,7 +3017,7 @@ int spider_db_oracle_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[roop_count + 1], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (item_func_case->else_expr_num != -1) @@ -3003,7 +3030,7 @@ int spider_db_oracle_util::open_item_func( } if ((error_num = spider_db_print_item_type( item_list[item_func_case->else_expr_num], spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (str) @@ -3040,7 +3067,7 @@ int spider_db_oracle_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if ( !strncasecmp("convert", func_name, func_name_length) ) { @@ -3065,41 +3092,110 @@ int spider_db_oracle_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if (func_name_length == 9 && !strncasecmp("isnottrue", func_name, func_name_length) ) { last_str = SPIDER_SQL_IS_NOT_TRUE_STR; last_str_length = SPIDER_SQL_IS_NOT_TRUE_LEN; break; - } else if (func_name_length == 10 && - !strncasecmp("isnotfalse", func_name, func_name_length) - ) { - last_str = SPIDER_SQL_IS_NOT_FALSE_STR; - last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN; - break; + } else if (func_name_length == 10) + { + if (!strncasecmp("isnotfalse", func_name, func_name_length)) + { + last_str = SPIDER_SQL_IS_NOT_FALSE_STR; + last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN; + break; + } else if (!strncasecmp("column_get", func_name, func_name_length)) + { + if (str) + { + str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); + if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(func_name, func_name_length); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); + } + func_name = SPIDER_SQL_COMMA_STR; + func_name_length = SPIDER_SQL_COMMA_LEN; + separete_str = SPIDER_SQL_COMMA_STR; + separete_str_length = SPIDER_SQL_COMMA_LEN; + break; + } } else if (func_name_length == 12) { if (!strncasecmp("cast_as_date", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_DATE_STR; last_str_length = SPIDER_SQL_AS_DATE_LEN; break; } else if (!strncasecmp("cast_as_time", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_TIME_STR; last_str_length = SPIDER_SQL_AS_TIME_LEN; @@ -3112,7 +3208,7 @@ int spider_db_oracle_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); } else if (!strncasecmp("timestampdiff", func_name, func_name_length)) { #ifdef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC @@ -3175,7 +3271,7 @@ int spider_db_oracle_util::open_item_func( str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } if ((error_num = spider_db_print_item_type(item_list[0], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3184,7 +3280,7 @@ int spider_db_oracle_util::open_item_func( str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } if ((error_num = spider_db_print_item_type(item_list[1], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3202,6 +3298,29 @@ int spider_db_oracle_util::open_item_func( { if (!strncasecmp("cast_as_binary", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3209,9 +3328,12 @@ int spider_db_oracle_util::open_item_func( tmp_str.init_calc_mem(123); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3230,12 +3352,38 @@ int spider_db_oracle_util::open_item_func( break; } else if (!strncasecmp("cast_as_signed", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_SIGNED_STR; last_str_length = SPIDER_SQL_AS_SIGNED_LEN; @@ -3245,12 +3393,38 @@ int spider_db_oracle_util::open_item_func( { if (!strncasecmp("cast_as_unsigned", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_UNSIGNED_STR; last_str_length = SPIDER_SQL_AS_UNSIGNED_LEN; @@ -3258,6 +3432,29 @@ int spider_db_oracle_util::open_item_func( } else if (!strncasecmp("decimal_typecast", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3265,9 +3462,12 @@ int spider_db_oracle_util::open_item_func( tmp_str.init_calc_mem(124); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3287,12 +3487,38 @@ int spider_db_oracle_util::open_item_func( } else if (!strncasecmp("cast_as_datetime", func_name, func_name_length)) { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } } last_str = SPIDER_SQL_AS_DATETIME_STR; last_str_length = SPIDER_SQL_AS_DATETIME_LEN; @@ -3320,7 +3546,7 @@ int spider_db_oracle_util::open_item_func( SPIDER_SQL_OPEN_PAREN_LEN); } if ((error_num = spider_db_print_item_type(item_list[0], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3338,7 +3564,7 @@ int spider_db_oracle_util::open_item_func( } } if ((error_num = spider_db_print_item_type(item_list[1], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3384,7 +3610,7 @@ int spider_db_oracle_util::open_item_func( case INTERVAL_SECOND: case INTERVAL_MICROSECOND: if ((error_num = spider_db_print_item_type(item_list[0], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3400,7 +3626,7 @@ int spider_db_oracle_util::open_item_func( } } if ((error_num = spider_db_print_item_type(item_list[1], spider, - str, alias, alias_length, dbton_id))) + str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3488,9 +3714,33 @@ int spider_db_oracle_util::open_item_func( if (str) str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::CHAR_TYPECAST_FUNC: + DBUG_PRINT("info",("spider CHAR_TYPECAST_FUNC")); { + item = item_list[0]; + if (item->type() == Item::FUNC_ITEM) + { + DBUG_PRINT("info",("spider child is FUNC_ITEM")); + Item_func *ifunc = (Item_func *) item; + if (ifunc->functype() == Item_func::UNKNOWN_FUNC) + { + const char *child_func_name; + int child_func_name_length; + DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); + child_func_name = (char*) ifunc->func_name(); + child_func_name_length = strlen(child_func_name); + DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); + if ( + child_func_name_length == 10 && + !strncasecmp("column_get", child_func_name, child_func_name_length) + ) { + DBUG_PRINT("info",("spider this is merge func")); + merge_func = TRUE; + } + } + } + if (str) { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; @@ -3498,9 +3748,12 @@ int spider_db_oracle_util::open_item_func( tmp_str.init_calc_mem(125); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + if (!merge_func) + { + if (str->reserve(SPIDER_SQL_CAST_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); + } #if MYSQL_VERSION_ID < 50500 item_func->print(tmp_str.get_str(), QT_IS); #else @@ -3533,12 +3786,15 @@ int spider_db_oracle_util::open_item_func( bool has_other_item = FALSE; while((item = lif++)) { +#ifdef SPIDER_HAS_EXPR_CACHE_ITEM if ( item->type() == Item::EXPR_CACHE_ITEM ) { DBUG_PRINT("info",("spider EXPR_CACHE_ITEM")); has_expr_cache_item = TRUE; - } else if ( + } else +#endif + if ( item->type() == Item::FUNC_ITEM && ((Item_func *) item)->functype() == Item_func::ISNOTNULL_FUNC ) { @@ -3642,7 +3898,7 @@ int spider_db_oracle_util::open_item_func( str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); DBUG_RETURN( spider_db_open_item_cond((Item_cond *) item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::TRIG_COND_FUNC: DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); case Item_func::GUSERVAR_FUNC: @@ -3650,10 +3906,10 @@ int spider_db_oracle_util::open_item_func( str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (item_func->result_type() == STRING_RESULT) DBUG_RETURN(spider_db_open_item_string(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); else DBUG_RETURN(spider_db_open_item_int(item_func, spider, str, - alias, alias_length, dbton_id)); + alias, alias_length, dbton_id, use_fields, fields)); case Item_func::FT_FUNC: if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY) DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); @@ -3759,7 +4015,7 @@ int spider_db_oracle_util::open_item_func( { item = item_list[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (roop_count == 1) { @@ -3777,7 +4033,7 @@ int spider_db_oracle_util::open_item_func( } item = item_list[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (item_func->functype() == Item_func::FT_FUNC) @@ -3791,7 +4047,7 @@ int spider_db_oracle_util::open_item_func( } item = item_list[0]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3819,7 +4075,8 @@ int spider_db_oracle_util::open_item_func( { Item_func_conv_charset *item_func_conv_charset = (Item_func_conv_charset *)item_func; - CHARSET_INFO *conv_charset = item_func_conv_charset->conv_charset; + CHARSET_INFO *conv_charset = + item_func_conv_charset->SPIDER_Item_func_conv_charset_conv_charset; uint cset_length = strlen(conv_charset->csname); if (str->reserve(SPIDER_SQL_USING_LEN + cset_length)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -3830,6 +4087,8 @@ int spider_db_oracle_util::open_item_func( } if (str) { + if (merge_func) + str->length(str->length() - SPIDER_SQL_CLOSE_PAREN_LEN); if (str->reserve(last_str_length + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(last_str, last_str_length); @@ -3844,7 +4103,9 @@ int spider_db_oracle_util::open_item_sum_func( ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ) { uint dbton_id = spider_dbton_oracle.dbton_id; uint roop_count, item_count = item_sum->get_arg_count(); @@ -3874,7 +4135,7 @@ int spider_db_oracle_util::open_item_sum_func( { item = args[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); if (str) { @@ -3885,7 +4146,7 @@ int spider_db_oracle_util::open_item_sum_func( } item = args[roop_count]; if ((error_num = spider_db_print_item_type(item, spider, str, - alias, alias_length, dbton_id))) + alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); } if (str) @@ -3942,6 +4203,123 @@ int spider_db_oracle_util::append_escaped_util( DBUG_RETURN(0); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_db_oracle_util::append_from_and_tables( + spider_fields *fields, + spider_string *str +) { + SPIDER_TABLE_HOLDER *table_holder; + int error_num; + uint dbton_id = spider_dbton_oracle.dbton_id, from_length; + spider_oracle_share *db_share; + spider_oracle_handler *dbton_hdl; + ha_spider *spider; + DBUG_ENTER("spider_db_oracle_util::append_from_and_tables"); + DBUG_PRINT("info",("spider this=%p", this)); + + /* calculate from size */ + from_length = SPIDER_SQL_FROM_LEN; + fields->set_pos_to_first_table_holder(); + while ((table_holder = fields->get_next_table_holder())) + { + spider = table_holder->spider; + db_share = (spider_oracle_share *) + spider->share->dbton_share[dbton_id]; + from_length += + db_share->db_nm_max_length + + SPIDER_SQL_DOT_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 4 + + db_share->table_nm_max_length + + SPIDER_SQL_SPACE_LEN + SPIDER_SQL_COMMA_LEN + + table_holder->alias->length() - SPIDER_SQL_DOT_LEN; + } + + if (str->reserve(from_length)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN); + + fields->set_pos_to_first_table_holder(); + while ((table_holder = fields->get_next_table_holder())) + { + spider = table_holder->spider; + db_share = (spider_oracle_share *) + spider->share->dbton_share[dbton_id]; + dbton_hdl = (spider_oracle_handler *) spider->dbton_handler[dbton_id]; + dbton_hdl->table_name_pos = str->length(); + if ((error_num = db_share->append_table_name_with_adjusting(str, + spider->conn_link_idx[dbton_hdl->first_link_idx]))) + { + DBUG_RETURN(error_num); + } + str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); + str->q_append(table_holder->alias->ptr(), + table_holder->alias->length() - SPIDER_SQL_DOT_LEN); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + DBUG_RETURN(0); +} + +int spider_db_oracle_util::reappend_tables( + spider_fields *fields, + SPIDER_LINK_IDX_CHAIN *link_idx_chain, + spider_string *str +) { + int error_num; + uint dbton_id = spider_dbton_oracle.dbton_id, length; + ha_spider *spider; + spider_oracle_share *db_share; + spider_oracle_handler *dbton_hdl; + SPIDER_TABLE_HOLDER *table_holder; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + DBUG_ENTER("spider_db_oracle_util::reappend_tables"); + DBUG_PRINT("info",("spider this=%p", this)); + length = str->length(); + fields->set_pos_to_first_table_on_link_idx_chain(link_idx_chain); + fields->set_pos_to_first_table_holder(); + while ((table_holder = fields->get_next_table_holder())) + { + link_idx_holder = fields->get_next_table_on_link_idx_chain(link_idx_chain); + spider = table_holder->spider; + db_share = (spider_oracle_share *) + spider->share->dbton_share[dbton_id]; + if (!db_share->same_db_table_name) + { + dbton_hdl = (spider_oracle_handler *) spider->dbton_handler[dbton_id]; + str->length(dbton_hdl->table_name_pos); + if ((error_num = db_share->append_table_name_with_adjusting(str, + spider->conn_link_idx[link_idx_holder->link_idx]))) + { + DBUG_RETURN(error_num); + } + } + } + str->length(length); + DBUG_RETURN(0); +} + +int spider_db_oracle_util::append_where( + spider_string *str +) { + DBUG_ENTER("spider_db_oracle_util::append_where"); + DBUG_PRINT("info",("spider this=%p", this)); + if (str->reserve(SPIDER_SQL_WHERE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_WHERE_STR, SPIDER_SQL_WHERE_LEN); + DBUG_RETURN(0); +} + +int spider_db_oracle_util::append_having( + spider_string *str +) { + DBUG_ENTER("spider_db_oracle_util::append_having"); + DBUG_PRINT("info",("spider this=%p", this)); + if (str->reserve(SPIDER_SQL_HAVING_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_HAVING_STR, SPIDER_SQL_HAVING_LEN); + DBUG_RETURN(0); +} +#endif + spider_oracle_share::spider_oracle_share( st_spider_share *share ) : spider_db_share( @@ -4985,6 +5363,16 @@ int spider_oracle_handler::init() DBUG_RETURN(0); } +int spider_oracle_handler::append_index_hint( + spider_string *str, + int link_idx, + ulong sql_type + ) +{ + DBUG_ENTER("spider_oracle_handler::append_index_hint"); + DBUG_RETURN(0); +} + int spider_oracle_handler::append_table_name_with_adjusting( spider_string *str, int link_idx, @@ -6023,7 +6411,7 @@ int spider_oracle_handler::append_update_columns( value = vi++; if ((error_num = spider_db_print_item_type( (Item *) field, spider, str, alias, alias_length, - spider_dbton_oracle.dbton_id))) + spider_dbton_oracle.dbton_id, FALSE, NULL))) { if ( error_num == ER_SPIDER_COND_SKIP_NUM && @@ -6041,7 +6429,7 @@ int spider_oracle_handler::append_update_columns( } if ((error_num = spider_db_print_item_type( (Item *) value, spider, str, alias, alias_length, - spider_dbton_oracle.dbton_id))) + spider_dbton_oracle.dbton_id, FALSE, NULL))) DBUG_RETURN(error_num); if (str) { @@ -6443,7 +6831,7 @@ int spider_oracle_handler::check_item_type( DBUG_ENTER("spider_oracle_handler::check_item_type"); DBUG_PRINT("info",("spider this=%p", this)); error_num = spider_db_print_item_type(item, spider, NULL, NULL, 0, - spider_dbton_oracle.dbton_id); + spider_dbton_oracle.dbton_id, FALSE, NULL); DBUG_RETURN(error_num); } @@ -7224,7 +7612,7 @@ int spider_oracle_handler::append_condition( } if ((error_num = spider_db_print_item_type( (Item *) tmp_cond->cond, spider, str, alias, alias_length, - spider_dbton_oracle.dbton_id))) + spider_dbton_oracle.dbton_id, FALSE, NULL))) { if (str && error_num == ER_SPIDER_COND_SKIP_NUM) { @@ -7431,7 +7819,7 @@ int spider_oracle_handler::append_sum_select( for (item_sum_ptr = join->sum_funcs; *item_sum_ptr; ++item_sum_ptr) { if ((error_num = spider_db_oracle_utility.open_item_sum_func(*item_sum_ptr, - spider, str, alias, alias_length))) + spider, str, alias, alias_length, FALSE, NULL))) { DBUG_RETURN(error_num); } @@ -7546,7 +7934,7 @@ int spider_oracle_handler::append_group_by( for (; group; group = group->next) { if ((error_num = spider_db_print_item_type((*group->item), spider, str, - alias, alias_length, spider_dbton_oracle.dbton_id))) + alias, alias_length, spider_dbton_oracle.dbton_id, FALSE, NULL))) { DBUG_RETURN(error_num); } @@ -7885,12 +8273,12 @@ int spider_oracle_handler::append_key_order_for_direct_order_limit_with_alias( { if ((error_num = spider_db_print_item_type((*order->item), spider, &sql_part, alias, - alias_length, spider_dbton_oracle.dbton_id))) + alias_length, spider_dbton_oracle.dbton_id, FALSE, NULL))) { DBUG_PRINT("info",("spider error=%d", error_num)); DBUG_RETURN(error_num); } - if (order->asc) + if (SPIDER_order_direction_is_asc(order)) { if (sql_part.reserve(SPIDER_SQL_COMMA_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -7976,12 +8364,12 @@ int spider_oracle_handler::append_key_order_for_direct_order_limit_with_alias( { if ((error_num = spider_db_print_item_type((*order->item), spider, str, alias, - alias_length, spider_dbton_oracle.dbton_id))) + alias_length, spider_dbton_oracle.dbton_id, FALSE, NULL))) { DBUG_PRINT("info",("spider error=%d", error_num)); DBUG_RETURN(error_num); } - if (order->asc) + if (SPIDER_order_direction_is_asc(order)) { if (str->reserve(SPIDER_SQL_COMMA_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -9587,49 +9975,49 @@ int spider_oracle_handler::append_explain_select( ********************************************************************/ bool spider_oracle_handler::is_sole_projection_field( uint16 field_index ) { - // Determine whether the projection list consists solely of the field of interest - bool is_field_in_projection_list = FALSE; - TABLE* table = spider->get_table(); - uint16 projection_field_count = 0; - uint16 projection_field_index; - Field** field; - DBUG_ENTER( "spider_oracle_handler::is_sole_projection_field" ); + // Determine whether the projection list consists solely of the field of interest + bool is_field_in_projection_list = FALSE; + TABLE* table = spider->get_table(); + uint16 projection_field_count = 0; + uint16 projection_field_index; + Field** field; + DBUG_ENTER( "spider_oracle_handler::is_sole_projection_field" ); - for ( field = table->field; *field; field++ ) - { - projection_field_index = ( *field )->field_index; - - if ( !( minimum_select_bit_is_set( projection_field_index ) ) ) - { - // Current field is not in the projection list - continue; - } + for ( field = table->field; *field; field++ ) + { + projection_field_index = ( *field )->field_index; - projection_field_count++; + if ( !( minimum_select_bit_is_set( projection_field_index ) ) ) + { + // Current field is not in the projection list + continue; + } - if ( !is_field_in_projection_list ) - { - if (field_index == projection_field_index) - { - // Field of interest is in the projection list - is_field_in_projection_list = TRUE; - } - } + projection_field_count++; - if ( is_field_in_projection_list && ( projection_field_count != 1 ) ) - { - // Field of interest is not the sole column in the projection list - DBUG_RETURN( FALSE ); - } + if ( !is_field_in_projection_list ) + { + if (field_index == projection_field_index) + { + // Field of interest is in the projection list + is_field_in_projection_list = TRUE; + } } - if ( is_field_in_projection_list && ( projection_field_count == 1 ) ) + if ( is_field_in_projection_list && ( projection_field_count != 1 ) ) { - // Field of interest is the only column in the projection list - DBUG_RETURN( TRUE ); + // Field of interest is not the sole column in the projection list + DBUG_RETURN( FALSE ); } + } - DBUG_RETURN( FALSE ); + if ( is_field_in_projection_list && ( projection_field_count == 1 ) ) + { + // Field of interest is the only column in the projection list + DBUG_RETURN( TRUE ); + } + + DBUG_RETURN( FALSE ); } bool spider_oracle_handler::is_bulk_insert_exec_period( @@ -10101,6 +10489,53 @@ bool spider_oracle_handler::need_lock_before_set_sql_for_exec( DBUG_RETURN(FALSE); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_oracle_handler::set_sql_for_exec( + ulong sql_type, + int link_idx, + SPIDER_LINK_IDX_CHAIN *link_idx_chain +) { + int error_num; + SPIDER_RESULT_LIST *result_list = &spider->result_list; + int all_link_idx = spider->conn_link_idx[link_idx]; + DBUG_ENTER("spider_oracle_handler::set_sql_for_exec"); + DBUG_PRINT("info",("spider this=%p", this)); + if (sql_type & SPIDER_SQL_TYPE_SELECT_SQL) + { + if (table_lock_mode) + { + spider_string *str = &result_list->insert_sqls[link_idx]; + str->length(0); + if (str->reserve(SPIDER_SQL_LOCK_TABLE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_LOCK_TABLE_STR, SPIDER_SQL_LOCK_TABLE_LEN); + if ((error_num = oracle_share->append_table_name(str, all_link_idx))) + DBUG_RETURN(error_num); + if (table_lock_mode == SPIDER_LOCK_MODE_EXCLUSIVE) + { + if (str->reserve(SPIDER_SQL_LOCK_TABLE_EXCLUSIVE_MODE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_LOCK_TABLE_EXCLUSIVE_MODE_STR, + SPIDER_SQL_LOCK_TABLE_EXCLUSIVE_MODE_LEN); + } else if (table_lock_mode == SPIDER_LOCK_MODE_SHARED) + { + if (str->reserve(SPIDER_SQL_LOCK_TABLE_SHARE_MODE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_LOCK_TABLE_SHARE_MODE_STR, + SPIDER_SQL_LOCK_TABLE_SHARE_MODE_LEN); + } + exec_lock_sql = str; + } + + if ((error_num = spider_db_oracle_utility.reappend_tables( + spider->fields, link_idx_chain, &sql))) + DBUG_RETURN(error_num); + exec_sql = &sql; + } + DBUG_RETURN(0); +} +#endif + int spider_oracle_handler::set_sql_for_exec( ulong sql_type, int link_idx @@ -12008,6 +12443,306 @@ int spider_oracle_handler::reset_union_table_name( DBUG_RETURN(0); } +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +int spider_oracle_handler::append_from_and_tables_part( + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::append_from_and_tables_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_oracle_utility.append_from_and_tables(fields, str); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::reappend_tables_part( + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::reappend_tables_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_oracle_utility.reappend_tables(fields, + link_idx_chain, str); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::append_where_part( + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::append_where_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_oracle_utility.append_where(str); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::append_having_part( + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::append_having_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_oracle_utility.append_having(str); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::append_item_type_part( + Item *item, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::append_item_type_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = spider_db_print_item_type(item, spider, str, alias, alias_length, + spider_dbton_oracle.dbton_id, use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::append_list_item_select_part( + List<Item> *select, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::append_list_item_select_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = append_list_item_select(select, str, alias, alias_length, + use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::append_list_item_select( + List<Item> *select, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields +) { + int error_num; + uint dbton_id = spider_dbton_oracle.dbton_id, length; + List_iterator_fast<Item> it(*select); + Item *item; + Field **field_ptr; + DBUG_ENTER("spider_oracle_handler::append_list_item_select"); + DBUG_PRINT("info",("spider this=%p", this)); + while ((item = it++)) + { + if ((error_num = spider_db_print_item_type(item, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + { + DBUG_RETURN(error_num); + } + field_ptr = fields->get_next_field_ptr(); + length = strlen((*field_ptr)->field_name); + if (str->reserve( + SPIDER_SQL_COMMA_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + + SPIDER_SQL_SPACE_LEN + length + )) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); + if ((error_num = spider_db_oracle_utility.append_name(str, + (*field_ptr)->field_name, length))) + { + DBUG_RETURN(error_num); + } + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + DBUG_RETURN(0); +} + +int spider_oracle_handler::append_group_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::append_group_by_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = append_group_by(order, str, alias, alias_length, + use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::append_group_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields +) { + int error_num; + uint dbton_id = spider_dbton_oracle.dbton_id; + DBUG_ENTER("spider_oracle_handler::append_group_by"); + DBUG_PRINT("info",("spider this=%p", this)); + if (order) + { + if (str->reserve(SPIDER_SQL_GROUP_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_GROUP_STR, SPIDER_SQL_GROUP_LEN); + for (; order; order = order->next) + { + if ((error_num = spider_db_print_item_type((*order->item), spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + { + DBUG_RETURN(error_num); + } + if (str->reserve(SPIDER_SQL_COMMA_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + } + DBUG_RETURN(0); +} + +int spider_oracle_handler::append_order_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type +) { + int error_num; + spider_string *str; + DBUG_ENTER("spider_oracle_handler::append_order_by_part"); + DBUG_PRINT("info",("spider this=%p", this)); + switch (sql_type) + { + case SPIDER_SQL_TYPE_SELECT_SQL: + str = &sql; + break; + default: + DBUG_RETURN(0); + } + error_num = append_order_by(order, str, alias, alias_length, + use_fields, fields); + DBUG_RETURN(error_num); +} + +int spider_oracle_handler::append_order_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields +) { + int error_num; + uint dbton_id = spider_dbton_oracle.dbton_id; + DBUG_ENTER("spider_oracle_handler::append_order_by"); + DBUG_PRINT("info",("spider this=%p", this)); + if (order) + { + if (str->reserve(SPIDER_SQL_ORDER_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_ORDER_STR, SPIDER_SQL_ORDER_LEN); + for (; order; order = order->next) + { + if ((error_num = spider_db_print_item_type((*order->item), spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + { + DBUG_RETURN(error_num); + } +#ifdef SPIDER_ORDER_HAS_ENUM_ORDER + if (order->direction == ORDER::ORDER_DESC) +#else + if (!order->asc) +#endif + { + if (str->reserve(SPIDER_SQL_COMMA_LEN + SPIDER_SQL_DESC_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_DESC_STR, SPIDER_SQL_DESC_LEN); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } else { + if (str->reserve(SPIDER_SQL_COMMA_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + } + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + } + DBUG_RETURN(0); +} +#endif + spider_oracle_copy_table::spider_oracle_copy_table( spider_oracle_share *db_share ) : spider_db_copy_table( diff --git a/storage/spider/spd_db_oracle.h b/storage/spider/spd_db_oracle.h index 7a070f498da..2e9da5cab84 100644 --- a/storage/spider/spd_db_oracle.h +++ b/storage/spider/spd_db_oracle.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2014 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ class spider_db_oracle; class spider_db_oracle_result; @@ -102,7 +102,9 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ); #ifdef HANDLER_HAS_DIRECT_AGGREGATE int open_item_sum_func( @@ -110,7 +112,9 @@ public: ha_spider *spider, spider_string *str, const char *alias, - uint alias_length + uint alias_length, + bool use_fields, + spider_fields *fields ); #endif size_t escape_string( @@ -123,6 +127,23 @@ public: spider_string *to, String *from ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int append_from_and_tables( + spider_fields *fields, + spider_string *str + ); + int reappend_tables( + spider_fields *fields, + SPIDER_LINK_IDX_CHAIN *link_idx_chain, + spider_string *str + ); + int append_where( + spider_string *str + ); + int append_having( + spider_string *str + ); +#endif }; class spider_db_oracle_row: public spider_db_row @@ -195,7 +216,7 @@ public: spider_db_oracle_row row; int store_error_num; - spider_db_oracle_result(); + spider_db_oracle_result(SPIDER_DB_CONN *in_db_conn); ~spider_db_oracle_result(); bool has_result(); void free_result(); @@ -409,6 +430,17 @@ public: Time_zone *time_zone, int *need_mon ); + int show_master_status( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + int all_link_idx, + int *need_mon, + TABLE *table, + spider_string *str, + int mode, + SPIDER_DB_RESULT **res1, + SPIDER_DB_RESULT **res2 + ); #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) int append_sql( char *sql, @@ -586,7 +618,9 @@ class spider_oracle_handler: public spider_db_handler int where_pos; int order_pos; int limit_pos; +public: int table_name_pos; +private: int update_set_pos; int ha_read_pos; int ha_next_pos; @@ -634,6 +668,11 @@ public: ); ~spider_oracle_handler(); int init(); + int spider_oracle_handler::append_index_hint( + spider_string *str, + int link_idx, + ulong sql_type + ); int append_table_name_with_adjusting( spider_string *str, int link_idx, @@ -1209,7 +1248,7 @@ public: int link_idx ); bool is_sole_projection_field( - uint16 field_index + uint16 field_index ); bool is_bulk_insert_exec_period( bool bulk_end @@ -1279,6 +1318,13 @@ public: bool need_lock_before_set_sql_for_exec( ulong sql_type ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int set_sql_for_exec( + ulong sql_type, + int link_idx, + SPIDER_LINK_IDX_CHAIN *link_idx_chain + ); +#endif int set_sql_for_exec( ulong sql_type, int link_idx @@ -1393,6 +1439,78 @@ public: int link_idx, ulong sql_type ); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + int append_from_and_tables_part( + spider_fields *fields, + ulong sql_type + ); + int reappend_tables_part( + spider_fields *fields, + ulong sql_type + ); + int append_where_part( + ulong sql_type + ); + int append_having_part( + ulong sql_type + ); + int append_item_type_part( + Item *item, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_list_item_select_part( + List<Item> *select, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_list_item_select( + List<Item> *select, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields + ); + int append_group_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_group_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields + ); + int append_order_by_part( + ORDER *order, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields, + ulong sql_type + ); + int append_order_by( + ORDER *order, + spider_string *str, + const char *alias, + uint alias_length, + bool use_fields, + spider_fields *fields + ); +#endif }; class spider_oracle_copy_table: public spider_db_copy_table diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 0ef19673e89..045c885e211 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2015 Kentoku Shiba +/* Copyright (C) 2009-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -59,7 +59,11 @@ extern PSI_cond_key spd_key_cond_bg_direct_sql; #endif extern HASH spider_open_connections; +extern HASH spider_ipport_conns; extern pthread_mutex_t spider_conn_mutex; +extern pthread_mutex_t spider_conn_id_mutex; +extern pthread_mutex_t spider_ipport_conn_mutex; +extern ulonglong spider_conn_id; uint spider_udf_calc_hash( char *key, @@ -351,6 +355,27 @@ int spider_udf_direct_sql_create_conn_key( #endif } } + if (direct_sql->dbton_id == SPIDER_DBTON_SIZE) + { +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + if (direct_sql->access_mode == 0) + { +#endif + my_printf_error( + ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM, + ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR, + MYF(0), direct_sql->tgt_wrapper); + DBUG_RETURN(ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM); +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + } else { + my_printf_error( + ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM, + ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR, + MYF(0), direct_sql->tgt_wrapper); + DBUG_RETURN(ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM); + } +#endif + } #ifdef SPIDER_HAS_HASH_VALUE_TYPE direct_sql->conn_key_hash_value = my_calc_hash(&spider_open_connections, (uchar*) direct_sql->conn_key, direct_sql->conn_key_length); @@ -363,6 +388,7 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( int *error_num ) { SPIDER_CONN *conn; + SPIDER_IP_PORT_CONN *ip_port_conn; char *tmp_name, *tmp_host, *tmp_username, *tmp_password, *tmp_socket; char *tmp_wrapper, *tmp_ssl_ca, *tmp_ssl_capath, *tmp_ssl_cert; char *tmp_ssl_cipher, *tmp_ssl_key, *tmp_default_file, *tmp_default_group; @@ -560,12 +586,57 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( goto error; conn->ping_time = (time_t) time((time_t*) 0); conn->connect_error_time = conn->ping_time; + pthread_mutex_lock(&spider_conn_id_mutex); + conn->conn_id = spider_conn_id; + ++spider_conn_id; + pthread_mutex_unlock(&spider_conn_id_mutex); + + pthread_mutex_lock(&spider_ipport_conn_mutex); +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search_using_hash_value( + &spider_ipport_conns, conn->conn_key_hash_value, + (uchar*)conn->conn_key, conn->conn_key_length))) +#else + if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search( + &spider_ipport_conns, (uchar*)conn->conn_key, conn->conn_key_length))) +#endif + { /* exists, +1 */ + pthread_mutex_unlock(&spider_ipport_conn_mutex); + pthread_mutex_lock(&ip_port_conn->mutex); + if (spider_param_max_connections()) + { /* enable conncetion pool */ + if (ip_port_conn->ip_port_count >= spider_param_max_connections()) + { /* bigger than the max num of connections, free conn and return NULL */ + pthread_mutex_unlock(&ip_port_conn->mutex); + goto error_too_many_ipport_count; + } + } + ip_port_conn->ip_port_count++; + pthread_mutex_unlock(&ip_port_conn->mutex); + } + else + {// do not exist + ip_port_conn = spider_create_ipport_conn(conn); + if (!ip_port_conn) { + /* failed, always do not effect 'create conn' */ + pthread_mutex_unlock(&spider_ipport_conn_mutex); + DBUG_RETURN(conn); + } + if (my_hash_insert(&spider_ipport_conns, (uchar *)ip_port_conn)) { + /* insert failed, always do not effect 'create conn' */ + pthread_mutex_unlock(&spider_ipport_conn_mutex); + DBUG_RETURN(conn); + } + pthread_mutex_unlock(&spider_ipport_conn_mutex); + } + conn->ip_port_conn = ip_port_conn; DBUG_RETURN(conn); error: DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name); pthread_mutex_destroy(&conn->mta_conn_mutex); +error_too_many_ipport_count: error_mta_conn_mutex_init: error_db_conn_init: delete conn->db_conn; @@ -1624,6 +1695,15 @@ long long spider_direct_sql_body( goto error; } } +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + if (trx->trx_start && direct_sql->access_mode != 1) + { +#endif + trx->updated_in_this_trx = TRUE; + DBUG_PRINT("info",("spider trx->updated_in_this_trx=TRUE")); +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + } +#endif #if MYSQL_VERSION_ID < 50500 #else use_real_table = spider_param_udf_ds_use_real_table(thd, @@ -1642,7 +1722,7 @@ long long spider_direct_sql_body( table_list.table_name = direct_sql->table_names[roop_count]; #endif if (!(direct_sql->tables[roop_count] = - thd->find_temporary_table(&table_list))) + SPIDER_find_temporary_table(thd, &table_list))) { #if MYSQL_VERSION_ID < 50500 #else diff --git a/storage/spider/spd_direct_sql.h b/storage/spider/spd_direct_sql.h index 12d81346f0d..26e3043dd94 100644 --- a/storage/spider/spd_direct_sql.h +++ b/storage/spider/spd_direct_sql.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ uint spider_udf_calc_hash( char *key, diff --git a/storage/spider/spd_environ.h b/storage/spider/spd_environ.h index fa462c75230..31316e60978 100644 --- a/storage/spider/spd_environ.h +++ b/storage/spider/spd_environ.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba & 2017 MariaDB corp +/* Copyright (C) 2008-2017 Kentoku Shiba & 2017 MariaDB corp This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,13 +23,14 @@ #define SPIDER_HANDLER_START_BULK_INSERT_HAS_FLAGS #endif -#if MYSQL_VERSION_ID >= 100204 +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100100 +#define SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE +#endif + +#if defined(MARIADB_BASE_VERSION) && 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 -#define PARTITION_HAS_EXTRA_ATTACH_CHILDREN #define PARTITION_HAS_GET_CHILD_HANDLERS #define HA_EXTRA_HAS_STARTING_ORDERED_INDEX_SCAN #define HANDLER_HAS_NEED_INFO_FOR_AUTO_INC diff --git a/storage/spider/spd_err.h b/storage/spider/spd_err.h index ed26359f98b..1523df21cf1 100644 --- a/storage/spider/spd_err.h +++ b/storage/spider/spd_err.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2014 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define ER_SPIDER_INVALID_CONNECT_INFO_NUM 12501 #define ER_SPIDER_INVALID_CONNECT_INFO_STR "The connect info '%-.64s' is invalid" @@ -21,10 +21,10 @@ #define ER_SPIDER_INVALID_UDF_PARAM_STR "The UDF parameter '%-.64s' is invalid" #define ER_SPIDER_DIFFERENT_LINK_COUNT_NUM 12504 #define ER_SPIDER_DIFFERENT_LINK_COUNT_STR "Different multiple table link parameter's count" -#define ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_NUM 12505 -#define ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_STR "Server name or table name are too long" -#define ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_NUM 12506 -#define ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_STR "Server name or table name are required" +#define ER_SPIDER_UDF_PARAM_TOO_LONG_NUM 12505 +#define ER_SPIDER_UDF_PARAM_TOO_LONG_STR "The UDF parameter '%-.64s' is too long" +#define ER_SPIDER_UDF_PARAM_REQIRED_NUM 12506 +#define ER_SPIDER_UDF_PARAM_REQIRED_STR "The UDF parameter '%-.64s' is required" #define ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM 12507 #define ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR "This UDF can't execute if other tables are opened" #define ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM "This UDF can't execute if other tables are opened '%s'=%lld" @@ -65,6 +65,10 @@ #define ER_SPIDER_CANT_OPEN_SYS_TABLE_STR "Can't open system table %s.%s" #define ER_SPIDER_LINK_MON_JUST_NG_NUM 12525 #define ER_SPIDER_LINK_MON_JUST_NG_STR "Table '%s.%s' just got a problem" +#define ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_NUM 12526 +#define ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_STR "The connect info '%-.64s' for %s cannot start with number" +#define ER_SPIDER_INVALID_CONNECT_INFO_SAME_NUM 12527 +#define ER_SPIDER_INVALID_CONNECT_INFO_SAME_STR "The connect info '%-.64s' for %s cannot use same name in same table" #define ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_NUM 12601 #define ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_STR "Can't use both spider_use_consistent_snapshot = 1 and spider_internal_xa = 1" @@ -116,6 +120,10 @@ #define ER_SPIDER_ORACLE_STR "Error from Oracle %d %d %s" #define ER_SPIDER_ORACLE_NUM 12712 #define ER_SPIDER_ORACLE_ERR "Oracle error" +#define ER_SPIDER_CON_COUNT_ERROR 12713 +#define ER_SPIDER_CON_COUNT_ERROR_STR "Too many connections between spider and remote" +#define ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM 12714 +#define ER_SPIDER_TABLE_OPEN_TIMEOUT_STR "Table %s.%s open timeout" #define ER_SPIDER_COND_SKIP_NUM 12801 #define ER_SPIDER_UNKNOWN_NUM 12500 diff --git a/storage/spider/spd_group_by_handler.cc b/storage/spider/spd_group_by_handler.cc new file mode 100644 index 00000000000..9e30d0d1fa0 --- /dev/null +++ b/storage/spider/spd_group_by_handler.cc @@ -0,0 +1,2019 @@ +/* Copyright (C) 2008-2017 Kentoku Shiba + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#define MYSQL_SERVER 1 +#include <my_global.h> +#include "mysql_version.h" +#include "spd_environ.h" +#if MYSQL_VERSION_ID < 50500 +#include "mysql_priv.h" +#include <mysql/plugin.h> +#else +#include "sql_priv.h" +#include "probes_mysql.h" +#include "sql_class.h" +#include "sql_partition.h" +#include "ha_partition.h" +#endif +#include "sql_common.h" +#include <errmsg.h> +#include "spd_err.h" +#include "spd_param.h" +#include "spd_db_include.h" +#include "spd_include.h" +#include "ha_spider.h" +#include "spd_conn.h" +#include "spd_db_conn.h" +#include "spd_malloc.h" +#include "spd_table.h" +#include "spd_ping_table.h" +#include "spd_group_by_handler.h" + +extern handlerton *spider_hton_ptr; +extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; + +spider_fields::spider_fields() : + dbton_count(0), current_dbton_num(0), + table_count(0), current_table_num(0), table_holder(NULL), + first_link_idx_chain(NULL), last_link_idx_chain(NULL), current_link_idx_chain(NULL), + first_conn_holder(NULL), last_conn_holder(NULL), current_conn_holder(NULL), + first_field_holder(NULL), last_field_holder(NULL), current_field_holder(NULL), + first_field_chain(NULL), last_field_chain(NULL), current_field_chain(NULL) +{ + DBUG_ENTER("spider_fields::spider_fields"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_VOID_RETURN; +} + +spider_fields::~spider_fields() +{ + DBUG_ENTER("spider_fields::~spider_fields"); + DBUG_PRINT("info",("spider this=%p", this)); + if (first_link_idx_chain) + { + while ((current_link_idx_chain = first_link_idx_chain)) + { + first_link_idx_chain = current_link_idx_chain->next; + spider_free(spider_current_trx, current_link_idx_chain, MYF(0)); + } + } + if (first_field_chain) + { + while ((current_field_chain = first_field_chain)) + { + first_field_chain = current_field_chain->next; + spider_free(spider_current_trx, current_field_chain, MYF(0)); + } + } + if (first_field_holder) + { + while ((current_field_holder = first_field_holder)) + { + first_field_holder = current_field_holder->next; + spider_free(spider_current_trx, current_field_holder, MYF(0)); + } + } + if (table_holder) + spider_free(spider_current_trx, table_holder, MYF(0)); + if (first_conn_holder) + { + while ((current_conn_holder = first_conn_holder)) + { + first_conn_holder = current_conn_holder->next; + free_conn_holder(current_conn_holder); + } + } + DBUG_VOID_RETURN; +} + +void spider_fields::add_dbton_id( + uint dbton_id_arg +) { + uint roop_count; + DBUG_ENTER("spider_fields::add_dbton_id"); + DBUG_PRINT("info",("spider this=%p", this)); + for (roop_count = 0; roop_count < dbton_count; ++roop_count) + { + if (dbton_ids[roop_count] == dbton_id_arg) + { + DBUG_VOID_RETURN; + } + } + dbton_ids[roop_count] = dbton_id_arg; + ++dbton_count; + DBUG_VOID_RETURN; +} + +void spider_fields::set_pos_to_first_dbton_id( +) { + DBUG_ENTER("spider_fields::set_pos_to_first_dbton_id"); + DBUG_PRINT("info",("spider this=%p", this)); + current_dbton_num = 0; + DBUG_VOID_RETURN; +} + +uint spider_fields::get_next_dbton_id( +) { + uint return_dbton_id; + DBUG_ENTER("spider_fields::get_next_dbton_id"); + DBUG_PRINT("info",("spider this=%p", this)); + if (current_dbton_num >= dbton_count) + DBUG_RETURN(SPIDER_DBTON_SIZE); + return_dbton_id = dbton_ids[current_dbton_num]; + ++current_dbton_num; + DBUG_RETURN(return_dbton_id); +} + +int spider_fields::make_link_idx_chain( + int link_status +) { + uint roop_count, roop_count2; + SPIDER_CONN *conn; + SPIDER_CONN_HOLDER *conn_holder; + SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder; + SPIDER_LINK_IDX_HOLDER *link_idx_holder, *add_link_idx_holder, + *dup_link_idx_holder, *current_link_idx_holder; + ha_spider *spider; + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + SPIDER_SHARE *share; + DBUG_ENTER("spider_fields::make_link_idx_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + conn_holder = first_conn_holder; + bool has_remain, skip; + do { + for (roop_count2 = 0; roop_count2 < table_count; ++roop_count2) + { + table_link_idx_holder = &conn_holder->table_link_idx_holder[roop_count2]; + link_idx_holder = table_link_idx_holder->first_link_idx_holder; + dup_link_idx_holder = NULL; + for (roop_count = 0; + roop_count < conn_holder->link_idx_holder_count_max - 1; ++roop_count) + { + if (!link_idx_holder->next) + { + DBUG_PRINT("info",("spider fill link_idx_holder for %u", + roop_count2)); + if (!(add_link_idx_holder = create_link_idx_holder())) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + dup_link_idx_holder = get_dup_link_idx_holder( + table_link_idx_holder, dup_link_idx_holder); + add_link_idx_holder->table_link_idx_holder = + dup_link_idx_holder->table_link_idx_holder; + add_link_idx_holder->link_idx = dup_link_idx_holder->link_idx; + link_idx_holder->next = add_link_idx_holder; + } + link_idx_holder = link_idx_holder->next; + } + } + + for (roop_count2 = 0; roop_count2 < table_count; ++roop_count2) + { + table_link_idx_holder = &conn_holder->table_link_idx_holder[roop_count2]; + table_link_idx_holder->current_link_idx_holder = + table_link_idx_holder->first_link_idx_holder; + } + for (roop_count = 0; + roop_count < conn_holder->link_idx_holder_count_max; ++roop_count) + { + link_idx_holder = NULL; + for (roop_count2 = 0; roop_count2 < table_count; ++roop_count2) + { + table_link_idx_holder = + &conn_holder->table_link_idx_holder[roop_count2]; + if (link_idx_holder) + { + link_idx_holder->next_table = + table_link_idx_holder->current_link_idx_holder; + } + link_idx_holder = table_link_idx_holder->current_link_idx_holder; + table_link_idx_holder->current_link_idx_holder = link_idx_holder->next; + } + } + } while ((conn_holder = conn_holder->next)); + + current_conn_holder = first_conn_holder; + do { + table_link_idx_holder = + ¤t_conn_holder->table_link_idx_holder[0]; + table_link_idx_holder->current_link_idx_holder = + table_link_idx_holder->first_link_idx_holder; + } while ((current_conn_holder = current_conn_holder->next)); + + spider = table_holder[0].spider; + share = spider->share; + DBUG_PRINT("info",("spider create link_idx_chain sorted by 0")); + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + link_status); + roop_count < share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + link_status) + ) { + conn = spider->conns[roop_count]; + if (!conn->conn_holder_for_direct_join) + { + continue; + } + table_link_idx_holder = + &conn->conn_holder_for_direct_join->table_link_idx_holder[0]; + link_idx_holder = table_link_idx_holder->current_link_idx_holder; + table_link_idx_holder->current_link_idx_holder = link_idx_holder->next; + DBUG_ASSERT(link_idx_holder->link_idx == (int) roop_count); + if (!(link_idx_chain = create_link_idx_chain())) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + if (!first_link_idx_chain) + { + first_link_idx_chain = link_idx_chain; + } else { + last_link_idx_chain->next = link_idx_chain; + } + last_link_idx_chain = link_idx_chain; + link_idx_chain->conn = conn; + link_idx_chain->link_idx_holder = link_idx_holder; + do { + if (link_idx_chain->link_status < link_idx_holder->link_status) + { + link_idx_chain->link_status = link_idx_holder->link_status; + } + } while ((link_idx_holder = link_idx_holder->next_table)); + } + + do { + has_remain = FALSE; + current_conn_holder = first_conn_holder; + do { + table_link_idx_holder = + ¤t_conn_holder->table_link_idx_holder[0]; + link_idx_holder = table_link_idx_holder->current_link_idx_holder; + if (link_idx_holder) + { + has_remain = TRUE; + for (roop_count2 = 1; roop_count2 < table_count; ++roop_count2) + { + if (table_link_idx_holder[roop_count2].link_idx_holder_count == + current_conn_holder->link_idx_holder_count_max) + { + break; + } + } + break; + } + } while ((current_conn_holder = current_conn_holder->next)); + + if (has_remain) + { + current_conn_holder = first_conn_holder; + do { + table_link_idx_holder = + ¤t_conn_holder->table_link_idx_holder[0]; + link_idx_holder = table_link_idx_holder->current_link_idx_holder; + if (link_idx_holder) + { + for (roop_count = 1; roop_count <= roop_count2; ++roop_count) + { + link_idx_holder = link_idx_holder->next_table; + } + table_link_idx_holder[roop_count2].current_link_idx_holder = + link_idx_holder; + } else { + table_link_idx_holder[roop_count2].current_link_idx_holder = NULL; + } + } while ((current_conn_holder = current_conn_holder->next)); + + spider = table_holder[roop_count2].spider; + share = spider->share; + DBUG_PRINT("info",("spider create link_idx_chain sorted by %d", + roop_count2)); + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + link_status); + roop_count < share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + link_status) + ) { + conn = spider->conns[roop_count]; + if (!conn->conn_holder_for_direct_join) + { + continue; + } + table_link_idx_holder = + &conn->conn_holder_for_direct_join->table_link_idx_holder[0]; + link_idx_holder = + table_link_idx_holder[roop_count2].current_link_idx_holder; + skip = FALSE; + if (link_idx_holder) + { + current_link_idx_holder = table_link_idx_holder->first_link_idx_holder; + while (current_link_idx_holder != link_idx_holder) + { + if (current_link_idx_holder->link_idx == + link_idx_holder->link_idx) + { + skip = TRUE; + break; + } + current_link_idx_holder = current_link_idx_holder->next; + } + } + if (skip) + { + continue; + } + DBUG_PRINT("info",("spider create link_idx_chain for %d", + roop_count2)); + table_link_idx_holder[roop_count2].current_link_idx_holder = + link_idx_holder->next; + link_idx_holder = + table_link_idx_holder->current_link_idx_holder; + table_link_idx_holder->current_link_idx_holder = + link_idx_holder->next; + if (!(link_idx_chain = create_link_idx_chain())) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + DBUG_ASSERT(first_link_idx_chain); + last_link_idx_chain->next = link_idx_chain; + last_link_idx_chain = link_idx_chain; + link_idx_chain->conn = conn; + link_idx_chain->link_idx_holder = link_idx_holder; + do { + if (link_idx_chain->link_status < link_idx_holder->link_status) + { + link_idx_chain->link_status = link_idx_holder->link_status; + } + } while ((link_idx_holder = link_idx_holder->next_table)); + } + } + } while (has_remain); + DBUG_RETURN(0); +} + +SPIDER_LINK_IDX_CHAIN *spider_fields::create_link_idx_chain( +) { + DBUG_ENTER("spider_fields::create_link_idx_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN((SPIDER_LINK_IDX_CHAIN *) + spider_malloc(spider_current_trx, 254, sizeof(SPIDER_LINK_IDX_CHAIN), + MYF(MY_WME | MY_ZEROFILL))); +} + +void spider_fields::set_pos_to_first_link_idx_chain( +) { + DBUG_ENTER("spider_fields::set_pos_to_first_link_idx_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + current_link_idx_chain = first_link_idx_chain; + DBUG_VOID_RETURN; +} + +SPIDER_LINK_IDX_CHAIN *spider_fields::get_next_link_idx_chain( +) { + SPIDER_LINK_IDX_CHAIN *return_link_idx_chain = current_link_idx_chain; + DBUG_ENTER("spider_fields::get_next_link_idx_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + if (current_link_idx_chain) + current_link_idx_chain = current_link_idx_chain->next; + DBUG_RETURN(return_link_idx_chain); +} + +SPIDER_LINK_IDX_HOLDER *spider_fields::get_dup_link_idx_holder( + SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder, + SPIDER_LINK_IDX_HOLDER *current +) { + SPIDER_LINK_IDX_HOLDER *return_link_idx_holder; + DBUG_ENTER("spider_fields::get_dup_link_idx_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + if (!current) + { + return_link_idx_holder = table_link_idx_holder->first_link_idx_holder; + do { + if (return_link_idx_holder->link_status == SPIDER_LINK_STATUS_OK) + break; + } while ((return_link_idx_holder = return_link_idx_holder->next)); + if (!return_link_idx_holder) + { + return_link_idx_holder = table_link_idx_holder->first_link_idx_holder; + } + } else { + if (current->link_status == SPIDER_LINK_STATUS_OK) + { + return_link_idx_holder = current; + while ((return_link_idx_holder = return_link_idx_holder->next)) + { + if (return_link_idx_holder->link_status == SPIDER_LINK_STATUS_OK) + break; + } + if (!return_link_idx_holder) + { + return_link_idx_holder = table_link_idx_holder->first_link_idx_holder; + do { + if ( + return_link_idx_holder->link_status == SPIDER_LINK_STATUS_OK + ) + break; + DBUG_ASSERT(return_link_idx_holder != current); + } while ((return_link_idx_holder = return_link_idx_holder->next)); + } + } else { + if (!current->next) + { + return_link_idx_holder = table_link_idx_holder->first_link_idx_holder; + } else { + return_link_idx_holder = current->next; + } + } + } + DBUG_RETURN(return_link_idx_holder); +} + +bool spider_fields::check_link_ok_chain( +) { + DBUG_ENTER("spider_fields::check_link_ok_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + for (current_link_idx_chain = first_link_idx_chain; current_link_idx_chain; + current_link_idx_chain = current_link_idx_chain->next) + { + if (current_link_idx_chain->link_status == SPIDER_LINK_STATUS_OK) + { + first_ok_link_idx_chain = current_link_idx_chain; + DBUG_RETURN(FALSE); + } + } + DBUG_RETURN(TRUE); +} + +bool spider_fields::is_first_link_ok_chain( + SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg +) { + DBUG_ENTER("spider_fields::is_first_link_ok_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN(first_ok_link_idx_chain == link_idx_chain_arg); +} + +int spider_fields::get_ok_link_idx( +) { + DBUG_ENTER("spider_fields::get_ok_link_idx"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN(first_ok_link_idx_chain->link_idx_holder->link_idx); +} + +void spider_fields::set_first_link_idx( +) { + SPIDER_TABLE_HOLDER *table_holder; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + uint dbton_id; + ha_spider *spider; + spider_db_handler *dbton_hdl; + DBUG_ENTER("spider_fields::set_first_link_idx"); + DBUG_PRINT("info",("spider this=%p", this)); + set_pos_to_first_dbton_id(); + while ((dbton_id = get_next_dbton_id()) < SPIDER_DBTON_SIZE) + { + set_pos_to_first_link_idx_chain(); + while ((link_idx_chain = get_next_link_idx_chain())) + { + if (link_idx_chain->conn->dbton_id == dbton_id) + { + break; + } + } + DBUG_ASSERT(link_idx_chain); + set_pos_to_first_table_on_link_idx_chain(link_idx_chain); + + set_pos_to_first_table_holder(); + while ((table_holder = get_next_table_holder())) + { + link_idx_holder = get_next_table_on_link_idx_chain(link_idx_chain); + spider = table_holder->spider; + dbton_hdl = spider->dbton_handler[dbton_id]; + dbton_hdl->first_link_idx = link_idx_holder->link_idx; + } + } + DBUG_VOID_RETURN; +} + +int spider_fields::add_link_idx( + SPIDER_CONN_HOLDER *conn_holder_arg, + ha_spider *spider_arg, + int link_idx +) { + SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + DBUG_ENTER("spider_fields::add_link_idx"); + DBUG_PRINT("info",("spider this=%p", this)); + table_link_idx_holder = + &conn_holder_arg->table_link_idx_holder[spider_arg->idx_for_direct_join]; + if (!table_link_idx_holder->first_link_idx_holder) + { + link_idx_holder = create_link_idx_holder(); + DBUG_PRINT("info",("spider link_idx_holder=%p", link_idx_holder)); + if (!link_idx_holder) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + table_link_idx_holder->first_link_idx_holder = link_idx_holder; + table_link_idx_holder->last_link_idx_holder = link_idx_holder; + table_link_idx_holder->table_holder = + &table_holder[spider_arg->idx_for_direct_join]; + } else { + link_idx_holder = create_link_idx_holder(); + DBUG_PRINT("info",("spider link_idx_holder=%p", link_idx_holder)); + if (!link_idx_holder) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + table_link_idx_holder->last_link_idx_holder->next = link_idx_holder; + table_link_idx_holder->last_link_idx_holder = link_idx_holder; + } + link_idx_holder->table_link_idx_holder = table_link_idx_holder; + link_idx_holder->link_idx = link_idx; + link_idx_holder->link_status = spider_conn_get_link_status( + spider_arg->share->link_statuses, spider_arg->conn_link_idx, + link_idx); + ++table_link_idx_holder->link_idx_holder_count; + if (conn_holder_arg->link_idx_holder_count_max < + table_link_idx_holder->link_idx_holder_count) + { + conn_holder_arg->link_idx_holder_count_max = + table_link_idx_holder->link_idx_holder_count; + } + DBUG_RETURN(0); +} + +SPIDER_LINK_IDX_HOLDER *spider_fields::create_link_idx_holder( +) { + DBUG_ENTER("spider_fields::create_link_idx_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN((SPIDER_LINK_IDX_HOLDER *) + spider_malloc(spider_current_trx, 253, sizeof(SPIDER_LINK_IDX_HOLDER), + MYF(MY_WME | MY_ZEROFILL))); +} + +void spider_fields::set_pos_to_first_table_on_link_idx_chain( + SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg +) { + DBUG_ENTER("spider_fields::set_pos_to_first_table_on_link_idx_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + link_idx_chain_arg->current_link_idx_holder = + link_idx_chain_arg->link_idx_holder; + DBUG_VOID_RETURN; +} + +SPIDER_LINK_IDX_HOLDER *spider_fields::get_next_table_on_link_idx_chain( + SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg +) { + SPIDER_LINK_IDX_HOLDER *return_link_idx_holder; + DBUG_ENTER("spider_fields::get_next_table_on_link_idx_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + if (!link_idx_chain_arg->current_link_idx_holder) + DBUG_RETURN(NULL); + return_link_idx_holder = link_idx_chain_arg->current_link_idx_holder; + link_idx_chain_arg->current_link_idx_holder = + link_idx_chain_arg->current_link_idx_holder->next_table; + DBUG_RETURN(return_link_idx_holder); +} + +SPIDER_CONN_HOLDER *spider_fields::add_conn( + SPIDER_CONN *conn_arg, + long access_balance +) { + SPIDER_CONN_HOLDER *conn_holder; + DBUG_ENTER("spider_fields::add_conn"); + DBUG_PRINT("info",("spider this=%p", this)); + if (!first_conn_holder) + { + conn_holder = create_conn_holder(); + DBUG_PRINT("info",("spider conn_holder=%p", conn_holder)); + if (!conn_holder) + DBUG_RETURN(NULL); + conn_holder->conn = conn_arg; + conn_holder->access_balance = access_balance; + first_conn_holder = conn_holder; + last_conn_holder = conn_holder; + conn_arg->conn_holder_for_direct_join = conn_holder; + add_dbton_id(conn_arg->dbton_id); + } else { + conn_holder = first_conn_holder; + do { + if (conn_holder->conn == conn_arg) + break; + } while ((conn_holder = conn_holder->next)); + if (!conn_holder) + { + conn_holder = create_conn_holder(); + DBUG_PRINT("info",("spider conn_holder=%p", conn_holder)); + if (!conn_holder) + DBUG_RETURN(NULL); + conn_holder->conn = conn_arg; + conn_holder->access_balance = access_balance; + conn_holder->prev = last_conn_holder; + last_conn_holder->next = conn_holder; + last_conn_holder = conn_holder; + conn_arg->conn_holder_for_direct_join = conn_holder; + add_dbton_id(conn_arg->dbton_id); + } + } + DBUG_RETURN(conn_holder); +} + +SPIDER_CONN_HOLDER *spider_fields::create_conn_holder( +) { + SPIDER_CONN_HOLDER *return_conn_holder; + SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder; + DBUG_ENTER("spider_fields::create_conn_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + return_conn_holder = (SPIDER_CONN_HOLDER *) + spider_bulk_malloc(spider_current_trx, 252, MYF(MY_WME | MY_ZEROFILL), + &return_conn_holder, sizeof(SPIDER_CONN_HOLDER), + &table_link_idx_holder, + table_count * sizeof(SPIDER_TABLE_LINK_IDX_HOLDER), + NullS + ); + if (!return_conn_holder) + DBUG_RETURN(NULL); + DBUG_PRINT("info",("spider table_count=%u", table_count)); + DBUG_PRINT("info",("spider table_link_idx_holder=%p", table_link_idx_holder)); + return_conn_holder->table_link_idx_holder = table_link_idx_holder; + DBUG_RETURN(return_conn_holder); +} + +void spider_fields::set_pos_to_first_conn_holder( +) { + DBUG_ENTER("spider_fields::set_pos_to_first_conn_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + current_conn_holder = first_conn_holder; + DBUG_VOID_RETURN; +} + +SPIDER_CONN_HOLDER *spider_fields::get_next_conn_holder( +) { + SPIDER_CONN_HOLDER *return_conn_holder = current_conn_holder; + DBUG_ENTER("spider_fields::get_next_conn_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + if (current_conn_holder) + current_conn_holder = current_conn_holder->next; + DBUG_RETURN(return_conn_holder); +} + +bool spider_fields::has_conn_holder( +) { + DBUG_ENTER("spider_fields::has_conn_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN(first_conn_holder); +} + +void spider_fields::clear_conn_holder_from_conn( +) { + DBUG_ENTER("spider_fields::clear_conn_checked_for_same_conn"); + DBUG_PRINT("info",("spider this=%p", this)); + for (current_conn_holder = first_conn_holder; current_conn_holder; + current_conn_holder = current_conn_holder->next) + { + current_conn_holder->checked_for_same_conn = FALSE; + } + DBUG_VOID_RETURN; +} + +bool spider_fields::check_conn_same_conn( + SPIDER_CONN *conn_arg +) { + DBUG_ENTER("spider_fields::check_conn_same_conn"); + DBUG_PRINT("info",("spider this=%p", this)); + for (current_conn_holder = first_conn_holder; current_conn_holder; + current_conn_holder = current_conn_holder->next) + { + if (current_conn_holder->conn == conn_arg) + { + current_conn_holder->checked_for_same_conn = TRUE; + DBUG_RETURN(TRUE); + } + } + DBUG_RETURN(FALSE); +} + +bool spider_fields::remove_conn_if_not_checked( +) { + SPIDER_CONN_HOLDER *conn_holder; + bool removed = FALSE; + DBUG_ENTER("spider_fields::remove_conn_if_not_checked"); + DBUG_PRINT("info",("spider this=%p", this)); + current_conn_holder = first_conn_holder; + while (current_conn_holder) + { + if (!current_conn_holder->checked_for_same_conn) + { + removed = TRUE; + DBUG_PRINT("info",("spider remove connection %p", + current_conn_holder->conn)); + if (!current_conn_holder->prev) + { + first_conn_holder = current_conn_holder->next; + if (current_conn_holder->next) + { + current_conn_holder->next->prev = NULL; + } else { + last_conn_holder = NULL; + } + } else { + current_conn_holder->prev->next = current_conn_holder->next; + if (current_conn_holder->next) + { + current_conn_holder->next->prev = current_conn_holder->prev; + } else { + last_conn_holder = current_conn_holder->prev; + last_conn_holder->next = NULL; + } + } + conn_holder = current_conn_holder->next; + free_conn_holder(current_conn_holder); + current_conn_holder = conn_holder; + } else { + current_conn_holder = current_conn_holder->next; + } + } + DBUG_RETURN(removed); +} + +void spider_fields::check_support_dbton( + uchar *dbton_bitmap +) { + SPIDER_CONN_HOLDER *conn_holder; + DBUG_ENTER("spider_fields::check_support_dbton"); + DBUG_PRINT("info",("spider this=%p", this)); + current_conn_holder = first_conn_holder; + while (current_conn_holder) + { + if (!spider_bit_is_set(dbton_bitmap, current_conn_holder->conn->dbton_id)) + { + DBUG_PRINT("info",("spider remove connection %p", + current_conn_holder->conn)); + if (!current_conn_holder->prev) + { + first_conn_holder = current_conn_holder->next; + if (current_conn_holder->next) + { + current_conn_holder->next->prev = NULL; + } else { + last_conn_holder = NULL; + } + } else { + current_conn_holder->prev->next = current_conn_holder->next; + if (current_conn_holder->next) + { + current_conn_holder->next->prev = current_conn_holder->prev; + } else { + last_conn_holder = current_conn_holder->prev; + last_conn_holder->next = NULL; + } + } + conn_holder = current_conn_holder->next; + free_conn_holder(current_conn_holder); + current_conn_holder = conn_holder; + } else { + current_conn_holder = current_conn_holder->next; + } + } + DBUG_VOID_RETURN; +} + +void spider_fields::choose_a_conn( +) { + SPIDER_CONN_HOLDER *conn_holder; + longlong balance_total = 0, balance_val; + double rand_val; + THD *thd = table_holder[0].spider->trx->thd; + DBUG_ENTER("spider_fields::choose_a_conn"); + DBUG_PRINT("info",("spider this=%p", this)); + for (current_conn_holder = first_conn_holder; current_conn_holder; + current_conn_holder = current_conn_holder->next) + { + balance_total += current_conn_holder->access_balance; + } + + rand_val = spider_rand(thd->variables.server_id + thd_get_thread_id(thd)); + balance_val = (longlong) (rand_val * balance_total); + + current_conn_holder = first_conn_holder; + while (current_conn_holder) + { + if (balance_val < current_conn_holder->access_balance) + break; + balance_val -= current_conn_holder->access_balance; + + DBUG_PRINT("info",("spider remove connection %p", + current_conn_holder->conn)); + first_conn_holder = current_conn_holder->next; + DBUG_ASSERT(current_conn_holder->next); + first_conn_holder->prev = NULL; + free_conn_holder(current_conn_holder); + current_conn_holder = first_conn_holder; + } + + DBUG_PRINT("info",("spider choosed connection is %p", + current_conn_holder->conn)); + last_conn_holder = current_conn_holder; + current_conn_holder = current_conn_holder->next; + last_conn_holder->next = NULL; + + while (current_conn_holder) + { + DBUG_PRINT("info",("spider remove connection %p", + current_conn_holder->conn)); + conn_holder = current_conn_holder->next; + free_conn_holder(current_conn_holder); + current_conn_holder = conn_holder; + } + DBUG_VOID_RETURN; +} + +void spider_fields::free_conn_holder( + SPIDER_CONN_HOLDER *conn_holder_arg +) { + uint roop_count; + DBUG_ENTER("spider_fields::free_conn_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + for (roop_count = 0; roop_count < table_count; ++roop_count) + { + if (conn_holder_arg->table_link_idx_holder[roop_count].first_link_idx_holder) + { + SPIDER_LINK_IDX_HOLDER *first_link_idx_holder, *current_link_idx_holder; + first_link_idx_holder = + conn_holder_arg->table_link_idx_holder[roop_count].first_link_idx_holder; + while ((current_link_idx_holder = first_link_idx_holder)) + { + first_link_idx_holder = current_link_idx_holder->next; + spider_free(spider_current_trx, current_link_idx_holder, MYF(0)); + } + } + } + conn_holder_arg->conn->conn_holder_for_direct_join = NULL; + DBUG_PRINT("info",("spider free conn_holder=%p", conn_holder_arg)); + spider_free(spider_current_trx, conn_holder_arg, MYF(0)); + DBUG_VOID_RETURN; +} + +SPIDER_TABLE_HOLDER *spider_fields::add_table( + ha_spider *spider_arg +) { + spider_string *str; + uint length; + char tmp_buf[SPIDER_SQL_INT_LEN + 2]; + SPIDER_TABLE_HOLDER *return_table_holder; + SPIDER_FIELD_HOLDER *field_holder; + TABLE *table = spider_arg->get_table(); + Field *field; + DBUG_ENTER("spider_fields::add_table"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_PRINT("info",("spider table_count=%u", table_count)); + DBUG_PRINT("info",("spider idx_for_direct_join=%u", + spider_arg->idx_for_direct_join)); + length = my_sprintf(tmp_buf, (tmp_buf, "t%u", + spider_arg->idx_for_direct_join)); + str = &spider_arg->result_list.tmp_sqls[0]; + str->length(0); + if (str->reserve(length + SPIDER_SQL_DOT_LEN)) + { + DBUG_RETURN(NULL); + } + str->q_append(tmp_buf, length); + str->q_append(SPIDER_SQL_DOT_STR, SPIDER_SQL_DOT_LEN); + + return_table_holder = &table_holder[spider_arg->idx_for_direct_join]; + return_table_holder->table = spider_arg->get_table(); + return_table_holder->spider = spider_arg; + return_table_holder->alias = str; + + set_pos_to_first_field_holder(); + while ((field_holder = get_next_field_holder())) + { + if (!field_holder->spider) + { + field = field_holder->field; + if ( + field->field_index < table->s->fields && + field == table->field[field->field_index] + ) { + field_holder->spider = spider_arg; + field_holder->alias = str; + } + } + } + DBUG_RETURN(return_table_holder); +} + +int spider_fields::create_table_holder( + uint table_count_arg +) { + DBUG_ENTER("spider_fields::create_table_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_ASSERT(!table_holder); + table_holder = (SPIDER_TABLE_HOLDER *) + spider_malloc(spider_current_trx, 249, + table_count_arg * sizeof(SPIDER_TABLE_HOLDER), + MYF(MY_WME | MY_ZEROFILL)); + if (!table_holder) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + table_count = table_count_arg; + current_table_num = 0; + DBUG_RETURN(0); +} + +void spider_fields::set_pos_to_first_table_holder( +) { + DBUG_ENTER("spider_fields::set_pos_to_first_table_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + current_table_num = 0; + DBUG_VOID_RETURN; +} + +SPIDER_TABLE_HOLDER *spider_fields::get_next_table_holder( +) { + SPIDER_TABLE_HOLDER *return_table_holder; + DBUG_ENTER("spider_fields::get_next_table_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + if (current_table_num >= table_count) + DBUG_RETURN(NULL); + return_table_holder = &table_holder[current_table_num]; + ++current_table_num; + DBUG_RETURN(return_table_holder); +} + +int spider_fields::add_field( + Field *field_arg +) { + SPIDER_FIELD_HOLDER *field_holder; + SPIDER_FIELD_CHAIN *field_chain; + DBUG_ENTER("spider_fields::add_field"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_PRINT("info",("spider field=%p", field_arg)); + if (!first_field_holder) + { + field_holder = create_field_holder(); + DBUG_PRINT("info",("spider field_holder=%p", field_holder)); + if (!field_holder) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + field_holder->field = field_arg; + first_field_holder = field_holder; + last_field_holder = field_holder; + } else { + field_holder = first_field_holder; + do { + if (field_holder->field == field_arg) + break; + } while ((field_holder = field_holder->next)); + if (!field_holder) + { + field_holder = create_field_holder(); + DBUG_PRINT("info",("spider field_holder=%p", field_holder)); + if (!field_holder) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + field_holder->field = field_arg; + last_field_holder->next = field_holder; + last_field_holder = field_holder; + } + } + field_chain = create_field_chain(); + DBUG_PRINT("info",("spider field_chain=%p", field_chain)); + if (!field_chain) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + field_chain->field_holder = field_holder; + if (!first_field_chain) + { + first_field_chain = field_chain; + last_field_chain = field_chain; + } else { + last_field_chain->next = field_chain; + last_field_chain = field_chain; + } + DBUG_RETURN(0); +} + +SPIDER_FIELD_HOLDER *spider_fields::create_field_holder( +) { + DBUG_ENTER("spider_fields::create_field_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN((SPIDER_FIELD_HOLDER *) + spider_malloc(spider_current_trx, 250, sizeof(SPIDER_FIELD_HOLDER), + MYF(MY_WME | MY_ZEROFILL))); +} + +void spider_fields::set_pos_to_first_field_holder( +) { + DBUG_ENTER("spider_fields::set_pos_to_first_field_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + current_field_holder = first_field_holder; + DBUG_VOID_RETURN; +} + +SPIDER_FIELD_HOLDER *spider_fields::get_next_field_holder( +) { + SPIDER_FIELD_HOLDER *return_field_holder = current_field_holder; + DBUG_ENTER("spider_fields::get_next_field_holder"); + DBUG_PRINT("info",("spider this=%p", this)); + if (current_field_holder) + current_field_holder = current_field_holder->next; + DBUG_RETURN(return_field_holder); +} + +SPIDER_FIELD_CHAIN *spider_fields::create_field_chain( +) { + DBUG_ENTER("spider_fields::create_field_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_RETURN((SPIDER_FIELD_CHAIN *) + spider_malloc(spider_current_trx, 251, sizeof(SPIDER_FIELD_CHAIN), + MYF(MY_WME | MY_ZEROFILL))); +} + +void spider_fields::set_pos_to_first_field_chain( +) { + DBUG_ENTER("spider_fields::set_pos_to_first_field_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + current_field_chain = first_field_chain; + DBUG_VOID_RETURN; +} + +SPIDER_FIELD_CHAIN *spider_fields::get_next_field_chain( +) { + SPIDER_FIELD_CHAIN *return_field_chain = current_field_chain; + DBUG_ENTER("spider_fields::get_next_field_chain"); + DBUG_PRINT("info",("spider this=%p", this)); + if (current_field_chain) + current_field_chain = current_field_chain->next; + DBUG_RETURN(return_field_chain); +} + +void spider_fields::set_field_ptr( + Field **field_arg +) { + DBUG_ENTER("spider_fields::set_field_ptr"); + DBUG_PRINT("info",("spider this=%p", this)); + DBUG_PRINT("info",("spider field_ptr=%p", field_arg)); + first_field_ptr = field_arg; + current_field_ptr = field_arg; + DBUG_VOID_RETURN; +} + +Field **spider_fields::get_next_field_ptr( +) { + Field **return_field_ptr = current_field_ptr; + DBUG_ENTER("spider_fields::get_next_field_ptr"); + DBUG_PRINT("info",("spider this=%p", this)); + if (*current_field_ptr) + current_field_ptr++; + DBUG_PRINT("info",("spider field_ptr=%p", return_field_ptr)); + DBUG_RETURN(return_field_ptr); +} + +int spider_fields::ping_table_mon_from_table( + SPIDER_LINK_IDX_CHAIN *link_idx_chain +) { + int error_num = 0, error_num_buf; + ha_spider *tmp_spider; + SPIDER_SHARE *tmp_share; + int tmp_link_idx; + SPIDER_TABLE_HOLDER *table_holder; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + DBUG_ENTER("spider_fields::ping_table_mon_from_table"); + set_pos_to_first_table_on_link_idx_chain(link_idx_chain); + set_pos_to_first_table_holder(); + while ((table_holder = get_next_table_holder())) + { + link_idx_holder = get_next_table_on_link_idx_chain(link_idx_chain); + tmp_spider = table_holder->spider; + tmp_link_idx = link_idx_holder->link_idx; + tmp_share = tmp_spider->share; + if (tmp_share->monitoring_kind[tmp_link_idx]) + { + error_num_buf = spider_ping_table_mon_from_table( + tmp_spider->trx, + tmp_spider->trx->thd, + tmp_share, + tmp_link_idx, + (uint32) tmp_share->monitoring_sid[tmp_link_idx], + tmp_share->table_name, + tmp_share->table_name_length, + tmp_spider->conn_link_idx[tmp_link_idx], + NULL, + 0, + tmp_share->monitoring_kind[tmp_link_idx], + tmp_share->monitoring_limit[tmp_link_idx], + tmp_share->monitoring_flag[tmp_link_idx], + TRUE + ); + if (!error_num) + error_num = error_num_buf; + } + } + DBUG_RETURN(error_num); +} + +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +spider_group_by_handler::spider_group_by_handler( + THD *thd_arg, + Query *query_arg, + spider_fields *fields_arg +) : group_by_handler(thd_arg, spider_hton_ptr), + query(*query_arg), fields(fields_arg) +{ + DBUG_ENTER("spider_group_by_handler::spider_group_by_handler"); + fields->set_pos_to_first_table_holder(); + SPIDER_TABLE_HOLDER *table_holder = fields->get_next_table_holder(); + spider = table_holder->spider; + trx = spider->trx; + DBUG_VOID_RETURN; +} + +spider_group_by_handler::~spider_group_by_handler() +{ + DBUG_ENTER("spider_group_by_handler::~spider_group_by_handler"); + delete fields; + DBUG_VOID_RETURN; +} + +int spider_group_by_handler::init_scan() +{ + int error_num, link_idx; + uint dbton_id; + spider_db_handler *dbton_hdl; + st_select_lex *select_lex; + longlong select_limit; + longlong direct_order_limit; + SPIDER_SHARE *share = spider->share; + SPIDER_CONN *conn; + SPIDER_RESULT_LIST *result_list = &spider->result_list; + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + DBUG_ENTER("spider_group_by_handler::init_scan"); + store_error = 0; +#ifndef DBUG_OFF + Field **field; + for ( + field = table->field; + *field; + field++ + ) { + DBUG_PRINT("info",("spider field_name=%s", (*field)->field_name.str)); + } +#endif + + if (trx->thd->killed) + { + my_error(ER_QUERY_INTERRUPTED, MYF(0)); + DBUG_RETURN(ER_QUERY_INTERRUPTED); + } + + spider->use_fields = TRUE; + spider->fields = fields; + + spider->check_pre_call(TRUE); + + spider->pushed_pos = NULL; + result_list->sorted = (query.group_by || query.order_by); + spider_set_result_list_param(spider); + spider->mrr_with_cnt = FALSE; + spider->init_index_handler = FALSE; + spider->use_spatial_index = FALSE; + result_list->check_direct_order_limit = FALSE; + spider->select_column_mode = 0; + spider->search_link_idx = fields->get_ok_link_idx(); + spider->result_link_idx = spider->search_link_idx; + + spider_db_free_one_result_for_start_next(spider); + + spider->sql_kinds = SPIDER_SQL_KIND_SQL; + for (link_idx = 0; link_idx < (int) share->link_count; ++link_idx) + spider->sql_kind[link_idx] = SPIDER_SQL_KIND_SQL; + +#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS + spider->do_direct_update = FALSE; + spider->direct_update_kinds = 0; +#endif + spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit); + direct_order_limit = spider_param_direct_order_limit(thd, + share->direct_order_limit); + if ( + direct_order_limit && + select_lex->explicit_limit && + !(select_lex->options & OPTION_FOUND_ROWS) && + select_limit < direct_order_limit /* - offset_limit */ + ) { + result_list->internal_limit = select_limit /* + offset_limit */; + result_list->split_read = select_limit /* + offset_limit */; +#ifndef WITHOUT_SPIDER_BG_SEARCH + result_list->bgs_split_read = select_limit /* + offset_limit */; +#endif + + result_list->split_read_base = 9223372036854775807LL; + result_list->semi_split_read = 0; + result_list->semi_split_read_limit = 9223372036854775807LL; + result_list->first_read = 9223372036854775807LL; + result_list->second_read = 9223372036854775807LL; + trx->direct_order_limit_count++; + } + result_list->semi_split_read_base = 0; + result_list->set_split_read = TRUE; +#ifndef WITHOUT_SPIDER_BG_SEARCH + if ((error_num = spider_set_conn_bg_param(spider))) + DBUG_RETURN(error_num); +#endif + DBUG_PRINT("info",("spider result_list.finish_flg = FALSE")); + result_list->finish_flg = FALSE; + result_list->record_num = 0; + result_list->keyread = FALSE; + result_list->desc_flg = FALSE; + result_list->sorted = FALSE; + result_list->key_info = NULL; + result_list->key_order = 0; + result_list->limit_num = + result_list->internal_limit >= result_list->split_read ? + result_list->split_read : result_list->internal_limit; + + if (select_lex->explicit_limit) + { + result_list->internal_offset += offset_limit; + } else { + offset_limit = 0; + } + + /* making a query */ + fields->set_pos_to_first_dbton_id(); + while ((dbton_id = fields->get_next_dbton_id()) < SPIDER_DBTON_SIZE) + { + dbton_hdl = spider->dbton_handler[dbton_id]; + result_list->direct_distinct = query.distinct; + fields->set_pos_to_first_field_chain(); + if ((error_num = dbton_hdl->reset_sql(SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + if ((error_num = dbton_hdl->append_select_part(SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + fields->set_field_ptr(table->field); + if ((error_num = dbton_hdl->append_list_item_select_part( + query.select, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + if ((error_num = dbton_hdl->append_from_and_tables_part( + fields, SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + if (query.where) + { + if ((error_num = + dbton_hdl->append_where_part(SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + if ((error_num = dbton_hdl->append_item_type_part( + query.where, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + } + if (query.group_by) + { + if ((error_num = dbton_hdl->append_group_by_part( + query.group_by, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + } + if (query.having) + { + if ((error_num = + dbton_hdl->append_having_part(SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + if ((error_num = dbton_hdl->append_item_type_part( + query.having, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + } + if (query.order_by) + { + if ((error_num = dbton_hdl->append_order_by_part( + query.order_by, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + } + if ((error_num = dbton_hdl->append_limit_part(result_list->internal_offset, + result_list->limit_num, SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + if ((error_num = dbton_hdl->append_select_lock_part( + SPIDER_SQL_TYPE_SELECT_SQL))) + { + DBUG_RETURN(error_num); + } + } + + fields->set_pos_to_first_link_idx_chain(); + while ((link_idx_chain = fields->get_next_link_idx_chain())) + { + conn = link_idx_chain->conn; + link_idx_holder = link_idx_chain->link_idx_holder; + link_idx = link_idx_holder->link_idx; + dbton_hdl = spider->dbton_handler[conn->dbton_id]; + spider->link_idx_chain = link_idx_chain; +#ifndef WITHOUT_SPIDER_BG_SEARCH + if (result_list->bgs_phase > 0) + { + if ((error_num = spider_check_and_init_casual_read(trx->thd, spider, + link_idx))) + DBUG_RETURN(error_num); + if ((error_num = spider_bg_conn_search(spider, link_idx, + dbton_hdl->first_link_idx, TRUE, FALSE, + !fields->is_first_link_ok_chain(link_idx_chain)))) + { + if ( + error_num != HA_ERR_END_OF_FILE && + spider->need_mons[link_idx] + ) { + error_num = fields->ping_table_mon_from_table(link_idx_chain); + } + if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + { + store_error = HA_ERR_END_OF_FILE; + error_num = 0; + } + DBUG_RETURN(error_num); + } + } else { +#endif + if (dbton_hdl->need_lock_before_set_sql_for_exec( + SPIDER_SQL_TYPE_SELECT_SQL)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + if ((error_num = + dbton_hdl->set_sql_for_exec(SPIDER_SQL_TYPE_SELECT_SQL, link_idx, + link_idx_chain))) + { + DBUG_RETURN(error_num); + } + if (!dbton_hdl->need_lock_before_set_sql_for_exec( + SPIDER_SQL_TYPE_SELECT_SQL)) + { + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + } + conn->need_mon = &spider->need_mons[link_idx]; + conn->mta_conn_mutex_lock_already = TRUE; + conn->mta_conn_mutex_unlock_later = TRUE; + if ((error_num = spider_db_set_names(spider, conn, + link_idx))) + { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + if ( + spider->need_mons[link_idx] + ) { + error_num = fields->ping_table_mon_from_table(link_idx_chain); + } + if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + { + store_error = HA_ERR_END_OF_FILE; + error_num = 0; + } + DBUG_RETURN(error_num); + } + spider_conn_set_timeout_from_share(conn, link_idx, + trx->thd, share); + if (dbton_hdl->execute_sql( + SPIDER_SQL_TYPE_SELECT_SQL, + conn, + spider->result_list.quick_mode, + &spider->need_mons[link_idx]) + ) { + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + error_num = spider_db_errorno(conn); + if ( + spider->need_mons[link_idx] + ) { + error_num = fields->ping_table_mon_from_table(link_idx_chain); + } + if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + { + store_error = HA_ERR_END_OF_FILE; + error_num = 0; + } + DBUG_RETURN(error_num); + } + spider->connection_ids[link_idx] = conn->connection_id; + conn->mta_conn_mutex_lock_already = FALSE; + conn->mta_conn_mutex_unlock_later = FALSE; + if (fields->is_first_link_ok_chain(link_idx_chain)) + { + if ((error_num = spider_db_store_result(spider, link_idx, table))) + { + if ( + error_num != HA_ERR_END_OF_FILE && + spider->need_mons[link_idx] + ) { + error_num = fields->ping_table_mon_from_table(link_idx_chain); + } + if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + { + store_error = HA_ERR_END_OF_FILE; + error_num = 0; + } + DBUG_RETURN(error_num); + } + spider->result_link_idx = link_idx; + spider->result_link_idx_chain = link_idx_chain; + } else { + spider_db_discard_result(spider, link_idx, conn); + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + } +#ifndef WITHOUT_SPIDER_BG_SEARCH + } +#endif + } + + first = TRUE; + DBUG_RETURN(0); +} + +int spider_group_by_handler::next_row() +{ + int error_num, link_idx; + spider_db_handler *dbton_hdl; + SPIDER_CONN *conn; + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + DBUG_ENTER("spider_group_by_handler::next_row"); + if (trx->thd->killed) + { + my_error(ER_QUERY_INTERRUPTED, MYF(0)); + DBUG_RETURN(ER_QUERY_INTERRUPTED); + } + if (store_error) + { + if (store_error == HA_ERR_END_OF_FILE) + { + table->status = STATUS_NOT_FOUND; + } + DBUG_RETURN(store_error); + } + if (first) + { + first = FALSE; + if (spider->use_pre_call) + { + if (spider->store_error_num) + { + if (spider->store_error_num == HA_ERR_END_OF_FILE) + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(spider->store_error_num); + } +#ifndef WITHOUT_SPIDER_BG_SEARCH + if (spider->result_list.bgs_phase > 0) + { + fields->set_pos_to_first_link_idx_chain(); + while ((link_idx_chain = fields->get_next_link_idx_chain())) + { + conn = link_idx_chain->conn; + link_idx_holder = link_idx_chain->link_idx_holder; + link_idx = link_idx_holder->link_idx; + dbton_hdl = spider->dbton_handler[conn->dbton_id]; + spider->link_idx_chain = link_idx_chain; + if ((error_num = spider_bg_conn_search(spider, link_idx, + dbton_hdl->first_link_idx, TRUE, TRUE, + !fields->is_first_link_ok_chain(link_idx_chain)))) + { + if ( + error_num != HA_ERR_END_OF_FILE && + spider->need_mons[link_idx] + ) { + error_num = fields->ping_table_mon_from_table(link_idx_chain); + } + if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + { + table->status = STATUS_NOT_FOUND; + } + DBUG_RETURN(error_num); + } + } + } +#endif + spider->use_pre_call = FALSE; + } + } else if (offset_limit) + { + --offset_limit; + DBUG_RETURN(0); + } + if ((error_num = spider_db_seek_next(table->record[0], spider, + spider->search_link_idx, table))) + { + if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + { + table->status = STATUS_NOT_FOUND; + } + DBUG_RETURN(error_num); + } + DBUG_RETURN(0); +} + +int spider_group_by_handler::end_scan() +{ + DBUG_ENTER("spider_group_by_handler::end_scan"); + DBUG_RETURN(0); +} + +group_by_handler *spider_create_group_by_handler( + THD *thd, + Query *query +) { + spider_group_by_handler *group_by_handler; + Item *item; + TABLE_LIST *from; + SPIDER_CONN *conn; + ha_spider *spider; + SPIDER_SHARE *share; + int roop_count, lock_mode; + List_iterator_fast<Item> it(*query->select); + uchar dbton_bitmap[spider_bitmap_size(SPIDER_DBTON_SIZE)]; + uchar dbton_bitmap_tmp[spider_bitmap_size(SPIDER_DBTON_SIZE)]; + ORDER *order; + bool keep_going; + bool find_dbton = FALSE; + spider_fields *fields = NULL, *fields_arg = NULL; + uint table_idx, dbton_id; + long tgt_link_status; + DBUG_ENTER("spider_create_group_by_handler"); + + switch (thd_sql_command(thd)) + { + case SQLCOM_UPDATE: + case SQLCOM_UPDATE_MULTI: + case SQLCOM_DELETE: + case SQLCOM_DELETE_MULTI: + DBUG_PRINT("info",("spider update and delete does not support this feature")); + DBUG_RETURN(NULL); + default: + break; + } + +#ifdef WITH_PARTITION_STORAGE_ENGINE + from = query->from; + do { + DBUG_PRINT("info",("spider from=%p", from)); + if (from->table->part_info) + { + DBUG_PRINT("info",("spider partition handler")); +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + ha_partition *partition = (ha_partition *) from->table->file; + part_id_range *part_spec = partition->get_part_spec(); + DBUG_PRINT("info",("spider part_spec->start_part=%u", part_spec->start_part)); + DBUG_PRINT("info",("spider part_spec->end_part=%u", part_spec->end_part)); + if ( + part_spec->start_part == partition->get_no_current_part_id() || + part_spec->start_part != part_spec->end_part + ) { + DBUG_PRINT("info",("spider using multiple partitions is not supported by this feature yet")); +#else + DBUG_PRINT("info",("spider partition is not supported by this feature yet")); +#endif + DBUG_RETURN(NULL); +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + } +#endif + } + } while ((from = from->next_local)); +#endif + + table_idx = 0; + from = query->from; +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + if (from->table->part_info) + { + ha_partition *partition = (ha_partition *) from->table->file; + part_id_range *part_spec = partition->get_part_spec(); + handler **handlers = partition->get_child_handlers(); + spider = (ha_spider *) handlers[part_spec->start_part]; + } else { +#endif + spider = (ha_spider *) from->table->file; +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + } +#endif + share = spider->share; + spider->idx_for_direct_join = table_idx; + ++table_idx; + memset(dbton_bitmap, 0, spider_bitmap_size(SPIDER_DBTON_SIZE)); + for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count) + { + dbton_id = share->use_sql_dbton_ids[roop_count]; + if ( + spider_dbton[dbton_id].support_direct_join && + spider_dbton[dbton_id].support_direct_join() + ) { + spider_set_bit(dbton_bitmap, dbton_id); + } + } + while ((from = from->next_local)) + { +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + if (from->table->part_info) + { + ha_partition *partition = (ha_partition *) from->table->file; + part_id_range *part_spec = partition->get_part_spec(); + handler **handlers = partition->get_child_handlers(); + spider = (ha_spider *) handlers[part_spec->start_part]; + } else { +#endif + spider = (ha_spider *) from->table->file; +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + } +#endif + share = spider->share; + spider->idx_for_direct_join = table_idx; + ++table_idx; + memset(dbton_bitmap_tmp, 0, spider_bitmap_size(SPIDER_DBTON_SIZE)); + for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count) + { + dbton_id = share->use_sql_dbton_ids[roop_count]; + if ( + spider_dbton[dbton_id].support_direct_join && + spider_dbton[dbton_id].support_direct_join() + ) { + spider_set_bit(dbton_bitmap_tmp, dbton_id); + } + } + for (roop_count = 0; + roop_count < spider_bitmap_size(SPIDER_DBTON_SIZE); ++roop_count) + { + dbton_bitmap[roop_count] &= dbton_bitmap_tmp[roop_count]; + } + } + + from = query->from; + do { +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + if (from->table->part_info) + { + ha_partition *partition = (ha_partition *) from->table->file; + part_id_range *part_spec = partition->get_part_spec(); + handler **handlers = partition->get_child_handlers(); + spider = (ha_spider *) handlers[part_spec->start_part]; + } else { +#endif + spider = (ha_spider *) from->table->file; +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + } +#endif + share = spider->share; + if (spider_param_skip_default_condition(thd, + share->skip_default_condition)) + { + /* find skip_default_condition = 1 */ + break; + } + } while ((from = from->next_local)); + + for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; ++roop_count) + { + if (spider_bit_is_set(dbton_bitmap, roop_count)) + { + if (!fields) + { + fields_arg = new spider_fields(); + if (!fields_arg) + { + DBUG_RETURN(NULL); + } + } + keep_going = TRUE; + it.init(*query->select); + while ((item = it++)) + { + DBUG_PRINT("info",("spider select item=%p", item)); + if (spider_db_print_item_type(item, spider, NULL, NULL, 0, + roop_count, TRUE, fields_arg)) + { + DBUG_PRINT("info",("spider dbton_id=%d can't create select", roop_count)); + spider_clear_bit(dbton_bitmap, roop_count); + keep_going = FALSE; + break; + } + } + if (keep_going) + { + DBUG_PRINT("info",("spider query->where=%p", query->where)); + if (query->where) + { + if (spider_db_print_item_type(query->where, spider, NULL, NULL, 0, + roop_count, TRUE, fields_arg)) + { + DBUG_PRINT("info",("spider dbton_id=%d can't create where", roop_count)); + spider_clear_bit(dbton_bitmap, roop_count); + keep_going = FALSE; + } + } + } + if (keep_going) + { + DBUG_PRINT("info",("spider query->group_by=%p", query->group_by)); + if (query->group_by) + { + for (order = query->group_by; order; order = order->next) + { + if (spider_db_print_item_type((*order->item), spider, NULL, NULL, 0, + roop_count, TRUE, fields_arg)) + { + DBUG_PRINT("info",("spider dbton_id=%d can't create group by", roop_count)); + spider_clear_bit(dbton_bitmap, roop_count); + keep_going = FALSE; + break; + } + } + } + } + if (keep_going) + { + DBUG_PRINT("info",("spider query->order_by=%p", query->order_by)); + if (query->order_by) + { + for (order = query->order_by; order; order = order->next) + { + if (spider_db_print_item_type((*order->item), spider, NULL, NULL, 0, + roop_count, TRUE, fields_arg)) + { + DBUG_PRINT("info",("spider dbton_id=%d can't create order by", roop_count)); + spider_clear_bit(dbton_bitmap, roop_count); + keep_going = FALSE; + break; + } + } + } + } + if (keep_going) + { + DBUG_PRINT("info",("spider query->having=%p", query->having)); + if (query->having) + { + if (spider_db_print_item_type(query->having, spider, NULL, NULL, 0, + roop_count, TRUE, fields_arg)) + { + DBUG_PRINT("info",("spider dbton_id=%d can't create having", roop_count)); + spider_clear_bit(dbton_bitmap, roop_count); + keep_going = FALSE; + } + } + } + if (keep_going) + { + find_dbton = TRUE; + fields = fields_arg; + fields_arg = NULL; + } else { + delete fields_arg; + } + } + } + if (!find_dbton) + { + DBUG_RETURN(NULL); + } + + if (fields->create_table_holder(table_idx)) + { + delete fields; + DBUG_RETURN(NULL); + } + + from = query->from; +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + if (from->table->part_info) + { + ha_partition *partition = (ha_partition *) from->table->file; + part_id_range *part_spec = partition->get_part_spec(); + handler **handlers = partition->get_child_handlers(); + spider = (ha_spider *) handlers[part_spec->start_part]; + } else { +#endif + spider = (ha_spider *) from->table->file; +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + } +#endif + share = spider->share; + lock_mode = spider_conn_lock_mode(spider); + if (lock_mode) + { + tgt_link_status = SPIDER_LINK_STATUS_RECOVERY; + } else { + tgt_link_status = SPIDER_LINK_STATUS_OK; + } + DBUG_PRINT("info",("spider s->db=%s", from->table->s->db.str)); + DBUG_PRINT("info",("spider s->table_name=%s", from->table->s->table_name.str)); + if (!fields->add_table(spider)) + { + DBUG_PRINT("info",("spider can not add a table")); + delete fields; + DBUG_RETURN(NULL); + } + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + tgt_link_status); + roop_count < (int) share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + tgt_link_status) + ) { + if (spider_param_use_handler(thd, share->use_handlers[roop_count])) + { + DBUG_PRINT("info",("spider direct_join does not support use_handler")); + if (lock_mode) + { + delete fields; + DBUG_RETURN(NULL); + } + continue; + } + conn = spider->conns[roop_count]; + DBUG_PRINT("info",("spider roop_count=%d", roop_count)); + DBUG_PRINT("info",("spider conn=%p", conn)); + DBUG_ASSERT(conn); + if (conn->table_lock) + { + DBUG_PRINT("info",("spider direct_join does not support with lock tables yet")); + if (lock_mode) + { + delete fields; + DBUG_RETURN(NULL); + } + continue; + } + if (!fields->add_conn(conn, + share->access_balances[spider->conn_link_idx[roop_count]])) + { + DBUG_PRINT("info",("spider can not create conn_holder")); + delete fields; + DBUG_RETURN(NULL); + } + if (fields->add_link_idx(conn->conn_holder_for_direct_join, spider, roop_count)) + { + DBUG_PRINT("info",("spider can not create link_idx_holder")); + delete fields; + DBUG_RETURN(NULL); + } + } + if (!fields->has_conn_holder()) + { + delete fields; + DBUG_RETURN(NULL); + } + + while ((from = from->next_local)) + { + fields->clear_conn_holder_from_conn(); + +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + if (from->table->part_info) + { + ha_partition *partition = (ha_partition *) from->table->file; + part_id_range *part_spec = partition->get_part_spec(); + handler **handlers = partition->get_child_handlers(); + spider = (ha_spider *) handlers[part_spec->start_part]; + } else { +#endif + spider = (ha_spider *) from->table->file; +#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC) + } +#endif + share = spider->share; + if (!fields->add_table(spider)) + { + DBUG_PRINT("info",("spider can not add a table")); + delete fields; + DBUG_RETURN(NULL); + } + DBUG_PRINT("info",("spider s->db=%s", from->table->s->db.str)); + DBUG_PRINT("info",("spider s->table_name=%s", from->table->s->table_name.str)); + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + tgt_link_status); + roop_count < (int) share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + tgt_link_status) + ) { + DBUG_PRINT("info",("spider roop_count=%d", roop_count)); + if (spider_param_use_handler(thd, share->use_handlers[roop_count])) + { + DBUG_PRINT("info",("spider direct_join does not support use_handler")); + if (lock_mode) + { + delete fields; + DBUG_RETURN(NULL); + } + continue; + } + conn = spider->conns[roop_count]; + DBUG_PRINT("info",("spider conn=%p", conn)); + if (!fields->check_conn_same_conn(conn)) + { + DBUG_PRINT("info",("spider connection %p can not be used for this query with locking", + conn)); + if (lock_mode) + { + delete fields; + DBUG_RETURN(NULL); + } + continue; + } + if (fields->add_link_idx(conn->conn_holder_for_direct_join, spider, roop_count)) + { + DBUG_PRINT("info",("spider can not create link_idx_holder")); + delete fields; + DBUG_RETURN(NULL); + } + } + + if (fields->remove_conn_if_not_checked()) + { + if (lock_mode) + { + DBUG_PRINT("info",("spider some connections can not be used for this query with locking")); + delete fields; + DBUG_RETURN(NULL); + } + } + if (!fields->has_conn_holder()) + { + delete fields; + DBUG_RETURN(NULL); + } + } + + fields->check_support_dbton(dbton_bitmap); + if (!fields->has_conn_holder()) + { + DBUG_PRINT("info",("spider all choosed connections can't match dbton_id")); + delete fields; + DBUG_RETURN(NULL); + } + + /* choose a connection */ + if (!lock_mode) + { + fields->choose_a_conn(); + } + + if (fields->make_link_idx_chain(tgt_link_status)) + { + DBUG_PRINT("info",("spider can not create link_idx_chain")); + delete fields; + DBUG_RETURN(NULL); + } + + /* choose link_id */ + if (fields->check_link_ok_chain()) + { + DBUG_PRINT("info",("spider do not have link ok status")); + delete fields; + DBUG_RETURN(NULL); + } + + fields->set_first_link_idx(); + + if (!(group_by_handler = new spider_group_by_handler(thd, query, fields))) + { + DBUG_PRINT("info",("spider can't create group_by_handler")); + delete fields; + DBUG_RETURN(NULL); + } + query->distinct = FALSE; + query->where = NULL; + query->group_by = NULL; + query->having = NULL; + query->order_by = NULL; + DBUG_RETURN(group_by_handler); +} +#endif diff --git a/storage/spider/spd_group_by_handler.h b/storage/spider/spd_group_by_handler.h new file mode 100644 index 00000000000..09f82168708 --- /dev/null +++ b/storage/spider/spd_group_by_handler.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2016 Kentoku Shiba + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef SPIDER_HAS_GROUP_BY_HANDLER +class spider_group_by_handler: public group_by_handler +{ + Query query; + spider_fields *fields; + ha_spider *spider; + SPIDER_TRX *trx; + spider_db_result *result; + bool first; + longlong offset_limit; + int store_error; + +public: + spider_group_by_handler( + THD *thd_arg, + Query *query_arg, + spider_fields *fields_arg + ); + ~spider_group_by_handler(); + int init_scan(); + int next_row(); + int end_scan(); +}; + +group_by_handler *spider_create_group_by_handler( + THD *thd, + Query *query +); +#endif diff --git a/storage/spider/spd_i_s.cc b/storage/spider/spd_i_s.cc index f9fb5e17b2a..3ef04a0dacc 100644 --- a/storage/spider/spd_i_s.cc +++ b/storage/spider/spd_i_s.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2014 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 37d9db3ba57..e6a2a8ef3b2 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,14 +11,15 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define SPIDER_DETAIL_VERSION "3.2.37" -#define SPIDER_HEX_VERSION 0x0302 +#define SPIDER_DETAIL_VERSION "3.3.13" +#define SPIDER_HEX_VERSION 0x0303 #if MYSQL_VERSION_ID < 50500 +#define spider_my_free(A,B) my_free(A,B) #else -#define my_free(A,B) my_free(A) +#define spider_my_free(A,B) my_free(A) #ifdef pthread_mutex_t #undef pthread_mutex_t #endif @@ -66,6 +67,7 @@ #define my_sprintf(A,B) sprintf B #endif + #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100004 #define spider_stmt_da_message(A) thd_get_error_message(A) #define spider_stmt_da_sql_errno(A) thd_get_error_number(A) @@ -129,6 +131,55 @@ #define SPIDER_Item_args_arg_count_IS_PROTECTED #endif +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100112 +#define SPIDER_Item_func_conv_charset_conv_charset collation.collation +#else +#define SPIDER_Item_func_conv_charset_conv_charset conv_charset +#endif + +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100200 +#define SPIDER_WITHOUT_HA_STATISTIC_INCREMENT +#define SPIDER_init_read_record(A,B,C,D,E,F,G,H) init_read_record(A,B,C,D,E,F,G,H) +#define SPIDER_HAS_NEXT_THREAD_ID +#define SPIDER_new_THD(A) (new THD(A)) +#define SPIDER_order_direction_is_asc(A) (A->direction == ORDER::ORDER_ASC) +#else +#define SPIDER_init_read_record(A,B,C,D,E,F,G,H) init_read_record(A,B,C,D,F,G,H) +#define SPIDER_new_THD(A) (new THD()) +#define SPIDER_order_direction_is_asc(A) (A->asc) +#endif + +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100201 +#define SPIDER_HAS_MY_CHARLEN +#define SPIDER_find_temporary_table(A,B) A->find_temporary_table(B) +#else +#define SPIDER_find_temporary_table(A,B) find_temporary_table(A,B) +#endif + +#if defined(MARIADB_BASE_VERSION) +#if MYSQL_VERSION_ID >= 100209 +#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(A,B,C,E,F,G) +#elif MYSQL_VERSION_ID >= 100200 +#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(A,B,C,D,E,F,G,H) +#elif MYSQL_VERSION_ID >= 100007 +#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(B,C,D,E,F,G,H) +#else +#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(B,C,D,E,F,G) +#endif +#else +#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) +#endif + +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100209 +#define SPIDER_create_partition_name(A,B,C,D,E,F) create_partition_name(A,B,C,D,E,F) +#define SPIDER_create_subpartition_name(A,B,C,D,E,F) create_subpartition_name(A,B,C,D,E,F) +#define SPIDER_free_part_syntax(A,B) +#else +#define SPIDER_create_partition_name(A,B,C,D,E,F) create_partition_name(A,C,D,E,F) +#define SPIDER_create_subpartition_name(A,B,C,D,E,F) create_subpartition_name(A,C,D,E,F) +#define SPIDER_free_part_syntax(A,B) spider_my_free(A,B) +#endif + #if MYSQL_VERSION_ID >= 50500 #define SPIDER_HAS_HASH_VALUE_TYPE #endif @@ -151,12 +202,13 @@ #define SPIDER_LINK_MON_DRAW_FEW_MON 1 #define SPIDER_LINK_MON_DRAW 2 -#define SPIDER_TMP_SHARE_CHAR_PTR_COUNT 19 +#define SPIDER_TMP_SHARE_CHAR_PTR_COUNT 20 #define SPIDER_TMP_SHARE_UINT_COUNT 17 -#define SPIDER_TMP_SHARE_LONG_COUNT 18 +#define SPIDER_TMP_SHARE_LONG_COUNT 19 #define SPIDER_TMP_SHARE_LONGLONG_COUNT 3 -#define SPIDER_MEM_CALC_LIST_NUM 247 +#define SPIDER_MEM_CALC_LIST_NUM 257 +#define SPIDER_CONN_META_BUF_LEN 64 #define SPIDER_BACKUP_DASTATUS \ bool da_status; if (thd) da_status = thd->is_error(); else da_status = FALSE; @@ -176,6 +228,25 @@ class ha_spider; typedef struct st_spider_share SPIDER_SHARE; +typedef struct st_spider_table_mon_list SPIDER_TABLE_MON_LIST; +typedef struct st_spider_ip_port_conn SPIDER_IP_PORT_CONN; + +#ifndef WITHOUT_SPIDER_BG_SEARCH +typedef struct st_spider_thread +{ + uint thread_idx; + THD *thd; + volatile bool killed; + volatile bool thd_wait; + volatile bool first_free_wait; + pthread_t thread; + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_cond_t sync_cond; + volatile SPIDER_SHARE *queue_first; + volatile SPIDER_SHARE *queue_last; +} SPIDER_THREAD; +#endif typedef struct st_spider_file_pos { @@ -224,8 +295,10 @@ typedef struct st_spider_alter_table char **tmp_tgt_ssl_keys; char **tmp_tgt_default_files; char **tmp_tgt_default_groups; + char **tmp_static_link_ids; long *tmp_tgt_ports; long *tmp_tgt_ssl_vscs; + long *tmp_monitoring_binlog_pos_at_failing; long *tmp_link_statuses; uint *tmp_server_names_lengths; @@ -243,6 +316,7 @@ typedef struct st_spider_alter_table uint *tmp_tgt_ssl_keys_lengths; uint *tmp_tgt_default_files_lengths; uint *tmp_tgt_default_groups_lengths; + uint *tmp_static_link_ids_lengths; uint tmp_server_names_charlen; uint tmp_tgt_table_names_charlen; @@ -259,6 +333,7 @@ typedef struct st_spider_alter_table uint tmp_tgt_ssl_keys_charlen; uint tmp_tgt_default_files_charlen; uint tmp_tgt_default_groups_charlen; + uint tmp_static_link_ids_charlen; uint tmp_server_names_length; uint tmp_tgt_table_names_length; @@ -275,8 +350,10 @@ typedef struct st_spider_alter_table uint tmp_tgt_ssl_keys_length; uint tmp_tgt_default_files_length; uint tmp_tgt_default_groups_length; + uint tmp_static_link_ids_length; uint tmp_tgt_ports_length; uint tmp_tgt_ssl_vscs_length; + uint tmp_monitoring_binlog_pos_at_failing_length; uint tmp_link_statuses_length; } SPIDER_ALTER_TABLE; @@ -455,6 +532,12 @@ typedef struct st_spider_conn THD *connect_error_thd; query_id_t connect_error_query_id; time_t connect_error_time; + +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + SPIDER_CONN_HOLDER *conn_holder_for_direct_join; + SPIDER_LINK_IDX_CHAIN *link_idx_chain; +#endif + SPIDER_IP_PORT_CONN *ip_port_conn; } SPIDER_CONN; typedef struct st_spider_lgtm_tblhnd_share @@ -489,6 +572,7 @@ typedef struct st_spider_patition_handler_share bool between_flg; bool idx_bitmap_is_set; bool rnd_bitmap_is_set; + query_id_t parallel_search_query_id; } SPIDER_PARTITION_HANDLER_SHARE; typedef struct st_spider_patition_share @@ -544,6 +628,8 @@ typedef struct st_spider_transaction bool tmp_flg; bool registed_allocated_thds; + bool updated_in_this_trx; + THD *thd; #ifdef SPIDER_HAS_HASH_VALUE_TYPE my_hash_value_type thd_hash_value; @@ -608,6 +694,7 @@ typedef struct st_spider_transaction ulonglong direct_delete_count; ulonglong direct_order_limit_count; ulonglong direct_aggregate_count; + ulonglong parallel_search_count; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) ulonglong hs_result_free_count; #endif @@ -719,6 +806,27 @@ typedef struct st_spider_share pthread_cond_t *bg_mon_conds; pthread_cond_t *bg_mon_sleep_conds; #endif +#ifndef WITHOUT_SPIDER_BG_SEARCH + /* static bg thread for sts and crd */ + TABLE table; + ha_spider *sts_spider; + ha_spider *crd_spider; + SPIDER_THREAD *sts_thread; + SPIDER_THREAD *crd_thread; + volatile bool sts_spider_init; + volatile bool sts_working; + volatile bool sts_wait; + volatile bool crd_spider_init; + volatile bool crd_working; + volatile bool crd_wait; + volatile SPIDER_SHARE *sts_prev; + volatile SPIDER_SHARE *sts_next; + volatile SPIDER_SHARE *crd_prev; + volatile SPIDER_SHARE *crd_next; +#endif + + MEM_ROOT mem_root; + /* volatile bool auto_increment_init; volatile ulonglong auto_increment_lclval; @@ -755,6 +863,8 @@ typedef struct st_spider_share #ifdef WITH_PARTITION_STORAGE_ENGINE int sts_sync; #endif + int store_last_sts; + int load_sts_at_startup; #ifndef WITHOUT_SPIDER_BG_SEARCH int crd_bg_mode; #endif @@ -763,6 +873,8 @@ typedef struct st_spider_share #ifdef WITH_PARTITION_STORAGE_ENGINE int crd_sync; #endif + int store_last_crd; + int load_crd_at_startup; int crd_type; double crd_weight; longlong internal_offset; @@ -804,6 +916,7 @@ typedef struct st_spider_share int use_table_charset; int use_pushdown_udf; int skip_default_condition; + int skip_parallel_search; int direct_dup_insert; longlong direct_order_limit; int read_only_mode; @@ -851,6 +964,7 @@ typedef struct st_spider_share char **tgt_ssl_keys; char **tgt_default_files; char **tgt_default_groups; + char **static_link_ids; char **tgt_pk_names; char **tgt_sequence_names; char **conn_keys; @@ -867,6 +981,7 @@ typedef struct st_spider_share long *monitoring_bg_flag; long *monitoring_bg_kind; #endif + long *monitoring_binlog_pos_at_failing; long *monitoring_flag; long *monitoring_kind; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -903,6 +1018,7 @@ typedef struct st_spider_share uint *tgt_ssl_keys_lengths; uint *tgt_default_files_lengths; uint *tgt_default_groups_lengths; + uint *static_link_ids_lengths; uint *tgt_pk_names_lengths; uint *tgt_sequence_names_lengths; uint *conn_keys_lengths; @@ -932,6 +1048,7 @@ typedef struct st_spider_share uint tgt_ssl_keys_charlen; uint tgt_default_files_charlen; uint tgt_default_groups_charlen; + uint static_link_ids_charlen; uint tgt_pk_names_charlen; uint tgt_sequence_names_charlen; uint conn_keys_charlen; @@ -957,6 +1074,7 @@ typedef struct st_spider_share uint tgt_ssl_keys_length; uint tgt_default_files_length; uint tgt_default_groups_length; + uint static_link_ids_length; uint tgt_pk_names_length; uint tgt_sequence_names_length; uint conn_keys_length; @@ -973,6 +1091,7 @@ typedef struct st_spider_share uint monitoring_bg_flag_length; uint monitoring_bg_kind_length; #endif + uint monitoring_binlog_pos_at_failing_length; uint monitoring_flag_length; uint monitoring_kind_length; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -1143,6 +1262,7 @@ typedef struct st_spider_table_mon { SPIDER_SHARE *share; uint32 server_id; + st_spider_table_mon_list *parent; st_spider_table_mon *next; } SPIDER_TABLE_MON; @@ -1276,3 +1396,19 @@ char *spider_create_string( const char *str, uint length ); + + +typedef struct st_spider_ip_port_conn { + char *key; + size_t key_len; +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + my_hash_value_type key_hash_value; +#endif + char remote_ip_str[SPIDER_CONN_META_BUF_LEN]; + long remote_port; + ulong ip_port_count; + volatile ulong waiting_count; + pthread_mutex_t mutex; + pthread_cond_t cond; + ulonglong conn_id; /* each conn has it's own conn_id */ +} SPIDER_IP_PORT_CONN; diff --git a/storage/spider/spd_malloc.cc b/storage/spider/spd_malloc.cc index 4135cd9beb2..e7a6e710cbc 100644 --- a/storage/spider/spd_malloc.cc +++ b/storage/spider/spd_malloc.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2014 Kentoku Shiba +/* Copyright (C) 2012-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -184,7 +184,7 @@ void spider_free_mem( size = *((uint *) tmp_ptr); tmp_ptr -= ALIGN_SIZE(sizeof(uint)); id = *((uint *) tmp_ptr); - my_free(tmp_ptr, my_flags); + spider_my_free(tmp_ptr, my_flags); spider_free_mem_calc(trx, id, size); DBUG_VOID_RETURN; diff --git a/storage/spider/spd_malloc.h b/storage/spider/spd_malloc.h index 3c5c6e67c2a..42e6abd407c 100644 --- a/storage/spider/spd_malloc.h +++ b/storage/spider/spd_malloc.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define spider_free(A,B,C) spider_free_mem(A,B,C) #define spider_malloc(A,B,C,D) \ diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc index c419e05a459..6970f19e85f 100644 --- a/storage/spider/spd_param.cc +++ b/storage/spider/spd_param.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,11 +11,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> -#include <my_global.h> #include "mysql_version.h" #include "spd_environ.h" #if MYSQL_VERSION_ID < 50500 @@ -89,6 +88,17 @@ static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, char *buff) DBUG_RETURN(error_num); } +static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff) +{ + int error_num = 0; + SPIDER_TRX *trx; + DBUG_ENTER("spider_parallel_search"); + var->type = SHOW_LONGLONG; + if ((trx = spider_get_trx(thd, TRUE, &error_num))) + var->value = (char *) &trx->parallel_search_count; + DBUG_RETURN(error_num); +} + #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) static int spider_hs_result_free(THD *thd, SHOW_VAR *var, char *buff) { @@ -122,11 +132,15 @@ struct st_mysql_show_var spider_status_variables[] = (char *) &spider_direct_order_limit, SHOW_SIMPLE_FUNC}, {"Spider_direct_aggregate", (char *) &spider_direct_aggregate, SHOW_SIMPLE_FUNC}, + {"Spider_parallel_search", + (char *) &spider_parallel_search, SHOW_SIMPLE_FUNC}, #else {"Spider_direct_order_limit", (char *) &spider_direct_order_limit, SHOW_FUNC}, {"Spider_direct_aggregate", (char *) &spider_direct_aggregate, SHOW_FUNC}, + {"Spider_parallel_search", + (char *) &spider_parallel_search, SHOW_FUNC}, #endif #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) #ifdef SPIDER_HAS_SHOW_SIMPLE_FUNC @@ -411,6 +425,29 @@ uint spider_param_force_commit( } /* + 0: register all XA transaction + 1: register only write XA transaction + */ +static MYSQL_THDVAR_UINT( + xa_register_mode, /* name */ + PLUGIN_VAR_RQCMDARG, /* opt */ + "Mode of XA transaction register into system table", /* comment */ + NULL, /* check */ + NULL, /* update */ + 1, /* def */ + 0, /* min */ + 1, /* max */ + 0 /* blk */ +); + +uint spider_param_xa_register_mode( + THD *thd +) { + DBUG_ENTER("spider_param_xa_register_mode"); + DBUG_RETURN(THDVAR(thd, xa_register_mode)); +} + +/* -1 :use table parameter 0-:offset */ @@ -1668,7 +1705,8 @@ double spider_param_crd_weight( /* -1 :use table parameter 0 :Background confirmation is disabled - 1 :Background confirmation is enabled + 1 :Background confirmation is enabled (create thread per table/partition) + 2 :Background confirmation is enabled (use static threads) */ static MYSQL_THDVAR_INT( crd_bg_mode, /* name */ @@ -1678,7 +1716,7 @@ static MYSQL_THDVAR_INT( NULL, /* update */ -1, /* def */ -1, /* min */ - 1, /* max */ + 2, /* max */ 0 /* blk */ ); @@ -1779,7 +1817,8 @@ int spider_param_sts_sync( /* -1 :use table parameter 0 :Background confirmation is disabled - 1 :Background confirmation is enabled + 1 :Background confirmation is enabled (create thread per table/partition) + 2 :Background confirmation is enabled (use static threads) */ static MYSQL_THDVAR_INT( sts_bg_mode, /* name */ @@ -1789,7 +1828,7 @@ static MYSQL_THDVAR_INT( NULL, /* update */ -1, /* def */ -1, /* min */ - 1, /* max */ + 2, /* max */ 0 /* blk */ ); @@ -2704,6 +2743,34 @@ int spider_param_skip_default_condition( /* -1 :use table parameter + 0 :not skip + 1 :skip parallel search if query is not SELECT statement + 2 :skip parallel search if query has SQL_NO_CACHE + 3 :1+2 + */ +static MYSQL_THDVAR_INT( + skip_parallel_search, /* name */ + PLUGIN_VAR_RQCMDARG, /* opt */ + "Skip parallel search by specific conditions", /* comment */ + NULL, /* check */ + NULL, /* update */ + -1, /* def */ + -1, /* min */ + 3, /* max */ + 0 /* blk */ +); + +int spider_param_skip_parallel_search( + THD *thd, + int skip_parallel_search +) { + DBUG_ENTER("spider_param_skip_parallel_search"); + DBUG_RETURN(THDVAR(thd, skip_parallel_search) == -1 ? + skip_parallel_search : THDVAR(thd, skip_parallel_search)); +} + +/* + -1 :use table parameter 0 :not send directly 1-:send directly */ @@ -2829,6 +2896,66 @@ my_bool spider_param_general_log() DBUG_RETURN(spider_general_log); } +/* + FALSE: no pushdown hints + TRUE: pushdown hints + */ +static MYSQL_THDVAR_BOOL( + index_hint_pushdown, /* name */ + PLUGIN_VAR_OPCMDARG, /* opt */ + "switch to control if push down index hint, like force_index", /* comment */ + NULL, /* check */ + NULL, /* update */ + FALSE /* def */ +); + +my_bool spider_param_index_hint_pushdown( + THD *thd +) { + DBUG_ENTER("spider_param_index_hint_pushdown"); + DBUG_RETURN(THDVAR(thd, index_hint_pushdown)); +} + +static uint spider_max_connections; +static MYSQL_SYSVAR_UINT( + max_connections, + spider_max_connections, + PLUGIN_VAR_RQCMDARG, + "the values, as the max conncetion from spider to remote mysql. Default 0, mean unlimit the connections", + NULL, + NULL, + 0, /* def */ + 0, /* min */ + 99999, /* max */ + 0 /* blk */ +); + +uint spider_param_max_connections() +{ + DBUG_ENTER("spider_param_max_connections"); + DBUG_RETURN(spider_max_connections); +} + +static uint spider_conn_wait_timeout; +static MYSQL_SYSVAR_UINT( + conn_wait_timeout, + spider_conn_wait_timeout, + PLUGIN_VAR_RQCMDARG, + "the values, as the max waiting time when spider get a remote conn", + NULL, + NULL, + 10, /* def */ + 0, /* min */ + 1000, /* max */ + 0 /* blk */ +); + +uint spider_param_conn_wait_timeout() +{ + DBUG_ENTER("spider_param_conn_wait_timeout"); + DBUG_RETURN(spider_conn_wait_timeout); +} + static uint spider_log_result_errors; /* 0: no log @@ -3012,6 +3139,162 @@ int spider_param_bka_table_name_type( bka_table_name_type : THDVAR(thd, bka_table_name_type)); } +static int spider_store_last_sts; +/* + -1 : use table parameter + 0 : do not store + 1 : do store + */ +static MYSQL_SYSVAR_INT( + store_last_sts, + spider_store_last_sts, + PLUGIN_VAR_RQCMDARG, + "Store last sts result into system table", + NULL, + NULL, + -1, + -1, + 1, + 0 +); + +int spider_param_store_last_sts( + int store_last_sts +) { + DBUG_ENTER("spider_param_store_last_sts"); + DBUG_RETURN(spider_store_last_sts == -1 ? + store_last_sts : spider_store_last_sts); +} + +static int spider_store_last_crd; +/* + -1 : use table parameter + 0 : do not store + 1 : do store + */ +static MYSQL_SYSVAR_INT( + store_last_crd, + spider_store_last_crd, + PLUGIN_VAR_RQCMDARG, + "Store last crd result into system table", + NULL, + NULL, + -1, + -1, + 1, + 0 +); + +int spider_param_store_last_crd( + int store_last_crd +) { + DBUG_ENTER("spider_param_store_last_crd"); + DBUG_RETURN(spider_store_last_crd == -1 ? + store_last_crd : spider_store_last_crd); +} + +static int spider_load_sts_at_startup; +/* + -1 : use table parameter + 0 : do not load + 1 : do load + */ +static MYSQL_SYSVAR_INT( + load_sts_at_startup, + spider_load_sts_at_startup, + PLUGIN_VAR_RQCMDARG, + "Load sts from system table at startup", + NULL, + NULL, + -1, + -1, + 1, + 0 +); + +int spider_param_load_sts_at_startup( + int load_sts_at_startup +) { + DBUG_ENTER("spider_param_load_sts_at_startup"); + DBUG_RETURN(spider_load_sts_at_startup == -1 ? + load_sts_at_startup : spider_load_sts_at_startup); +} + +static int spider_load_crd_at_startup; +/* + -1 : use table parameter + 0 : do not load + 1 : do load + */ +static MYSQL_SYSVAR_INT( + load_crd_at_startup, + spider_load_crd_at_startup, + PLUGIN_VAR_RQCMDARG, + "Load crd from system table at startup", + NULL, + NULL, + -1, + -1, + 1, + 0 +); + +int spider_param_load_crd_at_startup( + int load_crd_at_startup +) { + DBUG_ENTER("spider_param_load_crd_at_startup"); + DBUG_RETURN(spider_load_crd_at_startup == -1 ? + load_crd_at_startup : spider_load_crd_at_startup); +} + +#ifndef WITHOUT_SPIDER_BG_SEARCH +static uint spider_table_sts_thread_count; +/* + 1-: thread count + */ +static MYSQL_SYSVAR_UINT( + table_sts_thread_count, + spider_table_sts_thread_count, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Static thread count of table sts", + NULL, + NULL, + 10, + 1, + 4294967295U, + 0 +); + +uint spider_param_table_sts_thread_count() +{ + DBUG_ENTER("spider_param_table_sts_thread_count"); + DBUG_RETURN(spider_table_sts_thread_count); +} + +static uint spider_table_crd_thread_count; +/* + 1-: thread count + */ +static MYSQL_SYSVAR_UINT( + table_crd_thread_count, + spider_table_crd_thread_count, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Static thread count of table crd", + NULL, + NULL, + 10, + 1, + 4294967295U, + 0 +); + +uint spider_param_table_crd_thread_count() +{ + DBUG_ENTER("spider_param_table_crd_thread_count"); + DBUG_RETURN(spider_table_crd_thread_count); +} +#endif + static struct st_mysql_storage_engine spider_storage_engine = { MYSQL_HANDLERTON_INTERFACE_VERSION }; @@ -3026,6 +3309,7 @@ static struct st_mysql_sys_var* spider_system_variables[] = { MYSQL_SYSVAR(internal_xa), MYSQL_SYSVAR(internal_xa_snapshot), MYSQL_SYSVAR(force_commit), + MYSQL_SYSVAR(xa_register_mode), MYSQL_SYSVAR(internal_offset), MYSQL_SYSVAR(internal_limit), MYSQL_SYSVAR(split_read), @@ -3077,6 +3361,8 @@ static struct st_mysql_sys_var* spider_system_variables[] = { #ifdef WITH_PARTITION_STORAGE_ENGINE MYSQL_SYSVAR(crd_sync), #endif + MYSQL_SYSVAR(store_last_crd), + MYSQL_SYSVAR(load_crd_at_startup), MYSQL_SYSVAR(crd_type), MYSQL_SYSVAR(crd_weight), #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -3087,6 +3373,8 @@ static struct st_mysql_sys_var* spider_system_variables[] = { #ifdef WITH_PARTITION_STORAGE_ENGINE MYSQL_SYSVAR(sts_sync), #endif + MYSQL_SYSVAR(store_last_sts), + MYSQL_SYSVAR(load_sts_at_startup), #ifndef WITHOUT_SPIDER_BG_SEARCH MYSQL_SYSVAR(sts_bg_mode), #endif @@ -3128,6 +3416,7 @@ static struct st_mysql_sys_var* spider_system_variables[] = { MYSQL_SYSVAR(error_read_mode), MYSQL_SYSVAR(error_write_mode), MYSQL_SYSVAR(skip_default_condition), + MYSQL_SYSVAR(skip_parallel_search), MYSQL_SYSVAR(direct_order_limit), MYSQL_SYSVAR(read_only_mode), #ifdef HA_CAN_BULK_ACCESS @@ -3138,6 +3427,9 @@ static struct st_mysql_sys_var* spider_system_variables[] = { MYSQL_SYSVAR(udf_ds_use_real_table), #endif MYSQL_SYSVAR(general_log), + MYSQL_SYSVAR(index_hint_pushdown), + MYSQL_SYSVAR(max_connections), + MYSQL_SYSVAR(conn_wait_timeout), MYSQL_SYSVAR(log_result_errors), MYSQL_SYSVAR(log_result_error_with_sql), MYSQL_SYSVAR(version), @@ -3147,6 +3439,10 @@ static struct st_mysql_sys_var* spider_system_variables[] = { MYSQL_SYSVAR(delete_all_rows_type), MYSQL_SYSVAR(bka_table_name_type), MYSQL_SYSVAR(connect_error_interval), +#ifndef WITHOUT_SPIDER_BG_SEARCH + MYSQL_SYSVAR(table_sts_thread_count), + MYSQL_SYSVAR(table_crd_thread_count), +#endif NULL }; diff --git a/storage/spider/spd_param.h b/storage/spider/spd_param.h index d62917adb37..d4af48a75ea 100644 --- a/storage/spider/spd_param.h +++ b/storage/spider/spd_param.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software); you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program); if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ my_bool spider_param_support_xa(); my_bool spider_param_connect_mutex(); @@ -41,6 +41,9 @@ uint spider_param_internal_xa_snapshot( uint spider_param_force_commit( THD *thd ); +uint spider_param_xa_register_mode( + THD *thd +); longlong spider_param_internal_offset( THD *thd, longlong internal_offset @@ -349,6 +352,10 @@ int spider_param_skip_default_condition( THD *thd, int skip_default_condition ); +int spider_param_skip_parallel_search( + THD *thd, + int skip_parallel_search +); longlong spider_param_direct_order_limit( THD *thd, longlong direct_order_limit @@ -370,6 +377,11 @@ int spider_param_udf_ds_use_real_table( ); #endif my_bool spider_param_general_log(); +my_bool spider_param_index_hint_pushdown( + THD *thd +); +uint spider_param_max_connections(); +uint spider_param_conn_wait_timeout(); uint spider_param_log_result_errors(); uint spider_param_log_result_error_with_sql(); uint spider_param_internal_xa_id_type( @@ -388,3 +400,19 @@ int spider_param_bka_table_name_type( THD *thd, int bka_table_name_type ); +int spider_param_store_last_sts( + int store_last_sts +); +int spider_param_store_last_crd( + int store_last_crd +); +int spider_param_load_sts_at_startup( + int load_sts_at_startup +); +int spider_param_load_crd_at_startup( + int load_crd_at_startup +); +#ifndef WITHOUT_SPIDER_BG_SEARCH +uint spider_param_table_sts_thread_count(); +uint spider_param_table_crd_thread_count(); +#endif diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc index c4b8588ad7c..58b44ec202e 100644 --- a/storage/spider/spd_ping_table.cc +++ b/storage/spider/spd_ping_table.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2015 Kentoku Shiba +/* Copyright (C) 2009-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -82,6 +82,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( spider_string *str, uint conv_name_length, int link_idx, + char *static_link_id, + uint static_link_id_length, uint32 server_id, bool need_lock, int *error_num @@ -140,7 +142,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list); if (!(table_mon_list = spider_get_ping_table_tgt(thd, str->c_ptr(), - conv_name_length, link_idx, server_id, str, need_lock, error_num))) + conv_name_length, link_idx, static_link_id, static_link_id_length, + server_id, str, need_lock, error_num))) { pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]); goto error; @@ -228,14 +231,14 @@ void spider_release_ping_table_mon_list_loop( DBUG_VOID_RETURN; } -void spider_release_ping_table_mon_list( +int spider_release_ping_table_mon_list( const char *conv_name, uint conv_name_length, int link_idx ) { uint mutex_hash; SPIDER_TABLE_MON_LIST *table_mon_list; - char link_idx_str[SPIDER_SQL_INT_LEN]; + char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1]; int link_idx_str_length; DBUG_ENTER("spider_release_ping_table_mon_list"); DBUG_PRINT("info", ("spider conv_name=%s", conv_name)); @@ -243,14 +246,14 @@ void spider_release_ping_table_mon_list( DBUG_PRINT("info", ("spider link_idx=%d", link_idx)); link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d", link_idx)); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_string conv_name_str(conv_name_length + link_idx_str_length + 1); - conv_name_str.set_charset(system_charset_info); -#else - char buf[conv_name_length + link_idx_str_length + 1]; + char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1); + if (!buf) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1, system_charset_info); -#endif conv_name_str.init_calc_mem(134); conv_name_str.length(0); conv_name_str.q_append(conv_name, conv_name_length); @@ -276,7 +279,8 @@ void spider_release_ping_table_mon_list( #endif spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list); pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]); - DBUG_VOID_RETURN; + my_afree(buf); + DBUG_RETURN(0); } int spider_get_ping_table_mon( @@ -315,6 +319,28 @@ int spider_get_ping_table_mon( my_error(error_num, MYF(0)); goto error; } + if (table_mon_list->share->static_link_ids[0]) + { + spider_store_tables_name(table_link_mon, name, name_length); + spider_store_tables_link_idx_str(table_link_mon, + table_mon_list->share->static_link_ids[0], + table_mon_list->share->static_link_ids_lengths[0]); + if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root))) + goto create_table_mon; + if (error_num == HA_ERR_OUT_OF_MEM) + goto error; + if ((tmp_ptr = strstr(name, "#P#"))) + { + *tmp_ptr = '\0'; + spider_store_tables_name(table_link_mon, name, strlen(name)); + *tmp_ptr = '#'; + if (!(error_num = spider_ping_table_cache_compare(table_link_mon, + mem_root))) + goto create_table_mon; + if (error_num == HA_ERR_OUT_OF_MEM) + goto error; + } + } spider_store_tables_name(table_link_mon, name, name_length); spider_store_tables_link_idx(table_link_mon, link_idx); if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root))) @@ -364,6 +390,7 @@ create_table_mon: tmp_connect_info_length, tmp_long, tmp_longlong); tmp_share->link_statuses[0] = -1; table_mon->share = tmp_share; + table_mon->parent = table_mon_list; if (table_mon_prev) table_mon_prev->next = table_mon; else @@ -442,6 +469,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( char *name, uint name_length, int link_idx, + char *static_link_id, + uint static_link_id_length, uint32 server_id, spider_string *str, bool need_lock, @@ -498,9 +527,29 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( goto error; } spider_store_tables_name(table_tables, name, name_length); - spider_store_tables_link_idx(table_tables, link_idx); + if (static_link_id) + { + spider_store_tables_static_link_id(table_tables, + static_link_id, static_link_id_length); + if ( + (*error_num = spider_get_sys_table_by_idx(table_tables, table_key, 2, + SPIDER_SYS_TABLES_UIDX1_COL_CNT)) || + (*error_num = spider_get_sys_tables_link_idx( + table_tables, &link_idx, &mem_root)) + ) { + table_tables->file->print_error(*error_num, MYF(0)); + goto error; + } + } else { + spider_store_tables_link_idx(table_tables, link_idx); + if ( + (*error_num = spider_check_sys_table(table_tables, table_key)) + ) { + table_tables->file->print_error(*error_num, MYF(0)); + goto error; + } + } if ( - (*error_num = spider_check_sys_table(table_tables, table_key)) || (*error_num = spider_get_sys_tables_connect_info( table_tables, tmp_share, 0, &mem_root)) || (*error_num = spider_get_sys_tables_link_status( @@ -650,6 +699,165 @@ error: DBUG_RETURN(NULL); } +int spider_get_ping_table_gtid_pos( + SPIDER_TRX *trx, + THD *thd, + spider_string *str, + uint conv_name_length, + int failed_link_idx, + uint32 server_id, + bool need_lock, + spider_string *tmp_str +) { + int error_num, source_link_idx, need_mon; + char table_key[MAX_KEY_LENGTH]; + TABLE *table_tables, *table_gtid_pos; +#if MYSQL_VERSION_ID < 50500 + Open_tables_state open_tables_backup_tables; + Open_tables_state open_tables_backup_gtid_pos; +#else + Open_tables_backup open_tables_backup_tables; + Open_tables_backup open_tables_backup_gtid_pos; +#endif + MEM_ROOT mem_root; + long link_status; + long monitoring_binlog_pos_at_failing; + SPIDER_TABLE_MON_LIST *table_mon_list; + SPIDER_CONN *ping_conn = NULL; + char *static_link_id; + uint static_link_id_length; + DBUG_ENTER("spider_get_ping_table_gtid_pos"); + + /* + select * from + mysql.spider_tables + where + db_name = setted db_name and + table_name = setted table_name + */ + if ( + !(table_tables = spider_open_sys_table( + thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, + SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup_tables, + need_lock, &error_num)) + ) + goto error_open_table_tables; + + if ( + !(table_gtid_pos = spider_open_sys_table( + thd, SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR, + SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN, TRUE, + &open_tables_backup_gtid_pos, need_lock, &error_num)) + ) + goto error_open_table_gtid_pos; + + table_tables->use_all_columns(); + table_gtid_pos->use_all_columns(); + spider_store_tables_name(table_tables, str->ptr(), conv_name_length); + spider_store_tables_name(table_gtid_pos, str->ptr(), conv_name_length); + spider_store_binlog_pos_failed_link_idx(table_gtid_pos, failed_link_idx); + if ((error_num = spider_get_sys_table_by_idx(table_tables, table_key, 0, + SPIDER_SYS_TABLES_PK_COL_CNT - 1))) + { + if (error_num == HA_ERR_KEY_NOT_FOUND || error_num == HA_ERR_END_OF_FILE) + { + error_num = 0; + } + goto error_get_sys_table_by_idx; + } + + SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); + do { + if ( + (error_num = spider_get_sys_tables_link_status(table_tables, + &link_status, &mem_root)) || + (error_num = spider_get_sys_tables_static_link_id(table_tables, + &static_link_id, &static_link_id_length, &mem_root)) || + (error_num = spider_get_sys_tables_monitoring_binlog_pos_at_failing( + table_tables, &monitoring_binlog_pos_at_failing, &mem_root)) + ) { + goto error_get_sys_tables_link_status; + } + + if (link_status == 1 && monitoring_binlog_pos_at_failing > 0) + { + if ((error_num = spider_get_sys_tables_link_idx(table_tables, + &source_link_idx, &mem_root))) + { + goto error_get_sys_tables_link_idx; + } + if ( + (table_mon_list = spider_get_ping_table_mon_list( + trx, + thd, + str, + conv_name_length, + source_link_idx, + static_link_id, + static_link_id_length, + server_id, + need_lock, + &error_num + )) + ) { + SPIDER_DB_RESULT *res1 = NULL; + SPIDER_DB_RESULT *res2 = NULL; + if ( + (ping_conn = spider_get_ping_table_tgt_conn(trx, + table_mon_list->share, &error_num + )) && + !(error_num = ping_conn->db_conn->show_master_status( + trx, table_mon_list->share, 0, &need_mon, table_gtid_pos, tmp_str, + monitoring_binlog_pos_at_failing == 1 ? 0 : 1, &res1, &res2)) + ) { + spider_store_binlog_pos_source_link_idx( + table_gtid_pos, source_link_idx); + spider_insert_sys_table(table_gtid_pos); + } + if (res1) + { + res1->free_result(); + delete res1; + } + if (res2) + { + res2->free_result(); + delete res2; + } + spider_free_ping_table_mon_list(table_mon_list); + } + } + + error_num = spider_sys_index_next_same(table_tables, table_key); + } while (error_num == 0); + free_root(&mem_root, MYF(0)); + + if ((error_num = spider_sys_index_end(table_tables))) + { + goto error_sys_index_end; + } + spider_close_sys_table(thd, table_gtid_pos, &open_tables_backup_gtid_pos, + need_lock); + spider_close_sys_table(thd, table_tables, &open_tables_backup_tables, + need_lock); + + DBUG_RETURN(0); + +error_get_sys_tables_link_idx: +error_get_sys_tables_link_status: + free_root(&mem_root, MYF(0)); + spider_sys_index_end(table_tables); +error_sys_index_end: +error_get_sys_table_by_idx: + spider_close_sys_table(thd, table_gtid_pos, &open_tables_backup_gtid_pos, + need_lock); +error_open_table_gtid_pos: + spider_close_sys_table(thd, table_tables, &open_tables_backup_tables, + need_lock); +error_open_table_tables: + DBUG_RETURN(error_num); +} + int spider_init_ping_table_mon_cache( THD *thd, MEM_ROOT *mem_root, @@ -820,7 +1028,7 @@ long long spider_ping_table_body( ) { int error_num = 0, link_idx, flags, full_mon_count, current_mon_count, success_count, fault_count, tmp_error_num = 0; - uint32 first_sid; + uint32 first_sid, server_id; longlong limit, tmp_sid = -1; SPIDER_MON_TABLE_RESULT *mon_table_result = (SPIDER_MON_TABLE_RESULT *) initid->ptr; @@ -831,15 +1039,24 @@ long long spider_ping_table_body( SPIDER_TABLE_MON_LIST *table_mon_list; SPIDER_TABLE_MON *table_mon; - char buf[MAX_FIELD_WIDTH]; + char buf[MAX_FIELD_WIDTH], buf2[MAX_FIELD_WIDTH]; spider_string conv_name(buf, sizeof(buf), system_charset_info); + spider_string tmp_str(buf2, sizeof(buf2), system_charset_info); int conv_name_length; - char link_idx_str[SPIDER_SQL_INT_LEN]; + char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1]; int link_idx_str_length; - bool get_lock = FALSE; + char *static_link_id = NULL; + int static_link_id_length = 0; + bool get_lock = FALSE, status_changed_to_ng = FALSE; DBUG_ENTER("spider_ping_table_body"); conv_name.init_calc_mem(135); + tmp_str.init_calc_mem(247); conv_name.length(0); +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002 + server_id = global_system_variables.server_id; +#else + server_id = thd->server_id; +#endif if ( thd->open_tables != 0 || thd->handler_tables_hash.records != 0 || @@ -905,26 +1122,52 @@ long long spider_ping_table_body( if ( args->lengths[0] > SPIDER_CONNECT_INFO_MAX_LEN ) { - my_printf_error(ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_NUM, - ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_STR, MYF(0)); + my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM, + ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "table name"); goto error; } if ( args->lengths[0] == 0 ) { - my_printf_error(ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_NUM, - ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_STR, MYF(0)); + my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM, + ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "table name"); goto error; } - - link_idx = (int) (args->args[1] ? *((longlong *) args->args[1]) : 0); + if (args->arg_type[1] == STRING_RESULT) + { + if ( + !args->args[1] + ) { + my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM, + ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "link id"); + goto error; + } + if ( + args->lengths[1] > SPIDER_CONNECT_INFO_MAX_LEN + ) { + my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM, + ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "link id"); + goto error; + } + link_idx_str_length = args->lengths[1]; + memcpy(link_idx_str, args->args[1], link_idx_str_length + 1); + if (link_idx_str[0] >= '0' && link_idx_str[0] <= '9') + { + link_idx = atoi(link_idx_str); + } else { + link_idx = -1; + static_link_id = link_idx_str; + static_link_id_length = link_idx_str_length; + } + } else { + link_idx = (int) (args->args[1] ? *((longlong *) args->args[1]) : 0); + link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d", + link_idx)); + } flags = (int) (args->args[2] ? *((longlong *) args->args[2]) : 0); limit = args->args[3] ? *((longlong *) args->args[3]) : 0; where_clause = args->args[4] ? args->args[4] : (char *) ""; - link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d", - link_idx)); - if (conv_name.append(args->args[0], args->lengths[0], trx->thd->variables.character_set_client)) { @@ -940,14 +1183,10 @@ long long spider_ping_table_body( conv_name.q_append(link_idx_str, link_idx_str_length + 1); conv_name.length(conv_name.length() - 1); -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002 if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd, - &conv_name, conv_name_length, link_idx, global_system_variables.server_id, - TRUE, &error_num))) -#else - if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd, - &conv_name, conv_name_length, link_idx, thd->server_id, TRUE, &error_num))) -#endif + &conv_name, conv_name_length, link_idx, + static_link_id, static_link_id_length, + server_id, TRUE, &error_num))) goto error; if (table_mon_list->mon_status == SPIDER_LINK_MON_NG) @@ -974,11 +1213,7 @@ long long spider_ping_table_body( goto error_with_free_table_mon_list; } } else { -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002 - first_sid = global_system_variables.server_id; -#else - first_sid = thd->server_id; -#endif + first_sid = server_id; full_mon_count = table_mon_list->list_size; current_mon_count = 1; } @@ -1040,11 +1275,21 @@ long long spider_ping_table_body( SPIDER_LINK_STATUS_NG, TRUE); spider_sys_log_tables_link_failed(trx->thd, conv_name.c_ptr(), conv_name_length, link_idx, TRUE); + status_changed_to_ng = TRUE; } /* pthread_mutex_unlock(&table_mon_list->update_status_mutex); */ pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); + if (status_changed_to_ng) + { + bool is_error = trx->thd->is_error(); + spider_get_ping_table_gtid_pos(trx, trx->thd, + &conv_name, conv_name_length, link_idx, server_id, TRUE, + &tmp_str); + if (!is_error && trx->thd->is_error()) + trx->thd->clear_error(); + } } goto end; } @@ -1103,11 +1348,21 @@ long long spider_ping_table_body( SPIDER_LINK_STATUS_NG, TRUE); spider_sys_log_tables_link_failed(trx->thd, conv_name.c_ptr(), conv_name_length, link_idx, TRUE); + status_changed_to_ng = TRUE; } /* pthread_mutex_unlock(&table_mon_list->update_status_mutex); */ pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); + if (status_changed_to_ng) + { + bool is_error = trx->thd->is_error(); + spider_get_ping_table_gtid_pos(trx, trx->thd, + &conv_name, conv_name_length, link_idx, server_id, TRUE, + &tmp_str); + if (!is_error && trx->thd->is_error()) + trx->thd->clear_error(); + } } } else if ( (flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) && @@ -1156,11 +1411,21 @@ long long spider_ping_table_body( SPIDER_LINK_STATUS_NG, TRUE); spider_sys_log_tables_link_failed(trx->thd, conv_name.c_ptr(), conv_name_length, link_idx, TRUE); + status_changed_to_ng = TRUE; } /* pthread_mutex_unlock(&table_mon_list->update_status_mutex); */ pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); + if (status_changed_to_ng) + { + bool is_error = trx->thd->is_error(); + spider_get_ping_table_gtid_pos(trx, trx->thd, + &conv_name, conv_name_length, link_idx, server_id, TRUE, + &tmp_str); + if (!is_error && trx->thd->is_error()) + trx->thd->clear_error(); + } } table_mon_list->last_receptor_result = mon_table_result->result_status; @@ -1216,7 +1481,6 @@ my_bool spider_ping_table_init_body( goto error; } if ( - args->arg_type[1] != INT_RESULT || args->arg_type[2] != INT_RESULT || args->arg_type[3] != INT_RESULT || args->arg_type[5] != INT_RESULT || @@ -1225,10 +1489,18 @@ my_bool spider_ping_table_init_body( args->arg_type[8] != INT_RESULT || args->arg_type[9] != INT_RESULT ) { - strcpy(message, "spider_ping_table() requires integer 2nd, 3rd, 4,6,7,8," + strcpy(message, "spider_ping_table() requires integer 3rd, 4,6,7,8," "9th and 10th argument"); goto error; } + if ( + args->arg_type[1] != INT_RESULT && + args->arg_type[1] != STRING_RESULT + ) { + strcpy(message, "spider_ping_table() requires string or integer for " + "2nd argument"); + goto error; + } if (!(trx = spider_get_trx(thd, TRUE, &error_num))) { @@ -1312,6 +1584,7 @@ int spider_ping_table_mon_from_table( SPIDER_TRX *trx, THD *thd, SPIDER_SHARE *share, + int base_link_idx, uint32 server_id, char *conv_name, uint conv_name_length, @@ -1333,7 +1606,7 @@ int spider_ping_table_mon_from_table( SPIDER_MON_TABLE_RESULT mon_table_result; SPIDER_CONN *mon_conn; TABLE_SHARE *table_share = share->table_share; - char link_idx_str[SPIDER_SQL_INT_LEN]; + char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1]; int link_idx_str_length; uint sql_command = thd_sql_command(thd); DBUG_ENTER("spider_ping_table_mon_from_table"); @@ -1362,19 +1635,24 @@ int spider_ping_table_mon_from_table( DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); } - link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d", - link_idx)); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_string conv_name_str(conv_name_length + link_idx_str_length + 1); - conv_name_str.set_charset(system_charset_info); - *((char *)(conv_name_str.ptr() + conv_name_length + link_idx_str_length)) = - '\0'; -#else - char buf[conv_name_length + link_idx_str_length + 1]; + if (share->static_link_ids[link_idx]) + { + memcpy(link_idx_str, share->static_link_ids[link_idx], + share->static_link_ids_lengths[link_idx] + 1); + link_idx_str_length = share->static_link_ids_lengths[link_idx]; + } else { + link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d", + link_idx)); + } + char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1); + if (!buf) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } buf[conv_name_length + link_idx_str_length] = '\0'; spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1, system_charset_info); -#endif conv_name_str.init_calc_mem(136); conv_name_str.length(0); conv_name_str.q_append(conv_name, conv_name_length); @@ -1392,9 +1670,14 @@ int spider_ping_table_mon_from_table( flags |= SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES; if (!(table_mon_list = spider_get_ping_table_mon_list(trx, thd, - &conv_name_str, conv_name_length, link_idx, server_id, need_lock, - &error_num))) + &conv_name_str, conv_name_length, link_idx, + share->static_link_ids[link_idx], + share->static_link_ids_lengths[link_idx], + server_id, need_lock, &error_num))) + { + my_afree(buf); goto end; + } if (table_mon_list->mon_status == SPIDER_LINK_MON_NG) { @@ -1408,6 +1691,7 @@ int spider_ping_table_mon_from_table( ER_SPIDER_LINK_MON_NG_STR, MYF(0), table_mon_list->share->tgt_dbs[0], table_mon_list->share->tgt_table_names[0]); + my_afree(buf); goto end_with_free_table_mon_list; } @@ -1580,6 +1864,7 @@ int spider_ping_table_mon_from_table( pthread_mutex_unlock(&table_mon_list->caller_mutex); } + my_afree(buf); end_with_free_table_mon_list: spider_free_ping_table_mon_list(table_mon_list); end: diff --git a/storage/spider/spd_ping_table.h b/storage/spider/spd_ping_table.h index 8d12010e524..24d477996db 100644 --- a/storage/spider/spd_ping_table.h +++ b/storage/spider/spd_ping_table.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2014 Kentoku Shiba +/* Copyright (C) 2009-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( SPIDER_TRX *trx, @@ -19,6 +19,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( spider_string *str, uint conv_name_length, int link_idx, + char *static_link_id, + uint static_link_id_length, uint32 server_id, bool need_lock, int *error_num @@ -33,7 +35,7 @@ void spider_release_ping_table_mon_list_loop( SPIDER_TABLE_MON_LIST *table_mon_list ); -void spider_release_ping_table_mon_list( +int spider_release_ping_table_mon_list( const char *conv_name, uint conv_name_length, int link_idx @@ -55,6 +57,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( char *name, uint name_length, int link_idx, + char *static_link_id, + uint static_link_id_length, uint32 server_id, spider_string *str, bool need_lock, @@ -67,6 +71,17 @@ SPIDER_CONN *spider_get_ping_table_tgt_conn( int *error_num ); +int spider_get_ping_table_gtid_pos( + SPIDER_TRX *trx, + THD *thd, + spider_string *str, + uint conv_name_length, + int failed_link_idx, + uint32 server_id, + bool need_lock, + spider_string *tmp_str +); + int spider_init_ping_table_mon_cache( THD *thd, MEM_ROOT *mem_root, @@ -90,6 +105,7 @@ int spider_ping_table_mon_from_table( SPIDER_TRX *trx, THD *thd, SPIDER_SHARE *share, + int base_link_idx, uint32 server_id, char *conv_name, uint conv_name_length, diff --git a/storage/spider/spd_sys_table.cc b/storage/spider/spd_sys_table.cc index 4ebbd3b0a13..a966cd32857 100644 --- a/storage/spider/spd_sys_table.cc +++ b/storage/spider/spd_sys_table.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -26,6 +26,7 @@ #include "sql_class.h" #include "key.h" #include "sql_base.h" +#include "tztime.h" #endif #include "sql_select.h" #include "spd_err.h" @@ -36,6 +37,7 @@ #include "spd_malloc.h" extern handlerton *spider_hton_ptr; +extern Time_zone *spd_tz_system; #if MYSQL_VERSION_ID < 50500 TABLE *spider_open_sys_table( @@ -193,6 +195,22 @@ TABLE *spider_open_sys_table( *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; goto error_col_num_chk; } + } else if (table_name_length == SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN) + { + if ( + !memcmp(table_name, + SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR, + SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN) && + table->s->fields != SPIDER_SYS_POS_FOR_RECOVERY_TABLE_COL_CNT + ) { + spider_close_sys_table(thd, table, open_tables_backup, need_lock); + table = NULL; + my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, + ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), + SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR); + *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; + goto error_col_num_chk; + } } DBUG_RETURN(table); @@ -229,8 +247,7 @@ void spider_close_sys_table( close_performance_schema_table(thd, open_tables_backup); } else { table->file->ha_reset(); - closefrm(table); - tdc_release_share(table->s); + closefrm(table, TRUE); spider_free(spider_current_trx, table, MYF(0)); thd->restore_backup_open_tables_state(open_tables_backup); } @@ -373,6 +390,29 @@ int spider_check_sys_table_with_find_flag( #endif } +int spider_check_sys_table_for_update_all_columns( + TABLE *table, + char *table_key +) { + DBUG_ENTER("spider_check_sys_table_for_update_all_columns"); + + key_copy( + (uchar *) table_key, + table->record[0], + table->key_info, + table->key_info->key_length); + +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50200 + DBUG_RETURN(table->file->ha_index_read_idx_map( + table->record[1], 0, (uchar *) table_key, + HA_WHOLE_KEY, HA_READ_KEY_EXACT)); +#else + DBUG_RETURN(table->file->index_read_idx_map( + table->record[1], 0, (uchar *) table_key, + HA_WHOLE_KEY, HA_READ_KEY_EXACT)); +#endif +} + int spider_get_sys_table_by_idx( TABLE *table, char *table_key, @@ -679,13 +719,13 @@ void spider_store_tables_name( } table->field[0]->store( ptr_db, - (uint)(ptr_diff_table - 1), + ptr_diff_table - 1, system_charset_info); DBUG_PRINT("info",("spider field[0]->null_bit = %d", table->field[0]->null_bit)); table->field[1]->store( ptr_table, - (uint)(name_length - ptr_diff_db - ptr_diff_table), + name_length - ptr_diff_db - ptr_diff_table, system_charset_info); DBUG_PRINT("info",("spider field[1]->null_bit = %d", table->field[1]->null_bit)); @@ -740,6 +780,26 @@ void spider_store_tables_link_idx_str( DBUG_VOID_RETURN; } +void spider_store_tables_static_link_id( + TABLE *table, + const char *static_link_id, + const uint static_link_id_length +) { + DBUG_ENTER("spider_store_tables_static_link_id"); + if (static_link_id) + { + table->field[24]->set_notnull(); + table->field[24]->store( + static_link_id, + static_link_id_length, + system_charset_info); + } else { + table->field[24]->set_null(); + table->field[24]->reset(); + } + DBUG_VOID_RETURN; +} + void spider_store_tables_priority( TABLE *table, longlong priority @@ -895,50 +955,73 @@ void spider_store_tables_connect_info( table->field[16]->set_null(); table->field[16]->reset(); } - if (alter_table->tmp_tgt_default_files[link_idx]) + table->field[17]->set_notnull(); + if (alter_table->tmp_monitoring_binlog_pos_at_failing[link_idx] >= 0) { - table->field[17]->set_notnull(); table->field[17]->store( - alter_table->tmp_tgt_default_files[link_idx], - (uint) alter_table->tmp_tgt_default_files_lengths[link_idx], - system_charset_info); + alter_table->tmp_monitoring_binlog_pos_at_failing[link_idx]); } else { - table->field[17]->set_null(); - table->field[17]->reset(); + table->field[17]->store(0); } - if (alter_table->tmp_tgt_default_groups[link_idx]) + if (alter_table->tmp_tgt_default_files[link_idx]) { table->field[18]->set_notnull(); table->field[18]->store( - alter_table->tmp_tgt_default_groups[link_idx], - (uint) alter_table->tmp_tgt_default_groups_lengths[link_idx], + alter_table->tmp_tgt_default_files[link_idx], + (uint) alter_table->tmp_tgt_default_files_lengths[link_idx], system_charset_info); } else { table->field[18]->set_null(); table->field[18]->reset(); } - if (alter_table->tmp_tgt_dbs[link_idx]) + if (alter_table->tmp_tgt_default_groups[link_idx]) { table->field[19]->set_notnull(); table->field[19]->store( - alter_table->tmp_tgt_dbs[link_idx], - (uint) alter_table->tmp_tgt_dbs_lengths[link_idx], + alter_table->tmp_tgt_default_groups[link_idx], + (uint) alter_table->tmp_tgt_default_groups_lengths[link_idx], system_charset_info); } else { table->field[19]->set_null(); table->field[19]->reset(); } - if (alter_table->tmp_tgt_table_names[link_idx]) + if (alter_table->tmp_tgt_dbs[link_idx]) { table->field[20]->set_notnull(); table->field[20]->store( - alter_table->tmp_tgt_table_names[link_idx], - (uint) alter_table->tmp_tgt_table_names_lengths[link_idx], + alter_table->tmp_tgt_dbs[link_idx], + (uint) alter_table->tmp_tgt_dbs_lengths[link_idx], system_charset_info); } else { table->field[20]->set_null(); table->field[20]->reset(); } + if (alter_table->tmp_tgt_table_names[link_idx]) + { + table->field[21]->set_notnull(); + table->field[21]->store( + alter_table->tmp_tgt_table_names[link_idx], + (uint) alter_table->tmp_tgt_table_names_lengths[link_idx], + system_charset_info); + } else { + table->field[21]->set_null(); + table->field[21]->reset(); + } + table->field[23]->store((longlong) 0, FALSE); + if (alter_table->tmp_static_link_ids[link_idx]) + { + DBUG_PRINT("info",("spider static_link_id[%d] = %s", + link_idx, alter_table->tmp_static_link_ids[link_idx])); + table->field[24]->set_notnull(); + table->field[24]->store( + alter_table->tmp_static_link_ids[link_idx], + (uint) alter_table->tmp_static_link_ids_lengths[link_idx], + system_charset_info); + } else { + DBUG_PRINT("info",("spider static_link_id[%d] = NULL", link_idx)); + table->field[24]->set_null(); + table->field[24]->reset(); + } DBUG_VOID_RETURN; } @@ -949,7 +1032,7 @@ void spider_store_tables_link_status( DBUG_ENTER("spider_store_tables_link_status"); DBUG_PRINT("info",("spider link_status = %ld", link_status)); if (link_status > SPIDER_LINK_STATUS_NO_CHANGE) - table->field[21]->store(link_status, FALSE); + table->field[22]->store(link_status, FALSE); DBUG_VOID_RETURN; } @@ -963,6 +1046,116 @@ void spider_store_link_chk_server_id( DBUG_VOID_RETURN; } +void spider_store_binlog_pos_failed_link_idx( + TABLE *table, + int failed_link_idx +) { + DBUG_ENTER("spider_store_binlog_pos_failed_link_idx"); + table->field[2]->set_notnull(); + table->field[2]->store(failed_link_idx); + DBUG_VOID_RETURN; +} + +void spider_store_binlog_pos_source_link_idx( + TABLE *table, + int source_link_idx +) { + DBUG_ENTER("spider_store_binlog_pos_source_link_idx"); + table->field[3]->set_notnull(); + table->field[3]->store(source_link_idx); + DBUG_VOID_RETURN; +} + +void spider_store_binlog_pos_binlog_file( + TABLE *table, + const char *file_name, + int file_name_length, + const char *position, + int position_length, + CHARSET_INFO *binlog_pos_cs +) { + DBUG_ENTER("spider_store_binlog_pos_binlog_file"); + if (!file_name) + { + DBUG_PRINT("info",("spider file_name is NULL")); + table->field[4]->set_null(); + table->field[4]->reset(); + } else { + DBUG_PRINT("info",("spider file_name = %s", file_name)); + table->field[4]->set_notnull(); + table->field[4]->store(file_name, file_name_length, binlog_pos_cs); + } + if (!position) + { + DBUG_PRINT("info",("spider position is NULL")); + table->field[5]->set_null(); + table->field[5]->reset(); + } else { + DBUG_PRINT("info",("spider position = %s", position)); + table->field[5]->set_notnull(); + table->field[5]->store(position, position_length, binlog_pos_cs); + } + DBUG_VOID_RETURN; +} + +void spider_store_binlog_pos_gtid( + TABLE *table, + const char *gtid, + int gtid_length, + CHARSET_INFO *binlog_pos_cs +) { + DBUG_ENTER("spider_store_binlog_pos_gtid"); + if (!gtid) + { + DBUG_PRINT("info",("spider gtid is NULL")); + table->field[6]->set_null(); + table->field[6]->reset(); + } else { + DBUG_PRINT("info",("spider gtid = %s", gtid)); + table->field[6]->set_notnull(); + table->field[6]->store(gtid, gtid_length, binlog_pos_cs); + } + DBUG_VOID_RETURN; +} + +void spider_store_table_sts_info( + TABLE *table, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time +) { + MYSQL_TIME mysql_time; + DBUG_ENTER("spider_store_table_sts_info"); + table->field[2]->store((longlong) *data_file_length, TRUE); + table->field[3]->store((longlong) *max_data_file_length, TRUE); + table->field[4]->store((longlong) *index_file_length, TRUE); + table->field[5]->store((longlong) *records, TRUE); + table->field[6]->store((longlong) *mean_rec_length, TRUE); + spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) *check_time); + table->field[7]->store_time(&mysql_time); + spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) *create_time); + table->field[8]->store_time(&mysql_time); + spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) *update_time); + table->field[9]->store_time(&mysql_time); + DBUG_VOID_RETURN; +} + +void spider_store_table_crd_info( + TABLE *table, + uint *seq, + longlong *cardinality +) { + DBUG_ENTER("spider_store_table_crd_info"); + table->field[2]->store((longlong) *seq, TRUE); + table->field[3]->store((longlong) *cardinality, FALSE); + DBUG_VOID_RETURN; +} + int spider_insert_xa( TABLE *table, XID *xid, @@ -1063,6 +1256,114 @@ int spider_insert_tables( DBUG_RETURN(0); } +int spider_insert_sys_table( + TABLE *table +) { + int error_num; + DBUG_ENTER("spider_insert_sys_table"); + if ((error_num = table->file->ha_write_row(table->record[0]))) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + DBUG_RETURN(0); +} + +int spider_insert_or_update_table_sts( + TABLE *table, + const char *name, + uint name_length, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time +) { + int error_num; + char table_key[MAX_KEY_LENGTH]; + DBUG_ENTER("spider_insert_or_update_table_sts"); + table->use_all_columns(); + spider_store_tables_name(table, name, name_length); + spider_store_table_sts_info( + table, + data_file_length, + max_data_file_length, + index_file_length, + records, + mean_rec_length, + check_time, + create_time, + update_time + ); + + if ((error_num = spider_check_sys_table_for_update_all_columns(table, table_key))) + { + if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + if ((error_num = table->file->ha_write_row(table->record[0]))) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + } else { + if ((error_num = table->file->ha_update_row(table->record[1], + table->record[0]))) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + } + + DBUG_RETURN(0); +} + +int spider_insert_or_update_table_crd( + TABLE *table, + const char *name, + uint name_length, + longlong *cardinality, + uint number_of_keys +) { + int error_num; + uint roop_count; + char table_key[MAX_KEY_LENGTH]; + DBUG_ENTER("spider_insert_or_update_table_crd"); + table->use_all_columns(); + spider_store_tables_name(table, name, name_length); + + for (roop_count = 0; roop_count < number_of_keys; ++roop_count) + { + spider_store_table_crd_info(table, &roop_count, &cardinality[roop_count]); + if ((error_num = spider_check_sys_table_for_update_all_columns(table, table_key))) + { + if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + if ((error_num = table->file->ha_write_row(table->record[0]))) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + } else { + if ((error_num = table->file->ha_update_row(table->record[1], + table->record[0]))) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + } + } + DBUG_RETURN(0); +} + int spider_log_tables_link_failed( TABLE *table, char *name, @@ -1439,6 +1740,78 @@ int spider_delete_tables( DBUG_RETURN(0); } +int spider_delete_table_sts( + TABLE *table, + const char *name, + uint name_length +) { + int error_num; + char table_key[MAX_KEY_LENGTH]; + DBUG_ENTER("spider_delete_table_sts"); + table->use_all_columns(); + spider_store_tables_name(table, name, name_length); + + if ((error_num = spider_check_sys_table(table, table_key))) + { + if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + /* no record is ok */ + DBUG_RETURN(0); + } else { + if ((error_num = table->file->ha_delete_row(table->record[0]))) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + } + + DBUG_RETURN(0); +} + +int spider_delete_table_crd( + TABLE *table, + const char *name, + uint name_length +) { + int error_num; + char table_key[MAX_KEY_LENGTH]; + DBUG_ENTER("spider_delete_table_crd"); + table->use_all_columns(); + spider_store_tables_name(table, name, name_length); + + if ((error_num = spider_get_sys_table_by_idx(table, table_key, 0, + SPIDER_SYS_TABLE_CRD_PK_COL_CNT - 1))) + { + if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + /* no record is ok */ + DBUG_RETURN(0); + } else { + do { + if ((error_num = table->file->ha_delete_row(table->record[0]))) + { + spider_sys_index_end(table); + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + error_num = spider_sys_index_next_same(table, table_key); + } while (error_num == 0); + } + if ((error_num = spider_sys_index_end(table))) + { + table->file->print_error(error_num, MYF(0)); + DBUG_RETURN(error_num); + } + + DBUG_RETURN(0); +} + int spider_get_sys_xid( TABLE *table, XID *xid, @@ -1821,6 +2194,13 @@ int spider_get_sys_tables_connect_info( !table->field[17]->is_null() && (ptr = get_field(mem_root, table->field[17])) ) { + share->monitoring_binlog_pos_at_failing[link_idx] = atol(ptr); + } else + share->monitoring_binlog_pos_at_failing[link_idx] = 0; + if ( + !table->field[18]->is_null() && + (ptr = get_field(mem_root, table->field[18])) + ) { share->tgt_default_files_lengths[link_idx] = strlen(ptr); share->tgt_default_files[link_idx] = spider_create_string(ptr, share->tgt_default_files_lengths[link_idx]); @@ -1829,8 +2209,8 @@ int spider_get_sys_tables_connect_info( share->tgt_default_files[link_idx] = NULL; } if ( - !table->field[18]->is_null() && - (ptr = get_field(mem_root, table->field[18])) + !table->field[19]->is_null() && + (ptr = get_field(mem_root, table->field[19])) ) { share->tgt_default_groups_lengths[link_idx] = strlen(ptr); share->tgt_default_groups[link_idx] = @@ -1840,8 +2220,8 @@ int spider_get_sys_tables_connect_info( share->tgt_default_groups[link_idx] = NULL; } if ( - !table->field[19]->is_null() && - (ptr = get_field(mem_root, table->field[19])) + !table->field[20]->is_null() && + (ptr = get_field(mem_root, table->field[20])) ) { share->tgt_dbs_lengths[link_idx] = strlen(ptr); share->tgt_dbs[link_idx] = @@ -1851,8 +2231,8 @@ int spider_get_sys_tables_connect_info( share->tgt_dbs[link_idx] = NULL; } if ( - !table->field[20]->is_null() && - (ptr = get_field(mem_root, table->field[20])) + !table->field[21]->is_null() && + (ptr = get_field(mem_root, table->field[21])) ) { share->tgt_table_names_lengths[link_idx] = strlen(ptr); share->tgt_table_names[link_idx] = @@ -1861,6 +2241,35 @@ int spider_get_sys_tables_connect_info( share->tgt_table_names_lengths[link_idx] = 0; share->tgt_table_names[link_idx] = NULL; } + if ( + !table->field[24]->is_null() && + (ptr = get_field(mem_root, table->field[24])) + ) { + share->static_link_ids_lengths[link_idx] = strlen(ptr); + share->static_link_ids[link_idx] = + spider_create_string(ptr, share->static_link_ids_lengths[link_idx]); + } else { + share->static_link_ids_lengths[link_idx] = 0; + share->static_link_ids[link_idx] = NULL; + } + DBUG_RETURN(error_num); +} + +int spider_get_sys_tables_monitoring_binlog_pos_at_failing( + TABLE *table, + long *monitoring_binlog_pos_at_failing, + MEM_ROOT *mem_root +) { + char *ptr; + int error_num = 0; + DBUG_ENTER("spider_get_sys_tables_monitoring_binlog_pos_at_failing"); + if ((ptr = get_field(mem_root, table->field[17]))) + *monitoring_binlog_pos_at_failing = (long) my_strtoll10(ptr, (char**) NULL, + &error_num); + else + *monitoring_binlog_pos_at_failing = 1; + DBUG_PRINT("info",("spider monitoring_binlog_pos_at_failing=%ld", + *monitoring_binlog_pos_at_failing)); DBUG_RETURN(error_num); } @@ -1873,7 +2282,7 @@ int spider_get_sys_tables_link_status( char *ptr; int error_num = 0; DBUG_ENTER("spider_get_sys_tables_link_status"); - if ((ptr = get_field(mem_root, table->field[21]))) + if ((ptr = get_field(mem_root, table->field[22]))) { share->link_statuses[link_idx] = (long) my_strtoll10(ptr, (char**) NULL, &error_num); @@ -1884,6 +2293,22 @@ int spider_get_sys_tables_link_status( DBUG_RETURN(error_num); } +int spider_get_sys_tables_link_status( + TABLE *table, + long *link_status, + MEM_ROOT *mem_root +) { + char *ptr; + int error_num = 0; + DBUG_ENTER("spider_get_sys_tables_link_status"); + if ((ptr = get_field(mem_root, table->field[22]))) + *link_status = (long) my_strtoll10(ptr, (char**) NULL, &error_num); + else + *link_status = 1; + DBUG_PRINT("info",("spider link_statuses=%ld", *link_status)); + DBUG_RETURN(error_num); +} + int spider_get_sys_tables_link_idx( TABLE *table, int *link_idx, @@ -1891,7 +2316,7 @@ int spider_get_sys_tables_link_idx( ) { char *ptr; int error_num = 0; - DBUG_ENTER("spider_get_sys_tables_link_status"); + DBUG_ENTER("spider_get_sys_tables_link_idx"); if ((ptr = get_field(mem_root, table->field[2]))) *link_idx = (int) my_strtoll10(ptr, (char**) NULL, &error_num); else @@ -1900,6 +2325,92 @@ int spider_get_sys_tables_link_idx( DBUG_RETURN(error_num); } +int spider_get_sys_tables_static_link_id( + TABLE *table, + char **static_link_id, + uint *static_link_id_length, + MEM_ROOT *mem_root +) { + int error_num = 0; + DBUG_ENTER("spider_get_sys_tables_static_link_id"); + if ( + !table->field[24]->is_null() && + (*static_link_id = get_field(mem_root, table->field[24])) + ) { + *static_link_id_length = strlen(*static_link_id); + } else { + *static_link_id_length = 0; + } + DBUG_PRINT("info",("spider static_link_id=%s", *static_link_id ? *static_link_id : "NULL")); + DBUG_RETURN(error_num); +} + +void spider_get_sys_table_sts_info( + TABLE *table, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time +) { + MYSQL_TIME mysql_time; +#ifdef MARIADB_BASE_VERSION + uint not_used_uint; +#else + my_bool not_used_my_bool; +#endif + long not_used_long; + DBUG_ENTER("spider_get_sys_table_sts_info"); + *data_file_length = (ulonglong) table->field[2]->val_int(); + *max_data_file_length = (ulonglong) table->field[3]->val_int(); + *index_file_length = (ulonglong) table->field[4]->val_int(); + *records = (ha_rows) table->field[5]->val_int(); + *mean_rec_length = (ulong) table->field[6]->val_int(); + table->field[7]->get_date(&mysql_time, 0); +#ifdef MARIADB_BASE_VERSION + *check_time = (time_t) my_system_gmt_sec(&mysql_time, + ¬_used_long, ¬_used_uint); +#else + *check_time = (time_t) my_system_gmt_sec(&mysql_time, + ¬_used_long, ¬_used_my_bool); +#endif + table->field[8]->get_date(&mysql_time, 0); +#ifdef MARIADB_BASE_VERSION + *create_time = (time_t) my_system_gmt_sec(&mysql_time, + ¬_used_long, ¬_used_uint); +#else + *create_time = (time_t) my_system_gmt_sec(&mysql_time, + ¬_used_long, ¬_used_my_bool); +#endif + table->field[9]->get_date(&mysql_time, 0); +#ifdef MARIADB_BASE_VERSION + *update_time = (time_t) my_system_gmt_sec(&mysql_time, + ¬_used_long, ¬_used_uint); +#else + *update_time = (time_t) my_system_gmt_sec(&mysql_time, + ¬_used_long, ¬_used_my_bool); +#endif + DBUG_VOID_RETURN; +} + +void spider_get_sys_table_crd_info( + TABLE *table, + longlong *cardinality, + uint number_of_keys +) { + uint seq; + DBUG_ENTER("spider_get_sys_table_crd_info"); + seq = (uint) table->field[2]->val_int(); + if (seq < number_of_keys) + { + cardinality[seq] = (longlong) table->field[3]->val_int(); + } + DBUG_VOID_RETURN; +} + int spider_sys_update_tables_link_status( THD *thd, char *name, @@ -2298,6 +2809,310 @@ int spider_get_link_statuses( DBUG_RETURN(0); } +int spider_sys_insert_or_update_table_sts( + THD *thd, + const char *name, + uint name_length, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time, + bool need_lock +) { + int error_num; + TABLE *table_sts = NULL; +#if MYSQL_VERSION_ID < 50500 + Open_tables_state open_tables_backup; +#else + Open_tables_backup open_tables_backup; +#endif + DBUG_ENTER("spider_sys_insert_or_update_table_sts"); + if ( + !(table_sts = spider_open_sys_table( + thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR, + SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE, + &open_tables_backup, need_lock, &error_num)) + ) { + goto error; + } + if ((error_num = spider_insert_or_update_table_sts( + table_sts, + name, + name_length, + data_file_length, + max_data_file_length, + index_file_length, + records, + mean_rec_length, + check_time, + create_time, + update_time + ))) + goto error; + spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); + table_sts = NULL; + DBUG_RETURN(0); + +error: + if (table_sts) + spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); + DBUG_RETURN(error_num); +} + +int spider_sys_insert_or_update_table_crd( + THD *thd, + const char *name, + uint name_length, + longlong *cardinality, + uint number_of_keys, + bool need_lock +) { + int error_num; + TABLE *table_crd = NULL; +#if MYSQL_VERSION_ID < 50500 + Open_tables_state open_tables_backup; +#else + Open_tables_backup open_tables_backup; +#endif + DBUG_ENTER("spider_sys_insert_or_update_table_crd"); + if ( + !(table_crd = spider_open_sys_table( + thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR, + SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE, + &open_tables_backup, need_lock, &error_num)) + ) { + goto error; + } + if ((error_num = spider_insert_or_update_table_crd( + table_crd, + name, + name_length, + cardinality, + number_of_keys + ))) + goto error; + spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); + table_crd = NULL; + DBUG_RETURN(0); + +error: + if (table_crd) + spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); + DBUG_RETURN(error_num); +} + +int spider_sys_delete_table_sts( + THD *thd, + const char *name, + uint name_length, + bool need_lock +) { + int error_num; + TABLE *table_sts = NULL; +#if MYSQL_VERSION_ID < 50500 + Open_tables_state open_tables_backup; +#else + Open_tables_backup open_tables_backup; +#endif + DBUG_ENTER("spider_sys_delete_table_sts"); + if ( + !(table_sts = spider_open_sys_table( + thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR, + SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE, + &open_tables_backup, need_lock, &error_num)) + ) { + goto error; + } + if ((error_num = spider_delete_table_sts( + table_sts, + name, + name_length + ))) + goto error; + spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); + table_sts = NULL; + DBUG_RETURN(0); + +error: + if (table_sts) + spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); + DBUG_RETURN(error_num); +} + +int spider_sys_delete_table_crd( + THD *thd, + const char *name, + uint name_length, + bool need_lock +) { + int error_num; + TABLE *table_crd = NULL; +#if MYSQL_VERSION_ID < 50500 + Open_tables_state open_tables_backup; +#else + Open_tables_backup open_tables_backup; +#endif + DBUG_ENTER("spider_sys_delete_table_crd"); + if ( + !(table_crd = spider_open_sys_table( + thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR, + SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE, + &open_tables_backup, need_lock, &error_num)) + ) { + goto error; + } + if ((error_num = spider_delete_table_crd( + table_crd, + name, + name_length + ))) + goto error; + spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); + table_crd = NULL; + DBUG_RETURN(0); + +error: + if (table_crd) + spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); + DBUG_RETURN(error_num); +} + +int spider_sys_get_table_sts( + THD *thd, + const char *name, + uint name_length, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time, + bool need_lock +) { + int error_num; + char table_key[MAX_KEY_LENGTH]; + TABLE *table_sts = NULL; +#if MYSQL_VERSION_ID < 50500 + Open_tables_state open_tables_backup; +#else + Open_tables_backup open_tables_backup; +#endif + DBUG_ENTER("spider_sys_get_table_sts"); + if ( + !(table_sts = spider_open_sys_table( + thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR, + SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE, + &open_tables_backup, need_lock, &error_num)) + ) { + goto error; + } + + table_sts->use_all_columns(); + spider_store_tables_name(table_sts, name, name_length); + if ((error_num = spider_check_sys_table(table_sts, table_key))) + { + if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + { + table_sts->file->print_error(error_num, MYF(0)); + } + goto error; + } else { + spider_get_sys_table_sts_info( + table_sts, + data_file_length, + max_data_file_length, + index_file_length, + records, + mean_rec_length, + check_time, + create_time, + update_time + ); + } + + spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); + table_sts = NULL; + DBUG_RETURN(0); + +error: + if (table_sts) + spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); + DBUG_RETURN(error_num); +} + +int spider_sys_get_table_crd( + THD *thd, + const char *name, + uint name_length, + longlong *cardinality, + uint number_of_keys, + bool need_lock +) { + int error_num; + char table_key[MAX_KEY_LENGTH]; + bool index_inited = FALSE; + TABLE *table_crd = NULL; +#if MYSQL_VERSION_ID < 50500 + Open_tables_state open_tables_backup; +#else + Open_tables_backup open_tables_backup; +#endif + DBUG_ENTER("spider_sys_get_table_crd"); + if ( + !(table_crd = spider_open_sys_table( + thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR, + SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE, + &open_tables_backup, need_lock, &error_num)) + ) { + goto error; + } + + table_crd->use_all_columns(); + spider_store_tables_name(table_crd, name, name_length); + if ((error_num = spider_get_sys_table_by_idx(table_crd, table_key, 0, + SPIDER_SYS_TABLE_CRD_PK_COL_CNT - 1))) + { + if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + { + table_crd->file->print_error(error_num, MYF(0)); + } + goto error; + } else { + index_inited = TRUE; + do { + spider_get_sys_table_crd_info( + table_crd, + cardinality, + number_of_keys + ); + error_num = spider_sys_index_next_same(table_crd, table_key); + } while (error_num == 0); + } + index_inited = FALSE; + if ((error_num = spider_sys_index_end(table_crd))) + { + table_crd->file->print_error(error_num, MYF(0)); + goto error; + } + + spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); + table_crd = NULL; + DBUG_RETURN(0); + +error: + if (index_inited) + spider_sys_index_end(table_crd); + if (table_crd) + spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); + DBUG_RETURN(error_num); +} + int spider_sys_replace( TABLE *table, bool *modified_non_trans_table @@ -2391,9 +3206,15 @@ TABLE *spider_mk_sys_tmp_table( LEX_CSTRING name= { field_name, strlen(field_name) }; DBUG_ENTER("spider_mk_sys_tmp_table"); +#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR + if (!(field = new (thd->mem_root) Field_blob( + (uint32) 4294967295U, FALSE, &name, cs, TRUE))) + goto error_alloc_field; +#else if (!(field = new Field_blob( 4294967295U, FALSE, &name, cs, TRUE))) goto error_alloc_field; +#endif field->init(table); #ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR @@ -2452,9 +3273,15 @@ TABLE *spider_mk_sys_tmp_table_for_result( LEX_CSTRING name3= { field_name3, strlen(field_name3) }; DBUG_ENTER("spider_mk_sys_tmp_table_for_result"); +#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR + if (!(field1 = new (thd->mem_root) Field_blob( + (uint32) 4294967295U, FALSE, &name1, cs, TRUE))) + goto error_alloc_field1; +#else if (!(field1 = new Field_blob( 4294967295U, FALSE, &name1, cs, TRUE))) goto error_alloc_field1; +#endif field1->init(table); #ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR @@ -2468,9 +3295,15 @@ TABLE *spider_mk_sys_tmp_table_for_result( if (i_list.push_back(i_field1)) goto error_push_item1; +#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR if (!(field2 = new (thd->mem_root) Field_blob( 4294967295U, FALSE, &name2, cs, TRUE))) goto error_alloc_field2; +#else + if (!(field2 = new Field_blob( + 4294967295U, FALSE, &name2, cs, TRUE))) + goto error_alloc_field2; +#endif field2->init(table); #ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR @@ -2484,9 +3317,15 @@ TABLE *spider_mk_sys_tmp_table_for_result( if (i_list.push_back(i_field2)) goto error_push_item2; +#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR if (!(field3 = new (thd->mem_root) Field_blob( 4294967295U, FALSE, &name3, cs, TRUE))) goto error_alloc_field3; +#else + if (!(field3 = new Field_blob( + 4294967295U, FALSE, field_name3, cs, TRUE))) + goto error_alloc_field3; +#endif field3->init(table); #ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR diff --git a/storage/spider/spd_sys_table.h b/storage/spider/spd_sys_table.h index fc9d3fc38bd..009ef2ac8ca 100644 --- a/storage/spider/spd_sys_table.h +++ b/storage/spider/spd_sys_table.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2014 Kentoku Shiba +/* Copyright (C) 2008-2016 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define SPIDER_SYS_XA_TABLE_NAME_STR "spider_xa" #define SPIDER_SYS_XA_TABLE_NAME_LEN (sizeof(SPIDER_SYS_XA_TABLE_NAME_STR) - 1) @@ -25,6 +25,12 @@ #define SPIDER_SYS_LINK_FAILED_TABLE_NAME_LEN (sizeof(SPIDER_SYS_LINK_FAILED_TABLE_NAME_STR) - 1) #define SPIDER_SYS_XA_FAILED_TABLE_NAME_STR "spider_xa_failed_log" #define SPIDER_SYS_XA_FAILED_TABLE_NAME_LEN (sizeof(SPIDER_SYS_XA_FAILED_TABLE_NAME_STR) - 1) +#define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR "spider_table_position_for_recovery" +#define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN (sizeof(SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR) - 1) +#define SPIDER_SYS_TABLE_STS_TABLE_NAME_STR "spider_table_sts" +#define SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN (sizeof(SPIDER_SYS_TABLE_STS_TABLE_NAME_STR) - 1) +#define SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR "spider_table_crd" +#define SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN (sizeof(SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR) - 1) #define SPIDER_SYS_XA_PREPARED_STR "PREPARED" #define SPIDER_SYS_XA_NOT_YET_STR "NOT YET" @@ -36,14 +42,20 @@ #define SPIDER_SYS_XA_IDX1_COL_CNT 1 #define SPIDER_SYS_XA_MEMBER_COL_CNT 18 #define SPIDER_SYS_XA_MEMBER_PK_COL_CNT 6 -#define SPIDER_SYS_TABLES_COL_CNT 22 -#define SPIDER_SYS_TABLES_PK_COL_CNT 2 +#define SPIDER_SYS_TABLES_COL_CNT 25 +#define SPIDER_SYS_TABLES_PK_COL_CNT 3 #define SPIDER_SYS_TABLES_IDX1_COL_CNT 1 +#define SPIDER_SYS_TABLES_UIDX1_COL_CNT 3 #define SPIDER_SYS_LINK_MON_TABLE_COL_CNT 19 +#define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_COL_CNT 7 +#define SPIDER_SYS_TABLE_STS_COL_CNT 10 +#define SPIDER_SYS_TABLE_STS_PK_COL_CNT 2 +#define SPIDER_SYS_TABLE_CRD_COL_CNT 4 +#define SPIDER_SYS_TABLE_CRD_PK_COL_CNT 3 #define SPIDER_SYS_LINK_MON_TABLE_DB_NAME_SIZE 64 #define SPIDER_SYS_LINK_MON_TABLE_TABLE_NAME_SIZE 64 -#define SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE 10 +#define SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE 64 class SPIDER_MON_KEY: public SPIDER_SORT { @@ -139,6 +151,11 @@ int spider_check_sys_table_with_find_flag( enum ha_rkey_function find_flag ); +int spider_check_sys_table_for_update_all_columns( + TABLE *table, + char *table_key +); + int spider_get_sys_table_by_idx( TABLE *table, char *table_key, @@ -212,6 +229,12 @@ void spider_store_tables_link_idx_str( const uint link_idx_length ); +void spider_store_tables_static_link_id( + TABLE *table, + const char *static_link_id, + const uint static_link_id_length +); + void spider_store_tables_priority( TABLE *table, longlong priority @@ -233,6 +256,50 @@ void spider_store_link_chk_server_id( uint32 server_id ); +void spider_store_binlog_pos_failed_link_idx( + TABLE *table, + int failed_link_idx +); + +void spider_store_binlog_pos_source_link_idx( + TABLE *table, + int source_link_idx +); + +void spider_store_binlog_pos_binlog_file( + TABLE *table, + const char *file_name, + int file_name_length, + const char *position, + int position_length, + CHARSET_INFO *binlog_pos_cs +); + +void spider_store_binlog_pos_gtid( + TABLE *table, + const char *gtid, + int gtid_length, + CHARSET_INFO *binlog_pos_cs +); + +void spider_store_table_sts_info( + TABLE *table, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time +); + +void spider_store_table_crd_info( + TABLE *table, + uint *seq, + longlong *cardinality +); + int spider_insert_xa( TABLE *table, XID *xid, @@ -250,6 +317,32 @@ int spider_insert_tables( SPIDER_SHARE *share ); +int spider_insert_sys_table( + TABLE *table +); + +int spider_insert_or_update_table_sts( + TABLE *table, + const char *name, + uint name_length, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time +); + +int spider_insert_or_update_table_crd( + TABLE *table, + const char *name, + uint name_length, + longlong *cardinality, + uint number_of_keys +); + int spider_log_tables_link_failed( TABLE *table, char *name, @@ -309,6 +402,18 @@ int spider_delete_tables( int *old_link_count ); +int spider_delete_table_sts( + TABLE *table, + const char *name, + uint name_length +); + +int spider_delete_table_crd( + TABLE *table, + const char *name, + uint name_length +); + int spider_get_sys_xid( TABLE *table, XID *xid, @@ -345,6 +450,12 @@ int spider_get_sys_tables_connect_info( MEM_ROOT *mem_root ); +int spider_get_sys_tables_monitoring_binlog_pos_at_failing( + TABLE *table, + long *monitoring_binlog_pos_at_failing, + MEM_ROOT *mem_root +); + int spider_get_sys_tables_link_status( TABLE *table, SPIDER_SHARE *share, @@ -352,12 +463,43 @@ int spider_get_sys_tables_link_status( MEM_ROOT *mem_root ); +int spider_get_sys_tables_link_status( + TABLE *table, + long *link_status, + MEM_ROOT *mem_root +); + int spider_get_sys_tables_link_idx( TABLE *table, int *link_idx, MEM_ROOT *mem_root ); +int spider_get_sys_tables_static_link_id( + TABLE *table, + char **static_link_id, + uint *static_link_id_length, + MEM_ROOT *mem_root +); + +void spider_get_sys_table_sts_info( + TABLE *table, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time +); + +void spider_get_sys_table_crd_info( + TABLE *table, + longlong *cardinality, + uint number_of_keys +); + int spider_sys_update_tables_link_status( THD *thd, char *name, @@ -409,6 +551,68 @@ int spider_get_link_statuses( MEM_ROOT *mem_root ); +int spider_sys_insert_or_update_table_sts( + THD *thd, + const char *name, + uint name_length, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time, + bool need_lock +); + +int spider_sys_insert_or_update_table_crd( + THD *thd, + const char *name, + uint name_length, + longlong *cardinality, + uint number_of_keys, + bool need_lock +); + +int spider_sys_delete_table_sts( + THD *thd, + const char *name, + uint name_length, + bool need_lock +); + +int spider_sys_delete_table_crd( + THD *thd, + const char *name, + uint name_length, + bool need_lock +); + +int spider_sys_get_table_sts( + THD *thd, + const char *name, + uint name_length, + ulonglong *data_file_length, + ulonglong *max_data_file_length, + ulonglong *index_file_length, + ha_rows *records, + ulong *mean_rec_length, + time_t *check_time, + time_t *create_time, + time_t *update_time, + bool need_lock +); + +int spider_sys_get_table_crd( + THD *thd, + const char *name, + uint name_length, + longlong *cardinality, + uint number_of_keys, + bool need_lock +); + int spider_sys_replace( TABLE *table, bool *modified_non_trans_table diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 802acd3996f..a5de9d9749b 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -28,6 +28,7 @@ #include "sql_partition.h" #include "sql_servers.h" #include "sql_select.h" +#include "tztime.h" #endif #include "spd_err.h" #include "spd_param.h" @@ -42,7 +43,21 @@ #include "spd_ping_table.h" #include "spd_direct_sql.h" #include "spd_malloc.h" +#include "spd_group_by_handler.h" +#ifndef SPIDER_HAS_NEXT_THREAD_ID +ulong *spd_db_att_thread_id; +#endif +#ifdef SPIDER_HAS_NEXT_THREAD_ID +#define SPIDER_set_next_thread_id(A) +#else +inline void SPIDER_set_next_thread_id(THD *A) +{ + pthread_mutex_lock(&LOCK_thread_count); + A->thread_id = (*spd_db_att_thread_id)++; + pthread_mutex_unlock(&LOCK_thread_count); +} +#endif #ifdef SPIDER_XID_USES_xid_cache_iterate #else #ifdef XID_CACHE_IS_SPLITTED @@ -55,7 +70,8 @@ struct charset_info_st *spd_charset_utf8_bin; const char **spd_defaults_extra_file; const char **spd_defaults_file; bool volatile *spd_abort_loop; - +Time_zone *spd_tz_system; +extern long spider_conn_mutex_id; handlerton *spider_hton_ptr; SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; extern SPIDER_DBTON spider_dbton_mysql; @@ -65,6 +81,10 @@ extern SPIDER_DBTON spider_dbton_handlersocket; #ifdef HAVE_ORACLE_OCI extern SPIDER_DBTON spider_dbton_oracle; #endif +#ifndef WITHOUT_SPIDER_BG_SEARCH +SPIDER_THREAD *spider_table_sts_threads; +SPIDER_THREAD *spider_table_crd_threads; +#endif #ifdef HAVE_PSI_INTERFACE PSI_mutex_key spd_key_mutex_tbl; @@ -111,6 +131,12 @@ PSI_mutex_key spd_key_mutex_udf_table; PSI_mutex_key spd_key_mutex_mem_calc; PSI_mutex_key spd_key_thread_id; PSI_mutex_key spd_key_conn_id; +PSI_mutex_key spd_key_mutex_ipport_count; +PSI_mutex_key spd_key_mutex_conn_i; +#ifndef WITHOUT_SPIDER_BG_SEARCH +PSI_mutex_key spd_key_mutex_bg_stss; +PSI_mutex_key spd_key_mutex_bg_crds; +#endif static PSI_mutex_info all_spider_mutexes[]= { @@ -135,6 +161,12 @@ static PSI_mutex_info all_spider_mutexes[]= { &spd_key_mutex_mem_calc, "mem_calc", PSI_FLAG_GLOBAL}, { &spd_key_thread_id, "thread_id", PSI_FLAG_GLOBAL}, { &spd_key_conn_id, "conn_id", PSI_FLAG_GLOBAL}, + { &spd_key_mutex_ipport_count, "ipport_count", PSI_FLAG_GLOBAL}, +#ifndef WITHOUT_SPIDER_BG_SEARCH + { &spd_key_mutex_bg_stss, "bg_stss", PSI_FLAG_GLOBAL}, + { &spd_key_mutex_bg_crds, "bg_crds", PSI_FLAG_GLOBAL}, +#endif + { &spd_key_mutex_conn_i, "conn_i", 0}, { &spd_key_mutex_mta_conn, "mta_conn", 0}, #ifndef WITHOUT_SPIDER_BG_SEARCH { &spd_key_mutex_bg_conn_chain, "bg_conn_chain", 0}, @@ -172,6 +204,13 @@ PSI_cond_key spd_key_cond_bg_mon_sleep; PSI_cond_key spd_key_cond_bg_direct_sql; #endif PSI_cond_key spd_key_cond_udf_table_mon; +PSI_cond_key spd_key_cond_conn_i; +#ifndef WITHOUT_SPIDER_BG_SEARCH +PSI_cond_key spd_key_cond_bg_stss; +PSI_cond_key spd_key_cond_bg_sts_syncs; +PSI_cond_key spd_key_cond_bg_crds; +PSI_cond_key spd_key_cond_bg_crd_syncs; +#endif static PSI_cond_info all_spider_conds[] = { #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -186,6 +225,13 @@ static PSI_cond_info all_spider_conds[] = { {&spd_key_cond_bg_direct_sql, "bg_direct_sql", 0}, #endif {&spd_key_cond_udf_table_mon, "udf_table_mon", 0}, + {&spd_key_cond_conn_i, "conn_i", 0}, +#ifndef WITHOUT_SPIDER_BG_SEARCH + {&spd_key_cond_bg_stss, "bg_stss", 0}, + {&spd_key_cond_bg_sts_syncs, "bg_sts_syncs", 0}, + {&spd_key_cond_bg_crds, "bg_crds", 0}, + {&spd_key_cond_bg_crd_syncs, "bg_crd_syncs", 0}, +#endif }; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -193,6 +239,8 @@ PSI_thread_key spd_key_thd_bg; PSI_thread_key spd_key_thd_bg_sts; PSI_thread_key spd_key_thd_bg_crd; PSI_thread_key spd_key_thd_bg_mon; +PSI_thread_key spd_key_thd_bg_stss; +PSI_thread_key spd_key_thd_bg_crds; #endif static PSI_thread_info all_spider_threads[] = { @@ -201,11 +249,14 @@ static PSI_thread_info all_spider_threads[] = { {&spd_key_thd_bg_sts, "bg_sts", 0}, {&spd_key_thd_bg_crd, "bg_crd", 0}, {&spd_key_thd_bg_mon, "bg_mon", 0}, + {&spd_key_thd_bg_stss, "bg_stss", 0}, + {&spd_key_thd_bg_crds, "bg_crds", 0}, #endif }; #endif extern HASH spider_open_connections; +extern HASH spider_ipport_conns; extern uint spider_open_connections_id; extern const char *spider_open_connections_func_name; extern const char *spider_open_connections_file_name; @@ -255,6 +306,7 @@ pthread_mutex_t spider_init_error_tbl_mutex; extern pthread_mutex_t spider_thread_id_mutex; extern pthread_mutex_t spider_conn_id_mutex; +extern pthread_mutex_t spider_ipport_conn_mutex; #ifdef WITH_PARTITION_STORAGE_ENGINE HASH spider_open_pt_share; @@ -518,14 +570,12 @@ int spider_free_share_alloc( ) { int roop_count; DBUG_ENTER("spider_free_share_alloc"); + for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; roop_count--) { - for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; roop_count--) + if (share->dbton_share[roop_count]) { - if (share->dbton_share[roop_count]) - { - delete share->dbton_share[roop_count]; - share->dbton_share[roop_count] = NULL; - } + delete share->dbton_share[roop_count]; + share->dbton_share[roop_count] = NULL; } } if (share->server_names) @@ -713,6 +763,17 @@ int spider_free_share_alloc( } spider_free(spider_current_trx, share->tgt_sequence_names, MYF(0)); } + if (share->static_link_ids) + { + for (roop_count = 0; roop_count < (int) share->static_link_ids_length; + roop_count++) + { + if (share->static_link_ids[roop_count]) + spider_free(spider_current_trx, share->static_link_ids[roop_count], + MYF(0)); + } + spider_free(spider_current_trx, share->static_link_ids, MYF(0)); + } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) if (share->hs_read_socks) { @@ -753,6 +814,8 @@ int spider_free_share_alloc( if (share->monitoring_bg_kind) spider_free(spider_current_trx, share->monitoring_bg_kind, MYF(0)); #endif + if (share->monitoring_binlog_pos_at_failing) + spider_free(spider_current_trx, share->monitoring_binlog_pos_at_failing, MYF(0)); if (share->monitoring_flag) spider_free(spider_current_trx, share->monitoring_flag, MYF(0)); if (share->monitoring_kind) @@ -893,6 +956,11 @@ void spider_free_tmp_share_alloc( spider_free(spider_current_trx, share->tgt_sequence_names[0], MYF(0)); share->tgt_sequence_names[0] = NULL; } + if (share->static_link_ids && share->static_link_ids[0]) + { + spider_free(spider_current_trx, share->static_link_ids[0], MYF(0)); + share->static_link_ids[0] = NULL; + } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) if (share->hs_read_socks && share->hs_read_socks[0]) { @@ -1396,6 +1464,56 @@ error: DBUG_RETURN(HA_ERR_OUT_OF_MEM); } +int spider_increase_null_string_list( + char ***string_list, + uint **string_length_list, + uint *list_length, + uint *list_charlen, + uint link_count +) { + int roop_count; + char **tmp_str_list; + uint *tmp_length_list; + DBUG_ENTER("spider_increase_null_string_list"); + if (*list_length == link_count) + DBUG_RETURN(0); + + if (!(tmp_str_list = (char**) + spider_bulk_malloc(spider_current_trx, 247, MYF(MY_WME | MY_ZEROFILL), + &tmp_str_list, sizeof(char*) * link_count, + &tmp_length_list, sizeof(uint) * link_count, + NullS)) + ) { + my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + + for (roop_count = 0; roop_count < (int) *list_length; roop_count++) + { + tmp_str_list[roop_count] = (*string_list)[roop_count]; + tmp_length_list[roop_count] = (*string_length_list)[roop_count]; + } + if (*string_list) + { + spider_free(spider_current_trx, *string_list, MYF(0)); + } + *list_length = link_count; + *string_list = tmp_str_list; + *string_length_list = tmp_length_list; +#ifndef DBUG_OFF + DBUG_PRINT("info",("spider list_length=%u", *list_length)); + for (roop_count = 0; roop_count < (int) *list_length; roop_count++) + { + DBUG_PRINT("info",("spider string_list[%d]=%s", roop_count, + (*string_list)[roop_count] ? (*string_list)[roop_count] : "NULL")); + DBUG_PRINT("info",("spider string_length_list[%d]=%u", roop_count, + (*string_length_list)[roop_count])); + } +#endif + + DBUG_RETURN(0); +} + int spider_increase_long_list( long **long_list, uint *list_length, @@ -1799,6 +1917,8 @@ int spider_parse_connect_info( #ifdef WITH_PARTITION_STORAGE_ENGINE share->sts_sync = -1; #endif + share->store_last_sts = -1; + share->load_sts_at_startup = -1; #ifndef WITHOUT_SPIDER_BG_SEARCH share->crd_bg_mode = -1; #endif @@ -1807,6 +1927,8 @@ int spider_parse_connect_info( #ifdef WITH_PARTITION_STORAGE_ENGINE share->crd_sync = -1; #endif + share->store_last_crd = -1; + share->load_crd_at_startup = -1; share->crd_type = -1; share->crd_weight = -1; share->internal_offset = -1; @@ -1848,6 +1970,7 @@ int spider_parse_connect_info( share->use_table_charset = -1; share->use_pushdown_udf = -1; share->skip_default_condition = -1; + share->skip_parallel_search = -1; share->direct_dup_insert = -1; share->direct_order_limit = -1; share->bka_mode = -1; @@ -2002,7 +2125,7 @@ int spider_parse_connect_info( SPIDER_PARAM_INT_WITH_MAX("bum", bulk_update_mode, 0, 2); SPIDER_PARAM_INT("bus", bulk_update_size, 0); #ifndef WITHOUT_SPIDER_BG_SEARCH - SPIDER_PARAM_INT_WITH_MAX("cbm", crd_bg_mode, 0, 1); + SPIDER_PARAM_INT_WITH_MAX("cbm", crd_bg_mode, 0, 2); #endif SPIDER_PARAM_DOUBLE("civ", crd_interval, 0); SPIDER_PARAM_INT_WITH_MAX("cmd", crd_mode, 0, 3); @@ -2046,6 +2169,8 @@ int spider_parse_connect_info( SPIDER_PARAM_INT_WITH_MAX("iom", internal_optimize, 0, 1); SPIDER_PARAM_INT_WITH_MAX("iol", internal_optimize_local, 0, 1); SPIDER_PARAM_INT_WITH_MAX("lmr", low_mem_read, 0, 1); + SPIDER_PARAM_INT_WITH_MAX("lcs", load_crd_at_startup, 0, 1); + SPIDER_PARAM_INT_WITH_MAX("lss", load_sts_at_startup, 0, 1); SPIDER_PARAM_LONG_LIST_WITH_MAX("lst", link_statuses, 0, 3); #ifndef WITHOUT_SPIDER_BG_SEARCH SPIDER_PARAM_LONG_LIST_WITH_MAX("mbf", monitoring_bg_flag, 0, 1); @@ -2053,6 +2178,7 @@ int spider_parse_connect_info( "mbi", monitoring_bg_interval, 0, 4294967295LL); SPIDER_PARAM_LONG_LIST_WITH_MAX("mbk", monitoring_bg_kind, 0, 3); #endif + SPIDER_PARAM_LONG_LIST_WITH_MAX("mbp", monitoring_binlog_pos_at_failing, 0, 2); SPIDER_PARAM_LONG_LIST_WITH_MAX("mfg", monitoring_flag, 0, 1); SPIDER_PARAM_LONG_LIST_WITH_MAX("mkd", monitoring_kind, 0, 3); SPIDER_PARAM_LONGLONG_LIST_WITH_MAX( @@ -2075,7 +2201,7 @@ int spider_parse_connect_info( SPIDER_PARAM_DOUBLE("rrt", read_rate, 0); SPIDER_PARAM_INT_WITH_MAX("rsa", reset_sql_alloc, 0, 1); #ifndef WITHOUT_SPIDER_BG_SEARCH - SPIDER_PARAM_INT_WITH_MAX("sbm", sts_bg_mode, 0, 1); + SPIDER_PARAM_INT_WITH_MAX("sbm", sts_bg_mode, 0, 2); #endif SPIDER_PARAM_STR_LIST("sca", tgt_ssl_cas); SPIDER_PARAM_STR_LIST("sch", tgt_ssl_ciphers); @@ -2085,10 +2211,14 @@ int spider_parse_connect_info( SPIDER_PARAM_INT_WITH_MAX("sdc", skip_default_condition, 0, 1); SPIDER_PARAM_DOUBLE("siv", sts_interval, 0); SPIDER_PARAM_STR_LIST("sky", tgt_ssl_keys); + SPIDER_PARAM_STR_LIST("sli", static_link_ids); + SPIDER_PARAM_INT_WITH_MAX("slc", store_last_crd, 0, 1); SPIDER_PARAM_INT_WITH_MAX("slm", selupd_lock_mode, 0, 2); + SPIDER_PARAM_INT_WITH_MAX("sls", store_last_sts, 0, 1); SPIDER_PARAM_INT_WITH_MAX("smd", sts_mode, 1, 2); SPIDER_PARAM_LONGLONG("smr", static_mean_rec_length, 0); SPIDER_PARAM_LONGLONG("spr", split_read, 0); + SPIDER_PARAM_INT_WITH_MAX("sps", skip_parallel_search, 0, 3); SPIDER_PARAM_STR_LIST("sqn", tgt_sequence_names); SPIDER_PARAM_LONGLONG("srd", second_read, 0); SPIDER_PARAM_DOUBLE("srt", scan_rate, 0); @@ -2197,8 +2327,8 @@ int spider_parse_connect_info( case 11: SPIDER_PARAM_INT_WITH_MAX("query_cache", query_cache, 0, 2); #ifndef WITHOUT_SPIDER_BG_SEARCH - SPIDER_PARAM_INT_WITH_MAX("crd_bg_mode", crd_bg_mode, 0, 1); - SPIDER_PARAM_INT_WITH_MAX("sts_bg_mode", sts_bg_mode, 0, 1); + SPIDER_PARAM_INT_WITH_MAX("crd_bg_mode", crd_bg_mode, 0, 2); + SPIDER_PARAM_INT_WITH_MAX("sts_bg_mode", sts_bg_mode, 0, 2); #endif SPIDER_PARAM_LONG_LIST_WITH_MAX("link_status", link_statuses, 0, 3); SPIDER_PARAM_LONG_LIST_WITH_MAX("use_handler", use_handlers, 0, 3); @@ -2248,6 +2378,9 @@ int spider_parse_connect_info( SPIDER_PARAM_INT_WITH_MAX("read_only_mode", read_only_mode, 0, 1); SPIDER_PARAM_LONG_LIST_WITH_MAX("access_balance", access_balances, 0, 2147483647); + SPIDER_PARAM_STR_LIST("static_link_id", static_link_ids); + SPIDER_PARAM_INT_WITH_MAX("store_last_crd", store_last_crd, 0, 1); + SPIDER_PARAM_INT_WITH_MAX("store_last_sts", store_last_sts, 0, 1); error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM; my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR, MYF(0), tmp_ptr); @@ -2354,6 +2487,10 @@ int spider_parse_connect_info( #endif SPIDER_PARAM_LONG_LIST_WITH_MAX("bka_table_name_type", bka_table_name_types, 0, 1); + SPIDER_PARAM_INT_WITH_MAX( + "load_crd_at_startup", load_crd_at_startup, 0, 1); + SPIDER_PARAM_INT_WITH_MAX( + "load_sts_at_startup", load_sts_at_startup, 0, 1); error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM; my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR, MYF(0), tmp_ptr); @@ -2363,6 +2500,8 @@ int spider_parse_connect_info( "monitoring_server_id", monitoring_sid, 0, 4294967295LL); SPIDER_PARAM_INT_WITH_MAX( "delete_all_rows_type", delete_all_rows_type, 0, 1); + SPIDER_PARAM_INT_WITH_MAX( + "skip_parallel_search", skip_parallel_search, 0, 3); error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM; my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR, MYF(0), tmp_ptr); @@ -2412,6 +2551,13 @@ int spider_parse_connect_info( my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR, MYF(0), tmp_ptr); goto error; + case 32: + SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_binlog_pos_at_failing", + monitoring_binlog_pos_at_failing, 0, 2); + error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM; + my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR, + MYF(0), tmp_ptr); + goto error; default: error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM; my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR, @@ -2457,12 +2603,16 @@ int spider_parse_connect_info( share->all_link_count = share->tgt_pk_names_length; if (share->all_link_count < share->tgt_sequence_names_length) share->all_link_count = share->tgt_sequence_names_length; + if (share->all_link_count < share->static_link_ids_length) + share->all_link_count = share->static_link_ids_length; if (share->all_link_count < share->tgt_ports_length) share->all_link_count = share->tgt_ports_length; if (share->all_link_count < share->tgt_ssl_vscs_length) share->all_link_count = share->tgt_ssl_vscs_length; if (share->all_link_count < share->link_statuses_length) share->all_link_count = share->link_statuses_length; + if (share->all_link_count < share->monitoring_binlog_pos_at_failing_length) + share->all_link_count = share->monitoring_binlog_pos_at_failing_length; if (share->all_link_count < share->monitoring_flag_length) share->all_link_count = share->monitoring_flag_length; if (share->all_link_count < share->monitoring_kind_length) @@ -2626,6 +2776,13 @@ int spider_parse_connect_info( &share->tgt_sequence_names_charlen, share->all_link_count))) goto error; + if ((error_num = spider_increase_null_string_list( + &share->static_link_ids, + &share->static_link_ids_lengths, + &share->static_link_ids_length, + &share->static_link_ids_charlen, + share->all_link_count))) + goto error; if ((error_num = spider_increase_long_list( &share->tgt_ports, &share->tgt_ports_length, @@ -2654,6 +2811,11 @@ int spider_parse_connect_info( goto error; #endif if ((error_num = spider_increase_long_list( + &share->monitoring_binlog_pos_at_failing, + &share->monitoring_binlog_pos_at_failing_length, + share->all_link_count))) + goto error; + if ((error_num = spider_increase_long_list( &share->monitoring_flag, &share->monitoring_flag_length, share->all_link_count))) @@ -2758,13 +2920,15 @@ int spider_parse_connect_info( if (!(share_alter->tmp_server_names = (char **) spider_bulk_malloc(spider_current_trx, 43, MYF(MY_WME | MY_ZEROFILL), &share_alter->tmp_server_names, - sizeof(char *) * 15 * share->all_link_count, + sizeof(char *) * 16 * share->all_link_count, &share_alter->tmp_server_names_lengths, - sizeof(uint *) * 15 * share->all_link_count, + sizeof(uint *) * 16 * share->all_link_count, &share_alter->tmp_tgt_ports, sizeof(long) * share->all_link_count, &share_alter->tmp_tgt_ssl_vscs, sizeof(long) * share->all_link_count, + &share_alter->tmp_monitoring_binlog_pos_at_failing, + sizeof(long) * share->all_link_count, &share_alter->tmp_link_statuses, sizeof(long) * share->all_link_count, NullS)) @@ -2832,11 +2996,18 @@ int spider_parse_connect_info( share_alter->tmp_tgt_default_files + share->all_link_count; memcpy(share_alter->tmp_tgt_default_groups, share->tgt_default_groups, sizeof(char *) * share->all_link_count); + share_alter->tmp_static_link_ids = + share_alter->tmp_tgt_default_groups + share->all_link_count; + memcpy(share_alter->tmp_static_link_ids, share->static_link_ids, + sizeof(char *) * share->all_link_count); memcpy(share_alter->tmp_tgt_ports, share->tgt_ports, sizeof(long) * share->all_link_count); memcpy(share_alter->tmp_tgt_ssl_vscs, share->tgt_ssl_vscs, sizeof(long) * share->all_link_count); + memcpy(share_alter->tmp_monitoring_binlog_pos_at_failing, + share->monitoring_binlog_pos_at_failing, + sizeof(long) * share->all_link_count); memcpy(share_alter->tmp_link_statuses, share->link_statuses, sizeof(long) * share->all_link_count); @@ -2910,6 +3081,11 @@ int spider_parse_connect_info( memcpy(share_alter->tmp_tgt_default_groups_lengths, share->tgt_default_groups_lengths, sizeof(uint) * share->all_link_count); + share_alter->tmp_static_link_ids_lengths = + share_alter->tmp_tgt_default_groups_lengths + share->all_link_count; + memcpy(share_alter->tmp_static_link_ids_lengths, + share->static_link_ids_lengths, + sizeof(uint) * share->all_link_count); share_alter->tmp_server_names_charlen = share->server_names_charlen; share_alter->tmp_tgt_table_names_charlen = share->tgt_table_names_charlen; @@ -2928,6 +3104,8 @@ int spider_parse_connect_info( share->tgt_default_files_charlen; share_alter->tmp_tgt_default_groups_charlen = share->tgt_default_groups_charlen; + share_alter->tmp_static_link_ids_charlen = + share->static_link_ids_charlen; share_alter->tmp_server_names_length = share->server_names_length; share_alter->tmp_tgt_table_names_length = share->tgt_table_names_length; @@ -2945,8 +3123,12 @@ int spider_parse_connect_info( share_alter->tmp_tgt_default_files_length = share->tgt_default_files_length; share_alter->tmp_tgt_default_groups_length = share->tgt_default_groups_length; + share_alter->tmp_static_link_ids_length = + share->static_link_ids_length; share_alter->tmp_tgt_ports_length = share->tgt_ports_length; share_alter->tmp_tgt_ssl_vscs_length = share->tgt_ssl_vscs_length; + share_alter->tmp_monitoring_binlog_pos_at_failing_length = + share->monitoring_binlog_pos_at_failing_length; share_alter->tmp_link_statuses_length = share->link_statuses_length; /* copy for tables end */ @@ -3186,6 +3368,51 @@ int spider_parse_connect_info( MYF(0), share->tgt_sequence_names[roop_count], "sequence_name"); goto error; } + + DBUG_PRINT("info", + ("spider static_link_ids_lengths[%d] = %u", roop_count, + share->static_link_ids_lengths[roop_count])); + if (share->static_link_ids_lengths[roop_count] > + SPIDER_CONNECT_INFO_MAX_LEN) + { + error_num = ER_SPIDER_INVALID_CONNECT_INFO_TOO_LONG_NUM; + my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_TOO_LONG_STR, + MYF(0), share->static_link_ids[roop_count], "static_link_id"); + goto error; + } + if (share->static_link_ids[roop_count]) + { + if ( + share->static_link_ids_lengths[roop_count] > 0 && + share->static_link_ids[roop_count][0] >= '0' && + share->static_link_ids[roop_count][0] <= '9' + ) { + error_num = ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_NUM; + my_printf_error(error_num, + ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_STR, + MYF(0), share->static_link_ids[roop_count], "static_link_id"); + goto error; + } + for (roop_count2 = roop_count + 1; + roop_count2 < (int) share->all_link_count; + roop_count2++) + { + if ( + share->static_link_ids_lengths[roop_count] == + share->static_link_ids_lengths[roop_count2] && + !memcmp(share->static_link_ids[roop_count], + share->static_link_ids[roop_count2], + share->static_link_ids_lengths[roop_count]) + ) { + error_num = ER_SPIDER_INVALID_CONNECT_INFO_SAME_NUM; + my_printf_error(error_num, + ER_SPIDER_INVALID_CONNECT_INFO_SAME_STR, + MYF(0), share->static_link_ids[roop_count], + "static_link_id"); + goto error; + } + } + } } } @@ -3342,6 +3569,22 @@ int spider_set_connect_info_default( } } +/* + if (!share->static_link_ids[roop_count]) + { + DBUG_PRINT("info",("spider create default static_link_ids")); + share->static_link_ids_lengths[roop_count] = + SPIDER_DB_STATIC_LINK_ID_LEN; + if ( + !(share->static_link_ids[roop_count] = spider_create_string( + SPIDER_DB_STATIC_LINK_ID_STR, + share->static_link_ids_lengths[roop_count])) + ) { + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + } +*/ + if (share->tgt_ports[roop_count] == -1) { share->tgt_ports[roop_count] = MYSQL_PORT; @@ -3381,6 +3624,8 @@ int spider_set_connect_info_default( if (share->monitoring_bg_kind[roop_count] == -1) share->monitoring_bg_kind[roop_count] = 0; #endif + if (share->monitoring_binlog_pos_at_failing[roop_count] == -1) + share->monitoring_binlog_pos_at_failing[roop_count] = 0; if (share->monitoring_flag[roop_count] == -1) share->monitoring_flag[roop_count] = 0; if (share->monitoring_kind[roop_count] == -1) @@ -3450,7 +3695,7 @@ int spider_set_connect_info_default( #ifndef WITHOUT_SPIDER_BG_SEARCH if (share->sts_bg_mode == -1) - share->sts_bg_mode = 1; + share->sts_bg_mode = 2; #endif if (share->sts_interval == -1) share->sts_interval = 10; @@ -3460,9 +3705,13 @@ int spider_set_connect_info_default( if (share->sts_sync == -1) share->sts_sync = 0; #endif + if (share->store_last_sts == -1) + share->store_last_sts = 1; + if (share->load_sts_at_startup == -1) + share->load_sts_at_startup = 1; #ifndef WITHOUT_SPIDER_BG_SEARCH if (share->crd_bg_mode == -1) - share->crd_bg_mode = 1; + share->crd_bg_mode = 2; #endif if (share->crd_interval == -1) share->crd_interval = 51; @@ -3472,6 +3721,10 @@ int spider_set_connect_info_default( if (share->crd_sync == -1) share->crd_sync = 0; #endif + if (share->store_last_crd == -1) + share->store_last_crd = 1; + if (share->load_crd_at_startup == -1) + share->load_crd_at_startup = 1; if (share->crd_type == -1) share->crd_type = 2; if (share->crd_weight == -1) @@ -3552,6 +3805,8 @@ int spider_set_connect_info_default( share->use_pushdown_udf = 1; if (share->skip_default_condition == -1) share->skip_default_condition = 0; + if (share->skip_parallel_search == -1) + share->skip_parallel_search = 0; if (share->direct_dup_insert == -1) share->direct_dup_insert = 0; if (share->direct_order_limit == -1) @@ -3703,31 +3958,28 @@ int spider_create_conn_keys( #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) char *tmp_hs_r_name, *tmp_hs_w_name; #endif -#if defined(_MSC_VER) || defined(__SUNPRO_CC) uint *conn_keys_lengths; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) uint *hs_r_conn_keys_lengths; uint *hs_w_conn_keys_lengths; #endif -#else - uint conn_keys_lengths[share->all_link_count]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint hs_r_conn_keys_lengths[share->all_link_count]; - uint hs_w_conn_keys_lengths[share->all_link_count]; -#endif -#endif DBUG_ENTER("spider_create_conn_keys"); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - if (!(conn_keys_lengths = - (uint *) spider_bulk_alloc_mem(spider_current_trx, 44, - __func__, __FILE__, __LINE__, MYF(MY_WME), - &conn_keys_lengths, sizeof(uint) * share->all_link_count, + char *ptr; + uint length = sizeof(uint) * share->all_link_count; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &hs_r_conn_keys_lengths, sizeof(uint) * share->all_link_count, - &hs_w_conn_keys_lengths, sizeof(uint) * share->all_link_count, + length += (sizeof(uint) * share->all_link_count) * 2; #endif - NullS))) + ptr = (char *) my_alloca(length); + if (!ptr) + { DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + conn_keys_lengths = (uint *) ptr; + ptr += (sizeof(uint) * share->all_link_count); +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + hs_r_conn_keys_lengths = (uint *) ptr; + ptr += (sizeof(uint) * share->all_link_count); + hs_w_conn_keys_lengths = (uint *) ptr; #endif share->conn_keys_charlen = 0; @@ -3806,9 +4058,7 @@ int spider_create_conn_keys( #endif NullS)) ) { -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(spider_current_trx, conn_keys_lengths, MYF(MY_WME)); -#endif + my_afree(conn_keys_lengths); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } share->conn_keys_length = share->all_link_count; @@ -3823,9 +4073,7 @@ int spider_create_conn_keys( sizeof(uint) * share->all_link_count); #endif -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(spider_current_trx, conn_keys_lengths, MYF(MY_WME)); -#endif + my_afree(conn_keys_lengths); for (roop_count = 0; roop_count < (int) share->all_link_count; roop_count++) { @@ -4094,6 +4342,7 @@ SPIDER_SHARE *spider_create_share( goto error_alloc_share; } + SPD_INIT_ALLOC_ROOT(&share->mem_root, 4096, 0, MYF(MY_WME)); share->use_count = 0; share->use_dbton_count = 0; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) @@ -4115,6 +4364,12 @@ SPIDER_SHARE *spider_create_share( (uchar*) table_share->path.str, table_share->path.length); #endif #endif +#ifndef WITHOUT_SPIDER_BG_SEARCH + share->table.s = table_share; + share->table.field = table_share->field; + share->table.key_info = table_share->key_info; + share->table.read_set = &table_share->all_set; +#endif if (table_share->keys > 0 && !(share->key_hint = new spider_string[table_share->keys]) @@ -4306,6 +4561,9 @@ SPIDER_SHARE *spider_get_share( MEM_ROOT mem_root; TABLE *table_tables = NULL; bool init_mem_root = FALSE; + bool same_server_link; + int load_sts_at_startup; + int load_crd_at_startup; DBUG_ENTER("spider_get_share"); length = (uint) strlen(table_name); @@ -4397,6 +4655,9 @@ SPIDER_SHARE *spider_get_share( pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); } pthread_mutex_unlock(&share->mutex); + share->init_error = TRUE; + share->init_error_time = (time_t) time((time_t*) 0); + share->init = TRUE; spider_free_share(share); goto error_open_sys_table; } @@ -4416,6 +4677,9 @@ SPIDER_SHARE *spider_get_share( pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); } pthread_mutex_unlock(&share->mutex); + share->init_error = TRUE; + share->init_error_time = (time_t) time((time_t*) 0); + share->init = TRUE; spider_free_share(share); goto error_get_link_statuses; } @@ -4467,6 +4731,64 @@ SPIDER_SHARE *spider_get_share( spider->set_error_mode(); #ifndef WITHOUT_SPIDER_BG_SEARCH + if (!share->sts_spider_init) + { + pthread_mutex_lock(&share->mutex); + if (!share->sts_spider_init) + { + if ((*error_num = spider_create_spider_object_for_share( + spider->trx, share, &share->sts_spider))) + { + pthread_mutex_unlock(&share->mutex); + share->init_error = TRUE; + share->init_error_time = (time_t) time((time_t*) 0); + share->init = TRUE; + spider_free_share(share); + goto error_sts_spider_init; + } +#ifdef HASH_UPDATE_WITH_HASH_VALUE + share->sts_thread = &spider_table_sts_threads[ + hash_value % spider_param_table_sts_thread_count()]; +#else + share->sts_thread = &spider_table_sts_threads[ + my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % + spider_param_table_sts_thread_count()]; +#endif + share->sts_spider_init = TRUE; + } + pthread_mutex_unlock(&share->mutex); + } + + if (!share->crd_spider_init) + { + pthread_mutex_lock(&share->mutex); + if (!share->crd_spider_init) + { + if ((*error_num = spider_create_spider_object_for_share( + spider->trx, share, &share->crd_spider))) + { + pthread_mutex_unlock(&share->mutex); + share->init_error = TRUE; + share->init_error_time = (time_t) time((time_t*) 0); + share->init = TRUE; + spider_free_share(share); + goto error_crd_spider_init; + } +#ifdef HASH_UPDATE_WITH_HASH_VALUE + share->crd_thread = &spider_table_crd_threads[ + hash_value % spider_param_table_crd_thread_count()]; +#else + share->crd_thread = &spider_table_crd_threads[ + my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % + spider_param_table_crd_thread_count()]; +#endif + share->crd_spider_init = TRUE; + } + pthread_mutex_unlock(&share->mutex); + } +#endif + +#ifndef WITHOUT_SPIDER_BG_SEARCH if ( sql_command != SQLCOM_DROP_TABLE && sql_command != SQLCOM_ALTER_TABLE && @@ -4619,6 +4941,10 @@ SPIDER_SHARE *spider_get_share( spider->dbton_handler[dbton_id] = NULL; } } + share->init_error = TRUE; + share->init_error_time = (time_t) time((time_t*) 0); + share->init = TRUE; + spider_free_share(share); goto error_but_no_delete; } @@ -4650,6 +4976,7 @@ SPIDER_SHARE *spider_get_share( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4676,14 +5003,10 @@ SPIDER_SHARE *spider_get_share( share->link_count, SPIDER_LINK_STATUS_OK); if (search_link_idx == -1) { -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - char *db, *table_name; - if (!(db = (char *) - spider_bulk_malloc(spider_current_trx, 48, MYF(MY_WME), - &db, table_share->db.length + 1, - &table_name, table_share->table_name.length + 1, - NullS)) - ) { + char *db = (char *) my_alloca( + table_share->db.length + 1 + table_share->table_name.length + 1); + if (!db) + { *error_num = HA_ERR_OUT_OF_MEM; share->init_error = TRUE; share->init_error_time = (time_t) time((time_t*) 0); @@ -4691,10 +5014,7 @@ SPIDER_SHARE *spider_get_share( spider_free_share(share); goto error_but_no_delete; } -#else - char db[table_share->db.length + 1], - table_name[table_share->table_name.length + 1]; -#endif + char *table_name = db + table_share->db.length + 1; memcpy(db, table_share->db.str, table_share->db.length); db[table_share->db.length] = '\0'; memcpy(table_name, table_share->table_name.str, @@ -4702,24 +5022,39 @@ SPIDER_SHARE *spider_get_share( table_name[table_share->table_name.length] = '\0'; my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM, ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(spider->trx, db, MYF(MY_WME)); -#endif + my_afree(db); *error_num = ER_SPIDER_ALL_LINKS_FAILED_NUM; share->init_error = TRUE; share->init_error_time = (time_t) time((time_t*) 0); share->init = TRUE; spider_free_share(share); goto error_but_no_delete; + } else if (search_link_idx == -2) + { + *error_num = HA_ERR_OUT_OF_MEM; + share->init_error = TRUE; + share->init_error_time = (time_t) time((time_t*) 0); + share->init = TRUE; + spider_free_share(share); + goto error_but_no_delete; } spider->search_link_idx = search_link_idx; + same_server_link = spider_param_same_server_link(thd); + load_sts_at_startup = + spider_param_load_sts_at_startup(share->load_sts_at_startup); + load_crd_at_startup = + spider_param_load_crd_at_startup(share->load_crd_at_startup); if ( sql_command != SQLCOM_DROP_TABLE && sql_command != SQLCOM_ALTER_TABLE && sql_command != SQLCOM_SHOW_CREATE && !spider->error_mode && - !spider_param_same_server_link(thd) + ( + !same_server_link || + load_sts_at_startup || + load_crd_at_startup + ) ) { SPIDER_INIT_ERROR_TABLE *spider_init_error_table; sts_interval = spider_param_sts_interval(thd, share->sts_interval); @@ -4763,22 +5098,32 @@ SPIDER_SHARE *spider_get_share( } } - if (spider_get_sts(share, spider->search_link_idx, tmp_time, - spider, sts_interval, sts_mode, + if ( + ( + !same_server_link || + load_sts_at_startup + ) && + spider_get_sts(share, spider->search_link_idx, tmp_time, + spider, sts_interval, sts_mode, #ifdef WITH_PARTITION_STORAGE_ENGINE - sts_sync, + sts_sync, #endif - 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)) - { + 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO) + ) { thd->clear_error(); } - if (spider_get_crd(share, spider->search_link_idx, tmp_time, - spider, table, crd_interval, crd_mode, + if ( + ( + !same_server_link || + load_crd_at_startup + ) && + spider_get_crd(share, spider->search_link_idx, tmp_time, + spider, table, crd_interval, crd_mode, #ifdef WITH_PARTITION_STORAGE_ENGINE - crd_sync, + crd_sync, #endif - 1)) - { + 1) + ) { thd->clear_error(); } pthread_mutex_unlock(&share->crd_mutex); @@ -4790,9 +5135,22 @@ SPIDER_SHARE *spider_get_share( share->use_count++; pthread_mutex_unlock(&spider_tbl_mutex); + int sleep_cnt = 0; while (!share->init) { - my_sleep(10); + // avoid for dead loop + if (sleep_cnt++ > 1000) + { + fprintf(stderr, " [WARN SPIDER RESULT] " + "Wait share->init too long, table_name %s %s %ld\n", + share->table_name, share->tgt_hosts[0], share->tgt_ports[0]); + *error_num = ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM; + my_printf_error(ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM, + ER_SPIDER_TABLE_OPEN_TIMEOUT_STR, MYF(0), + table_share->db.str, table_share->table_name.str); + goto error_but_no_delete; + } + my_sleep(10000); // wait 10 ms } if (!share->link_status_init) @@ -4900,6 +5258,58 @@ SPIDER_SHARE *spider_get_share( spider->set_error_mode(); #ifndef WITHOUT_SPIDER_BG_SEARCH + if (!share->sts_spider_init) + { + pthread_mutex_lock(&share->mutex); + if (!share->sts_spider_init) + { + if ((*error_num = spider_create_spider_object_for_share( + spider->trx, share, &share->sts_spider))) + { + pthread_mutex_unlock(&share->mutex); + spider_free_share(share); + goto error_sts_spider_init; + } +#ifdef HASH_UPDATE_WITH_HASH_VALUE + share->sts_thread = &spider_table_sts_threads[ + hash_value % spider_param_table_sts_thread_count()]; +#else + share->sts_thread = &spider_table_sts_threads[ + my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % + spider_param_table_sts_thread_count()]; +#endif + share->sts_spider_init = TRUE; + } + pthread_mutex_unlock(&share->mutex); + } + + if (!share->crd_spider_init) + { + pthread_mutex_lock(&share->mutex); + if (!share->crd_spider_init) + { + if ((*error_num = spider_create_spider_object_for_share( + spider->trx, share, &share->crd_spider))) + { + pthread_mutex_unlock(&share->mutex); + spider_free_share(share); + goto error_crd_spider_init; + } +#ifdef HASH_UPDATE_WITH_HASH_VALUE + share->crd_thread = &spider_table_crd_threads[ + hash_value % spider_param_table_crd_thread_count()]; +#else + share->crd_thread = &spider_table_crd_threads[ + my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % + spider_param_table_crd_thread_count()]; +#endif + share->crd_spider_init = TRUE; + } + pthread_mutex_unlock(&share->mutex); + } +#endif + +#ifndef WITHOUT_SPIDER_BG_SEARCH if ( sql_command != SQLCOM_DROP_TABLE && sql_command != SQLCOM_ALTER_TABLE && @@ -5077,6 +5487,7 @@ SPIDER_SHARE *spider_get_share( spider->trx, spider->trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -5100,22 +5511,15 @@ SPIDER_SHARE *spider_get_share( share->link_count, SPIDER_LINK_STATUS_OK); if (search_link_idx == -1) { -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - char *db, *table_name; - if (!(db = (char *) - spider_bulk_malloc(spider_current_trx, 50, MYF(MY_WME), - &db, table_share->db.length + 1, - &table_name, table_share->table_name.length + 1, - NullS)) - ) { + char *db = (char *) my_alloca( + table_share->db.length + 1 + table_share->table_name.length + 1); + if (!db) + { *error_num = HA_ERR_OUT_OF_MEM; spider_free_share(share); goto error_but_no_delete; } -#else - char db[table_share->db.length + 1], - table_name[table_share->table_name.length + 1]; -#endif + char *table_name = db + table_share->db.length + 1; memcpy(db, table_share->db.str, table_share->db.length); db[table_share->db.length] = '\0'; memcpy(table_name, table_share->table_name.str, @@ -5123,12 +5527,15 @@ SPIDER_SHARE *spider_get_share( table_name[table_share->table_name.length] = '\0'; my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM, ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(spider->trx, db, MYF(MY_WME)); -#endif + my_afree(db); *error_num = ER_SPIDER_ALL_LINKS_FAILED_NUM; spider_free_share(share); goto error_but_no_delete; + } else if (search_link_idx == -2) + { + *error_num = HA_ERR_OUT_OF_MEM; + spider_free_share(share); + goto error_but_no_delete; } spider->search_link_idx = search_link_idx; @@ -5138,12 +5545,21 @@ SPIDER_SHARE *spider_get_share( pthread_mutex_lock(&share->crd_mutex); if (share->init_error) { + same_server_link = spider_param_same_server_link(thd); + load_sts_at_startup = + spider_param_load_sts_at_startup(share->load_sts_at_startup); + load_crd_at_startup = + spider_param_load_crd_at_startup(share->load_crd_at_startup); if ( sql_command != SQLCOM_DROP_TABLE && sql_command != SQLCOM_ALTER_TABLE && sql_command != SQLCOM_SHOW_CREATE && !spider->error_mode && - !spider_param_same_server_link(thd) + ( + !same_server_link || + load_sts_at_startup || + load_crd_at_startup + ) ) { SPIDER_INIT_ERROR_TABLE *spider_init_error_table; sts_interval = spider_param_sts_interval(thd, share->sts_interval); @@ -5183,22 +5599,32 @@ SPIDER_SHARE *spider_get_share( } } - if (spider_get_sts(share, spider->search_link_idx, - tmp_time, spider, sts_interval, sts_mode, + if ( + ( + !same_server_link || + load_sts_at_startup + ) && + spider_get_sts(share, spider->search_link_idx, + tmp_time, spider, sts_interval, sts_mode, #ifdef WITH_PARTITION_STORAGE_ENGINE - sts_sync, + sts_sync, #endif - 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)) - { + 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO) + ) { thd->clear_error(); } - if (spider_get_crd(share, spider->search_link_idx, - tmp_time, spider, table, crd_interval, crd_mode, + if ( + ( + !same_server_link || + load_crd_at_startup + ) && + spider_get_crd(share, spider->search_link_idx, + tmp_time, spider, table, crd_interval, crd_mode, #ifdef WITH_PARTITION_STORAGE_ENGINE - crd_sync, + crd_sync, #endif - 1)) - { + 1) + ) { thd->clear_error(); } } @@ -5224,6 +5650,10 @@ error_get_link_statuses: table_tables = NULL; } error_open_sys_table: +#ifndef WITHOUT_SPIDER_BG_SEARCH +error_crd_spider_init: +error_sts_spider_init: +#endif if (init_mem_root) { free_root(&mem_root, MYF(0)); @@ -5257,7 +5687,49 @@ int spider_free_share( spider_free_sts_thread(share); spider_free_crd_thread(share); spider_free_mon_threads(share); + if (share->sts_spider_init) + { + spider_table_remove_share_from_sts_thread(share); + spider_free_spider_object_for_share(&share->sts_spider); + } + if (share->crd_spider_init) + { + spider_table_remove_share_from_crd_thread(share); + spider_free_spider_object_for_share(&share->crd_spider); + } #endif + if ( + share->sts_init && + spider_param_store_last_sts(share->store_last_sts) + ) { + spider_sys_insert_or_update_table_sts( + current_thd, + share->lgtm_tblhnd_share->table_name, + share->lgtm_tblhnd_share->table_name_length, + &share->data_file_length, + &share->max_data_file_length, + &share->index_file_length, + &share->records, + &share->mean_rec_length, + &share->check_time, + &share->create_time, + &share->update_time, + FALSE + ); + } + if ( + share->crd_init && + spider_param_store_last_crd(share->store_last_crd) + ) { + spider_sys_insert_or_update_table_crd( + current_thd, + share->lgtm_tblhnd_share->table_name, + share->lgtm_tblhnd_share->table_name_length, + share->cardinality, + share->table_share->fields, + FALSE + ); + } spider_free_share_alloc(share); #ifdef HASH_UPDATE_WITH_HASH_VALUE my_hash_delete_with_hash_value(&spider_open_tables, @@ -5269,6 +5741,7 @@ int spider_free_share( pthread_mutex_destroy(&share->crd_mutex); pthread_mutex_destroy(&share->sts_mutex); pthread_mutex_destroy(&share->mutex); + free_root(&share->mem_root, MYF(0)); spider_free(spider_current_trx, share, MYF(0)); } pthread_mutex_unlock(&spider_tbl_mutex); @@ -6069,6 +6542,20 @@ int spider_db_done( } } +#ifndef WITHOUT_SPIDER_BG_SEARCH + for (roop_count = spider_param_table_crd_thread_count() - 1; + roop_count >= 0; roop_count--) + { + spider_free_crd_threads(&spider_table_crd_threads[roop_count]); + } + for (roop_count = spider_param_table_sts_thread_count() - 1; + roop_count >= 0; roop_count--) + { + spider_free_sts_threads(&spider_table_sts_threads[roop_count]); + } + spider_free(NULL, spider_table_sts_threads, MYF(0)); +#endif + for (roop_count = spider_param_udf_table_mon_mutex_count() - 1; roop_count >= 0; roop_count--) { @@ -6186,6 +6673,7 @@ int spider_db_done( spider_open_connections.array.max_element * spider_open_connections.array.size_of_element); my_hash_free(&spider_open_connections); + my_hash_free(&spider_ipport_conns); spider_free_mem_calc(spider_current_trx, spider_lgtm_tblhnd_share_hash_id, spider_lgtm_tblhnd_share_hash.array.max_element * @@ -6241,6 +6729,7 @@ int spider_db_done( #endif pthread_mutex_destroy(&spider_init_error_tbl_mutex); pthread_mutex_destroy(&spider_conn_id_mutex); + pthread_mutex_destroy(&spider_ipport_conn_mutex); pthread_mutex_destroy(&spider_thread_id_mutex); pthread_mutex_destroy(&spider_tbl_mutex); #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -6287,6 +6776,9 @@ int spider_db_init( spider_hton->state = SHOW_OPTION_YES; spider_hton->flags = HTON_NO_FLAGS; +#ifdef HTON_CAN_READ_CONNECT_STRING_IN_PARTITION + spider_hton->flags |= HTON_CAN_READ_CONNECT_STRING_IN_PARTITION; +#endif /* spider_hton->db_type = DB_TYPE_SPIDER; */ /* spider_hton->savepoint_offset; @@ -6316,6 +6808,9 @@ int spider_db_init( spider_hton->create = spider_create_handler; spider_hton->drop_database = spider_drop_database; spider_hton->show_status = spider_show_status; +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + spider_hton->create_group_by = spider_create_group_by_handler; +#endif memset(&spider_alloc_func_name, 0, sizeof(spider_alloc_func_name)); memset(&spider_alloc_file_name, 0, sizeof(spider_alloc_file_name)); @@ -6327,6 +6822,10 @@ int spider_db_init( #ifdef _WIN32 HMODULE current_module = GetModuleHandle(NULL); +#ifndef SPIDER_HAS_NEXT_THREAD_ID + spd_db_att_thread_id = (ulong *) + GetProcAddress(current_module, "?thread_id@@3KA"); +#endif #ifdef SPIDER_XID_USES_xid_cache_iterate #else #ifdef XID_CACHE_IS_SPLITTED @@ -6338,7 +6837,7 @@ int spider_db_init( "?LOCK_xid_cache@@3PAUst_mysql_mutex@@A")); spd_db_att_xid_cache = *((HASH **) GetProcAddress(current_module, "?xid_cache@@3PAUst_hash@@A")); -#elif MYSQL_VERSION_ID < 100103 +#else spd_db_att_LOCK_xid_cache = (pthread_mutex_t *) #if MYSQL_VERSION_ID < 50500 GetProcAddress(current_module, @@ -6359,14 +6858,23 @@ int spider_db_init( GetProcAddress(current_module, "my_defaults_file"); spd_abort_loop = (bool volatile *) GetProcAddress(current_module, "?abort_loop@@3_NC"); + spd_tz_system = *(Time_zone **) +#ifdef _WIN64 + GetProcAddress(current_module, "?my_tz_SYSTEM@@3PEAVTime_zone@@EA"); #else + GetProcAddress(current_module, "?my_tz_SYSTEM@@3PAVTime_zone@@A"); +#endif +#else +#ifndef SPIDER_HAS_NEXT_THREAD_ID + spd_db_att_thread_id = &thread_id; +#endif #ifdef SPIDER_XID_USES_xid_cache_iterate #else #ifdef XID_CACHE_IS_SPLITTED spd_db_att_xid_cache_split_num = &opt_xid_cache_split_num; spd_db_att_LOCK_xid_cache = LOCK_xid_cache; spd_db_att_xid_cache = xid_cache; -#elif MYSQL_VERSION_ID < 100103 +#else spd_db_att_LOCK_xid_cache = &LOCK_xid_cache; spd_db_att_xid_cache = &xid_cache; #endif @@ -6375,6 +6883,7 @@ int spider_db_init( spd_defaults_extra_file = &my_defaults_extra_file; spd_defaults_file = &my_defaults_file; spd_abort_loop = &abort_loop; + spd_tz_system = my_tz_SYSTEM; #endif #ifdef HAVE_PSI_INTERFACE @@ -6427,6 +6936,17 @@ int spider_db_init( goto error_conn_id_mutex_init; } #if MYSQL_VERSION_ID < 50500 + if (pthread_mutex_init(&spider_ipport_conn_mutex, MY_MUTEX_INIT_FAST)) +#else + if (mysql_mutex_init(spd_key_mutex_ipport_count, + &spider_ipport_conn_mutex, MY_MUTEX_INIT_FAST)) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_ipport_count_mutex_init; + } + +#if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_init_error_tbl_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_mutex_init_error_tbl, @@ -6602,6 +7122,13 @@ int spider_db_init( error_num = HA_ERR_OUT_OF_MEM; goto error_open_connections_hash_init; } + if( + my_hash_init(&spider_ipport_conns, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_ipport_conn_get_key, spider_free_ipport_conn, 0) + ) { + error_num = HA_ERR_OUT_OF_MEM; + goto error_ipport_conn__hash_init; + } spider_alloc_calc_mem_init(spider_open_connections, 146); spider_alloc_calc_mem(NULL, spider_open_connections, @@ -6720,6 +7247,37 @@ int spider_db_init( spider_udf_table_mon_list_hash[roop_count].array.size_of_element); } +#ifndef WITHOUT_SPIDER_BG_SEARCH + if (!(spider_table_sts_threads = (SPIDER_THREAD *) + spider_bulk_malloc(NULL, 256, MYF(MY_WME | MY_ZEROFILL), + &spider_table_sts_threads, sizeof(SPIDER_THREAD) * + spider_param_table_sts_thread_count(), + &spider_table_crd_threads, sizeof(SPIDER_THREAD) * + spider_param_table_crd_thread_count(), + NullS)) + ) + goto error_alloc_mon_mutxes; + + for (roop_count = 0; + roop_count < (int) spider_param_table_sts_thread_count(); + roop_count++) + { + if ((error_num = spider_create_sts_threads(&spider_table_sts_threads[roop_count]))) + { + goto error_init_table_sts_threads; + } + } + for (roop_count = 0; + roop_count < (int) spider_param_table_crd_thread_count(); + roop_count++) + { + if ((error_num = spider_create_crd_threads(&spider_table_crd_threads[roop_count]))) + { + goto error_init_table_crd_threads; + } + } +#endif + spider_dbton_mysql.dbton_id = dbton_id; spider_dbton[dbton_id] = spider_dbton_mysql; ++dbton_id; @@ -6762,6 +7320,19 @@ error_init_dbton: spider_dbton[roop_count].deinit(); } } + roop_count = spider_param_table_crd_thread_count() - 1; +error_init_table_crd_threads: + for (; roop_count >= 0; roop_count--) + { + spider_free_crd_threads(&spider_table_crd_threads[roop_count]); + } + roop_count = spider_param_table_sts_thread_count() - 1; +error_init_table_sts_threads: + for (; roop_count >= 0; roop_count--) + { + spider_free_sts_threads(&spider_table_sts_threads[roop_count]); + } + spider_free(NULL, spider_table_sts_threads, MYF(0)); roop_count = spider_param_udf_table_mon_mutex_count() - 1; #endif error_init_udf_table_mon_list_hash: @@ -6795,6 +7366,8 @@ error_mon_table_cache_array_init: spider_allocated_thds.array.size_of_element); my_hash_free(&spider_allocated_thds); error_allocated_thds_hash_init: + my_hash_free(&spider_ipport_conns); +error_ipport_conn__hash_init: #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) spider_free_mem_calc(NULL, spider_hs_w_conn_hash_id, @@ -6869,6 +7442,8 @@ error_pt_share_mutex_init: #endif pthread_mutex_destroy(&spider_init_error_tbl_mutex); error_init_error_tbl_mutex_init: + pthread_mutex_destroy(&spider_ipport_conn_mutex); +error_ipport_count_mutex_init: pthread_mutex_destroy(&spider_conn_id_mutex); error_conn_id_mutex_init: pthread_mutex_destroy(&spider_thread_id_mutex); @@ -6960,10 +7535,13 @@ void spider_get_partition_info( List_iterator<partition_element> sub_it((*part_elem)->subpartitions); while ((*sub_elem = sub_it++)) { - if (create_subpartition_name(tmp_name, sizeof(tmp_name), - table_share->path.str, (*part_elem)->partition_name, - (*sub_elem)->partition_name, NORMAL_PART_NAME)) + if (SPIDER_create_subpartition_name( + tmp_name, FN_REFLEN + 1, table_share->path.str, + (*part_elem)->partition_name, (*sub_elem)->partition_name, + NORMAL_PART_NAME)) + { DBUG_VOID_RETURN; + } DBUG_PRINT("info",("spider tmp_name=%s", tmp_name)); if (!memcmp(table_name, tmp_name, table_name_length + 1)) DBUG_VOID_RETURN; @@ -6979,10 +7557,12 @@ void spider_get_partition_info( } } } else { - if (create_partition_name(tmp_name, sizeof(tmp_name), - table_share->path.str, (*part_elem)->partition_name, - NORMAL_PART_NAME, TRUE)) + if (SPIDER_create_partition_name( + tmp_name, FN_REFLEN + 1, table_share->path.str, + (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE)) + { DBUG_VOID_RETURN; + } DBUG_PRINT("info",("spider tmp_name=%s", tmp_name)); if (!memcmp(table_name, tmp_name, table_name_length + 1)) DBUG_VOID_RETURN; @@ -7026,6 +7606,7 @@ int spider_get_sts( ) { int get_type; int error_num = 0; + bool need_to_get = TRUE; DBUG_ENTER("spider_get_sts"); #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -7064,11 +7645,45 @@ int spider_get_sts( /* copy */ get_type = 0; } - if (get_type == 0) - spider_copy_sts_to_share(share, share->partition_share); - else #endif - error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag); + if ( + !share->sts_init && + spider_param_load_sts_at_startup(share->load_sts_at_startup) && + (!share->init || share->init_error) + ) { + error_num = spider_sys_get_table_sts( + current_thd, + share->lgtm_tblhnd_share->table_name, + share->lgtm_tblhnd_share->table_name_length, + &share->data_file_length, + &share->max_data_file_length, + &share->index_file_length, + &share->records, + &share->mean_rec_length, + &share->check_time, + &share->create_time, + &share->update_time, + FALSE + ); + if ( + !error_num || + (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + ) + need_to_get = FALSE; + } + + if (need_to_get) + { +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (get_type == 0) + spider_copy_sts_to_share(share, share->partition_share); + else { +#endif + error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag); +#ifdef WITH_PARTITION_STORAGE_ENGINE + } +#endif + } #ifdef WITH_PARTITION_STORAGE_ENGINE if (get_type >= 2) pthread_mutex_unlock(&share->partition_share->sts_mutex); @@ -7148,6 +7763,7 @@ int spider_get_crd( ) { int get_type; int error_num = 0; + bool need_to_get = TRUE; DBUG_ENTER("spider_get_crd"); #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -7186,12 +7802,39 @@ int spider_get_crd( /* copy */ get_type = 0; } - if (get_type == 0) - spider_copy_crd_to_share(share, share->partition_share, - table->s->fields); - else #endif - error_num = spider_db_show_index(spider, link_idx, table, crd_mode); + if ( + !share->crd_init && + spider_param_load_sts_at_startup(share->load_crd_at_startup) + ) { + error_num = spider_sys_get_table_crd( + current_thd, + share->lgtm_tblhnd_share->table_name, + share->lgtm_tblhnd_share->table_name_length, + share->cardinality, + table->s->fields, + FALSE + ); + if ( + !error_num || + (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + ) + need_to_get = FALSE; + } + + if (need_to_get) + { +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (get_type == 0) + spider_copy_crd_to_share(share, share->partition_share, + table->s->fields); + else { +#endif + error_num = spider_db_show_index(spider, link_idx, table, crd_mode); +#ifdef WITH_PARTITION_STORAGE_ENGINE + } +#endif + } #ifdef WITH_PARTITION_STORAGE_ENGINE if (get_type >= 2) pthread_mutex_unlock(&share->partition_share->crd_mutex); @@ -7549,35 +8192,37 @@ void spider_set_tmp_share_pointer( tmp_share->tgt_default_groups = &tmp_connect_info[14]; tmp_share->tgt_pk_names = &tmp_connect_info[15]; tmp_share->tgt_sequence_names = &tmp_connect_info[16]; + tmp_share->static_link_ids = &tmp_connect_info[17]; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->hs_read_socks = &tmp_connect_info[17]; - tmp_share->hs_write_socks = &tmp_connect_info[18]; + tmp_share->hs_read_socks = &tmp_connect_info[18]; + tmp_share->hs_write_socks = &tmp_connect_info[19]; #endif tmp_share->tgt_ports = &tmp_long[0]; tmp_share->tgt_ssl_vscs = &tmp_long[1]; tmp_share->link_statuses = &tmp_long[2]; - tmp_share->monitoring_flag = &tmp_long[3]; - tmp_share->monitoring_kind = &tmp_long[4]; + tmp_share->monitoring_binlog_pos_at_failing = &tmp_long[3]; + tmp_share->monitoring_flag = &tmp_long[4]; + tmp_share->monitoring_kind = &tmp_long[5]; #ifndef WITHOUT_SPIDER_BG_SEARCH - tmp_share->monitoring_bg_flag = &tmp_long[5]; - tmp_share->monitoring_bg_kind = &tmp_long[6]; + tmp_share->monitoring_bg_flag = &tmp_long[6]; + tmp_share->monitoring_bg_kind = &tmp_long[7]; #endif #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->use_hs_reads = &tmp_long[7]; - tmp_share->use_hs_writes = &tmp_long[8]; - tmp_share->hs_read_ports = &tmp_long[9]; - tmp_share->hs_write_ports = &tmp_long[10]; - tmp_share->hs_write_to_reads = &tmp_long[11]; -#endif - tmp_share->use_handlers = &tmp_long[12]; - tmp_share->connect_timeouts = &tmp_long[13]; + tmp_share->use_hs_reads = &tmp_long[8]; + tmp_share->use_hs_writes = &tmp_long[9]; + tmp_share->hs_read_ports = &tmp_long[10]; + tmp_share->hs_write_ports = &tmp_long[11]; + tmp_share->hs_write_to_reads = &tmp_long[12]; +#endif + tmp_share->use_handlers = &tmp_long[13]; + tmp_share->connect_timeouts = &tmp_long[14]; tmp_long[13] = -1; - tmp_share->net_read_timeouts = &tmp_long[14]; + tmp_share->net_read_timeouts = &tmp_long[15]; tmp_long[14] = -1; - tmp_share->net_write_timeouts = &tmp_long[15]; + tmp_share->net_write_timeouts = &tmp_long[16]; tmp_long[15] = -1; - tmp_share->access_balances = &tmp_long[16]; - tmp_share->bka_table_name_types = &tmp_long[17]; + tmp_share->access_balances = &tmp_long[17]; + tmp_share->bka_table_name_types = &tmp_long[18]; tmp_share->monitoring_limit = &tmp_longlong[0]; tmp_share->monitoring_sid = &tmp_longlong[1]; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -7600,9 +8245,10 @@ void spider_set_tmp_share_pointer( tmp_share->tgt_default_groups_lengths = &tmp_connect_info_length[14]; tmp_share->tgt_pk_names_lengths = &tmp_connect_info_length[15]; tmp_share->tgt_sequence_names_lengths = &tmp_connect_info_length[16]; + tmp_share->static_link_ids_lengths = &tmp_connect_info_length[17]; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->hs_read_socks_lengths = &tmp_connect_info_length[17]; - tmp_share->hs_write_socks_lengths = &tmp_connect_info_length[18]; + tmp_share->hs_read_socks_lengths = &tmp_connect_info_length[18]; + tmp_share->hs_write_socks_lengths = &tmp_connect_info_length[19]; #endif tmp_share->server_names_length = 1; tmp_share->tgt_table_names_length = 1; @@ -7621,9 +8267,11 @@ void spider_set_tmp_share_pointer( tmp_share->tgt_default_groups_length = 1; tmp_share->tgt_pk_names_length = 1; tmp_share->tgt_sequence_names_length = 1; + tmp_share->static_link_ids_length = 1; tmp_share->tgt_ports_length = 1; tmp_share->tgt_ssl_vscs_length = 1; tmp_share->link_statuses_length = 1; + tmp_share->monitoring_binlog_pos_at_failing_length = 1; tmp_share->monitoring_flag_length = 1; tmp_share->monitoring_kind_length = 1; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -7655,6 +8303,7 @@ void spider_set_tmp_share_pointer( tmp_share->monitoring_bg_flag[0] = -1; tmp_share->monitoring_bg_kind[0] = -1; #endif + tmp_share->monitoring_binlog_pos_at_failing[0] = -1; tmp_share->monitoring_flag[0] = -1; tmp_share->monitoring_kind[0] = -1; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -7754,6 +8403,19 @@ TABLE_LIST *spider_get_parent_table_list( DBUG_RETURN(NULL); } +List<Index_hint> *spider_get_index_hints( + ha_spider *spider + ) { + TABLE_LIST *table_list = spider_get_parent_table_list(spider); + DBUG_ENTER("spider_get_index_hint"); + if (table_list) + { + DBUG_RETURN(table_list->index_hints); + } + DBUG_RETURN(NULL); +} + + st_select_lex *spider_get_select_lex( ha_spider *spider ) { @@ -7766,6 +8428,24 @@ st_select_lex *spider_get_select_lex( DBUG_RETURN(NULL); } +void spider_get_select_limit_from_select_lex( + st_select_lex *select_lex, + longlong *select_limit, + longlong *offset_limit +) { + DBUG_ENTER("spider_get_select_limit_from_select_lex"); + *select_limit = 9223372036854775807LL; + *offset_limit = 0; + if (select_lex && select_lex->explicit_limit) + { + *select_limit = select_lex->select_limit ? + select_lex->select_limit->val_int() : 0; + *offset_limit = select_lex->offset_limit ? + select_lex->offset_limit->val_int() : 0; + } + DBUG_VOID_RETURN; +} + void spider_get_select_limit( ha_spider *spider, st_select_lex **select_lex, @@ -7774,15 +8454,8 @@ void spider_get_select_limit( ) { DBUG_ENTER("spider_get_select_limit"); *select_lex = spider_get_select_lex(spider); - *select_limit = 9223372036854775807LL; - *offset_limit = 0; - if (*select_lex && (*select_lex)->explicit_limit) - { - *select_limit = (*select_lex)->select_limit ? - (*select_lex)->select_limit->val_int() : 0; - *offset_limit = (*select_lex)->offset_limit ? - (*select_lex)->offset_limit->val_int() : 0; - } + spider_get_select_limit_from_select_lex( + *select_lex, select_limit, offset_limit); DBUG_VOID_RETURN; } @@ -7827,6 +8500,16 @@ longlong spider_split_read_param( DBUG_PRINT("info",("spider bulk_update_mode=%d", bulk_update_mode)); DBUG_PRINT("info",("spider support_bulk_update_sql=%s", spider->support_bulk_update_sql() ? "TRUE" : "FALSE")); +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + bool inserting = + ( +#ifdef HS_HAS_SQLCOM + spider->sql_command == SQLCOM_HS_INSERT || +#endif + spider->sql_command == SQLCOM_INSERT || + spider->sql_command == SQLCOM_INSERT_SELECT + ); +#endif bool updating = ( #ifdef HS_HAS_SQLCOM @@ -7853,6 +8536,12 @@ longlong spider_split_read_param( DBUG_PRINT("info",("spider replacing=%s", replacing ? "TRUE" : "FALSE")); TABLE *table = spider->get_table(); if ( +#ifdef SPIDER_HAS_GROUP_BY_HANDLER + ( + inserting && + spider->use_fields + ) || +#endif replacing || ( ( @@ -8210,6 +8899,104 @@ bool spider_check_direct_order_limit( DBUG_RETURN(FALSE); } +int spider_set_direct_limit_offset( + ha_spider *spider +) { + THD *thd = spider->trx->thd; + st_select_lex *select_lex; + longlong select_limit; + longlong offset_limit; + TABLE_LIST *table_list; + DBUG_ENTER("spider_set_direct_limit_offset"); + + if (spider->result_list.direct_limit_offset) + DBUG_RETURN(TRUE); + + if ( + spider->pt_handler_share_creator && + spider->pt_handler_share_creator != spider + ) { + if (spider->pt_handler_share_creator->result_list.direct_limit_offset == TRUE) + { + spider->result_list.direct_limit_offset = TRUE; + DBUG_RETURN(TRUE); + } else { + DBUG_RETURN(FALSE); + } + } + + if ( + spider->sql_command != SQLCOM_SELECT || +#ifdef HANDLER_HAS_DIRECT_AGGREGATE + spider->result_list.direct_aggregate || +#endif + spider->result_list.direct_order_limit || + spider->prev_index_rnd_init != SPD_RND // must be RND_INIT and not be INDEX_INIT + ) + DBUG_RETURN(FALSE); + + spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit); + + // limit and offset is non-zero + if (!(select_limit && offset_limit)) + DBUG_RETURN(FALSE); + + // more than one table + if ( + !select_lex || + select_lex->table_list.elements != 1 + ) + DBUG_RETURN(FALSE); + + table_list = (TABLE_LIST *) select_lex->table_list.first; + if (table_list->table->file->partition_ht() != spider_hton_ptr) + { + DBUG_PRINT("info",("spider ht1=%u ht2=%u", + table_list->table->file->partition_ht()->slot, + spider_hton_ptr->slot + )); + DBUG_RETURN(FALSE); + } + + // contain where + if ( +#if MYSQL_VERSION_ID < 50500 + !thd->variables.engine_condition_pushdown || +#else +#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON +#else + !(thd->variables.optimizer_switch & + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) || +#endif +#endif + spider->condition // conditions is null may be no where condition in rand_init + ) + DBUG_RETURN(FALSE); + + // ignore condition like 1=1 + if (select_lex->where && select_lex->where->with_subquery()) + DBUG_RETURN(FALSE); + + if ( + select_lex->group_list.elements || + select_lex->with_sum_func || + select_lex->having || + select_lex->order_list.elements + ) + DBUG_RETURN(FALSE); + + // must not be derived table + if (&thd->lex->select_lex != select_lex) + DBUG_RETURN(FALSE); + + spider->direct_select_offset = offset_limit; + spider->direct_current_offset = offset_limit; + spider->direct_select_limit = select_limit; + spider->result_list.direct_limit_offset = TRUE; + DBUG_RETURN(TRUE); +} + + bool spider_check_index_merge( TABLE *table, st_select_lex *select_lex @@ -8368,7 +9155,7 @@ int spider_discover_table_structure( TABLE_SHARE *share, HA_CREATE_INFO *info ) { - int error_num = HA_ERR_WRONG_COMMAND; + int error_num = HA_ERR_WRONG_COMMAND, dummy; SPIDER_SHARE *spider_share; const char *table_name = share->path.str; uint table_name_length = (uint) strlen(table_name); @@ -8376,6 +9163,8 @@ int spider_discover_table_structure( #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info = thd->work_part_info; #endif + Open_tables_backup open_tables_backup; + TABLE *table_tables; uint str_len; char buf[MAX_FIELD_WIDTH]; spider_string str(buf, sizeof(buf), system_charset_info); @@ -8431,15 +9220,25 @@ int spider_discover_table_structure( if (!error_num) { - Open_tables_backup open_tables_backup; - TABLE *table_tables; if ( (table_tables = spider_open_sys_table( thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, SPIDER_SYS_TABLES_TABLE_NAME_LEN, TRUE, &open_tables_backup, FALSE, &error_num)) ) { - error_num = spider_insert_tables(table_tables, spider_share); +#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE + if (thd->lex->create_info.or_replace()) + { + error_num = spider_delete_tables(table_tables, + spider_share->table_name, &dummy); + } + if (!error_num) + { +#endif + error_num = spider_insert_tables(table_tables, spider_share); +#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE + } +#endif spider_close_sys_table(thd, table_tables, &open_tables_backup, FALSE); } @@ -8450,6 +9249,7 @@ int spider_discover_table_structure( } else { char tmp_name[FN_REFLEN + 1]; List_iterator<partition_element> part_it(part_info->partitions); + List_iterator<partition_element> part_it2(part_info->partitions); partition_element *part_elem, *sub_elem; while ((part_elem = part_it++)) { @@ -8459,19 +9259,22 @@ int spider_discover_table_structure( while ((sub_elem = sub_it++)) { str.length(str_len); - if (create_subpartition_name(tmp_name, sizeof(tmp_name), table_name, - (part_elem)->partition_name, (sub_elem)->partition_name, - NORMAL_PART_NAME)) - DBUG_RETURN(1); + if ((error_num = SPIDER_create_subpartition_name( + tmp_name, FN_REFLEN + 1, table_name, + (part_elem)->partition_name, (sub_elem)->partition_name, + NORMAL_PART_NAME))) + { + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } DBUG_PRINT("info",("spider tmp_name=%s", tmp_name)); - if (!(spider_share = spider_create_share(table_name, share, + if (!(spider_share = spider_create_share(tmp_name, share, part_info, #ifdef SPIDER_HAS_HASH_VALUE_TYPE hash_value, #endif &error_num ))) { - continue; + DBUG_RETURN(error_num); } error_num = spider_discover_table_structure_internal( @@ -8485,18 +9288,21 @@ int spider_discover_table_structure( break; } else { str.length(str_len); - if (create_partition_name(tmp_name, sizeof(tmp_name), table_name, - (part_elem)->partition_name, NORMAL_PART_NAME, TRUE)) - DBUG_RETURN(1); + if ((error_num = SPIDER_create_partition_name( + tmp_name, FN_REFLEN + 1, table_name, + (part_elem)->partition_name, NORMAL_PART_NAME, TRUE))) + { + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } DBUG_PRINT("info",("spider tmp_name=%s", tmp_name)); - if (!(spider_share = spider_create_share(table_name, share, + if (!(spider_share = spider_create_share(tmp_name, share, part_info, #ifdef SPIDER_HAS_HASH_VALUE_TYPE hash_value, #endif &error_num ))) { - continue; + DBUG_RETURN(error_num); } error_num = spider_discover_table_structure_internal( @@ -8507,6 +9313,101 @@ int spider_discover_table_structure( break; } } + if (!error_num) + { + if ( + !(table_tables = spider_open_sys_table( + thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, + SPIDER_SYS_TABLES_TABLE_NAME_LEN, TRUE, &open_tables_backup, FALSE, + &error_num)) + ) { + DBUG_RETURN(error_num); + } + while ((part_elem = part_it2++)) + { + if ((part_elem)->subpartitions.elements) + { + List_iterator<partition_element> sub_it((part_elem)->subpartitions); + while ((sub_elem = sub_it++)) + { + if ((error_num = SPIDER_create_subpartition_name( + tmp_name, FN_REFLEN + 1, table_name, + (part_elem)->partition_name, (sub_elem)->partition_name, + NORMAL_PART_NAME))) + { + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + DBUG_PRINT("info",("spider tmp_name=%s", tmp_name)); + if (!(spider_share = spider_create_share(tmp_name, share, + part_info, +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + hash_value, +#endif + &error_num + ))) { + DBUG_RETURN(error_num); + } + +#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE + if (thd->lex->create_info.or_replace()) + { + error_num = spider_delete_tables(table_tables, + spider_share->table_name, &dummy); + } + if (!error_num) + { +#endif + error_num = spider_insert_tables(table_tables, spider_share); +#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE + } +#endif + + spider_free_share_resource_only(spider_share); + if (error_num) + break; + } + if (error_num) + break; + } else { + if ((error_num = SPIDER_create_partition_name( + tmp_name, FN_REFLEN + 1, table_name, + (part_elem)->partition_name, NORMAL_PART_NAME, TRUE))) + { + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + DBUG_PRINT("info",("spider tmp_name=%s", tmp_name)); + if (!(spider_share = spider_create_share(tmp_name, share, + part_info, +#ifdef SPIDER_HAS_HASH_VALUE_TYPE + hash_value, +#endif + &error_num + ))) { + DBUG_RETURN(error_num); + } + +#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE + if (thd->lex->create_info.or_replace()) + { + error_num = spider_delete_tables(table_tables, + spider_share->table_name, &dummy); + } + if (!error_num) + { +#endif + error_num = spider_insert_tables(table_tables, spider_share); +#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE + } +#endif + + spider_free_share_resource_only(spider_share); + if (error_num) + break; + } + } + spider_close_sys_table(thd, table_tables, + &open_tables_backup, FALSE); + } } #endif @@ -8578,13 +9479,8 @@ int spider_discover_table_structure( { DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM); } -#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE_COMMENT - if (!(part_syntax = generate_partition_syntax(thd, part_info, &part_syntax_len, - TRUE, info, NULL))) -#else - if (!(part_syntax = generate_partition_syntax(part_info, &part_syntax_len, - FALSE, TRUE, info, NULL))) -#endif + if (!(part_syntax = SPIDER_generate_partition_syntax(thd, part_info, + &part_syntax_len, FALSE, TRUE, info, NULL, NULL))) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } @@ -8593,6 +9489,7 @@ int spider_discover_table_structure( DBUG_RETURN(HA_ERR_OUT_OF_MEM); } str.q_append(part_syntax, part_syntax_len); + SPIDER_free_part_syntax(part_syntax, MYF(0)); } #endif DBUG_PRINT("info",("spider str=%s", str.c_ptr_safe())); @@ -8602,3 +9499,768 @@ int spider_discover_table_structure( DBUG_RETURN(error_num); } #endif + +#ifndef WITHOUT_SPIDER_BG_SEARCH +int spider_create_spider_object_for_share( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + ha_spider **spider +) { + int error_num, roop_count, *need_mons; + SPIDER_CONN **conns; + uint *conn_link_idx; + uchar *conn_can_fo; + char **conn_keys; +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + char **hs_r_conn_keys; + char **hs_w_conn_keys; +#endif + spider_db_handler **dbton_hdl; + DBUG_ENTER("spider_create_spider_object_for_share"); + DBUG_PRINT("info",("spider trx=%p", trx)); + DBUG_PRINT("info",("spider share=%p", share)); + DBUG_PRINT("info",("spider spider_ptr=%p", spider)); + DBUG_PRINT("info",("spider spider=%p", (*spider))); + + if (*spider) + { + /* already exists */ + DBUG_RETURN(0); + } + (*spider) = new (&share->mem_root) ha_spider(); + if (!(*spider)) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_spider_alloc; + } + DBUG_PRINT("info",("spider spider=%p", (*spider))); +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + if (!(need_mons = (int *) + spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL), + &need_mons, (sizeof(int) * share->link_count), + &conns, (sizeof(SPIDER_CONN *) * share->link_count), + &conn_link_idx, (sizeof(uint) * share->link_count), + &conn_can_fo, (sizeof(uchar) * share->link_bitmap_size), + &conn_keys, (sizeof(char *) * share->link_count), + &hs_r_conn_keys, (sizeof(char *) * share->link_count), + &hs_w_conn_keys, (sizeof(char *) * share->link_count), + &dbton_hdl, (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE), + NullS)) + ) +#else + if (!(need_mons = (int *) + spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL), + &need_mons, (sizeof(int) * share->link_count), + &conns, (sizeof(SPIDER_CONN *) * share->link_count), + &conn_link_idx, (sizeof(uint) * share->link_count), + &conn_can_fo, (sizeof(uchar) * share->link_bitmap_size), + &conn_keys, (sizeof(char *) * share->link_count), + &dbton_hdl, (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE), + NullS)) + ) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_need_mons_alloc; + } + DBUG_PRINT("info",("spider need_mons=%p", need_mons)); + (*spider)->trx = trx; + (*spider)->change_table_ptr(&share->table, share->table_share); + (*spider)->share = share; + (*spider)->conns = conns; + (*spider)->conn_link_idx = conn_link_idx; + (*spider)->conn_can_fo = conn_can_fo; + (*spider)->need_mons = need_mons; + (*spider)->conn_keys_first_ptr = share->conn_keys[0]; + (*spider)->conn_keys = conn_keys; +#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) + (*spider)->hs_r_conn_keys = hs_r_conn_keys; + (*spider)->hs_w_conn_keys = hs_w_conn_keys; +#endif + (*spider)->dbton_handler = dbton_hdl; + (*spider)->search_link_idx = -1; + for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++) + { + if ( + spider_bit_is_set(share->dbton_bitmap, roop_count) && + spider_dbton[roop_count].create_db_handler + ) { + if (!(dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler( + *spider, share->dbton_share[roop_count]))) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_init_db_handler; + } + if ((error_num = dbton_hdl[roop_count]->init())) + goto error_init_db_handler; + } + } + DBUG_PRINT("info",("spider share=%p", (*spider)->share)); + DBUG_PRINT("info",("spider need_mons=%p", (*spider)->need_mons)); + DBUG_RETURN(0); + +error_init_db_handler: + for (; roop_count >= 0; --roop_count) + { + if ( + spider_bit_is_set(share->dbton_bitmap, roop_count) && + dbton_hdl[roop_count] + ) { + delete dbton_hdl[roop_count]; + dbton_hdl[roop_count] = NULL; + } + } + spider_free(spider_current_trx, (*spider)->need_mons, MYF(0)); +error_need_mons_alloc: + delete (*spider); + (*spider) = NULL; +error_spider_alloc: + DBUG_RETURN(error_num); +} + +void spider_free_spider_object_for_share( + ha_spider **spider +) { + int roop_count; + SPIDER_SHARE *share = (*spider)->share; + spider_db_handler **dbton_hdl = (*spider)->dbton_handler; + DBUG_ENTER("spider_free_spider_object_for_share"); + DBUG_PRINT("info",("spider share=%p", share)); + DBUG_PRINT("info",("spider spider_ptr=%p", spider)); + DBUG_PRINT("info",("spider spider=%p", (*spider))); + for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count) + { + if ( + spider_bit_is_set(share->dbton_bitmap, roop_count) && + dbton_hdl[roop_count] + ) { + delete dbton_hdl[roop_count]; + dbton_hdl[roop_count] = NULL; + } + } + spider_free(spider_current_trx, (*spider)->need_mons, MYF(0)); + delete (*spider); + (*spider) = NULL; + DBUG_VOID_RETURN; +} + +int spider_create_sts_threads( + SPIDER_THREAD *spider_thread +) { + int error_num; + DBUG_ENTER("spider_create_sts_threads"); +#if MYSQL_VERSION_ID < 50500 + if (pthread_mutex_init(&spider_thread->mutex, + MY_MUTEX_INIT_FAST)) +#else + if (mysql_mutex_init(spd_key_mutex_bg_stss, + &spider_thread->mutex, MY_MUTEX_INIT_FAST)) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_mutex_init; + } +#if MYSQL_VERSION_ID < 50500 + if (pthread_cond_init(&spider_thread->cond, NULL)) +#else + if (mysql_cond_init(spd_key_cond_bg_stss, + &spider_thread->cond, NULL)) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_cond_init; + } +#if MYSQL_VERSION_ID < 50500 + if (pthread_cond_init(&spider_thread->sync_cond, NULL)) +#else + if (mysql_cond_init(spd_key_cond_bg_sts_syncs, + &spider_thread->sync_cond, NULL)) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_sync_cond_init; + } +#if MYSQL_VERSION_ID < 50500 + if (pthread_create(&spider_thread->thread, &spider_pt_attr, + spider_table_bg_sts_action, (void *) spider_thread) + ) +#else + if (mysql_thread_create(spd_key_thd_bg_stss, &spider_thread->thread, + &spider_pt_attr, spider_table_bg_sts_action, (void *) spider_thread) + ) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_thread_create; + } + DBUG_RETURN(0); + +error_thread_create: + pthread_cond_destroy(&spider_thread->sync_cond); +error_sync_cond_init: + pthread_cond_destroy(&spider_thread->cond); +error_cond_init: + pthread_mutex_destroy(&spider_thread->mutex); +error_mutex_init: + DBUG_RETURN(error_num); +} + +void spider_free_sts_threads( + SPIDER_THREAD *spider_thread +) { + DBUG_ENTER("spider_free_sts_threads"); + pthread_mutex_lock(&spider_thread->mutex); + spider_thread->killed = TRUE; + if (spider_thread->thd_wait) + { + pthread_cond_signal(&spider_thread->cond); + } + pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex); + pthread_mutex_unlock(&spider_thread->mutex); + pthread_join(spider_thread->thread, NULL); + pthread_cond_destroy(&spider_thread->sync_cond); + pthread_cond_destroy(&spider_thread->cond); + pthread_mutex_destroy(&spider_thread->mutex); + spider_thread->thd_wait = FALSE; + spider_thread->killed = FALSE; + DBUG_VOID_RETURN; +} + +int spider_create_crd_threads( + SPIDER_THREAD *spider_thread +) { + int error_num; + DBUG_ENTER("spider_create_crd_threads"); +#if MYSQL_VERSION_ID < 50500 + if (pthread_mutex_init(&spider_thread->mutex, + MY_MUTEX_INIT_FAST)) +#else + if (mysql_mutex_init(spd_key_mutex_bg_crds, + &spider_thread->mutex, MY_MUTEX_INIT_FAST)) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_mutex_init; + } +#if MYSQL_VERSION_ID < 50500 + if (pthread_cond_init(&spider_thread->cond, NULL)) +#else + if (mysql_cond_init(spd_key_cond_bg_crds, + &spider_thread->cond, NULL)) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_cond_init; + } +#if MYSQL_VERSION_ID < 50500 + if (pthread_cond_init(&spider_thread->sync_cond, NULL)) +#else + if (mysql_cond_init(spd_key_cond_bg_crd_syncs, + &spider_thread->sync_cond, NULL)) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_sync_cond_init; + } +#if MYSQL_VERSION_ID < 50500 + if (pthread_create(&spider_thread->thread, &spider_pt_attr, + spider_table_bg_crd_action, (void *) spider_thread) + ) +#else + if (mysql_thread_create(spd_key_thd_bg_crds, &spider_thread->thread, + &spider_pt_attr, spider_table_bg_crd_action, (void *) spider_thread) + ) +#endif + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_thread_create; + } + DBUG_RETURN(0); + +error_thread_create: + pthread_cond_destroy(&spider_thread->sync_cond); +error_sync_cond_init: + pthread_cond_destroy(&spider_thread->cond); +error_cond_init: + pthread_mutex_destroy(&spider_thread->mutex); +error_mutex_init: + DBUG_RETURN(error_num); +} + +void spider_free_crd_threads( + SPIDER_THREAD *spider_thread +) { + DBUG_ENTER("spider_free_crd_threads"); + pthread_mutex_lock(&spider_thread->mutex); + spider_thread->killed = TRUE; + if (spider_thread->thd_wait) + { + pthread_cond_signal(&spider_thread->cond); + } + pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex); + pthread_mutex_unlock(&spider_thread->mutex); + pthread_join(spider_thread->thread, NULL); + pthread_cond_destroy(&spider_thread->sync_cond); + pthread_cond_destroy(&spider_thread->cond); + pthread_mutex_destroy(&spider_thread->mutex); + spider_thread->thd_wait = FALSE; + spider_thread->killed = FALSE; + DBUG_VOID_RETURN; +} + +void *spider_table_bg_sts_action( + void *arg +) { + SPIDER_THREAD *thread = (SPIDER_THREAD *) arg; + SPIDER_SHARE *share; + SPIDER_TRX *trx; + int error_num; + ha_spider *spider; + SPIDER_CONN **conns; + THD *thd; + my_thread_init(); + DBUG_ENTER("spider_table_bg_sts_action"); + /* init start */ + pthread_mutex_lock(&thread->mutex); + if (!(thd = SPIDER_new_THD(next_thread_id()))) + { + thread->thd_wait = FALSE; + thread->killed = FALSE; + pthread_mutex_unlock(&thread->mutex); + my_thread_end(); + DBUG_RETURN(NULL); + } + SPIDER_set_next_thread_id(thd); +#ifdef HAVE_PSI_INTERFACE + mysql_thread_set_psi_id(thd->thread_id); +#endif + thd->thread_stack = (char*) &thd; + thd->store_globals(); + if (!(trx = spider_get_trx(NULL, FALSE, &error_num))) + { + delete thd; + thread->thd_wait = FALSE; + thread->killed = FALSE; + pthread_mutex_unlock(&thread->mutex); +#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32) + my_pthread_setspecific_ptr(THR_THD, NULL); +#endif + my_thread_end(); + DBUG_RETURN(NULL); + } + trx->thd = thd; + /* init end */ + + while (TRUE) + { + DBUG_PRINT("info",("spider bg sts loop start")); + if (thread->killed) + { + DBUG_PRINT("info",("spider bg sts kill start")); + trx->thd = NULL; + spider_free_trx(trx, TRUE); + delete thd; + pthread_cond_signal(&thread->sync_cond); + pthread_mutex_unlock(&thread->mutex); +#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32) + my_pthread_setspecific_ptr(THR_THD, NULL); +#endif + my_thread_end(); + DBUG_RETURN(NULL); + } + if (!thread->queue_first) + { + DBUG_PRINT("info",("spider bg sts has no job")); + thread->thd_wait = TRUE; + pthread_cond_wait(&thread->cond, &thread->mutex); + thread->thd_wait = FALSE; + continue; + } + share = (SPIDER_SHARE *) thread->queue_first; + share->sts_working = TRUE; + pthread_mutex_unlock(&thread->mutex); + + spider = share->sts_spider; + conns = spider->conns; + if (spider->search_link_idx < 0) + { + spider->trx = trx; + spider_trx_set_link_idx_for_all(spider); + spider->search_link_idx = spider_conn_first_link_idx(thd, + share->link_statuses, share->access_balances, spider->conn_link_idx, + share->link_count, SPIDER_LINK_STATUS_OK); + } + if (spider->search_link_idx >= 0) + { + DBUG_PRINT("info", + ("spider difftime=%f", + difftime(share->bg_sts_try_time, share->sts_get_time))); + DBUG_PRINT("info", + ("spider bg_sts_interval=%f", share->bg_sts_interval)); + if (difftime(share->bg_sts_try_time, share->sts_get_time) >= + share->bg_sts_interval) + { + if (!conns[spider->search_link_idx]) + { + spider_get_conn(share, spider->search_link_idx, + share->conn_keys[spider->search_link_idx], + trx, spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL, + &error_num); + if (conns[spider->search_link_idx]) + { + conns[spider->search_link_idx]->error_mode = 0; + } else { + spider->search_link_idx = -1; + } + } + DBUG_PRINT("info", + ("spider search_link_idx=%d", spider->search_link_idx)); + if (spider->search_link_idx >= 0 && conns[spider->search_link_idx]) + { +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (spider_get_sts(share, spider->search_link_idx, + share->bg_sts_try_time, spider, + share->bg_sts_interval, share->bg_sts_mode, + share->bg_sts_sync, + 2, HA_STATUS_CONST | HA_STATUS_VARIABLE)) +#else + if (spider_get_sts(share, spider->search_link_idx, + share->bg_sts_try_time, spider, + share->bg_sts_interval, share->bg_sts_mode, + 2, HA_STATUS_CONST | HA_STATUS_VARIABLE)) +#endif + { + spider->search_link_idx = -1; + } + } + } + } + memset(spider->need_mons, 0, sizeof(int) * share->link_count); + pthread_mutex_lock(&thread->mutex); + if (thread->queue_first == thread->queue_last) + { + thread->queue_first = NULL; + thread->queue_last = NULL; + } else { + thread->queue_first = share->sts_next; + share->sts_next->sts_prev = NULL; + share->sts_next = NULL; + } + share->sts_working = FALSE; + share->sts_wait = FALSE; + if (thread->first_free_wait) + { + pthread_cond_signal(&thread->sync_cond); + pthread_cond_wait(&thread->cond, &thread->mutex); + } + } +} + +void *spider_table_bg_crd_action( + void *arg +) { + SPIDER_THREAD *thread = (SPIDER_THREAD *) arg; + SPIDER_SHARE *share; + SPIDER_TRX *trx; + int error_num; + ha_spider *spider; + TABLE *table; + SPIDER_CONN **conns; + THD *thd; + my_thread_init(); + DBUG_ENTER("spider_table_bg_crd_action"); + /* init start */ + pthread_mutex_lock(&thread->mutex); + if (!(thd = SPIDER_new_THD(next_thread_id()))) + { + thread->thd_wait = FALSE; + thread->killed = FALSE; + pthread_mutex_unlock(&thread->mutex); + my_thread_end(); + DBUG_RETURN(NULL); + } + SPIDER_set_next_thread_id(thd); +#ifdef HAVE_PSI_INTERFACE + mysql_thread_set_psi_id(thd->thread_id); +#endif + thd->thread_stack = (char*) &thd; + thd->store_globals(); + if (!(trx = spider_get_trx(NULL, FALSE, &error_num))) + { + delete thd; + thread->thd_wait = FALSE; + thread->killed = FALSE; + pthread_mutex_unlock(&thread->mutex); +#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32) + my_pthread_setspecific_ptr(THR_THD, NULL); +#endif + my_thread_end(); + DBUG_RETURN(NULL); + } + trx->thd = thd; + /* init end */ + + while (TRUE) + { + DBUG_PRINT("info",("spider bg crd loop start")); + if (thread->killed) + { + DBUG_PRINT("info",("spider bg crd kill start")); + trx->thd = NULL; + spider_free_trx(trx, TRUE); + delete thd; + pthread_cond_signal(&thread->sync_cond); + pthread_mutex_unlock(&thread->mutex); +#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32) + my_pthread_setspecific_ptr(THR_THD, NULL); +#endif + my_thread_end(); + DBUG_RETURN(NULL); + } + if (!thread->queue_first) + { + DBUG_PRINT("info",("spider bg crd has no job")); + thread->thd_wait = TRUE; + pthread_cond_wait(&thread->cond, &thread->mutex); + thread->thd_wait = FALSE; + continue; + } + share = (SPIDER_SHARE *) thread->queue_first; + share->crd_working = TRUE; + pthread_mutex_unlock(&thread->mutex); + + table = &share->table; + spider = share->crd_spider; + conns = spider->conns; + if (spider->search_link_idx < 0) + { + spider->trx = trx; + spider_trx_set_link_idx_for_all(spider); + spider->search_link_idx = spider_conn_first_link_idx(thd, + share->link_statuses, share->access_balances, spider->conn_link_idx, + share->link_count, SPIDER_LINK_STATUS_OK); + } + if (spider->search_link_idx >= 0) + { + DBUG_PRINT("info", + ("spider difftime=%f", + difftime(share->bg_crd_try_time, share->crd_get_time))); + DBUG_PRINT("info", + ("spider bg_crd_interval=%f", share->bg_crd_interval)); + if (difftime(share->bg_crd_try_time, share->crd_get_time) >= + share->bg_crd_interval) + { + if (!conns[spider->search_link_idx]) + { + spider_get_conn(share, spider->search_link_idx, + share->conn_keys[spider->search_link_idx], + spider_global_trx, spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL, + &error_num); + if (conns[spider->search_link_idx]) + { + conns[spider->search_link_idx]->error_mode = 0; + } else { + spider->search_link_idx = -1; + } + } + DBUG_PRINT("info", + ("spider search_link_idx=%d", spider->search_link_idx)); + if (spider->search_link_idx >= 0 && conns[spider->search_link_idx]) + { +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (spider_get_crd(share, spider->search_link_idx, + share->bg_crd_try_time, spider, table, + share->bg_crd_interval, share->bg_crd_mode, + share->bg_crd_sync, + 2)) +#else + if (spider_get_crd(share, spider->search_link_idx, + share->bg_crd_try_time, spider, table, + share->bg_crd_interval, share->bg_crd_mode, + 2)) +#endif + { + spider->search_link_idx = -1; + } + } + } + } + memset(spider->need_mons, 0, sizeof(int) * share->link_count); + pthread_mutex_lock(&thread->mutex); + if (thread->queue_first == thread->queue_last) + { + thread->queue_first = NULL; + thread->queue_last = NULL; + } else { + thread->queue_first = share->crd_next; + share->crd_next->crd_prev = NULL; + share->crd_next = NULL; + } + share->crd_working = FALSE; + share->crd_wait = FALSE; + if (thread->first_free_wait) + { + pthread_cond_signal(&thread->sync_cond); + pthread_cond_wait(&thread->cond, &thread->mutex); + } + } +} + +void spider_table_add_share_to_sts_thread( + SPIDER_SHARE *share +) { + SPIDER_THREAD *spider_thread = share->sts_thread; + DBUG_ENTER("spider_table_add_share_to_sts_thread"); + if ( + !share->sts_wait && + !pthread_mutex_trylock(&spider_thread->mutex) + ) { + if (!share->sts_wait) + { + if (spider_thread->queue_last) + { + DBUG_PRINT("info",("spider add to last")); + share->sts_prev = spider_thread->queue_last; + spider_thread->queue_last->sts_next = share; + } else { + spider_thread->queue_first = share; + } + spider_thread->queue_last = share; + share->sts_wait = TRUE; + + if (spider_thread->thd_wait) + { + pthread_cond_signal(&spider_thread->cond); + } + } + pthread_mutex_unlock(&spider_thread->mutex); + } + DBUG_VOID_RETURN; +} + +void spider_table_add_share_to_crd_thread( + SPIDER_SHARE *share +) { + SPIDER_THREAD *spider_thread = share->crd_thread; + DBUG_ENTER("spider_table_add_share_to_crd_thread"); + if ( + !share->crd_wait && + !pthread_mutex_trylock(&spider_thread->mutex) + ) { + if (!share->crd_wait) + { + if (spider_thread->queue_last) + { + DBUG_PRINT("info",("spider add to last")); + share->crd_prev = spider_thread->queue_last; + spider_thread->queue_last->crd_next = share; + } else { + spider_thread->queue_first = share; + } + spider_thread->queue_last = share; + share->crd_wait = TRUE; + + if (spider_thread->thd_wait) + { + pthread_cond_signal(&spider_thread->cond); + } + } + pthread_mutex_unlock(&spider_thread->mutex); + } + DBUG_VOID_RETURN; +} + +void spider_table_remove_share_from_sts_thread( + SPIDER_SHARE *share +) { + SPIDER_THREAD *spider_thread = share->sts_thread; + DBUG_ENTER("spider_table_remove_share_from_sts_thread"); + if (share->sts_wait) + { + pthread_mutex_lock(&spider_thread->mutex); + if (share->sts_wait) + { + if (share->sts_working) + { + DBUG_PRINT("info",("spider waiting bg sts start")); + spider_thread->first_free_wait = TRUE; + pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex); + spider_thread->first_free_wait = FALSE; + pthread_cond_signal(&spider_thread->cond); + DBUG_PRINT("info",("spider waiting bg sts end")); + } + + if (share->sts_prev) + { + if (share->sts_next) + { + DBUG_PRINT("info",("spider remove middle one")); + share->sts_prev->sts_next = share->sts_next; + share->sts_next->sts_prev = share->sts_prev; + } else { + DBUG_PRINT("info",("spider remove last one")); + share->sts_prev->sts_next = NULL; + spider_thread->queue_last = share->sts_prev; + } + } else if (share->sts_next) { + DBUG_PRINT("info",("spider remove first one")); + share->sts_next->sts_prev = NULL; + spider_thread->queue_first = share->sts_next; + } else { + DBUG_PRINT("info",("spider empty")); + spider_thread->queue_first = NULL; + spider_thread->queue_last = NULL; + } + } + pthread_mutex_unlock(&spider_thread->mutex); + } + DBUG_VOID_RETURN; +} + +void spider_table_remove_share_from_crd_thread( + SPIDER_SHARE *share +) { + SPIDER_THREAD *spider_thread = share->crd_thread; + DBUG_ENTER("spider_table_remove_share_from_crd_thread"); + if (share->crd_wait) + { + pthread_mutex_lock(&spider_thread->mutex); + if (share->crd_wait) + { + if (share->crd_working) + { + DBUG_PRINT("info",("spider waiting bg crd start")); + spider_thread->first_free_wait = TRUE; + pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex); + spider_thread->first_free_wait = FALSE; + pthread_cond_signal(&spider_thread->cond); + DBUG_PRINT("info",("spider waiting bg crd end")); + } + + if (share->crd_prev) + { + if (share->crd_next) + { + DBUG_PRINT("info",("spider remove middle one")); + share->crd_prev->crd_next = share->crd_next; + share->crd_next->crd_prev = share->crd_prev; + } else { + DBUG_PRINT("info",("spider remove last one")); + share->crd_prev->crd_next = NULL; + spider_thread->queue_last = share->crd_prev; + } + } else if (share->crd_next) { + DBUG_PRINT("info",("spider remove first one")); + share->crd_next->crd_prev = NULL; + spider_thread->queue_first = share->crd_next; + } else { + DBUG_PRINT("info",("spider empty")); + spider_thread->queue_first = NULL; + spider_thread->queue_last = NULL; + } + } + pthread_mutex_unlock(&spider_thread->mutex); + } + DBUG_VOID_RETURN; +} +#endif diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h index 6140f5bbdc7..7165c4504f8 100644 --- a/storage/spider/spd_table.h +++ b/storage/spider/spd_table.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2014 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ uchar *spider_tbl_get_key( SPIDER_SHARE *share, @@ -389,11 +389,20 @@ void spider_free_tmp_dbton_handler( TABLE_LIST *spider_get_parent_table_list( ha_spider *spider ); +List<Index_hint> *spider_get_index_hints( + ha_spider *spider + ); st_select_lex *spider_get_select_lex( ha_spider *spider ); +void spider_get_select_limit_from_select_lex( + st_select_lex *select_lex, + longlong *select_limit, + longlong *offset_limit +); + void spider_get_select_limit( ha_spider *spider, st_select_lex **select_lex, @@ -421,6 +430,10 @@ bool spider_check_direct_order_limit( ha_spider *spider ); +int spider_set_direct_limit_offset( + ha_spider* spider + ); + bool spider_check_index_merge( TABLE *table, st_select_lex *select_lex @@ -454,3 +467,55 @@ int spider_discover_table_structure( HA_CREATE_INFO *info ); #endif + +#ifndef WITHOUT_SPIDER_BG_SEARCH +int spider_create_spider_object_for_share( + SPIDER_TRX *trx, + SPIDER_SHARE *share, + ha_spider **spider +); + +void spider_free_spider_object_for_share( + ha_spider **spider +); + +int spider_create_sts_threads( + SPIDER_THREAD *spider_thread +); + +void spider_free_sts_threads( + SPIDER_THREAD *spider_thread +); + +int spider_create_crd_threads( + SPIDER_THREAD *spider_thread +); + +void spider_free_crd_threads( + SPIDER_THREAD *spider_thread +); + +void *spider_table_bg_sts_action( + void *arg +); + +void *spider_table_bg_crd_action( + void *arg +); + +void spider_table_add_share_to_sts_thread( + SPIDER_SHARE *share +); + +void spider_table_add_share_to_crd_thread( + SPIDER_SHARE *share +); + +void spider_table_remove_share_from_sts_thread( + SPIDER_SHARE *share +); + +void spider_table_remove_share_from_crd_thread( + SPIDER_SHARE *share +); +#endif diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index 1a0f34eaa56..179156a0950 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Kentoku Shiba +/* Copyright (C) 2008-2017 Kentoku Shiba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> @@ -504,6 +504,7 @@ int spider_create_trx_alter_table( char **tmp_tgt_ssl_keys; char **tmp_tgt_default_files; char **tmp_tgt_default_groups; + char **tmp_static_link_ids; uint *tmp_server_names_lengths; uint *tmp_tgt_table_names_lengths; uint *tmp_tgt_dbs_lengths; @@ -519,8 +520,10 @@ int spider_create_trx_alter_table( uint *tmp_tgt_ssl_keys_lengths; uint *tmp_tgt_default_files_lengths; uint *tmp_tgt_default_groups_lengths; + uint *tmp_static_link_ids_lengths; long *tmp_tgt_ports; long *tmp_tgt_ssl_vscs; + long *tmp_monitoring_binlog_pos_at_failing; long *tmp_link_statuses; char *tmp_server_names_char; char *tmp_tgt_table_names_char; @@ -537,6 +540,7 @@ int spider_create_trx_alter_table( char *tmp_tgt_ssl_keys_char; char *tmp_tgt_default_files_char; char *tmp_tgt_default_groups_char; + char *tmp_static_link_ids_char; uint old_elements; DBUG_ENTER("spider_create_trx_alter_table"); @@ -562,6 +566,7 @@ int spider_create_trx_alter_table( &tmp_tgt_ssl_keys, sizeof(char *) * share->all_link_count, &tmp_tgt_default_files, sizeof(char *) * share->all_link_count, &tmp_tgt_default_groups, sizeof(char *) * share->all_link_count, + &tmp_static_link_ids, sizeof(char *) * share->all_link_count, &tmp_server_names_lengths, sizeof(uint) * share->all_link_count, &tmp_tgt_table_names_lengths, sizeof(uint) * share->all_link_count, @@ -578,9 +583,12 @@ int spider_create_trx_alter_table( &tmp_tgt_ssl_keys_lengths, sizeof(uint) * share->all_link_count, &tmp_tgt_default_files_lengths, sizeof(uint) * share->all_link_count, &tmp_tgt_default_groups_lengths, sizeof(uint) * share->all_link_count, + &tmp_static_link_ids_lengths, sizeof(uint) * share->all_link_count, &tmp_tgt_ports, sizeof(long) * share->all_link_count, &tmp_tgt_ssl_vscs, sizeof(long) * share->all_link_count, + &tmp_monitoring_binlog_pos_at_failing, + sizeof(long) * share->all_link_count, &tmp_link_statuses, sizeof(long) * share->all_link_count, &tmp_server_names_char, sizeof(char) * @@ -613,6 +621,8 @@ int spider_create_trx_alter_table( (share_alter->tmp_tgt_default_files_charlen + 1), &tmp_tgt_default_groups_char, sizeof(char) * (share_alter->tmp_tgt_default_groups_charlen + 1), + &tmp_static_link_ids_char, sizeof(char) * + (share_alter->tmp_static_link_ids_charlen + 1), NullS)) ) { error_num = HA_ERR_OUT_OF_MEM; @@ -646,9 +656,12 @@ int spider_create_trx_alter_table( alter_table->tmp_tgt_ssl_keys = tmp_tgt_ssl_keys; alter_table->tmp_tgt_default_files = tmp_tgt_default_files; alter_table->tmp_tgt_default_groups = tmp_tgt_default_groups; + alter_table->tmp_static_link_ids = tmp_static_link_ids; alter_table->tmp_tgt_ports = tmp_tgt_ports; alter_table->tmp_tgt_ssl_vscs = tmp_tgt_ssl_vscs; + alter_table->tmp_monitoring_binlog_pos_at_failing = + tmp_monitoring_binlog_pos_at_failing; alter_table->tmp_link_statuses = tmp_link_statuses; alter_table->tmp_server_names_lengths = tmp_server_names_lengths; @@ -666,6 +679,7 @@ int spider_create_trx_alter_table( alter_table->tmp_tgt_ssl_keys_lengths = tmp_tgt_ssl_keys_lengths; alter_table->tmp_tgt_default_files_lengths = tmp_tgt_default_files_lengths; alter_table->tmp_tgt_default_groups_lengths = tmp_tgt_default_groups_lengths; + alter_table->tmp_static_link_ids_lengths = tmp_static_link_ids_lengths; for(roop_count = 0; roop_count < (int) share->all_link_count; roop_count++) { @@ -764,12 +778,25 @@ int spider_create_trx_alter_table( sizeof(char) * share_alter->tmp_tgt_default_groups_lengths[roop_count]); tmp_tgt_default_groups_char += share_alter->tmp_tgt_default_groups_lengths[roop_count] + 1; + + if (share_alter->tmp_static_link_ids[roop_count]) + { + tmp_static_link_ids[roop_count] = tmp_static_link_ids_char; + memcpy(tmp_static_link_ids_char, + share_alter->tmp_static_link_ids[roop_count], + sizeof(char) * share_alter->tmp_static_link_ids_lengths[roop_count]); + tmp_static_link_ids_char += + share_alter->tmp_static_link_ids_lengths[roop_count] + 1; + } } memcpy(tmp_tgt_ports, share_alter->tmp_tgt_ports, sizeof(long) * share->all_link_count); memcpy(tmp_tgt_ssl_vscs, share_alter->tmp_tgt_ssl_vscs, sizeof(long) * share->all_link_count); + memcpy(tmp_monitoring_binlog_pos_at_failing, + share_alter->tmp_monitoring_binlog_pos_at_failing, + sizeof(long) * share->all_link_count); memcpy(tmp_link_statuses, share_alter->tmp_link_statuses, sizeof(long) * share->all_link_count); @@ -805,6 +832,9 @@ int spider_create_trx_alter_table( memcpy(tmp_tgt_default_groups_lengths, share_alter->tmp_tgt_default_groups_lengths, sizeof(uint) * share->all_link_count); + memcpy(tmp_static_link_ids_lengths, + share_alter->tmp_static_link_ids_lengths, + sizeof(uint) * share->all_link_count); alter_table->tmp_server_names_length = share_alter->tmp_server_names_length; @@ -836,10 +866,14 @@ int spider_create_trx_alter_table( share_alter->tmp_tgt_default_files_length; alter_table->tmp_tgt_default_groups_length = share_alter->tmp_tgt_default_groups_length; + alter_table->tmp_static_link_ids_length = + share_alter->tmp_static_link_ids_length; alter_table->tmp_tgt_ports_length = share_alter->tmp_tgt_ports_length; alter_table->tmp_tgt_ssl_vscs_length = share_alter->tmp_tgt_ssl_vscs_length; + alter_table->tmp_monitoring_binlog_pos_at_failing_length = + share_alter->tmp_monitoring_binlog_pos_at_failing_length; alter_table->tmp_link_statuses_length = share_alter->tmp_link_statuses_length; @@ -1035,9 +1069,21 @@ bool spider_cmp_trx_alter_table( cmp2->tmp_tgt_default_groups[roop_count]) ) ) || + ( + cmp1->tmp_static_link_ids[roop_count] != + cmp2->tmp_static_link_ids[roop_count] && + ( + !cmp1->tmp_static_link_ids[roop_count] || + !cmp2->tmp_static_link_ids[roop_count] || + strcmp(cmp1->tmp_static_link_ids[roop_count], + cmp2->tmp_static_link_ids[roop_count]) + ) + ) || cmp1->tmp_tgt_ports[roop_count] != cmp2->tmp_tgt_ports[roop_count] || cmp1->tmp_tgt_ssl_vscs[roop_count] != cmp2->tmp_tgt_ssl_vscs[roop_count] || + cmp1->tmp_monitoring_binlog_pos_at_failing[roop_count] != + cmp2->tmp_monitoring_binlog_pos_at_failing[roop_count] || cmp1->tmp_link_statuses[roop_count] != cmp2->tmp_link_statuses[roop_count] ) @@ -1660,7 +1706,8 @@ int spider_xa_lock( #ifdef SPIDER_XID_USES_xid_cache_iterate if (xid_cache_insert(thd, xid_state)) { - error_num = my_errno; + error_num = (spider_stmt_da_sql_errno(thd) == ER_XAER_DUPID ? + ER_SPIDER_XA_LOCKED_NUM : HA_ERR_OUT_OF_MEM); goto error; } #else @@ -1906,6 +1953,8 @@ int spider_internal_start_trx( } trx->trx_start = TRUE; trx->trx_xa_prepared = FALSE; + trx->updated_in_this_trx = FALSE; + DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE")); } DBUG_PRINT("info",("spider sync_autocommit = %d", sync_autocommit)); @@ -1984,7 +2033,7 @@ int spider_internal_xa_commit( TABLE *table_xa, TABLE *table_xa_member ) { - int error_num, tmp_error_num; + int error_num = 0, tmp_error_num; char xa_key[MAX_KEY_LENGTH]; SPIDER_CONN *conn; uint force_commit = spider_param_force_commit(thd); @@ -1998,72 +2047,75 @@ int spider_internal_xa_commit( bool table_xa_member_opened = FALSE; DBUG_ENTER("spider_internal_xa_commit"); - /* - select - status - from - mysql.spider_xa - where - format_id = xid->format_id and - gtrid_length = xid->gtrid_length and - data = xid->data - */ - if ( - !(table_xa = spider_open_sys_table( - thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, - TRUE, &open_tables_backup, TRUE, &error_num)) - ) - goto error_open_table; - table_xa_opened = TRUE; - spider_store_xa_pk(table_xa, &trx->xid); - if ( - (error_num = spider_check_sys_table(table_xa, xa_key)) - ) { - if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - { - table_xa->file->print_error(error_num, MYF(0)); + if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0) + { + /* + select + status + from + mysql.spider_xa + where + format_id = xid->format_id and + gtrid_length = xid->gtrid_length and + data = xid->data + */ + if ( + !(table_xa = spider_open_sys_table( + thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, + TRUE, &open_tables_backup, TRUE, &error_num)) + ) + goto error_open_table; + table_xa_opened = TRUE; + spider_store_xa_pk(table_xa, &trx->xid); + if ( + (error_num = spider_check_sys_table(table_xa, xa_key)) + ) { + if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) + { + table_xa->file->print_error(error_num, MYF(0)); + goto error; + } + my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR, + MYF(0)); + error_num = ER_SPIDER_XA_NOT_EXISTS_NUM; + goto error; + } + SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); + if ( + force_commit != 2 && + (error_num = spider_check_sys_xa_status( + table_xa, + SPIDER_SYS_XA_PREPARED_STR, + SPIDER_SYS_XA_COMMIT_STR, + NULL, + ER_SPIDER_XA_NOT_PREPARED_NUM, + &mem_root)) + ) { + free_root(&mem_root, MYF(0)); + if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM) + my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0)); goto error; } - my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR, - MYF(0)); - error_num = ER_SPIDER_XA_NOT_EXISTS_NUM; - goto error; - } - SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); - if ( - force_commit != 2 && - (error_num = spider_check_sys_xa_status( - table_xa, - SPIDER_SYS_XA_PREPARED_STR, - SPIDER_SYS_XA_COMMIT_STR, - NULL, - ER_SPIDER_XA_NOT_PREPARED_NUM, - &mem_root)) - ) { free_root(&mem_root, MYF(0)); - if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM) - my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0)); - goto error; - } - free_root(&mem_root, MYF(0)); - /* - update - mysql.spider_xa - set - status = 'COMMIT' - where - format_id = trx->xid.format_id and - gtrid_length = trx->xid.gtrid_length and - data = trx->xid.data - */ - if ( - (error_num = spider_update_xa( - table_xa, &trx->xid, SPIDER_SYS_XA_COMMIT_STR)) - ) - goto error; - spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); - table_xa_opened = FALSE; + /* + update + mysql.spider_xa + set + status = 'COMMIT' + where + format_id = trx->xid.format_id and + gtrid_length = trx->xid.gtrid_length and + data = trx->xid.data + */ + if ( + (error_num = spider_update_xa( + table_xa, &trx->xid, SPIDER_SYS_XA_COMMIT_STR)) + ) + goto error; + spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); + table_xa_opened = FALSE; + } SPIDER_BACKUP_DASTATUS; if ((conn = spider_tree_first(trx->join_trx_top))) @@ -2101,46 +2153,49 @@ int spider_internal_xa_commit( if (error_num) goto error_in_commit; - /* - delete from - mysql.spider_xa_member - where - format_id = xid->format_id and - gtrid_length = xid->gtrid_length and - data = xid->data - */ - if ( - !(table_xa_member = spider_open_sys_table( - thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR, - SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE, - &error_num)) - ) - goto error_open_table; - table_xa_member_opened = TRUE; - if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid))) - goto error; - spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE); - table_xa_member_opened = FALSE; + if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0) + { + /* + delete from + mysql.spider_xa_member + where + format_id = xid->format_id and + gtrid_length = xid->gtrid_length and + data = xid->data + */ + if ( + !(table_xa_member = spider_open_sys_table( + thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR, + SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE, + &error_num)) + ) + goto error_open_table; + table_xa_member_opened = TRUE; + if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid))) + goto error; + spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE); + table_xa_member_opened = FALSE; - /* - delete from - mysql.spider_xa - where - format_id = xid->format_id and - gtrid_length = xid->gtrid_length and - data = xid->data - */ - if ( - !(table_xa = spider_open_sys_table( - thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, - TRUE, &open_tables_backup, TRUE, &error_num)) - ) - goto error_open_table; - table_xa_opened = TRUE; - if ((error_num = spider_delete_xa(table_xa, &trx->xid))) - goto error; - spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); - table_xa_opened = FALSE; + /* + delete from + mysql.spider_xa + where + format_id = xid->format_id and + gtrid_length = xid->gtrid_length and + data = xid->data + */ + if ( + !(table_xa = spider_open_sys_table( + thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, + TRUE, &open_tables_backup, TRUE, &error_num)) + ) + goto error_open_table; + table_xa_opened = TRUE; + if ((error_num = spider_delete_xa(table_xa, &trx->xid))) + goto error; + spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); + table_xa_opened = FALSE; + } spider_xa_unlock(&trx->internal_xid_state); trx->internal_xid_state.xa_state = XA_NOTR; DBUG_RETURN(0); @@ -2177,8 +2232,13 @@ int spider_internal_xa_rollback( bool table_xa_member_opened = FALSE; DBUG_ENTER("spider_internal_xa_rollback"); - if (trx->trx_xa_prepared) - { + if ( + trx->trx_xa_prepared && + ( + trx->updated_in_this_trx || + spider_param_xa_register_mode(thd) == 0 + ) + ) { /* select status @@ -2327,7 +2387,11 @@ int spider_internal_xa_rollback( if ( trx->trx_xa_prepared && - !server_lost + !server_lost && + ( + trx->updated_in_this_trx || + spider_param_xa_register_mode(thd) == 0 + ) ) { /* delete from @@ -2404,35 +2468,38 @@ int spider_internal_xa_prepare( bool table_xa_opened = FALSE; bool table_xa_member_opened = FALSE; DBUG_ENTER("spider_internal_xa_prepare"); - /* - insert into mysql.spider_xa - (format_id, gtrid_length, bqual_length, data, status) values - (trx->xid.format_id, trx->xid.gtrid_length, trx->xid.bqual_length, - trx->xid.data, 'NOT YET') - */ - if ( - !(table_xa = spider_open_sys_table( - thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, - TRUE, &open_tables_backup, TRUE, &error_num)) - ) - goto error_open_table; - table_xa_opened = TRUE; - if ( - (error_num = spider_insert_xa( - table_xa, &trx->xid, SPIDER_SYS_XA_NOT_YET_STR)) - ) - goto error; - spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); - table_xa_opened = FALSE; + if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0) + { + /* + insert into mysql.spider_xa + (format_id, gtrid_length, bqual_length, data, status) values + (trx->xid.format_id, trx->xid.gtrid_length, trx->xid.bqual_length, + trx->xid.data, 'NOT YET') + */ + if ( + !(table_xa = spider_open_sys_table( + thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, + TRUE, &open_tables_backup, TRUE, &error_num)) + ) + goto error_open_table; + table_xa_opened = TRUE; + if ( + (error_num = spider_insert_xa( + table_xa, &trx->xid, SPIDER_SYS_XA_NOT_YET_STR)) + ) + goto error; + spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); + table_xa_opened = FALSE; - if ( - !(table_xa_member = spider_open_sys_table( - thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR, - SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE, - &error_num)) - ) - goto error_open_table; - table_xa_member_opened = TRUE; + if ( + !(table_xa_member = spider_open_sys_table( + thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR, + SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE, + &error_num)) + ) + goto error_open_table; + table_xa_member_opened = TRUE; + } SPIDER_BACKUP_DASTATUS; if ((conn = spider_tree_first(trx->join_trx_top))) { @@ -2458,26 +2525,29 @@ int spider_internal_xa_prepare( } conn->join_trx = 0; } else { - /* - insert into mysql.spider_xa_member - (format_id, gtrid_length, bqual_length, data, - scheme, host, port, socket, username, password) values - (trx->xid.format_id, trx->xid.gtrid_length, - trx->xid.bqual_length, trx->xid.data, - conn->tgt_wrapper, - conn->tgt_host, - conn->tgt_port, - conn->tgt_socket, - conn->tgt_username, - conn->tgt_password) - */ - if ( - (error_num = spider_insert_xa_member( - table_xa_member, &trx->xid, conn)) - ) { - SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM; - if (error_num) - goto error; + if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0) + { + /* + insert into mysql.spider_xa_member + (format_id, gtrid_length, bqual_length, data, + scheme, host, port, socket, username, password) values + (trx->xid.format_id, trx->xid.gtrid_length, + trx->xid.bqual_length, trx->xid.data, + conn->tgt_wrapper, + conn->tgt_host, + conn->tgt_port, + conn->tgt_socket, + conn->tgt_username, + conn->tgt_password) + */ + if ( + (error_num = spider_insert_xa_member( + table_xa_member, &trx->xid, conn)) + ) { + SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM; + if (error_num) + goto error; + } } if ((error_num = spider_db_xa_end(conn, &trx->xid))) @@ -2515,33 +2585,36 @@ int spider_internal_xa_prepare( trx->join_trx_top = NULL; */ } - spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE); - table_xa_member_opened = FALSE; + if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0) + { + spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE); + table_xa_member_opened = FALSE; - /* - update - mysql.spider_xa - set - status = 'PREPARED' - where - format_id = trx->xid.format_id and - gtrid_length = trx->xid.gtrid_length and - data = trx->xid.data - */ - if ( - !(table_xa = spider_open_sys_table( - thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, - TRUE, &open_tables_backup, TRUE, &error_num)) - ) - goto error_open_table; - table_xa_opened = TRUE; - if ( - (error_num = spider_update_xa( - table_xa, &trx->xid, SPIDER_SYS_XA_PREPARED_STR)) - ) - goto error; - spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); - table_xa_opened = FALSE; + /* + update + mysql.spider_xa + set + status = 'PREPARED' + where + format_id = trx->xid.format_id and + gtrid_length = trx->xid.gtrid_length and + data = trx->xid.data + */ + if ( + !(table_xa = spider_open_sys_table( + thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN, + TRUE, &open_tables_backup, TRUE, &error_num)) + ) + goto error_open_table; + table_xa_opened = TRUE; + if ( + (error_num = spider_update_xa( + table_xa, &trx->xid, SPIDER_SYS_XA_PREPARED_STR)) + ) + goto error; + spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); + table_xa_opened = FALSE; + } if (internal_xa) trx->internal_xid_state.xa_state = XA_PREPARED; DBUG_RETURN(0); @@ -2685,8 +2758,8 @@ int spider_initinal_xa_recover( FALSE, open_tables_backup, TRUE, &error_num)) ) goto error_open_table; - init_read_record(read_record, thd, table_xa, NULL, NULL, TRUE, FALSE, - FALSE); + SPIDER_init_read_record(read_record, thd, table_xa, NULL, NULL, TRUE, + FALSE, FALSE); } SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); while ((!(read_record->read_record())) && cnt < (int) len) @@ -3371,7 +3444,9 @@ int spider_commit( } } trx->trx_start = FALSE; + trx->updated_in_this_trx = FALSE; DBUG_PRINT("info",("spider trx->trx_start=FALSE")); + DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE")); } spider_reuse_trx_ha(trx); spider_free_trx_conn(trx, FALSE); @@ -3442,7 +3517,9 @@ int spider_rollback( } } trx->trx_start = FALSE; + trx->updated_in_this_trx = FALSE; DBUG_PRINT("info",("spider trx->trx_start=FALSE")); + DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE")); } spider_reuse_trx_ha(trx); spider_free_trx_conn(trx, FALSE); @@ -3713,21 +3790,14 @@ int spider_check_trx_and_get_conn( { TABLE *table = spider->get_table(); TABLE_SHARE *table_share = table->s; -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - char *db, *table_name; - if (!(db = (char *) - spider_bulk_malloc(spider_current_trx, 57, MYF(MY_WME), - &db, table_share->db.length + 1, - &table_name, table_share->table_name.length + 1, - NullS)) - ) { - my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); + char *db = (char *) my_alloca( + table_share->db.length + 1 + table_share->table_name.length + 1); + if (!db) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } -#else - char db[table_share->db.length + 1], - table_name[table_share->table_name.length + 1]; -#endif + char *table_name = db + table_share->db.length + 1; memcpy(db, table_share->db.str, table_share->db.length); db[table_share->db.length] = '\0'; memcpy(table_name, table_share->table_name.str, @@ -3735,10 +3805,12 @@ int spider_check_trx_and_get_conn( table_name[table_share->table_name.length] = '\0'; my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM, ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(trx, db, MYF(MY_WME)); -#endif + my_afree(db); DBUG_RETURN(ER_SPIDER_ALL_LINKS_FAILED_NUM); + } else if (search_link_idx == -2) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); } spider->search_link_idx = search_link_idx; spider->search_link_query_id = thd->query_id; @@ -3804,6 +3876,7 @@ int spider_check_trx_and_get_conn( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3846,6 +3919,7 @@ int spider_check_trx_and_get_conn( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3872,21 +3946,14 @@ int spider_check_trx_and_get_conn( { TABLE *table = spider->get_table(); TABLE_SHARE *table_share = table->s; -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - char *db, *table_name; - if (!(db = (char *) - spider_bulk_malloc(spider_current_trx, 57, MYF(MY_WME), - &db, table_share->db.length + 1, - &table_name, table_share->table_name.length + 1, - NullS)) - ) { - my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); + char *db = (char *) my_alloca( + table_share->db.length + 1 + table_share->table_name.length + 1); + if (!db) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } -#else - char db[table_share->db.length + 1], - table_name[table_share->table_name.length + 1]; -#endif + char *table_name = db + table_share->db.length + 1; memcpy(db, table_share->db.str, table_share->db.length); db[table_share->db.length] = '\0'; memcpy(table_name, table_share->table_name.str, @@ -3894,9 +3961,7 @@ int spider_check_trx_and_get_conn( table_name[table_share->table_name.length] = '\0'; my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM, ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(trx, db, MYF(MY_WME)); -#endif + my_afree(db); DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM); } } else { @@ -3950,6 +4015,7 @@ int spider_check_trx_and_get_conn( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -3993,6 +4059,7 @@ int spider_check_trx_and_get_conn( trx, trx->thd, share, + roop_count, (uint32) share->monitoring_sid[roop_count], share->table_name, share->table_name_length, @@ -4018,21 +4085,14 @@ int spider_check_trx_and_get_conn( { TABLE *table = spider->get_table(); TABLE_SHARE *table_share = table->s; -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - char *db, *table_name; - if (!(db = (char *) - spider_bulk_malloc(spider_current_trx, 57, MYF(MY_WME), - &db, table_share->db.length + 1, - &table_name, table_share->table_name.length + 1, - NullS)) - ) { - my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); + char *db = (char *) my_alloca( + table_share->db.length + 1 + table_share->table_name.length + 1); + if (!db) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } -#else - char db[table_share->db.length + 1], - table_name[table_share->table_name.length + 1]; -#endif + char *table_name = db + table_share->db.length + 1; memcpy(db, table_share->db.str, table_share->db.length); db[table_share->db.length] = '\0'; memcpy(table_name, table_share->table_name.str, @@ -4040,9 +4100,7 @@ int spider_check_trx_and_get_conn( table_name[table_share->table_name.length] = '\0'; my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM, ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name); -#if defined(_MSC_VER) || defined(__SUNPRO_CC) - spider_free(trx, db, MYF(MY_WME)); -#endif + my_afree(db); DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM); } } @@ -4057,7 +4115,7 @@ THD *spider_create_tmp_thd() { THD *thd; DBUG_ENTER("spider_create_tmp_thd"); - if (!(thd = new THD(0))) + if (!(thd = SPIDER_new_THD((my_thread_id) 0))) DBUG_RETURN(NULL); #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 thd->killed = NOT_KILLED; @@ -4068,6 +4126,10 @@ THD *spider_create_tmp_thd() thd->locked_tables = FALSE; #endif thd->proc_info = ""; +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100200 +#else + thd->thread_id = thd->variables.pseudo_thread_id = 0; +#endif thd->thread_stack = (char*) &thd; if (thd->store_globals()) DBUG_RETURN(NULL); diff --git a/storage/spider/spd_trx.h b/storage/spider/spd_trx.h index b4abecf457f..3f3ca7fabed 100644 --- a/storage/spider/spd_trx.h +++ b/storage/spider/spd_trx.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ int spider_free_trx_conn( SPIDER_TRX *trx, diff --git a/storage/spider/spd_udf.cc b/storage/spider/spd_udf.cc index 8381121aaab..17498fbd8de 100644 --- a/storage/spider/spd_udf.cc +++ b/storage/spider/spd_udf.cc @@ -11,10 +11,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MYSQL_SERVER 1 #include <my_global.h> +#include "spd_environ.h" #include "mysql.h" #include "spd_udf.h" diff --git a/storage/spider/spd_udf.h b/storage/spider/spd_udf.h index 30a2d6699d1..0b20a10393e 100644 --- a/storage/spider/spd_udf.h +++ b/storage/spider/spd_udf.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ long long spider_direct_sql_body( UDF_INIT *initid, |