mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-04 04:46:15 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			9239 lines
		
	
	
	
		
			316 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			9239 lines
		
	
	
	
		
			316 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* Copyright (C) 2008-2020 Kentoku Shiba
 | 
						|
   Copyright (C) 2019-2022 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
 | 
						|
  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
 | 
						|
 | 
						|
#define MYSQL_SERVER 1
 | 
						|
#include <my_global.h>
 | 
						|
#include "mysql_version.h"
 | 
						|
#include "sql_priv.h"
 | 
						|
#include "probes_mysql.h"
 | 
						|
#include "my_getopt.h"
 | 
						|
#include "sql_class.h"
 | 
						|
#include "sql_partition.h"
 | 
						|
#include "sql_servers.h"
 | 
						|
#include "sql_select.h"
 | 
						|
#include "tztime.h"
 | 
						|
#include "sql_parse.h"
 | 
						|
#include "create_options.h"
 | 
						|
#include "spd_err.h"
 | 
						|
#include "spd_param.h"
 | 
						|
#include "spd_db_include.h"
 | 
						|
#include "spd_include.h"
 | 
						|
#include "spd_sys_table.h"
 | 
						|
#include "ha_spider.h"
 | 
						|
#include "spd_trx.h"
 | 
						|
#include "spd_db_conn.h"
 | 
						|
#include "spd_table.h"
 | 
						|
#include "spd_conn.h"
 | 
						|
#include "spd_ping_table.h"
 | 
						|
#include "spd_direct_sql.h"
 | 
						|
#include "spd_malloc.h"
 | 
						|
#include "spd_group_by_handler.h"
 | 
						|
#include "spd_init_query.h"
 | 
						|
 | 
						|
/* Background thread management */
 | 
						|
#ifdef SPIDER_HAS_NEXT_THREAD_ID
 | 
						|
#define SPIDER_set_next_thread_id(A)
 | 
						|
MYSQL_THD create_thd();
 | 
						|
void destroy_thd(MYSQL_THD thd);
 | 
						|
#else
 | 
						|
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);
 | 
						|
}
 | 
						|
MYSQL_THD create_thd()
 | 
						|
{
 | 
						|
  THD *thd = SPIDER_new_THD(next_thread_id());
 | 
						|
  if (thd)
 | 
						|
  {
 | 
						|
    thd->thread_stack = (char*) &thd;
 | 
						|
    thd->store_globals();
 | 
						|
    thd->set_command(COM_DAEMON);
 | 
						|
    thd->security_ctx->host_or_ip = "";
 | 
						|
  }
 | 
						|
  return thd;
 | 
						|
}
 | 
						|
void destroy_thd(MYSQL_THD thd)
 | 
						|
{
 | 
						|
  delete thd;
 | 
						|
}
 | 
						|
#endif
 | 
						|
inline MYSQL_THD spider_create_sys_thd(SPIDER_THREAD *thread)
 | 
						|
{
 | 
						|
  THD *thd = create_thd();
 | 
						|
  if (thd)
 | 
						|
  {
 | 
						|
    SPIDER_set_next_thread_id(thd);
 | 
						|
    thd->mysys_var->current_cond = &thread->cond;
 | 
						|
    thd->mysys_var->current_mutex = &thread->mutex;
 | 
						|
  }
 | 
						|
  return thd;
 | 
						|
}
 | 
						|
inline void spider_destroy_sys_thd(MYSQL_THD thd)
 | 
						|
{
 | 
						|
  destroy_thd(thd);
 | 
						|
}
 | 
						|
inline MYSQL_THD spider_create_thd()
 | 
						|
{
 | 
						|
  THD *thd;
 | 
						|
  my_thread_init();
 | 
						|
  if (!(thd = new THD(next_thread_id())))
 | 
						|
    my_thread_end();
 | 
						|
  else
 | 
						|
  {
 | 
						|
#ifdef HAVE_PSI_INTERFACE
 | 
						|
    mysql_thread_set_psi_id(thd->thread_id);
 | 
						|
#endif
 | 
						|
    thd->thread_stack = (char *) &thd;
 | 
						|
    thd->store_globals();
 | 
						|
  }
 | 
						|
  return thd;
 | 
						|
}
 | 
						|
inline void spider_destroy_thd(MYSQL_THD thd)
 | 
						|
{
 | 
						|
  delete thd;
 | 
						|
}
 | 
						|
 | 
						|
struct charset_info_st *spd_charset_utf8mb3_bin;
 | 
						|
const char **spd_defaults_extra_file;
 | 
						|
const char **spd_defaults_file;
 | 
						|
const char **spd_mysqld_unix_port;
 | 
						|
uint *spd_mysqld_port;
 | 
						|
bool volatile *spd_abort_loop;
 | 
						|
Time_zone *spd_tz_system;
 | 
						|
extern long spider_conn_mutex_id;
 | 
						|
handlerton *spider_hton_ptr;
 | 
						|
/** All `SPIDER_DBTON`s */
 | 
						|
SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
 | 
						|
extern SPIDER_DBTON spider_dbton_mysql;
 | 
						|
extern SPIDER_DBTON spider_dbton_mariadb;
 | 
						|
SPIDER_THREAD *spider_table_sts_thread;
 | 
						|
SPIDER_THREAD *spider_table_crd_thread;
 | 
						|
extern volatile ulonglong spider_mon_table_cache_version;
 | 
						|
extern volatile ulonglong spider_mon_table_cache_version_req;
 | 
						|
extern ulonglong spider_conn_id;
 | 
						|
extern Time_zone *UTC;
 | 
						|
extern ulonglong spider_thread_id;
 | 
						|
 | 
						|
#ifdef HAVE_PSI_INTERFACE
 | 
						|
PSI_mutex_key spd_key_mutex_tbl;
 | 
						|
PSI_mutex_key spd_key_mutex_init_error_tbl;
 | 
						|
PSI_mutex_key spd_key_mutex_wide_share;
 | 
						|
PSI_mutex_key spd_key_mutex_lgtm_tblhnd_share;
 | 
						|
PSI_mutex_key spd_key_mutex_conn;
 | 
						|
PSI_mutex_key spd_key_mutex_open_conn;
 | 
						|
PSI_mutex_key spd_key_mutex_allocated_thds;
 | 
						|
PSI_mutex_key spd_key_mutex_mon_table_cache;
 | 
						|
PSI_mutex_key spd_key_mutex_udf_table_mon;
 | 
						|
PSI_mutex_key spd_key_mutex_mta_conn;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_conn_chain;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_conn_sync;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_conn;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_job_stack;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_mon;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_direct_sql;
 | 
						|
PSI_mutex_key spd_key_mutex_mon_list_caller;
 | 
						|
PSI_mutex_key spd_key_mutex_mon_list_receptor;
 | 
						|
PSI_mutex_key spd_key_mutex_mon_list_monitor;
 | 
						|
PSI_mutex_key spd_key_mutex_mon_list_update_status;
 | 
						|
PSI_mutex_key spd_key_mutex_share;
 | 
						|
PSI_mutex_key spd_key_mutex_share_sts;
 | 
						|
PSI_mutex_key spd_key_mutex_share_crd;
 | 
						|
PSI_mutex_key spd_key_mutex_share_auto_increment;
 | 
						|
PSI_mutex_key spd_key_mutex_wide_share_sts;
 | 
						|
PSI_mutex_key spd_key_mutex_wide_share_crd;
 | 
						|
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;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_stss;
 | 
						|
PSI_mutex_key spd_key_mutex_bg_crds;
 | 
						|
PSI_mutex_key spd_key_mutex_conn_loop_check;
 | 
						|
 | 
						|
static PSI_mutex_info all_spider_mutexes[]=
 | 
						|
{
 | 
						|
  { &spd_key_mutex_tbl, "tbl", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_init_error_tbl, "init_error_tbl", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_wide_share, "wide_share", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_lgtm_tblhnd_share, "lgtm_tblhnd_share", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_conn, "conn", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_open_conn, "open_conn", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_allocated_thds, "allocated_thds", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_mon_table_cache, "mon_table_cache", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_udf_table_mon, "udf_table_mon", PSI_FLAG_GLOBAL},
 | 
						|
  { &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},
 | 
						|
  { &spd_key_mutex_bg_stss, "bg_stss", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_bg_crds, "bg_crds", PSI_FLAG_GLOBAL},
 | 
						|
  { &spd_key_mutex_conn_i, "conn_i", 0},
 | 
						|
  { &spd_key_mutex_mta_conn, "mta_conn", 0},
 | 
						|
  { &spd_key_mutex_bg_conn_chain, "bg_conn_chain", 0},
 | 
						|
  { &spd_key_mutex_bg_conn_sync, "bg_conn_sync", 0},
 | 
						|
  { &spd_key_mutex_bg_conn, "bg_conn", 0},
 | 
						|
  { &spd_key_mutex_bg_job_stack, "bg_job_stack", 0},
 | 
						|
  { &spd_key_mutex_bg_mon, "bg_mon", 0},
 | 
						|
  { &spd_key_mutex_bg_direct_sql, "bg_direct_sql", 0},
 | 
						|
  { &spd_key_mutex_mon_list_caller, "mon_list_caller", 0},
 | 
						|
  { &spd_key_mutex_mon_list_receptor, "mon_list_receptor", 0},
 | 
						|
  { &spd_key_mutex_mon_list_monitor, "mon_list_monitor", 0},
 | 
						|
  { &spd_key_mutex_mon_list_update_status, "mon_list_update_status", 0},
 | 
						|
  { &spd_key_mutex_share, "share", 0},
 | 
						|
  { &spd_key_mutex_share_sts, "share_sts", 0},
 | 
						|
  { &spd_key_mutex_share_crd, "share_crd", 0},
 | 
						|
  { &spd_key_mutex_share_auto_increment, "share_auto_increment", 0},
 | 
						|
  { &spd_key_mutex_wide_share_sts, "wide_share_sts", 0},
 | 
						|
  { &spd_key_mutex_wide_share_crd, "wide_share_crd", 0},
 | 
						|
  { &spd_key_mutex_udf_table, "udf_table", 0},
 | 
						|
  { &spd_key_mutex_conn_loop_check, "conn_loop_check", 0},
 | 
						|
};
 | 
						|
 | 
						|
PSI_cond_key spd_key_cond_bg_conn_sync;
 | 
						|
PSI_cond_key spd_key_cond_bg_conn;
 | 
						|
PSI_cond_key spd_key_cond_bg_sts;
 | 
						|
PSI_cond_key spd_key_cond_bg_sts_sync;
 | 
						|
PSI_cond_key spd_key_cond_bg_crd;
 | 
						|
PSI_cond_key spd_key_cond_bg_crd_sync;
 | 
						|
PSI_cond_key spd_key_cond_bg_mon;
 | 
						|
PSI_cond_key spd_key_cond_bg_mon_sleep;
 | 
						|
PSI_cond_key spd_key_cond_bg_direct_sql;
 | 
						|
PSI_cond_key spd_key_cond_udf_table_mon;
 | 
						|
PSI_cond_key spd_key_cond_conn_i;
 | 
						|
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;
 | 
						|
 | 
						|
static PSI_cond_info all_spider_conds[] = {
 | 
						|
  {&spd_key_cond_bg_conn_sync, "bg_conn_sync", 0},
 | 
						|
  {&spd_key_cond_bg_conn, "bg_conn", 0},
 | 
						|
  {&spd_key_cond_bg_sts, "bg_sts", 0},
 | 
						|
  {&spd_key_cond_bg_sts_sync, "bg_sts_sync", 0},
 | 
						|
  {&spd_key_cond_bg_crd, "bg_crd", 0},
 | 
						|
  {&spd_key_cond_bg_crd_sync, "bg_crd_sync", 0},
 | 
						|
  {&spd_key_cond_bg_mon, "bg_mon", 0},
 | 
						|
  {&spd_key_cond_bg_mon_sleep, "bg_mon_sleep", 0},
 | 
						|
  {&spd_key_cond_bg_direct_sql, "bg_direct_sql", 0},
 | 
						|
  {&spd_key_cond_udf_table_mon, "udf_table_mon", 0},
 | 
						|
  {&spd_key_cond_conn_i, "conn_i", 0},
 | 
						|
  {&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},
 | 
						|
};
 | 
						|
 | 
						|
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;
 | 
						|
 | 
						|
static PSI_thread_info all_spider_threads[] = {
 | 
						|
  {&spd_key_thd_bg, "bg", 0},
 | 
						|
  {&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
 | 
						|
 | 
						|
/*
 | 
						|
  The spider table options. All fields are strings, with NULLness
 | 
						|
  indicating unspecified by the user.
 | 
						|
*/
 | 
						|
struct ha_table_option_struct
 | 
						|
{
 | 
						|
  char *auto_increment_mode;
 | 
						|
  char *bgs_mode;
 | 
						|
  char *bulk_size;
 | 
						|
  char *bulk_update_size;
 | 
						|
  char *connect_timeout;
 | 
						|
  char *database;
 | 
						|
  char *default_file;
 | 
						|
  char *default_group;
 | 
						|
  char *delete_all_rows_type;
 | 
						|
  char *driver;
 | 
						|
  char *dsn;
 | 
						|
  char *filedsn;
 | 
						|
  char *force_bulk_delete;
 | 
						|
  char *force_bulk_update;
 | 
						|
  char *host;
 | 
						|
  char *idx;
 | 
						|
  char *multi_split_read;
 | 
						|
  char *net_read_timeout;
 | 
						|
  char *net_write_timeout;
 | 
						|
  char *password;
 | 
						|
  char *port;
 | 
						|
  char *priority;
 | 
						|
  char *query_cache;
 | 
						|
  char *query_cache_sync;
 | 
						|
  char *read_only;
 | 
						|
  char *server;
 | 
						|
  char *skip_parallel_search;
 | 
						|
  char *socket;
 | 
						|
  char *ssl_capath;
 | 
						|
  char *ssl_ca;
 | 
						|
  char *ssl_cert;
 | 
						|
  char *ssl_cipher;
 | 
						|
  char *ssl_key;
 | 
						|
  char *ssl_vsc;
 | 
						|
  char *table;
 | 
						|
  char *table_count_mode;
 | 
						|
  char *username;
 | 
						|
  char *use_pushdown_udf;
 | 
						|
  char *wrapper;
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
  The spider table options with the names used in statements.
 | 
						|
*/
 | 
						|
ha_create_table_option spider_table_option_list[]= {
 | 
						|
  HA_TOPTION_STRING("AUTO_INCREMENT_MODE", auto_increment_mode),
 | 
						|
  HA_TOPTION_STRING("BGS_MODE", bgs_mode),
 | 
						|
  HA_TOPTION_STRING("BULK_SIZE", bulk_size),
 | 
						|
  HA_TOPTION_STRING("BULK_UPDATE_SIZE", bulk_update_size),
 | 
						|
  HA_TOPTION_STRING("CONNECT_TIMEOUT", connect_timeout),
 | 
						|
  HA_TOPTION_STRING("REMOTE_DATABASE", database),
 | 
						|
  HA_TOPTION_STRING("DEFAULT_FILE", default_file),
 | 
						|
  HA_TOPTION_STRING("DEFAULT_GROUP", default_group),
 | 
						|
  HA_TOPTION_STRING("DELETE_ALL_ROWS_TYPE", delete_all_rows_type),
 | 
						|
  HA_TOPTION_STRING("DRIVER", driver),
 | 
						|
  HA_TOPTION_STRING("DSN", dsn),
 | 
						|
  HA_TOPTION_STRING("FILEDSN", filedsn),
 | 
						|
  HA_TOPTION_STRING("FORCE_BULK_DELETE", force_bulk_delete),
 | 
						|
  HA_TOPTION_STRING("FORCE_BULK_UPDATE", force_bulk_update),
 | 
						|
  HA_TOPTION_STRING("REMOTE_HOST", host),
 | 
						|
  HA_TOPTION_STRING("IDX", idx),
 | 
						|
  HA_TOPTION_STRING("MULTI_SPLIT_READ", multi_split_read),
 | 
						|
  HA_TOPTION_STRING("NET_READ_TIMEOUT", net_read_timeout),
 | 
						|
  HA_TOPTION_STRING("NET_WRITE_TIMEOUT", net_write_timeout),
 | 
						|
  HA_TOPTION_STRING("REMOTE_PASSWORD", password),
 | 
						|
  HA_TOPTION_STRING("REMOTE_PORT", port),
 | 
						|
  HA_TOPTION_STRING("PRIORITY", priority),
 | 
						|
  HA_TOPTION_STRING("QUERY_CACHE", query_cache),
 | 
						|
  HA_TOPTION_STRING("QUERY_CACHE_SYNC", query_cache_sync),
 | 
						|
  HA_TOPTION_STRING("READ_ONLY", read_only),
 | 
						|
  HA_TOPTION_STRING("REMOTE_SERVER", server),
 | 
						|
  HA_TOPTION_STRING("SKIP_PARALLEL_SEARCH", skip_parallel_search),
 | 
						|
  HA_TOPTION_STRING("REMOTE_SOCKET", socket),
 | 
						|
  HA_TOPTION_STRING("SSL_CAPATH", ssl_capath),
 | 
						|
  HA_TOPTION_STRING("SSL_CA", ssl_ca),
 | 
						|
  HA_TOPTION_STRING("SSL_CERT", ssl_cert),
 | 
						|
  HA_TOPTION_STRING("SSL_CIPHER", ssl_cipher),
 | 
						|
  HA_TOPTION_STRING("SSL_KEY", ssl_key),
 | 
						|
  HA_TOPTION_STRING("SSL_VSC", ssl_vsc),
 | 
						|
  HA_TOPTION_STRING("REMOTE_TABLE", table),
 | 
						|
  HA_TOPTION_STRING("TABLE_COUNT_MODE", table_count_mode),
 | 
						|
  HA_TOPTION_STRING("REMOTE_USERNAME", username),
 | 
						|
  HA_TOPTION_STRING("USE_PUSHDOWN_UDF", use_pushdown_udf),
 | 
						|
  HA_TOPTION_STRING("WRAPPER", wrapper),
 | 
						|
  HA_TOPTION_END
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Determines how to populate sts (stat) / crd (cardinality) of a
 | 
						|
  spider share
 | 
						|
*/
 | 
						|
enum ha_sts_crd_get_type
 | 
						|
{
 | 
						|
  HA_GET_COPY = 0,              /* Get by copying from wide_share */
 | 
						|
  HA_GET_FETCH = 1,             /* Get by executing a sql query */
 | 
						|
  HA_GET_AFTER_LOCK = 2,        /* Get by executing a sql query after
 | 
						|
                                locking wide_share->sts_mutex. */
 | 
						|
  HA_GET_AFTER_TRYLOCK = 3      /* Get by executing a sql query after
 | 
						|
                                trylocking wide_share->sts_mutex. */
 | 
						|
};
 | 
						|
 | 
						|
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;
 | 
						|
extern ulong spider_open_connections_line_no;
 | 
						|
extern pthread_mutex_t spider_conn_mutex;
 | 
						|
extern HASH *spider_udf_table_mon_list_hash;
 | 
						|
extern uint spider_udf_table_mon_list_hash_id;
 | 
						|
extern const char *spider_udf_table_mon_list_hash_func_name;
 | 
						|
extern const char *spider_udf_table_mon_list_hash_file_name;
 | 
						|
extern ulong spider_udf_table_mon_list_hash_line_no;
 | 
						|
extern pthread_mutex_t *spider_udf_table_mon_mutexes;
 | 
						|
extern pthread_cond_t *spider_udf_table_mon_conds;
 | 
						|
extern pthread_mutex_t spider_open_conn_mutex;
 | 
						|
extern pthread_mutex_t spider_mon_table_cache_mutex;
 | 
						|
extern DYNAMIC_ARRAY spider_mon_table_cache;
 | 
						|
extern uint spider_mon_table_cache_id;
 | 
						|
extern const char *spider_mon_table_cache_func_name;
 | 
						|
extern const char *spider_mon_table_cache_file_name;
 | 
						|
extern ulong spider_mon_table_cache_line_no;
 | 
						|
 | 
						|
HASH spider_open_tables;
 | 
						|
uint spider_open_tables_id;
 | 
						|
const char *spider_open_tables_func_name;
 | 
						|
const char *spider_open_tables_file_name;
 | 
						|
ulong spider_open_tables_line_no;
 | 
						|
pthread_mutex_t spider_tbl_mutex;
 | 
						|
/** All the `SPIDER_INIT_ERROR_TABLE`s */
 | 
						|
HASH spider_init_error_tables;
 | 
						|
uint spider_init_error_tables_id;
 | 
						|
const char *spider_init_error_tables_func_name;
 | 
						|
const char *spider_init_error_tables_file_name;
 | 
						|
ulong spider_init_error_tables_line_no;
 | 
						|
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;
 | 
						|
 | 
						|
HASH spider_open_wide_share;
 | 
						|
uint spider_open_wide_share_id;
 | 
						|
const char *spider_open_wide_share_func_name;
 | 
						|
const char *spider_open_wide_share_file_name;
 | 
						|
ulong spider_open_wide_share_line_no;
 | 
						|
pthread_mutex_t spider_wide_share_mutex;
 | 
						|
 | 
						|
HASH spider_lgtm_tblhnd_share_hash;
 | 
						|
uint spider_lgtm_tblhnd_share_hash_id;
 | 
						|
const char *spider_lgtm_tblhnd_share_hash_func_name;
 | 
						|
const char *spider_lgtm_tblhnd_share_hash_file_name;
 | 
						|
ulong spider_lgtm_tblhnd_share_hash_line_no;
 | 
						|
pthread_mutex_t spider_lgtm_tblhnd_share_mutex;
 | 
						|
 | 
						|
HASH spider_allocated_thds;
 | 
						|
uint spider_allocated_thds_id;
 | 
						|
const char *spider_allocated_thds_func_name;
 | 
						|
const char *spider_allocated_thds_file_name;
 | 
						|
ulong spider_allocated_thds_line_no;
 | 
						|
pthread_mutex_t spider_allocated_thds_mutex;
 | 
						|
 | 
						|
pthread_attr_t spider_pt_attr;
 | 
						|
 | 
						|
extern pthread_mutex_t spider_mem_calc_mutex;
 | 
						|
 | 
						|
extern const char *spider_alloc_func_name[SPIDER_MEM_CALC_LIST_NUM];
 | 
						|
extern const char *spider_alloc_file_name[SPIDER_MEM_CALC_LIST_NUM];
 | 
						|
extern ulong      spider_alloc_line_no[SPIDER_MEM_CALC_LIST_NUM];
 | 
						|
extern ulonglong  spider_total_alloc_mem[SPIDER_MEM_CALC_LIST_NUM];
 | 
						|
extern longlong   spider_current_alloc_mem[SPIDER_MEM_CALC_LIST_NUM];
 | 
						|
extern ulonglong  spider_alloc_mem_count[SPIDER_MEM_CALC_LIST_NUM];
 | 
						|
extern ulonglong  spider_free_mem_count[SPIDER_MEM_CALC_LIST_NUM];
 | 
						|
 | 
						|
static char spider_wild_many = '%', spider_wild_one = '_',
 | 
						|
  spider_wild_prefix='\\';
 | 
						|
 | 
						|
/**
 | 
						|
 `spider_unique_id` is used for identifying a spider table. It is set
 | 
						|
 to be a concatenation of the MAC address and the PID, give or take
 | 
						|
 some separators
 | 
						|
*/
 | 
						|
static char spider_unique_id_buf[1 + 12 + 1 + (16 * 2) + 1 + 1];
 | 
						|
LEX_CSTRING spider_unique_id;
 | 
						|
 | 
						|
// for spider_open_tables
 | 
						|
const uchar *spider_tbl_get_key(
 | 
						|
  const void *share_,
 | 
						|
  size_t *length,
 | 
						|
  my_bool
 | 
						|
) {
 | 
						|
  auto share= static_cast<const SPIDER_SHARE *>(share_);
 | 
						|
  DBUG_ENTER("spider_tbl_get_key");
 | 
						|
  *length = share->table_name_length;
 | 
						|
  DBUG_RETURN(reinterpret_cast<const uchar *>(share->table_name));
 | 
						|
}
 | 
						|
 | 
						|
const uchar *spider_wide_share_get_key(
 | 
						|
  const void *share_,
 | 
						|
  size_t *length,
 | 
						|
  my_bool
 | 
						|
) {
 | 
						|
  auto share= static_cast<const SPIDER_WIDE_SHARE *>(share_);
 | 
						|
  DBUG_ENTER("spider_wide_share_get_key");
 | 
						|
  *length = share->table_name_length;
 | 
						|
  DBUG_RETURN(reinterpret_cast<const uchar *>(share->table_name));
 | 
						|
}
 | 
						|
 | 
						|
const uchar *spider_lgtm_tblhnd_share_hash_get_key(
 | 
						|
  const void *share_,
 | 
						|
  size_t *length,
 | 
						|
  my_bool
 | 
						|
) {
 | 
						|
  auto share= static_cast<const SPIDER_LGTM_TBLHND_SHARE *>(share_);
 | 
						|
  DBUG_ENTER("spider_lgtm_tblhnd_share_hash_get_key");
 | 
						|
  *length = share->table_name_length;
 | 
						|
  DBUG_RETURN(reinterpret_cast<const uchar *>(share->table_name));
 | 
						|
}
 | 
						|
 | 
						|
const uchar *spider_link_get_key(
 | 
						|
  const void *link_for_hash_,
 | 
						|
  size_t *length,
 | 
						|
  my_bool
 | 
						|
) {
 | 
						|
  auto link_for_hash=
 | 
						|
      static_cast<const SPIDER_LINK_FOR_HASH *>(link_for_hash_);
 | 
						|
  DBUG_ENTER("spider_link_get_key");
 | 
						|
  *length = link_for_hash->db_table_str->length();
 | 
						|
  DBUG_RETURN(reinterpret_cast<const uchar *>(link_for_hash->db_table_str->ptr()));
 | 
						|
}
 | 
						|
 | 
						|
const uchar *spider_udf_tbl_mon_list_key(
 | 
						|
  const void *table_mon_list_,
 | 
						|
  size_t *length,
 | 
						|
  my_bool
 | 
						|
) {
 | 
						|
  auto table_mon_list=
 | 
						|
      static_cast<const SPIDER_TABLE_MON_LIST *>(table_mon_list_);
 | 
						|
  DBUG_ENTER("spider_udf_tbl_mon_list_key");
 | 
						|
  DBUG_PRINT("info",("spider hash key=%s", table_mon_list->key));
 | 
						|
  DBUG_PRINT("info",("spider hash key length=%u", table_mon_list->key_length));
 | 
						|
  *length = table_mon_list->key_length;
 | 
						|
  DBUG_RETURN(reinterpret_cast<const uchar *>(table_mon_list->key));
 | 
						|
}
 | 
						|
 | 
						|
const uchar *spider_allocated_thds_get_key(
 | 
						|
  const void *thd,
 | 
						|
  size_t *length,
 | 
						|
  my_bool
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_allocated_thds_get_key");
 | 
						|
  *length = sizeof(THD *);
 | 
						|
  DBUG_RETURN(reinterpret_cast<const uchar *>(thd));
 | 
						|
}
 | 
						|
 | 
						|
#ifdef HAVE_PSI_INTERFACE
 | 
						|
static void init_spider_psi_keys()
 | 
						|
{
 | 
						|
  DBUG_ENTER("init_spider_psi_keys");
 | 
						|
  if (PSI_server == NULL)
 | 
						|
    DBUG_VOID_RETURN;
 | 
						|
 | 
						|
  PSI_server->register_mutex("spider", all_spider_mutexes,
 | 
						|
    array_elements(all_spider_mutexes));
 | 
						|
  PSI_server->register_cond("spider", all_spider_conds,
 | 
						|
    array_elements(all_spider_conds));
 | 
						|
  PSI_server->register_thread("spider", all_spider_threads,
 | 
						|
    array_elements(all_spider_threads));
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
int spider_get_server(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  int link_idx
 | 
						|
) {
 | 
						|
  MEM_ROOT mem_root;
 | 
						|
  int error_num, length;
 | 
						|
  FOREIGN_SERVER *server, server_buf;
 | 
						|
  DBUG_ENTER("spider_get_server");
 | 
						|
  SPD_INIT_ALLOC_ROOT(&mem_root, 128, 0, MYF(MY_WME));
 | 
						|
 | 
						|
  if (!(server
 | 
						|
       = get_server_by_name(&mem_root, share->server_names[link_idx],
 | 
						|
         &server_buf)))
 | 
						|
  {
 | 
						|
    error_num = ER_FOREIGN_SERVER_DOESNT_EXIST;
 | 
						|
    goto error;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!share->tgt_wrappers[link_idx] && server->scheme)
 | 
						|
  {
 | 
						|
    share->tgt_wrappers_lengths[link_idx] = strlen(server->scheme);
 | 
						|
    if (!(share->tgt_wrappers[link_idx] =
 | 
						|
      spider_create_string(server->scheme,
 | 
						|
      share->tgt_wrappers_lengths[link_idx])))
 | 
						|
    {
 | 
						|
      error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error;
 | 
						|
    }
 | 
						|
    DBUG_PRINT("info",("spider tgt_wrappers=%s",
 | 
						|
      share->tgt_wrappers[link_idx]));
 | 
						|
  }
 | 
						|
 | 
						|
  if (!share->tgt_hosts[link_idx] && server->host)
 | 
						|
  {
 | 
						|
    share->tgt_hosts_lengths[link_idx] = strlen(server->host);
 | 
						|
    if (!(share->tgt_hosts[link_idx] =
 | 
						|
      spider_create_string(server->host, share->tgt_hosts_lengths[link_idx])))
 | 
						|
    {
 | 
						|
      error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error;
 | 
						|
    }
 | 
						|
    DBUG_PRINT("info",("spider tgt_hosts=%s", share->tgt_hosts[link_idx]));
 | 
						|
  }
 | 
						|
 | 
						|
  if (share->tgt_ports[link_idx] == -1)
 | 
						|
  {
 | 
						|
    share->tgt_ports[link_idx] = server->port;
 | 
						|
    DBUG_PRINT("info",("spider tgt_ports=%ld", share->tgt_ports[link_idx]));
 | 
						|
  }
 | 
						|
 | 
						|
  if (!share->tgt_sockets[link_idx] && server->socket)
 | 
						|
  {
 | 
						|
    share->tgt_sockets_lengths[link_idx] = strlen(server->socket);
 | 
						|
    if (!(share->tgt_sockets[link_idx] =
 | 
						|
      spider_create_string(server->socket,
 | 
						|
      share->tgt_sockets_lengths[link_idx])))
 | 
						|
    {
 | 
						|
      error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error;
 | 
						|
    }
 | 
						|
    DBUG_PRINT("info",("spider tgt_sockets=%s", share->tgt_sockets[link_idx]));
 | 
						|
  }
 | 
						|
 | 
						|
  if (!share->tgt_dbs[link_idx] && server->db && (length = strlen(server->db)))
 | 
						|
  {
 | 
						|
    share->tgt_dbs_lengths[link_idx] = length;
 | 
						|
    if (!(share->tgt_dbs[link_idx] =
 | 
						|
      spider_create_string(server->db, length)))
 | 
						|
    {
 | 
						|
      error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error;
 | 
						|
    }
 | 
						|
    DBUG_PRINT("info",("spider tgt_dbs=%s", share->tgt_dbs[link_idx]));
 | 
						|
  }
 | 
						|
 | 
						|
  if (!share->tgt_usernames[link_idx] && server->username)
 | 
						|
  {
 | 
						|
    share->tgt_usernames_lengths[link_idx] = strlen(server->username);
 | 
						|
    if (!(share->tgt_usernames[link_idx] =
 | 
						|
      spider_create_string(server->username,
 | 
						|
      share->tgt_usernames_lengths[link_idx])))
 | 
						|
    {
 | 
						|
      error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error;
 | 
						|
    }
 | 
						|
    DBUG_PRINT("info",("spider tgt_usernames=%s",
 | 
						|
      share->tgt_usernames[link_idx]));
 | 
						|
  }
 | 
						|
 | 
						|
  if (!share->tgt_passwords[link_idx] && server->password)
 | 
						|
  {
 | 
						|
    share->tgt_passwords_lengths[link_idx] = strlen(server->password);
 | 
						|
    if (!(share->tgt_passwords[link_idx] =
 | 
						|
      spider_create_string(server->password,
 | 
						|
      share->tgt_passwords_lengths[link_idx])))
 | 
						|
    {
 | 
						|
      error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error;
 | 
						|
    }
 | 
						|
    DBUG_PRINT("info",("spider tgt_passwords=%s",
 | 
						|
      share->tgt_passwords[link_idx]));
 | 
						|
  }
 | 
						|
 | 
						|
  free_root(&mem_root, MYF(0));
 | 
						|
  DBUG_RETURN(0);
 | 
						|
 | 
						|
error:
 | 
						|
  free_root(&mem_root, MYF(0));
 | 
						|
  my_error(error_num, MYF(0), share->server_names[link_idx]);
 | 
						|
  DBUG_RETURN(error_num);
 | 
						|
}
 | 
						|
 | 
						|
int spider_free_share_alloc(
 | 
						|
  SPIDER_SHARE *share
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  DBUG_ENTER("spider_free_share_alloc");
 | 
						|
  for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; roop_count--)
 | 
						|
  {
 | 
						|
    if (share->dbton_share[roop_count])
 | 
						|
    {
 | 
						|
      delete share->dbton_share[roop_count];
 | 
						|
      share->dbton_share[roop_count] = NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (share->server_names)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->server_names_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->server_names[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->server_names[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->server_names, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_table_names)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_table_names_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_table_names[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_table_names[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_table_names, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_dbs)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_dbs_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_dbs[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_dbs[roop_count], MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_dbs, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_hosts)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_hosts_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_hosts[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_hosts[roop_count], MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_hosts, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_usernames)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_usernames_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_usernames[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_usernames[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_usernames, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_passwords)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_passwords_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_passwords[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_passwords[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_passwords, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_sockets)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_sockets_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_sockets[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_sockets[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_sockets, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_wrappers)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_wrappers_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_wrappers[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_wrappers[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_wrappers, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_cas)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_ssl_cas_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_ssl_cas[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_ssl_cas[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_cas, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_capaths)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_ssl_capaths_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_ssl_capaths[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_ssl_capaths[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_capaths, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_certs)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_ssl_certs_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_ssl_certs[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_ssl_certs[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_certs, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_ciphers)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_ssl_ciphers_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_ssl_ciphers[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_ssl_ciphers[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_ciphers, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_keys)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_ssl_keys_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_ssl_keys[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_ssl_keys[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_keys, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_default_files)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_default_files_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_default_files[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_default_files[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_default_files, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_default_groups)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_default_groups_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_default_groups[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_default_groups[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_default_groups, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_dsns)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_dsns_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_dsns[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_dsns[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_dsns, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_filedsns)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_filedsns_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_filedsns[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_filedsns[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_filedsns, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_drivers)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_drivers_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_drivers[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_drivers[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_drivers, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_odbc_conn_strs)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_odbc_conn_strs_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_odbc_conn_strs[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_odbc_conn_strs[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_odbc_conn_strs, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_pk_names)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_pk_names_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_pk_names[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_pk_names[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    spider_free(spider_current_trx, share->tgt_pk_names, MYF(0));
 | 
						|
  }
 | 
						|
  if (share->tgt_sequence_names)
 | 
						|
  {
 | 
						|
    for (roop_count = 0; roop_count < (int) share->tgt_sequence_names_length;
 | 
						|
      roop_count++)
 | 
						|
    {
 | 
						|
      if (share->tgt_sequence_names[roop_count])
 | 
						|
        spider_free(spider_current_trx, share->tgt_sequence_names[roop_count],
 | 
						|
          MYF(0));
 | 
						|
    }
 | 
						|
    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 (share->bka_engine)
 | 
						|
    spider_free(spider_current_trx, share->bka_engine, MYF(0));
 | 
						|
  if (share->conn_keys)
 | 
						|
    spider_free(spider_current_trx, share->conn_keys, MYF(0));
 | 
						|
  if (share->tgt_ports)
 | 
						|
    spider_free(spider_current_trx, share->tgt_ports, MYF(0));
 | 
						|
  if (share->tgt_ssl_vscs)
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_vscs, MYF(0));
 | 
						|
  if (share->link_statuses)
 | 
						|
    spider_free(spider_current_trx, share->link_statuses, MYF(0));
 | 
						|
  if (share->monitoring_bg_flag)
 | 
						|
    spider_free(spider_current_trx, share->monitoring_bg_flag, MYF(0));
 | 
						|
  if (share->monitoring_bg_kind)
 | 
						|
    spider_free(spider_current_trx, share->monitoring_bg_kind, MYF(0));
 | 
						|
  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)
 | 
						|
    spider_free(spider_current_trx, share->monitoring_kind, MYF(0));
 | 
						|
  if (share->connect_timeouts)
 | 
						|
    spider_free(spider_current_trx, share->connect_timeouts, MYF(0));
 | 
						|
  if (share->net_read_timeouts)
 | 
						|
    spider_free(spider_current_trx, share->net_read_timeouts, MYF(0));
 | 
						|
  if (share->net_write_timeouts)
 | 
						|
    spider_free(spider_current_trx, share->net_write_timeouts, MYF(0));
 | 
						|
  if (share->access_balances)
 | 
						|
    spider_free(spider_current_trx, share->access_balances, MYF(0));
 | 
						|
  if (share->bka_table_name_types)
 | 
						|
    spider_free(spider_current_trx, share->bka_table_name_types, MYF(0));
 | 
						|
  if (share->strict_group_bys)
 | 
						|
    spider_free(spider_current_trx, share->strict_group_bys, MYF(0));
 | 
						|
  if (share->monitoring_bg_interval)
 | 
						|
    spider_free(spider_current_trx, share->monitoring_bg_interval, MYF(0));
 | 
						|
  if (share->monitoring_limit)
 | 
						|
    spider_free(spider_current_trx, share->monitoring_limit, MYF(0));
 | 
						|
  if (share->monitoring_sid)
 | 
						|
    spider_free(spider_current_trx, share->monitoring_sid, MYF(0));
 | 
						|
  if (share->alter_table.tmp_server_names)
 | 
						|
    spider_free(spider_current_trx, share->alter_table.tmp_server_names,
 | 
						|
      MYF(0));
 | 
						|
  if (share->key_hint)
 | 
						|
  {
 | 
						|
    delete [] share->key_hint;
 | 
						|
    share->key_hint = NULL;
 | 
						|
  }
 | 
						|
  if (share->wide_share)
 | 
						|
    spider_free_wide_share(share->wide_share);
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
/* Free a tmp_share, which has only one link */
 | 
						|
void spider_free_tmp_share_alloc(
 | 
						|
  SPIDER_SHARE *share
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_free_tmp_share_alloc");
 | 
						|
  if (share->server_names && share->server_names[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->server_names[0], MYF(0));
 | 
						|
    share->server_names[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_table_names && share->tgt_table_names[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_table_names[0], MYF(0));
 | 
						|
    share->tgt_table_names[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_dbs && share->tgt_dbs[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_dbs[0], MYF(0));
 | 
						|
    share->tgt_dbs[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_hosts && share->tgt_hosts[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_hosts[0], MYF(0));
 | 
						|
    share->tgt_hosts[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_usernames && share->tgt_usernames[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_usernames[0], MYF(0));
 | 
						|
    share->tgt_usernames[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_passwords && share->tgt_passwords[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_passwords[0], MYF(0));
 | 
						|
    share->tgt_passwords[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_sockets && share->tgt_sockets[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_sockets[0], MYF(0));
 | 
						|
    share->tgt_sockets[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_wrappers && share->tgt_wrappers[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_wrappers[0], MYF(0));
 | 
						|
    share->tgt_wrappers[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_cas && share->tgt_ssl_cas[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_cas[0], MYF(0));
 | 
						|
    share->tgt_ssl_cas[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_capaths && share->tgt_ssl_capaths[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_capaths[0], MYF(0));
 | 
						|
    share->tgt_ssl_capaths[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_certs && share->tgt_ssl_certs[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_certs[0], MYF(0));
 | 
						|
    share->tgt_ssl_certs[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_ciphers && share->tgt_ssl_ciphers[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_ciphers[0], MYF(0));
 | 
						|
    share->tgt_ssl_ciphers[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_ssl_keys && share->tgt_ssl_keys[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_ssl_keys[0], MYF(0));
 | 
						|
    share->tgt_ssl_keys[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_default_files && share->tgt_default_files[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_default_files[0], MYF(0));
 | 
						|
    share->tgt_default_files[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_default_groups && share->tgt_default_groups[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_default_groups[0], MYF(0));
 | 
						|
    share->tgt_default_groups[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_dsns && share->tgt_dsns[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_dsns[0], MYF(0));
 | 
						|
    share->tgt_dsns[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_filedsns && share->tgt_filedsns[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_filedsns[0], MYF(0));
 | 
						|
    share->tgt_filedsns[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_drivers && share->tgt_drivers[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_drivers[0], MYF(0));
 | 
						|
    share->tgt_drivers[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_odbc_conn_strs && share->tgt_odbc_conn_strs[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_odbc_conn_strs[0], MYF(0));
 | 
						|
    share->tgt_odbc_conn_strs[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_pk_names && share->tgt_pk_names[0])
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->tgt_pk_names[0], MYF(0));
 | 
						|
    share->tgt_pk_names[0] = NULL;
 | 
						|
  }
 | 
						|
  if (share->tgt_sequence_names && share->tgt_sequence_names[0])
 | 
						|
  {
 | 
						|
    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 (share->bka_engine)
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->bka_engine, MYF(0));
 | 
						|
    share->bka_engine = NULL;
 | 
						|
  }
 | 
						|
  if (share->conn_keys)
 | 
						|
  {
 | 
						|
    spider_free(spider_current_trx, share->conn_keys, MYF(0));
 | 
						|
    share->conn_keys = NULL;
 | 
						|
  }
 | 
						|
  if (share->static_key_cardinality)
 | 
						|
    spider_free(spider_current_trx, share->static_key_cardinality, MYF(0));
 | 
						|
  if (share->key_hint)
 | 
						|
  {
 | 
						|
    delete [] share->key_hint;
 | 
						|
    share->key_hint = NULL;
 | 
						|
  }
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
int spider_create_string_list(
 | 
						|
  char ***string_list,
 | 
						|
  uint **string_length_list,
 | 
						|
  uint *list_length,
 | 
						|
  char *str,
 | 
						|
  uint length
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  char *tmp_ptr, *tmp_ptr2, *tmp_ptr3, *tmp_ptr4, *esc_ptr;
 | 
						|
  bool find_flg = FALSE;
 | 
						|
  DBUG_ENTER("spider_create_string_list");
 | 
						|
 | 
						|
  *list_length = 0;
 | 
						|
  if (!str)
 | 
						|
  {
 | 
						|
    *string_list = NULL;
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  }
 | 
						|
 | 
						|
  tmp_ptr = str;
 | 
						|
  while (*tmp_ptr == ' ')
 | 
						|
    tmp_ptr++;
 | 
						|
  *list_length= 1;
 | 
						|
 | 
						|
  bool last_esc_flg = FALSE;
 | 
						|
  while (TRUE)
 | 
						|
  {
 | 
						|
    if ((tmp_ptr2 = strchr(tmp_ptr, ' ')))
 | 
						|
    {
 | 
						|
      find_flg = FALSE;
 | 
						|
      last_esc_flg = FALSE;
 | 
						|
      esc_ptr = tmp_ptr;
 | 
						|
      while (!find_flg)
 | 
						|
      {
 | 
						|
        esc_ptr = strchr(esc_ptr, '\\');
 | 
						|
        if (!esc_ptr || esc_ptr > tmp_ptr2)
 | 
						|
        {
 | 
						|
          find_flg = TRUE;
 | 
						|
        }
 | 
						|
        else if (esc_ptr == tmp_ptr2 - 1)
 | 
						|
        {
 | 
						|
          last_esc_flg = TRUE;
 | 
						|
          tmp_ptr = tmp_ptr2 + 1;
 | 
						|
          break;
 | 
						|
        } else {
 | 
						|
          last_esc_flg = TRUE;
 | 
						|
          esc_ptr += 2;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (find_flg)
 | 
						|
      {
 | 
						|
        (*list_length)++;
 | 
						|
        tmp_ptr = tmp_ptr2 + 1;
 | 
						|
        while (*tmp_ptr == ' ')
 | 
						|
          tmp_ptr++;
 | 
						|
      }
 | 
						|
    } else
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(*string_list = (char**)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_STRING_LIST_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      string_list, (uint) (sizeof(char*) * (*list_length)),
 | 
						|
      string_length_list, (uint) (sizeof(int) * (*list_length)),
 | 
						|
      NullS))
 | 
						|
  ) {
 | 
						|
    my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
 | 
						|
  tmp_ptr = str;
 | 
						|
  while (*tmp_ptr == ' ')
 | 
						|
  {
 | 
						|
    *tmp_ptr = '\0';
 | 
						|
    tmp_ptr++;
 | 
						|
  }
 | 
						|
  tmp_ptr3 = tmp_ptr;
 | 
						|
 | 
						|
  for (roop_count = 0; roop_count < (int) *list_length - 1; roop_count++)
 | 
						|
  {
 | 
						|
    bool esc_flg = FALSE;
 | 
						|
    find_flg = FALSE;
 | 
						|
    while (TRUE)
 | 
						|
    {
 | 
						|
      tmp_ptr2 = strchr(tmp_ptr, ' ');
 | 
						|
 | 
						|
      esc_ptr = tmp_ptr;
 | 
						|
      while (!find_flg)
 | 
						|
      {
 | 
						|
        esc_ptr = strchr(esc_ptr, '\\');
 | 
						|
        if (!esc_ptr || esc_ptr > tmp_ptr2)
 | 
						|
        {
 | 
						|
          find_flg = TRUE;
 | 
						|
        }
 | 
						|
        else if (esc_ptr == tmp_ptr2 - 1)
 | 
						|
        {
 | 
						|
          esc_flg = TRUE;
 | 
						|
          tmp_ptr = tmp_ptr2 + 1;
 | 
						|
          break;
 | 
						|
        } else {
 | 
						|
          esc_flg = TRUE;
 | 
						|
          esc_ptr += 2;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (find_flg)
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    tmp_ptr = tmp_ptr2;
 | 
						|
 | 
						|
    while (*tmp_ptr == ' ')
 | 
						|
    {
 | 
						|
      *tmp_ptr = '\0';
 | 
						|
      tmp_ptr++;
 | 
						|
    }
 | 
						|
 | 
						|
    (*string_length_list)[roop_count] = strlen(tmp_ptr3);
 | 
						|
    if (!((*string_list)[roop_count] = spider_create_string(
 | 
						|
      tmp_ptr3, (*string_length_list)[roop_count]))
 | 
						|
    ) {
 | 
						|
      my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
    }
 | 
						|
 | 
						|
    if (esc_flg)
 | 
						|
    {
 | 
						|
      esc_ptr = (*string_list)[roop_count];
 | 
						|
      while (TRUE)
 | 
						|
      {
 | 
						|
        esc_ptr = strchr(esc_ptr, '\\');
 | 
						|
        if (!esc_ptr)
 | 
						|
          break;
 | 
						|
        switch(*(esc_ptr + 1))
 | 
						|
        {
 | 
						|
          case 'b':
 | 
						|
            *esc_ptr = '\b';
 | 
						|
            break;
 | 
						|
          case 'n':
 | 
						|
            *esc_ptr = '\n';
 | 
						|
            break;
 | 
						|
          case 'r':
 | 
						|
            *esc_ptr = '\r';
 | 
						|
            break;
 | 
						|
          case 't':
 | 
						|
            *esc_ptr = '\t';
 | 
						|
            break;
 | 
						|
          default:
 | 
						|
            *esc_ptr = *(esc_ptr + 1);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        esc_ptr++;
 | 
						|
        tmp_ptr4 = esc_ptr;
 | 
						|
        do
 | 
						|
        {
 | 
						|
          *tmp_ptr4 = *(tmp_ptr4 + 1);
 | 
						|
          tmp_ptr4++;
 | 
						|
        } while (*tmp_ptr4);
 | 
						|
        (*string_length_list)[roop_count] -= 1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    DBUG_PRINT("info",("spider string_list[%d]=%s", roop_count,
 | 
						|
      (*string_list)[roop_count]));
 | 
						|
    tmp_ptr3 = tmp_ptr;
 | 
						|
  }
 | 
						|
  (*string_length_list)[roop_count] = strlen(tmp_ptr3);
 | 
						|
  if (!((*string_list)[roop_count] = spider_create_string(
 | 
						|
    tmp_ptr3, (*string_length_list)[roop_count]))
 | 
						|
  ) {
 | 
						|
    my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  if (last_esc_flg)
 | 
						|
  {
 | 
						|
    esc_ptr = (*string_list)[roop_count];
 | 
						|
    while (TRUE)
 | 
						|
    {
 | 
						|
      esc_ptr = strchr(esc_ptr, '\\');
 | 
						|
      if (!esc_ptr)
 | 
						|
        break;
 | 
						|
      switch(*(esc_ptr + 1))
 | 
						|
      {
 | 
						|
        case 'b':
 | 
						|
          *esc_ptr = '\b';
 | 
						|
          break;
 | 
						|
        case 'n':
 | 
						|
          *esc_ptr = '\n';
 | 
						|
          break;
 | 
						|
        case 'r':
 | 
						|
          *esc_ptr = '\r';
 | 
						|
          break;
 | 
						|
        case 't':
 | 
						|
          *esc_ptr = '\t';
 | 
						|
          break;
 | 
						|
        default:
 | 
						|
          *esc_ptr = *(esc_ptr + 1);
 | 
						|
          break;
 | 
						|
      }
 | 
						|
      esc_ptr++;
 | 
						|
      tmp_ptr4 = esc_ptr;
 | 
						|
      do
 | 
						|
      {
 | 
						|
        *tmp_ptr4 = *(tmp_ptr4 + 1);
 | 
						|
        tmp_ptr4++;
 | 
						|
      } while (*tmp_ptr4);
 | 
						|
      (*string_length_list)[roop_count] -= 1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  DBUG_PRINT("info",("spider string_list[%d]=%s", roop_count,
 | 
						|
    (*string_list)[roop_count]));
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
int spider_create_long_list(
 | 
						|
  long **long_list,
 | 
						|
  uint *list_length,
 | 
						|
  char *str,
 | 
						|
  uint length,
 | 
						|
  long min_val,
 | 
						|
  long max_val
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  char *tmp_ptr;
 | 
						|
  DBUG_ENTER("spider_create_long_list");
 | 
						|
 | 
						|
  *list_length = 0;
 | 
						|
  if (!str)
 | 
						|
  {
 | 
						|
    *long_list = NULL;
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  }
 | 
						|
 | 
						|
  tmp_ptr = str;
 | 
						|
  while (*tmp_ptr == ' ')
 | 
						|
    tmp_ptr++;
 | 
						|
  if (*tmp_ptr)
 | 
						|
    *list_length = 1;
 | 
						|
  else {
 | 
						|
    *long_list = NULL;
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  }
 | 
						|
 | 
						|
  while (TRUE)
 | 
						|
  {
 | 
						|
    if ((tmp_ptr = strchr(tmp_ptr, ' ')))
 | 
						|
    {
 | 
						|
      (*list_length)++;
 | 
						|
      tmp_ptr = tmp_ptr + 1;
 | 
						|
      while (*tmp_ptr == ' ')
 | 
						|
        tmp_ptr++;
 | 
						|
    } else
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(*long_list = (long*)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_LONG_LIST_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      long_list, (uint) (sizeof(long) * (*list_length)),
 | 
						|
      NullS))
 | 
						|
  ) {
 | 
						|
    my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
 | 
						|
  tmp_ptr = str;
 | 
						|
  for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
 | 
						|
  {
 | 
						|
    if (roop_count != 0)
 | 
						|
      tmp_ptr = strchr(tmp_ptr, ' ');
 | 
						|
 | 
						|
    while (*tmp_ptr == ' ')
 | 
						|
    {
 | 
						|
      *tmp_ptr = '\0';
 | 
						|
      tmp_ptr++;
 | 
						|
    }
 | 
						|
    (*long_list)[roop_count] = atol(tmp_ptr);
 | 
						|
    if ((*long_list)[roop_count] < min_val)
 | 
						|
      (*long_list)[roop_count] = min_val;
 | 
						|
    else if ((*long_list)[roop_count] > max_val)
 | 
						|
      (*long_list)[roop_count] = max_val;
 | 
						|
  }
 | 
						|
 | 
						|
#ifndef DBUG_OFF
 | 
						|
  for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider long_list[%d]=%ld", roop_count,
 | 
						|
      (*long_list)[roop_count]));
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Parse a list of nonnegative longs with maximum value max_val.
 | 
						|
 | 
						|
  max_val <= INT_MAX, and the list is space separated and could have
 | 
						|
  leading or trailing spaces.
 | 
						|
*/
 | 
						|
int spider_create_bounded_nat_list(
 | 
						|
  long **long_list,
 | 
						|
  uint *list_length,
 | 
						|
  char *str,
 | 
						|
  uint length,
 | 
						|
  long max_val
 | 
						|
) {
 | 
						|
  int i, error_num;
 | 
						|
  char *cur, *tail;
 | 
						|
  DBUG_ENTER("spider_create_bounded_nat_list");
 | 
						|
 | 
						|
  *list_length = 0;
 | 
						|
  if (!str)
 | 
						|
  {
 | 
						|
    *long_list = NULL;
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  }
 | 
						|
 | 
						|
  cur = str;
 | 
						|
  while (*cur == ' ')
 | 
						|
    cur++;
 | 
						|
  if (*cur)
 | 
						|
    *list_length = 1;
 | 
						|
  else {
 | 
						|
    *long_list = NULL;
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  }
 | 
						|
 | 
						|
  while ((cur = strchr(cur, ' ')))
 | 
						|
  {
 | 
						|
     do {
 | 
						|
       cur++;
 | 
						|
     } while (*cur == ' ');
 | 
						|
     if (*cur)
 | 
						|
       (*list_length)++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(*long_list = (long*)
 | 
						|
        spider_bulk_malloc(spider_current_trx, 44, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
                           long_list, (uint) (sizeof(long) * (*list_length)),
 | 
						|
                           NullS))
 | 
						|
  ) {
 | 
						|
    my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
 | 
						|
  cur = str;
 | 
						|
  for (i = 0; i < (int) *list_length; i++)
 | 
						|
  {
 | 
						|
    while (*cur == ' ')
 | 
						|
      cur++;
 | 
						|
    tail= str + strlen(str);
 | 
						|
    longlong converted= my_strtoll10(cur, &tail, &error_num);
 | 
						|
    cur= tail;
 | 
						|
    if (error_num || (*cur && *cur != ' ') || converted < 0 ||
 | 
						|
        converted > max_val || converted > INT_MAX)
 | 
						|
      DBUG_RETURN(1);
 | 
						|
    (*long_list)[i]= (long) converted;
 | 
						|
  }
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
int spider_create_longlong_list(
 | 
						|
  longlong **longlong_list,
 | 
						|
  uint *list_length,
 | 
						|
  char *str,
 | 
						|
  uint length,
 | 
						|
  longlong min_val,
 | 
						|
  longlong max_val
 | 
						|
) {
 | 
						|
  int error_num, roop_count;
 | 
						|
  char *tmp_ptr;
 | 
						|
  DBUG_ENTER("spider_create_longlong_list");
 | 
						|
 | 
						|
  *list_length = 0;
 | 
						|
  if (!str)
 | 
						|
  {
 | 
						|
    *longlong_list = NULL;
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  }
 | 
						|
 | 
						|
  tmp_ptr = str;
 | 
						|
  while (*tmp_ptr == ' ')
 | 
						|
    tmp_ptr++;
 | 
						|
  if (*tmp_ptr)
 | 
						|
    *list_length = 1;
 | 
						|
  else {
 | 
						|
    *longlong_list = NULL;
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  }
 | 
						|
 | 
						|
  while (TRUE)
 | 
						|
  {
 | 
						|
    if ((tmp_ptr = strchr(tmp_ptr, ' ')))
 | 
						|
    {
 | 
						|
      (*list_length)++;
 | 
						|
      tmp_ptr = tmp_ptr + 1;
 | 
						|
      while (*tmp_ptr == ' ')
 | 
						|
        tmp_ptr++;
 | 
						|
    } else
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(*longlong_list = (longlong *)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_LONGLONG_LIST_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      longlong_list, (uint) (sizeof(longlong) * (*list_length)),
 | 
						|
      NullS))
 | 
						|
  ) {
 | 
						|
    my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
 | 
						|
  tmp_ptr = str;
 | 
						|
  for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
 | 
						|
  {
 | 
						|
    if (roop_count != 0)
 | 
						|
      tmp_ptr = strchr(tmp_ptr, ' ');
 | 
						|
 | 
						|
    while (*tmp_ptr == ' ')
 | 
						|
    {
 | 
						|
      *tmp_ptr = '\0';
 | 
						|
      tmp_ptr++;
 | 
						|
    }
 | 
						|
    (*longlong_list)[roop_count] = my_strtoll10(tmp_ptr, (char**) NULL,
 | 
						|
      &error_num);
 | 
						|
    if ((*longlong_list)[roop_count] < min_val)
 | 
						|
      (*longlong_list)[roop_count] = min_val;
 | 
						|
    else if ((*longlong_list)[roop_count] > max_val)
 | 
						|
      (*longlong_list)[roop_count] = max_val;
 | 
						|
  }
 | 
						|
 | 
						|
#ifndef DBUG_OFF
 | 
						|
  for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider longlong_list[%d]=%lld", roop_count,
 | 
						|
      (*longlong_list)[roop_count]));
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
int spider_increase_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, *tmp_str;
 | 
						|
  uint *tmp_length_list, tmp_length;
 | 
						|
  DBUG_ENTER("spider_increase_string_list");
 | 
						|
  if (*list_length == link_count)
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  if (*list_length > 1)
 | 
						|
  {
 | 
						|
    my_printf_error(ER_SPIDER_DIFFERENT_LINK_COUNT_NUM,
 | 
						|
      ER_SPIDER_DIFFERENT_LINK_COUNT_STR, MYF(0));
 | 
						|
    DBUG_RETURN(ER_SPIDER_DIFFERENT_LINK_COUNT_NUM);
 | 
						|
  }
 | 
						|
 | 
						|
  if (*string_list)
 | 
						|
  {
 | 
						|
    tmp_str = (*string_list)[0];
 | 
						|
    tmp_length = (*string_length_list)[0];
 | 
						|
  } else {
 | 
						|
    tmp_str = NULL;
 | 
						|
    tmp_length = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(tmp_str_list = (char**)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_INCREASE_STRING_LIST_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &tmp_str_list, (uint) (sizeof(char*) * link_count),
 | 
						|
      &tmp_length_list, (uint) (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) link_count; roop_count++)
 | 
						|
  {
 | 
						|
    tmp_length_list[roop_count] = tmp_length;
 | 
						|
    if (tmp_str)
 | 
						|
    {
 | 
						|
      if (!(tmp_str_list[roop_count] = spider_create_string(
 | 
						|
        tmp_str, tmp_length))
 | 
						|
      )
 | 
						|
        goto error;
 | 
						|
      DBUG_PRINT("info",("spider string_list[%d]=%s", roop_count,
 | 
						|
        tmp_str_list[roop_count]));
 | 
						|
    } else
 | 
						|
      tmp_str_list[roop_count] = NULL;
 | 
						|
  }
 | 
						|
  if (*string_list)
 | 
						|
  {
 | 
						|
    if ((*string_list)[0])
 | 
						|
      spider_free(spider_current_trx, (*string_list)[0], MYF(0));
 | 
						|
    spider_free(spider_current_trx, *string_list, MYF(0));
 | 
						|
  }
 | 
						|
  *list_charlen = (tmp_length + 1) * link_count - 1;
 | 
						|
  *list_length = link_count;
 | 
						|
  *string_list = tmp_str_list;
 | 
						|
  *string_length_list = tmp_length_list;
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
 | 
						|
error:
 | 
						|
  for (roop_count = 0; roop_count < (int) link_count; roop_count++)
 | 
						|
  {
 | 
						|
    if (tmp_str_list[roop_count])
 | 
						|
      spider_free(spider_current_trx, tmp_str_list[roop_count], MYF(0));
 | 
						|
  }
 | 
						|
  if (tmp_str_list)
 | 
						|
    spider_free(spider_current_trx, tmp_str_list, MYF(0));
 | 
						|
  my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
  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, SPD_MID_INCREASE_NULL_STRING_LIST_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &tmp_str_list, (uint) (sizeof(char*) * link_count),
 | 
						|
      &tmp_length_list, (uint) (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,
 | 
						|
  uint link_count
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  long *tmp_long_list, tmp_long;
 | 
						|
  DBUG_ENTER("spider_increase_long_list");
 | 
						|
  if (*list_length == link_count)
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  if (*list_length > 1)
 | 
						|
  {
 | 
						|
    my_printf_error(ER_SPIDER_DIFFERENT_LINK_COUNT_NUM,
 | 
						|
      ER_SPIDER_DIFFERENT_LINK_COUNT_STR, MYF(0));
 | 
						|
    DBUG_RETURN(ER_SPIDER_DIFFERENT_LINK_COUNT_NUM);
 | 
						|
  }
 | 
						|
 | 
						|
  if (*long_list)
 | 
						|
    tmp_long = (*long_list)[0];
 | 
						|
  else
 | 
						|
    tmp_long = -1;
 | 
						|
 | 
						|
  if (!(tmp_long_list = (long*)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_INCREASE_LONG_LIST_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &tmp_long_list, (uint) (sizeof(long) * 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) link_count; roop_count++)
 | 
						|
  {
 | 
						|
    tmp_long_list[roop_count] = tmp_long;
 | 
						|
    DBUG_PRINT("info",("spider long_list[%d]=%ld", roop_count,
 | 
						|
      tmp_long));
 | 
						|
  }
 | 
						|
  if (*long_list)
 | 
						|
    spider_free(spider_current_trx, *long_list, MYF(0));
 | 
						|
  *list_length = link_count;
 | 
						|
  *long_list = tmp_long_list;
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
int spider_increase_longlong_list(
 | 
						|
  longlong **longlong_list,
 | 
						|
  uint *list_length,
 | 
						|
  uint link_count
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  longlong *tmp_longlong_list, tmp_longlong;
 | 
						|
  DBUG_ENTER("spider_increase_longlong_list");
 | 
						|
  if (*list_length == link_count)
 | 
						|
    DBUG_RETURN(0);
 | 
						|
  if (*list_length > 1)
 | 
						|
  {
 | 
						|
    my_printf_error(ER_SPIDER_DIFFERENT_LINK_COUNT_NUM,
 | 
						|
      ER_SPIDER_DIFFERENT_LINK_COUNT_STR, MYF(0));
 | 
						|
    DBUG_RETURN(ER_SPIDER_DIFFERENT_LINK_COUNT_NUM);
 | 
						|
  }
 | 
						|
 | 
						|
  if (*longlong_list)
 | 
						|
    tmp_longlong = (*longlong_list)[0];
 | 
						|
  else
 | 
						|
    tmp_longlong = -1;
 | 
						|
 | 
						|
  if (!(tmp_longlong_list = (longlong*)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_INCREASE_LONGLONG_LIST_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &tmp_longlong_list, (uint) (sizeof(longlong) * 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) link_count; roop_count++)
 | 
						|
  {
 | 
						|
    tmp_longlong_list[roop_count] = tmp_longlong;
 | 
						|
    DBUG_PRINT("info",("spider longlong_list[%d]=%lld", roop_count,
 | 
						|
      tmp_longlong));
 | 
						|
  }
 | 
						|
  if (*longlong_list)
 | 
						|
    spider_free(spider_current_trx, *longlong_list, MYF(0));
 | 
						|
  *list_length = link_count;
 | 
						|
  *longlong_list = tmp_longlong_list;
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
static int spider_set_ll_value(
 | 
						|
  longlong *value,
 | 
						|
  char *str
 | 
						|
) {
 | 
						|
  int error_num = 0;
 | 
						|
  DBUG_ENTER("spider_set_ll_value");
 | 
						|
  *value = my_strtoll10(str, (char**) NULL, &error_num);
 | 
						|
  DBUG_RETURN(error_num);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Find the index of a given key name in a table.
 | 
						|
 | 
						|
  Return the index if found, or -1 otherwise.
 | 
						|
*/
 | 
						|
static int spider_find_key_index(char *key_begin, uint key_len,
 | 
						|
                                 TABLE_SHARE *share)
 | 
						|
{
 | 
						|
  for (uint i= 0; i < share->keys; i++)
 | 
						|
    if (share->key_info[i].name.length == key_len &&
 | 
						|
        !strncmp(share->key_info[i].name.str, key_begin, key_len))
 | 
						|
      return i;
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
/* Convert a short key hint verb and append it to a string */
 | 
						|
static int spider_convert_and_append_hint_verb(char *short_verb_begin,
 | 
						|
                                               int short_verb_len,
 | 
						|
                                               spider_string *key_hint)
 | 
						|
{
 | 
						|
  switch (short_verb_len)
 | 
						|
  {
 | 
						|
  case 1:
 | 
						|
    if (!strncasecmp("f", short_verb_begin, 1))
 | 
						|
    {
 | 
						|
      key_hint->append(SPIDER_SQL_INDEX_FORCE_STR);
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    if (!strncasecmp("u", short_verb_begin, 1))
 | 
						|
    {
 | 
						|
      key_hint->append(SPIDER_SQL_INDEX_USE_STR);
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case 2:
 | 
						|
    if (!strncasecmp("ig", short_verb_begin, 2))
 | 
						|
    {
 | 
						|
      key_hint->append(SPIDER_SQL_INDEX_IGNORE_STR);
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    return 1;
 | 
						|
  }
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
/* Parse the IDX spider option */
 | 
						|
static int spider_parse_option_hint(char *hint, SPIDER_SHARE *share,
 | 
						|
                                    TABLE_SHARE *table_share)
 | 
						|
{
 | 
						|
  char *short_verb_begin= hint, *short_verb_end, *key_begin, *key_end;
 | 
						|
  int key_index;
 | 
						|
  spider_string *key_hint;
 | 
						|
  while (*short_verb_begin)
 | 
						|
  {
 | 
						|
    while (*short_verb_begin == ' ' || *short_verb_begin == '\t')
 | 
						|
      short_verb_begin++;
 | 
						|
    if (!*short_verb_begin)
 | 
						|
      break;
 | 
						|
    short_verb_end= short_verb_begin;
 | 
						|
    while (*short_verb_end && *short_verb_end != ' ' && *short_verb_end != '\t')
 | 
						|
      short_verb_end++;
 | 
						|
    key_begin= short_verb_end;
 | 
						|
    while (*key_begin == ' ' || *key_begin == '\t')
 | 
						|
      key_begin++;
 | 
						|
    key_end= key_begin;
 | 
						|
    while (*key_end && *key_end != ' ' && *key_end != '\t')
 | 
						|
      key_end++;
 | 
						|
    if ((key_index=
 | 
						|
         spider_find_key_index(key_begin, (uint) (key_end - key_begin),
 | 
						|
                               table_share))
 | 
						|
        == -1)
 | 
						|
      return 1;
 | 
						|
    key_hint= &share->key_hint[key_index];
 | 
						|
    if (spider_convert_and_append_hint_verb(
 | 
						|
          short_verb_begin, (int) (short_verb_end - short_verb_begin),
 | 
						|
          key_hint))
 | 
						|
      return 1;
 | 
						|
    key_hint->append(SPIDER_SQL_OPEN_PAREN_STR);
 | 
						|
    key_hint->append(table_share->key_info[key_index].name.str,
 | 
						|
                     table_share->key_info[key_index].name.length);
 | 
						|
    key_hint->append(SPIDER_SQL_CLOSE_PAREN_STR);
 | 
						|
    short_verb_begin= key_end;
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
#define SPIDER_PARAM_LEN(name) name ## _length
 | 
						|
#define SPIDER_PARAM_LENS(name) name ## _lengths
 | 
						|
#define SPIDER_PARAM_CHARLEN(name) name ## _charlen
 | 
						|
#define SPIDER_PARAM_STR(title_name, param_name)                        \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length))        \
 | 
						|
  {                                                                     \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start"));                 \
 | 
						|
    if (!share->param_name)                                             \
 | 
						|
    {                                                                   \
 | 
						|
      if ((share->param_name = spider_create_string(parse.start_value,  \
 | 
						|
                                                    value_length)))     \
 | 
						|
        share->SPIDER_PARAM_LEN(param_name) = strlen(share->param_name); \
 | 
						|
      else {                                                            \
 | 
						|
        error_num= parse.fail(true);                                    \
 | 
						|
        goto error;                                                     \
 | 
						|
      }                                                                 \
 | 
						|
      DBUG_PRINT("info",("spider " title_name "=%s", share->param_name)); \
 | 
						|
    } \
 | 
						|
    break; \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_STR_LIST(title_name, param_name)                   \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length))        \
 | 
						|
  {                                                                     \
 | 
						|
    DBUG_PRINT("info", ("spider " title_name " start"));                \
 | 
						|
    if (!share->param_name)                                             \
 | 
						|
    {                                                                   \
 | 
						|
      share->SPIDER_PARAM_CHARLEN(param_name)= value_length;            \
 | 
						|
      if ((error_num= spider_create_string_list(                        \
 | 
						|
             &share->param_name,                                        \
 | 
						|
             &share->SPIDER_PARAM_LENS(param_name),                     \
 | 
						|
             &share->SPIDER_PARAM_LEN(param_name),                      \
 | 
						|
             parse.start_value,                                         \
 | 
						|
             share->SPIDER_PARAM_CHARLEN(param_name))))                 \
 | 
						|
        goto error;                                                     \
 | 
						|
      THD *thd= current_thd;                                            \
 | 
						|
      if (share->SPIDER_PARAM_LEN(param_name) > 1 && create_table)      \
 | 
						|
      {                                                                 \
 | 
						|
        push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,        \
 | 
						|
                            HA_ERR_UNSUPPORTED,                         \
 | 
						|
                            "The high availability feature of Spider "  \
 | 
						|
                            "has been deprecated "                      \
 | 
						|
                            "and will be removed in a future release"); \
 | 
						|
      }                                                                 \
 | 
						|
    }                                                                   \
 | 
						|
    break;                                                              \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_HINT(title_name, param_name, check_length, max_size, append_method) \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, check_length)) \
 | 
						|
  { \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start")); \
 | 
						|
    DBUG_PRINT("info",("spider max_size=%d", max_size)); \
 | 
						|
    int hint_num = atoi(parse.start_title + check_length); \
 | 
						|
    DBUG_PRINT("info",("spider hint_num=%d", hint_num)); \
 | 
						|
    DBUG_PRINT("info",("spider share->param_name=%p", \
 | 
						|
                       share->param_name)); \
 | 
						|
    if (share->param_name) \
 | 
						|
    { \
 | 
						|
      if (hint_num < 0 || hint_num >= max_size) \
 | 
						|
      { \
 | 
						|
        error_num= parse.fail(true); \
 | 
						|
        goto error; \
 | 
						|
      } else if (share->param_name[hint_num].length() > 0) \
 | 
						|
        break; \
 | 
						|
      if ((error_num= append_method(&share->param_name[hint_num], \
 | 
						|
                                    parse.start_value))) \
 | 
						|
        goto error; \
 | 
						|
      DBUG_PRINT("info",("spider " title_name "[%d]=%s", hint_num, \
 | 
						|
                         share->param_name[hint_num].ptr())); \
 | 
						|
    } else { \
 | 
						|
      error_num= parse.fail(true); \
 | 
						|
      goto error; \
 | 
						|
    } \
 | 
						|
    break; \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_NUMHINT(title_name, param_name, check_length, max_size, append_method) \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, check_length)) \
 | 
						|
  { \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start")); \
 | 
						|
    DBUG_PRINT("info",("spider max_size=%d", max_size)); \
 | 
						|
    int hint_num = atoi(parse.start_title + check_length); \
 | 
						|
    DBUG_PRINT("info",("spider hint_num=%d", hint_num)); \
 | 
						|
    DBUG_PRINT("info",("spider share->param_name=%p", share->param_name)); \
 | 
						|
    if (share->param_name) \
 | 
						|
    { \
 | 
						|
      if (hint_num < 0 || hint_num >= max_size) \
 | 
						|
      { \
 | 
						|
        error_num= parse.fail(true); \
 | 
						|
        goto error; \
 | 
						|
      } else if (share->param_name[hint_num] != -1) \
 | 
						|
        break; \
 | 
						|
      if ((error_num = \
 | 
						|
           append_method(&share->param_name[hint_num], parse.start_value))) \
 | 
						|
        goto error; \
 | 
						|
      DBUG_PRINT("info",("spider " title_name "[%d]=%lld", hint_num, \
 | 
						|
                         share->param_name[hint_num])); \
 | 
						|
    } else { \
 | 
						|
      error_num= parse.fail(true); \
 | 
						|
      goto error; \
 | 
						|
    } \
 | 
						|
    break; \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_LONG_LIST_WITH_MAX(title_name, param_name,   \
 | 
						|
                                        min_val, max_val)         \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length))  \
 | 
						|
  {                                                               \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start"));           \
 | 
						|
    if (!share->param_name)                                       \
 | 
						|
    {                                                             \
 | 
						|
      if ((error_num = spider_create_long_list(                   \
 | 
						|
             &share->param_name,                                  \
 | 
						|
             &share->SPIDER_PARAM_LEN(param_name),                \
 | 
						|
             parse.start_value,                                   \
 | 
						|
             value_length,                                        \
 | 
						|
             min_val, max_val)))                                  \
 | 
						|
        goto error;                                               \
 | 
						|
    }                                                             \
 | 
						|
    break;                                                        \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(title_name, param_name, \
 | 
						|
                                            min_val, max_val)       \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length))    \
 | 
						|
  {                                                                 \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start"));             \
 | 
						|
    if (!share->param_name)                                         \
 | 
						|
    {                                                               \
 | 
						|
      if ((error_num = spider_create_longlong_list(                 \
 | 
						|
             &share->param_name,                                    \
 | 
						|
             &share->SPIDER_PARAM_LEN(param_name),                  \
 | 
						|
             parse.start_value,                                     \
 | 
						|
             value_length,                                          \
 | 
						|
             min_val, max_val)))                                    \
 | 
						|
        goto error;                                                 \
 | 
						|
    }                                                               \
 | 
						|
    break;                                                          \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_INT_WITH_MAX(title_name, param_name, min_val, max_val) \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length)) \
 | 
						|
  { \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start")); \
 | 
						|
    if (share->param_name == -1) \
 | 
						|
    { \
 | 
						|
      share->param_name = atoi(parse.start_value); \
 | 
						|
      if (share->param_name < min_val) \
 | 
						|
        share->param_name = min_val; \
 | 
						|
      else if (share->param_name > max_val) \
 | 
						|
        share->param_name = max_val; \
 | 
						|
      DBUG_PRINT("info",("spider " title_name "=%d", share->param_name)); \
 | 
						|
    } \
 | 
						|
    break; \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_INT(title_name, param_name, min_val) \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length)) \
 | 
						|
  { \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start")); \
 | 
						|
    if (share->param_name == -1) \
 | 
						|
    { \
 | 
						|
      share->param_name = atoi(parse.start_value); \
 | 
						|
      if (share->param_name < min_val) \
 | 
						|
        share->param_name = min_val; \
 | 
						|
      DBUG_PRINT("info",("spider " title_name "=%d", share->param_name)); \
 | 
						|
    } \
 | 
						|
    break; \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_DOUBLE(title_name, param_name, min_val) \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length)) \
 | 
						|
  { \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start")); \
 | 
						|
    if (share->param_name == -1) \
 | 
						|
    { \
 | 
						|
      share->param_name = my_atof(parse.start_value); \
 | 
						|
      if (share->param_name < min_val) \
 | 
						|
        share->param_name = min_val; \
 | 
						|
      DBUG_PRINT("info",("spider " title_name "=%f", share->param_name)); \
 | 
						|
    } \
 | 
						|
    break; \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_LONGLONG(title_name, param_name, min_val) \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length)) \
 | 
						|
  { \
 | 
						|
    DBUG_PRINT("info",("spider " title_name " start")); \
 | 
						|
    if (share->param_name == -1) \
 | 
						|
    { \
 | 
						|
      share->param_name = my_strtoll10(parse.start_value, (char**) NULL, \
 | 
						|
                                       &error_num); \
 | 
						|
      if (share->param_name < min_val) \
 | 
						|
        share->param_name = min_val; \
 | 
						|
      DBUG_PRINT("info",("spider " title_name "=%lld", share->param_name)); \
 | 
						|
    } \
 | 
						|
    break; \
 | 
						|
  }
 | 
						|
#define SPIDER_PARAM_DEPRECATED_WARNING(title_name, VER)                      \
 | 
						|
  if (!strncasecmp(parse.start_title, title_name, title_length) && create_table)        \
 | 
						|
    warn_deprecated<VER>(current_thd, title_name)
 | 
						|
 | 
						|
/**
 | 
						|
  Parse an option string into a string list and assign it to a
 | 
						|
  `SPIDER_SHARE' field
 | 
						|
*/
 | 
						|
#define SPIDER_OPTION_STR_LIST(option_name, param_name)                 \
 | 
						|
  if (options && options->option_name)                                  \
 | 
						|
  {                                                                     \
 | 
						|
    option_specified= TRUE;                                             \
 | 
						|
    share->SPIDER_PARAM_CHARLEN(param_name)=                            \
 | 
						|
      strlen(options->option_name);                                     \
 | 
						|
    if ((error_num= spider_create_string_list(                          \
 | 
						|
           &share->param_name, &share->SPIDER_PARAM_LENS(param_name),   \
 | 
						|
           &share->SPIDER_PARAM_LEN(param_name),                        \
 | 
						|
           options->option_name,                                        \
 | 
						|
           share->SPIDER_PARAM_CHARLEN(param_name))))                   \
 | 
						|
    {                                                                   \
 | 
						|
      goto error;                                                       \
 | 
						|
    }                                                                   \
 | 
						|
    if (share->SPIDER_PARAM_LEN(param_name) > 1 && create_table)        \
 | 
						|
    {                                                                   \
 | 
						|
      push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,  \
 | 
						|
                          HA_ERR_UNSUPPORTED,                           \
 | 
						|
                          "The high availability feature of Spider "    \
 | 
						|
                          "has been deprecated "                        \
 | 
						|
                          "and will be removed in a future release");   \
 | 
						|
    }                                                                   \
 | 
						|
  }
 | 
						|
 | 
						|
/**
 | 
						|
  Parse an option string into a non-negative int with an upper
 | 
						|
  bound, and assign it to a `SPIDER_SHARE' field
 | 
						|
*/
 | 
						|
#define SPIDER_OPTION_BOUNDED_NAT(option_title, option_name,            \
 | 
						|
                                  param_name, max_val)                  \
 | 
						|
  if (options && options->option_name)                                  \
 | 
						|
  {                                                                     \
 | 
						|
    option_specified= TRUE;                                             \
 | 
						|
    char *tail= options->option_name + strlen(options->option_name);    \
 | 
						|
    longlong converted= my_strtoll10(options->option_name, &tail,       \
 | 
						|
                                     &error_num);                       \
 | 
						|
    if (error_num || *tail || converted < 0 ||                          \
 | 
						|
        converted > max_val || converted > INT_MAX)                     \
 | 
						|
    {                                                                   \
 | 
						|
      error_num= ER_SPIDER_INVALID_TABLE_OPTION_NUM;                    \
 | 
						|
      my_printf_error(error_num, ER_SPIDER_INVALID_TABLE_OPTION_STR,    \
 | 
						|
                      MYF(0), option_title, options->option_name);      \
 | 
						|
      goto error;                                                       \
 | 
						|
    }                                                                   \
 | 
						|
    share->param_name= (int) converted;                                 \
 | 
						|
  }                                                                     \
 | 
						|
 | 
						|
/**
 | 
						|
  Parse an option string into a non-negative long array with an upper
 | 
						|
  bound, and assign it to a `SPIDER_SHARE' field
 | 
						|
*/
 | 
						|
#define SPIDER_OPTION_BOUNDED_NAT_LIST(option_title, option_name,       \
 | 
						|
                                       param_name, max_val)             \
 | 
						|
  if (options && options->option_name)                                  \
 | 
						|
  {                                                                     \
 | 
						|
    option_specified= TRUE;                                             \
 | 
						|
    if ((error_num = spider_create_bounded_nat_list(                    \
 | 
						|
           &share->param_name,                                          \
 | 
						|
           &share->SPIDER_PARAM_LEN(param_name),                        \
 | 
						|
           options->option_name,                                        \
 | 
						|
           strlen(options->option_name),                                \
 | 
						|
           max_val)))                                                   \
 | 
						|
    {                                                                   \
 | 
						|
      if (error_num != HA_ERR_OUT_OF_MEM)                               \
 | 
						|
      {                                                                 \
 | 
						|
        error_num= ER_SPIDER_INVALID_TABLE_OPTION_NUM;                  \
 | 
						|
        my_printf_error(error_num, ER_SPIDER_INVALID_TABLE_OPTION_STR,  \
 | 
						|
                        MYF(0), option_title, options->option_name);    \
 | 
						|
      }                                                                 \
 | 
						|
      goto error;                                                       \
 | 
						|
    }                                                                   \
 | 
						|
    if (share->SPIDER_PARAM_LEN(param_name) > 1 && create_table)        \
 | 
						|
    {                                                                   \
 | 
						|
      push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,  \
 | 
						|
                          HA_ERR_UNSUPPORTED,                           \
 | 
						|
                          "The high availability feature of Spider "    \
 | 
						|
                          "has been deprecated "                        \
 | 
						|
                          "and will be removed in a future release");   \
 | 
						|
    }                                                                   \
 | 
						|
  }                                                                     \
 | 
						|
 | 
						|
/**
 | 
						|
  Parse an option string into a non-negative `longlong', and assign it
 | 
						|
  to a `SPIDER_SHARE' field
 | 
						|
*/
 | 
						|
#define SPIDER_OPTION_NAT_LONGLONG(option_title, option_name, param_name) \
 | 
						|
  if (options && options->option_name)                                  \
 | 
						|
  {                                                                     \
 | 
						|
    option_specified= TRUE;                                             \
 | 
						|
    char *tail= options->option_name + strlen(options->option_name);    \
 | 
						|
    longlong converted = my_strtoll10(options->option_name, &tail,      \
 | 
						|
                                      &error_num);                      \
 | 
						|
    if (error_num || *tail != '\0' || converted < 0)                    \
 | 
						|
    {                                                                   \
 | 
						|
      error_num= ER_SPIDER_INVALID_TABLE_OPTION_NUM;                    \
 | 
						|
      my_printf_error(error_num, ER_SPIDER_INVALID_TABLE_OPTION_STR,    \
 | 
						|
                      MYF(0), option_title, options->option_name);      \
 | 
						|
      goto error;                                                       \
 | 
						|
    }                                                                   \
 | 
						|
    share->param_name = converted;                                      \
 | 
						|
  }                                                                     \
 | 
						|
 | 
						|
/**
 | 
						|
  Parse an option string into a boolean, and assign it to a
 | 
						|
  `SPIDER_SHARE' field.
 | 
						|
*/
 | 
						|
#define SPIDER_OPTION_BOOL(option_title, option_name, param_name)     \
 | 
						|
  if (options && options->option_name)                                \
 | 
						|
  {                                                                   \
 | 
						|
    option_specified= TRUE;                                           \
 | 
						|
    if (!strcmp("YES", options->option_name) ||                       \
 | 
						|
        !strcmp("1", options->option_name))                           \
 | 
						|
      share->param_name= TRUE;                                        \
 | 
						|
    else if (!strcmp("NO", options->option_name) ||                   \
 | 
						|
             !strcmp("0", options->option_name))                      \
 | 
						|
      share->param_name= FALSE;                                       \
 | 
						|
    else                                                              \
 | 
						|
    {                                                                 \
 | 
						|
      error_num= ER_SPIDER_INVALID_TABLE_OPTION_NUM;                  \
 | 
						|
      my_printf_error(error_num, ER_SPIDER_INVALID_TABLE_OPTION_STR,  \
 | 
						|
                      MYF(0), option_title, options->option_name);    \
 | 
						|
      goto error;                                                     \
 | 
						|
    }                                                                 \
 | 
						|
  }                                                                   \
 | 
						|
 | 
						|
/**
 | 
						|
  Parse an option string into index hints, and assign them to
 | 
						|
  `SPIDER_SHARE::key_hint'
 | 
						|
*/
 | 
						|
#define SPIDER_OPTION_HINT(option_title, option_name)                   \
 | 
						|
  if (options && options->option_name)                                  \
 | 
						|
  {                                                                     \
 | 
						|
    option_specified= TRUE;                                             \
 | 
						|
    if ((error_num= spider_parse_option_hint(options->option_name,      \
 | 
						|
                                             share, table_share)))      \
 | 
						|
    {                                                                   \
 | 
						|
      error_num= ER_SPIDER_INVALID_TABLE_OPTION_NUM;                    \
 | 
						|
      my_printf_error(error_num, ER_SPIDER_INVALID_TABLE_OPTION_STR,    \
 | 
						|
                      MYF(0), option_title, options->option_name);      \
 | 
						|
      goto error;                                                       \
 | 
						|
    }                                                                   \
 | 
						|
  }                                                                     \
 | 
						|
 | 
						|
/**
 | 
						|
  Assign -1 to some `SPIDER_SHARE' numeric fields, to indicate they
 | 
						|
  have not been specified by the user yet.
 | 
						|
*/
 | 
						|
static void spider_minus_1(SPIDER_SHARE *share, TABLE_SHARE *table_share)
 | 
						|
{
 | 
						|
  share->sts_bg_mode = -1;
 | 
						|
  share->sts_interval = -1;
 | 
						|
  share->sts_mode = -1;
 | 
						|
  share->sts_sync = -1;
 | 
						|
  share->store_last_sts = -1;
 | 
						|
  share->load_sts_at_startup = -1;
 | 
						|
  share->crd_bg_mode = -1;
 | 
						|
  share->crd_interval = -1;
 | 
						|
  share->crd_mode = -1;
 | 
						|
  share->crd_sync = -1;
 | 
						|
  share->store_last_crd = -1;
 | 
						|
  share->load_crd_at_startup = -1;
 | 
						|
  share->crd_type = -1;
 | 
						|
  share->crd_weight = -1;
 | 
						|
  share->internal_offset = -1;
 | 
						|
  share->internal_limit = -1;
 | 
						|
  share->split_read = -1;
 | 
						|
  share->semi_split_read = -1;
 | 
						|
  share->semi_split_read_limit = -1;
 | 
						|
  share->init_sql_alloc_size = -1;
 | 
						|
  share->reset_sql_alloc = -1;
 | 
						|
  share->multi_split_read = -1;
 | 
						|
  share->max_order = -1;
 | 
						|
  share->semi_table_lock = -1;
 | 
						|
  share->semi_table_lock_conn = -1;
 | 
						|
  share->selupd_lock_mode = -1;
 | 
						|
  share->query_cache = -1;
 | 
						|
  share->query_cache_sync = -1;
 | 
						|
  share->bulk_size = -1;
 | 
						|
  share->bulk_update_mode = -1;
 | 
						|
  share->bulk_update_size = -1;
 | 
						|
  share->buffer_size = -1;
 | 
						|
  share->internal_optimize = -1;
 | 
						|
  share->internal_optimize_local = -1;
 | 
						|
  share->scan_rate = -1;
 | 
						|
  share->read_rate = -1;
 | 
						|
  share->priority = -1;
 | 
						|
  share->quick_mode = -1;
 | 
						|
  share->quick_page_size = -1;
 | 
						|
  share->quick_page_byte = -1;
 | 
						|
  share->low_mem_read = -1;
 | 
						|
  share->table_count_mode = -1;
 | 
						|
  share->select_column_mode = -1;
 | 
						|
  share->bgs_mode = -1;
 | 
						|
  share->bgs_first_read = -1;
 | 
						|
  share->bgs_second_read = -1;
 | 
						|
  share->first_read = -1;
 | 
						|
  share->second_read = -1;
 | 
						|
  share->auto_increment_mode = -1;
 | 
						|
  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;
 | 
						|
  share->read_only_mode = -1;
 | 
						|
  share->error_read_mode = -1;
 | 
						|
  share->error_write_mode = -1;
 | 
						|
  share->active_link_count = -1;
 | 
						|
#ifdef HA_CAN_FORCE_BULK_UPDATE
 | 
						|
  share->force_bulk_update = -1;
 | 
						|
#endif
 | 
						|
#ifdef HA_CAN_FORCE_BULK_DELETE
 | 
						|
  share->force_bulk_delete = -1;
 | 
						|
#endif
 | 
						|
  share->casual_read = -1;
 | 
						|
  share->delete_all_rows_type = -1;
 | 
						|
  share->static_records_for_status = -1;
 | 
						|
  share->static_mean_rec_length = -1;
 | 
						|
  for (uint i = 0; i < table_share->keys; i++)
 | 
						|
  {
 | 
						|
    share->static_key_cardinality[i] = -1;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get the connect info of a certain type.
 | 
						|
 | 
						|
  @param  type              The type of the connect info.
 | 
						|
                            4: partition; 3: subpartition; 2: comment;
 | 
						|
                            1: connect_string
 | 
						|
  @retval 0                 Success
 | 
						|
  @retval 1                 Not applicable. That is, the info with the
 | 
						|
                            type is missing
 | 
						|
  @retval HA_ERR_OUT_OF_MEM Failure
 | 
						|
*/
 | 
						|
static int spider_get_connect_info(const int type,
 | 
						|
                                   const partition_element *part_elem,
 | 
						|
                                   const partition_element *sub_elem,
 | 
						|
                                   const TABLE_SHARE* table_share,
 | 
						|
                                   char*& out)
 | 
						|
{
 | 
						|
  switch (type)
 | 
						|
  {
 | 
						|
  case 4:
 | 
						|
    if (!sub_elem || !sub_elem->part_comment)
 | 
						|
      return 1;
 | 
						|
    if (!(out = spider_create_string(
 | 
						|
            sub_elem->part_comment, strlen(sub_elem->part_comment))))
 | 
						|
      return HA_ERR_OUT_OF_MEM;
 | 
						|
    break;
 | 
						|
  case 3:
 | 
						|
    if (!part_elem || !part_elem->part_comment)
 | 
						|
      return 1;
 | 
						|
    if (!(out = spider_create_string(
 | 
						|
            part_elem->part_comment, strlen(part_elem->part_comment))))
 | 
						|
      return HA_ERR_OUT_OF_MEM;
 | 
						|
    break;
 | 
						|
  case 2:
 | 
						|
    if (table_share->comment.length == 0)
 | 
						|
      return 1;
 | 
						|
    if (!(out = spider_create_string(
 | 
						|
            table_share->comment.str, table_share->comment.length)))
 | 
						|
      return HA_ERR_OUT_OF_MEM;
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    if (table_share->connect_string.length == 0)
 | 
						|
      return 1;
 | 
						|
    DBUG_PRINT("info",("spider create out string"));
 | 
						|
    if (!(out = spider_create_string(
 | 
						|
          table_share->connect_string.str, table_share->connect_string.length)))
 | 
						|
      return HA_ERR_OUT_OF_MEM;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find the beginning and end of a parameter title
 | 
						|
 | 
						|
  Skip over whitespace to find the beginning of the parameter
 | 
						|
  title. Then skip over non-whitespace/quote/nul chars to find the end
 | 
						|
  of the parameter title
 | 
						|
 | 
						|
  @param  start_title  The start of the param definition. Will be
 | 
						|
                       moved to the start of the param title
 | 
						|
  @param  end_title    Will be moved to the end of the param title
 | 
						|
  @retval false        Success
 | 
						|
  @retval true         Failure
 | 
						|
*/
 | 
						|
static bool spider_parse_find_title(char*& start_title, char*& end_title)
 | 
						|
{
 | 
						|
  /* Skip leading whitespaces. */
 | 
						|
  while (*start_title == ' ' || *start_title == '\r' ||
 | 
						|
         *start_title == '\n' || *start_title == '\t')
 | 
						|
    start_title++;
 | 
						|
 | 
						|
  if (*start_title == '\0')
 | 
						|
    return true;
 | 
						|
 | 
						|
  end_title = start_title;
 | 
						|
  /* Move over non-whitespace/comma/nul/quote chars (parameter title). */
 | 
						|
  while (*end_title != ' ' && *end_title != '\r' &&
 | 
						|
         *end_title != '\n' && *end_title != '\t' &&
 | 
						|
         *end_title != '\0' && *end_title != ',' &&
 | 
						|
         *end_title != '\'' && *end_title != '"')
 | 
						|
    end_title++;
 | 
						|
 | 
						|
  /* Fail on invalid end: there should be at least one space between
 | 
						|
  title and value, and the value should be non-empty. */
 | 
						|
  if (*end_title == '\'' || *end_title == '"' ||
 | 
						|
      *end_title == '\0' || *end_title == ',')
 | 
						|
    return true;
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find the beginning and the end of a paramter value, and the value
 | 
						|
  delimiter
 | 
						|
 | 
						|
  Skip over whitespaces to find the start delimiter, then skip over
 | 
						|
  the param value to find the end delimiter
 | 
						|
 | 
						|
  @param  start_value  The end of the param title. Will be moved to
 | 
						|
                       the start of the param value, just after the
 | 
						|
                       delimiter
 | 
						|
  @param  end_value    Will be moved to the end of the param value, at
 | 
						|
                       the delimiter
 | 
						|
  @param  delim        Will be assigned the param value delimiter,
 | 
						|
                       either the single or double quote
 | 
						|
  @retval false        Success
 | 
						|
  @retval true         Failure
 | 
						|
*/
 | 
						|
static bool spider_parse_find_value(char*& start_value, char*& end_value,
 | 
						|
                                    char& delim)
 | 
						|
{
 | 
						|
  /* Skip over whitespaces */
 | 
						|
  while (*start_value == ' ' || *start_value == '\r' ||
 | 
						|
         *start_value == '\n' || *start_value == '\t')
 | 
						|
    start_value++;
 | 
						|
  if (*start_value != '"' && *start_value != '\'')
 | 
						|
    return true;
 | 
						|
  delim= *start_value;
 | 
						|
  end_value= start_value++;
 | 
						|
 | 
						|
  while (1)
 | 
						|
  {
 | 
						|
    end_value++;
 | 
						|
    /* Escaping */
 | 
						|
    if (*end_value == '\\')
 | 
						|
    {
 | 
						|
      end_value++;
 | 
						|
      /* The backslash cannot be at the end */
 | 
						|
      if (*end_value == '\0')
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
    else if (*end_value == delim)
 | 
						|
      return false;
 | 
						|
    else if (*end_value == '\0')
 | 
						|
      return true;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find the beginning of the next parameter
 | 
						|
 | 
						|
  Skip over whitespaces, then check that the first non-whitespace char
 | 
						|
  is a comma or the end of string
 | 
						|
 | 
						|
  @param  start_param  The end of the param value. Will be moved to
 | 
						|
                       the start of the next param definition, just
 | 
						|
                       after the comma, if there's one; otherwise will
 | 
						|
                       be moved to the end of the string
 | 
						|
  @retval false        Success
 | 
						|
  @retval true         Failure
 | 
						|
*/
 | 
						|
static bool spider_parse_find_next(char*& start_param)
 | 
						|
{
 | 
						|
  /* Skip over whitespaces */
 | 
						|
  while (*start_param == ' ' || *start_param == '\r' ||
 | 
						|
         *start_param == '\n' || *start_param == '\t')
 | 
						|
    start_param++;
 | 
						|
  /* No more param definitions */
 | 
						|
  if (*start_param == '\0')
 | 
						|
    return false;
 | 
						|
  else if (*start_param == ',')
 | 
						|
  {
 | 
						|
    start_param++;
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find the start and end of the current param title and value and the
 | 
						|
  value deliminator.
 | 
						|
 | 
						|
  @param  start_param    The beginning of the current param
 | 
						|
                         definition. Will be mutated to the beginning
 | 
						|
                         of the next param definition.
 | 
						|
  @retval false  success
 | 
						|
  @retval true   failure
 | 
						|
*/
 | 
						|
bool st_spider_param_string_parse::locate_param_def(char*& start_param)
 | 
						|
{
 | 
						|
  DBUG_ENTER("parse::locate_param_def");
 | 
						|
  start_title= start_param;
 | 
						|
  if (spider_parse_find_title(start_title, end_title))
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  start_value= end_title;
 | 
						|
  if (spider_parse_find_value(start_value, end_value, delim_value))
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  /* skip the delim */
 | 
						|
  start_param= end_value + 1;
 | 
						|
  if (spider_parse_find_next(start_param))
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Handle parsing failure.
 | 
						|
 | 
						|
  Print error and optionally restore param value end delimiter that
 | 
						|
  has been nulled before.
 | 
						|
 | 
						|
  @param  restore_delim  If true, restore the end value delimiter
 | 
						|
  @return                The error number
 | 
						|
*/
 | 
						|
int st_spider_param_string_parse::fail(bool restore_delim)
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_parse_print_param_error");
 | 
						|
  DBUG_ASSERT(error_num != 0);
 | 
						|
  /* Print the error message */
 | 
						|
  switch (error_num)
 | 
						|
  {
 | 
						|
  case ER_SPIDER_INVALID_UDF_PARAM_NUM:
 | 
						|
    my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
 | 
						|
                    MYF(0), start_title);
 | 
						|
    break;
 | 
						|
  case ER_SPIDER_INVALID_CONNECT_INFO_NUM:
 | 
						|
  default:
 | 
						|
    my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
 | 
						|
                    MYF(0), start_title);
 | 
						|
  }
 | 
						|
  if (restore_delim)
 | 
						|
    *end_value = delim_value;
 | 
						|
  DBUG_RETURN(error_num);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
  Parse connection information specified by COMMENT, CONNECT, or engine-defined
 | 
						|
  options.
 | 
						|
*/
 | 
						|
int spider_parse_connect_info(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  TABLE_SHARE *table_share,
 | 
						|
  partition_info *part_info,
 | 
						|
  uint create_table)
 | 
						|
{
 | 
						|
  int error_num = 0;
 | 
						|
  char *connect_string = NULL;
 | 
						|
  char *start_param;
 | 
						|
  int title_length, value_length;
 | 
						|
  SPIDER_PARAM_STRING_PARSE parse;
 | 
						|
  SPIDER_ALTER_TABLE *share_alter;
 | 
						|
  ha_table_option_struct *options;
 | 
						|
  partition_element *part_elem;
 | 
						|
  partition_element *sub_elem;
 | 
						|
  bool option_specified= FALSE;
 | 
						|
  DBUG_ENTER("spider_parse_connect_info");
 | 
						|
  DBUG_PRINT("info",("spider partition_info=%s",
 | 
						|
    table_share->partition_info_str));
 | 
						|
  DBUG_PRINT("info",("spider part_info=%p", part_info));
 | 
						|
  DBUG_PRINT("info",("spider s->db=%s", table_share->db.str));
 | 
						|
  DBUG_PRINT("info",("spider s->table_name=%s", table_share->table_name.str));
 | 
						|
  DBUG_PRINT("info",("spider s->path=%s", table_share->path.str));
 | 
						|
  DBUG_PRINT("info",
 | 
						|
    ("spider s->normalized_path=%s", table_share->normalized_path.str));
 | 
						|
  parse.error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
 | 
						|
  spider_get_partition_info(share->table_name, share->table_name_length,
 | 
						|
    table_share, part_info, &part_elem, &sub_elem);
 | 
						|
  /* Find the correct table options, depending on if we are parsing a
 | 
						|
  table, a partition, or a sub-partition. */
 | 
						|
  if (part_info)
 | 
						|
    if (part_info->is_sub_partitioned())
 | 
						|
      options= sub_elem->option_struct;
 | 
						|
    else
 | 
						|
      options= part_elem->option_struct;
 | 
						|
  else
 | 
						|
    options= table_share->option_struct;
 | 
						|
  spider_minus_1(share, table_share);
 | 
						|
 | 
						|
  /* Parse through all option fields, and flip option_specified if
 | 
						|
  any option field is not null. */
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("AUTO_INCREMENT_MODE", auto_increment_mode,
 | 
						|
                            auto_increment_mode, 3);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("BGS_MODE", bgs_mode, bgs_mode, 3);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("BULK_SIZE", bulk_size, bulk_size, 2147483647);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("BULK_UPDATE_SIZE", bulk_update_size,
 | 
						|
                            bulk_update_size, 2147483647);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT_LIST("CONNECT_TIMEOUT", connect_timeout,
 | 
						|
                                 connect_timeouts, 2147483647);
 | 
						|
  SPIDER_OPTION_STR_LIST(database, tgt_dbs);
 | 
						|
  SPIDER_OPTION_STR_LIST(default_file, tgt_default_files);
 | 
						|
  SPIDER_OPTION_STR_LIST(default_group, tgt_default_groups);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("DELETE_ALL_ROWS_TYPE", delete_all_rows_type,
 | 
						|
                            delete_all_rows_type, 1);
 | 
						|
  SPIDER_OPTION_STR_LIST(driver, tgt_drivers);
 | 
						|
  SPIDER_OPTION_STR_LIST(dsn, tgt_dsns);
 | 
						|
  SPIDER_OPTION_STR_LIST(filedsn, tgt_filedsns);
 | 
						|
  SPIDER_OPTION_BOOL("FORCE_BULK_DELETE", force_bulk_delete,
 | 
						|
                     force_bulk_delete);
 | 
						|
  SPIDER_OPTION_BOOL("FORCE_BULK_UPDATE", force_bulk_update,
 | 
						|
                     force_bulk_update);
 | 
						|
  SPIDER_OPTION_STR_LIST(host, tgt_hosts);
 | 
						|
  SPIDER_OPTION_HINT("IDX", idx);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("MULTI_SPLIT_READ", multi_split_read,
 | 
						|
                            multi_split_read, 2147483647);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT_LIST("NET_READ_TIMEOUT", net_read_timeout,
 | 
						|
                                 net_read_timeouts, 2147483647);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT_LIST("NET_WRITE_TIMEOUT", net_write_timeout,
 | 
						|
                                 net_write_timeouts, 2147483647);
 | 
						|
  SPIDER_OPTION_STR_LIST(password, tgt_passwords);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT_LIST("REMOTE_PORT", port, tgt_ports, 65535);
 | 
						|
  SPIDER_OPTION_NAT_LONGLONG("PRIORITY", priority, priority);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("QUERY_CACHE", query_cache, query_cache, 2);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("QUERY_CACHE_SYNC", query_cache_sync,
 | 
						|
                            query_cache_sync, 3);
 | 
						|
  SPIDER_OPTION_BOOL("READ_ONLY", read_only, read_only_mode);
 | 
						|
  SPIDER_OPTION_STR_LIST(server, server_names);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("SKIP_PARALLEL_SEARCH", skip_parallel_search,
 | 
						|
                            skip_parallel_search, 3);
 | 
						|
  SPIDER_OPTION_STR_LIST(socket, tgt_sockets);
 | 
						|
  SPIDER_OPTION_STR_LIST(ssl_capath, tgt_ssl_capaths);
 | 
						|
  SPIDER_OPTION_STR_LIST(ssl_ca, tgt_ssl_cas);
 | 
						|
  SPIDER_OPTION_STR_LIST(ssl_cert, tgt_ssl_certs);
 | 
						|
  SPIDER_OPTION_STR_LIST(ssl_cipher, tgt_ssl_ciphers);
 | 
						|
  SPIDER_OPTION_STR_LIST(ssl_key, tgt_ssl_keys);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT_LIST("SSL_VSC", ssl_vsc, tgt_ssl_vscs, 1);
 | 
						|
  SPIDER_OPTION_STR_LIST(table, tgt_table_names);
 | 
						|
  SPIDER_OPTION_BOUNDED_NAT("TABLE_COUNT_MODE", table_count_mode,
 | 
						|
                            table_count_mode, 3);
 | 
						|
  SPIDER_OPTION_STR_LIST(username, tgt_usernames);
 | 
						|
  SPIDER_OPTION_BOOL("USE_PUSHDOWN_UDF", use_pushdown_udf, use_pushdown_udf);
 | 
						|
  SPIDER_OPTION_STR_LIST(wrapper, tgt_wrappers);
 | 
						|
 | 
						|
  /* Parse the connect strings, from the most specific level
 | 
						|
  (sub-partition, i=4) to the least (CONNECTION string, i=1). */
 | 
						|
  for (int i = 4; i > 0; i--)
 | 
						|
  {
 | 
						|
    if (connect_string)
 | 
						|
    {
 | 
						|
      spider_free(spider_current_trx, connect_string, MYF(0));
 | 
						|
      connect_string = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Get the correct connect info for the current level. */
 | 
						|
    int error_num_1 = spider_get_connect_info(i, part_elem, sub_elem,
 | 
						|
                                              table_share, connect_string);
 | 
						|
    if (error_num_1 == 1)
 | 
						|
      continue;
 | 
						|
    if (error_num_1 == HA_ERR_OUT_OF_MEM)
 | 
						|
    {
 | 
						|
      error_num= HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_alloc_conn_string;
 | 
						|
    }
 | 
						|
    DBUG_ASSERT(error_num_1 == 0);
 | 
						|
    /*
 | 
						|
      If the COMMENT or CONNECTION string is explicitly ignored for
 | 
						|
      table param parsing, or if any option is specified, skip the
 | 
						|
      parsing.
 | 
						|
    */
 | 
						|
    if (spider_param_ignore_comments(current_thd) || option_specified)
 | 
						|
    {
 | 
						|
      if (!spider_param_suppress_comment_ignored_warning(current_thd))
 | 
						|
        push_warning_printf(
 | 
						|
          current_thd, Sql_condition::WARN_LEVEL_WARN,
 | 
						|
          ER_SPIDER_COMMENT_CONNECTION_IGNORED_BY_TABLE_OPTIONS_NUM,
 | 
						|
          ER_SPIDER_COMMENT_CONNECTION_IGNORED_BY_TABLE_OPTIONS_STR,
 | 
						|
          connect_string);
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (create_table)
 | 
						|
      push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
 | 
						|
                          HA_ERR_UNSUPPORTED,
 | 
						|
                          "Spider table params in COMMENT or CONNECTION "
 | 
						|
                          "strings have been deprecated "
 | 
						|
                          "and will be removed in a future release. "
 | 
						|
                          "Please use table options instead.");
 | 
						|
    start_param = connect_string;
 | 
						|
    while (*start_param != '\0')
 | 
						|
    {
 | 
						|
      if (parse.locate_param_def(start_param))
 | 
						|
      {
 | 
						|
        error_num= parse.fail(false);
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
      /* Null the end of the parameter value. */
 | 
						|
      *parse.end_value= '\0';
 | 
						|
      value_length= (int) (parse.end_value - parse.start_value);
 | 
						|
      switch (title_length = (int) (parse.end_title - parse.start_title))
 | 
						|
      {
 | 
						|
        case 0:
 | 
						|
          error_num= parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 3:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("abl", 1104);
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX("abl", access_balances, 0,
 | 
						|
            2147483647);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("aim", auto_increment_mode, 0, 3);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("alc", 1104);
 | 
						|
          SPIDER_PARAM_INT("alc", active_link_count, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("bfz", 1007);
 | 
						|
          SPIDER_PARAM_INT("bfz", buffer_size, 0);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("bfr", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG("bfr", bgs_first_read, 0);
 | 
						|
          SPIDER_PARAM_INT("bmd", bgs_mode, 0);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("bsr", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG("bsr", bgs_second_read, 0);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("bke", 1104);
 | 
						|
          SPIDER_PARAM_STR("bke", bka_engine);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("bkm", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("bkm", bka_mode, 0, 2);
 | 
						|
          SPIDER_PARAM_INT("bsz", bulk_size, 0);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("btt", 1007);
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX("btt", bka_table_name_types,
 | 
						|
            0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("bum", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("bum", bulk_update_mode, 0, 2);
 | 
						|
          SPIDER_PARAM_INT("bus", bulk_update_size, 0);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("cbm", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("cbm", crd_bg_mode, 0, 2);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("civ", 1104);
 | 
						|
          SPIDER_PARAM_DOUBLE("civ", crd_interval, 0);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("cmd", 1007);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("cmd", crd_mode, 0, 3);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("csr", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("csr", casual_read, 0, 63);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("csy", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("csy", crd_sync, 0, 2);
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX("cto", connect_timeouts, 0,
 | 
						|
            2147483647);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("ctp", 1007);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("ctp", crd_type, 0, 2);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("cwg", 1007);
 | 
						|
          SPIDER_PARAM_DOUBLE("cwg", crd_weight, 1);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("dat", delete_all_rows_type, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("ddi", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("ddi", direct_dup_insert, 0, 1);
 | 
						|
          SPIDER_PARAM_STR_LIST("dff", tgt_default_files);
 | 
						|
          SPIDER_PARAM_STR_LIST("dfg", tgt_default_groups);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("dol", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG("dol", direct_order_limit, 0);
 | 
						|
          SPIDER_PARAM_STR_LIST("drv", tgt_drivers);
 | 
						|
          SPIDER_PARAM_STR_LIST("dsn", tgt_dsns);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("erm", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("erm", error_read_mode, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("ewm", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("ewm", error_write_mode, 0, 1);
 | 
						|
#ifdef HA_CAN_FORCE_BULK_DELETE
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("fbd", force_bulk_delete, 0, 1);
 | 
						|
#endif
 | 
						|
#ifdef HA_CAN_FORCE_BULK_UPDATE
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX("fbu", force_bulk_update, 0, 1);
 | 
						|
#endif
 | 
						|
        SPIDER_PARAM_STR_LIST("fds", tgt_filedsns);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("frd", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("frd", first_read, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("isa", 1007);
 | 
						|
        SPIDER_PARAM_INT("isa", init_sql_alloc_size, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("ilm", 1007);
 | 
						|
        SPIDER_PARAM_LONGLONG("ilm", internal_limit, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("ios", 1007);
 | 
						|
        SPIDER_PARAM_LONGLONG("ios", internal_offset, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("iom", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("iom", internal_optimize, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("iol", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("iol", internal_optimize_local, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("lmr", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("lmr", low_mem_read, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("lcs", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("lcs", load_crd_at_startup, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("lss", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("lss", load_sts_at_startup, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("lst", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("lst", link_statuses, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mbf", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("mbf", monitoring_bg_flag, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mbi", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
 | 
						|
          "mbi", monitoring_bg_interval, 0, 4294967295LL);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mbk", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("mbk", monitoring_bg_kind, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mbp", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("mbp", monitoring_binlog_pos_at_failing, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mfg", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("mfg", monitoring_flag, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mkd", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("mkd", monitoring_kind, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mlt", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
 | 
						|
          "mlt", monitoring_limit, 0, 9223372036854775807LL);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("mod", 1104);
 | 
						|
        SPIDER_PARAM_INT("mod", max_order, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("msi", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
 | 
						|
          "msi", monitoring_sid, 0, 4294967295LL);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("msr", multi_split_read, 0, 2147483647);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("nrt", net_read_timeouts, 0,
 | 
						|
                                        2147483647);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("nwt", net_write_timeouts, 0,
 | 
						|
                                        2147483647);
 | 
						|
        SPIDER_PARAM_STR_LIST("pkn", tgt_pk_names);
 | 
						|
        SPIDER_PARAM_LONGLONG("prt", priority, 0);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("qch", query_cache, 0, 2);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("qcs", query_cache_sync, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("qmd", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("qmd", quick_mode, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("qpb", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("qpb", quick_page_byte, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("qps", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("qps", quick_page_size, 0);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("rom", read_only_mode, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("rrt", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("rrt", read_rate, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("rsa", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("rsa", reset_sql_alloc, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sbm", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("sbm", sts_bg_mode, 0, 2);
 | 
						|
        SPIDER_PARAM_STR_LIST("sca", tgt_ssl_cas);
 | 
						|
        SPIDER_PARAM_STR_LIST("sch", tgt_ssl_ciphers);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("scm", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("scm", select_column_mode, 0, 1);
 | 
						|
        SPIDER_PARAM_STR_LIST("scp", tgt_ssl_capaths);
 | 
						|
        SPIDER_PARAM_STR_LIST("scr", tgt_ssl_certs);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sdc", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("sdc", skip_default_condition, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sgb", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("sgb", strict_group_bys, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("siv", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("siv", sts_interval, 0);
 | 
						|
        SPIDER_PARAM_STR_LIST("sky", tgt_ssl_keys);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sli", 1104);
 | 
						|
        SPIDER_PARAM_STR_LIST("sli", static_link_ids);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("slc", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("slc", store_last_crd, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("slm", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("slm", selupd_lock_mode, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sls", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("sls", store_last_sts, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("smd", 1007);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("smd", sts_mode, 1, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("smr", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("smr", static_mean_rec_length, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("spr", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("spr", split_read, 0);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("sps", skip_parallel_search, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sqn", 1104);
 | 
						|
        SPIDER_PARAM_STR_LIST("sqn", tgt_sequence_names);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("srd", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("srd", second_read, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("srt", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("srt", scan_rate, 0);
 | 
						|
        SPIDER_PARAM_STR_LIST("srv", server_names);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("ssr", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("ssr", semi_split_read, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("ssl", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("ssl", semi_split_read_limit, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("ssy", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("ssy", sts_sync, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("stc", 1007);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("stc", semi_table_lock_conn, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("stl", 1007);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("stl", semi_table_lock, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("srs", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("srs", static_records_for_status, 0);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("svc", tgt_ssl_vscs, 0, 1);
 | 
						|
        SPIDER_PARAM_STR_LIST("tbl", tgt_table_names);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("tcm", table_count_mode, 0, 3);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("upu", use_pushdown_udf, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("utc", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("utc", use_table_charset, 0, 1);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 4:
 | 
						|
        SPIDER_PARAM_STR_LIST("host", tgt_hosts);
 | 
						|
        SPIDER_PARAM_STR_LIST("user", tgt_usernames);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("port", tgt_ports, 0, 65535);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 5:
 | 
						|
        SPIDER_PARAM_STR_LIST("table", tgt_table_names);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 6:
 | 
						|
        SPIDER_PARAM_STR_LIST("driver", tgt_drivers);
 | 
						|
        SPIDER_PARAM_STR_LIST("server", server_names);
 | 
						|
        SPIDER_PARAM_STR_LIST("socket", tgt_sockets);
 | 
						|
        SPIDER_PARAM_HINT("idx", key_hint, 3, (int) table_share->keys,
 | 
						|
                          spider_db_append_key_hint);
 | 
						|
        SPIDER_PARAM_STR_LIST("ssl_ca", tgt_ssl_cas);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("skc", 1104);
 | 
						|
        SPIDER_PARAM_NUMHINT("skc", static_key_cardinality, 3,
 | 
						|
                             (int) table_share->keys, spider_set_ll_value);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 7:
 | 
						|
        SPIDER_PARAM_STR_LIST("filedsn", tgt_filedsns);
 | 
						|
        SPIDER_PARAM_STR_LIST("wrapper", tgt_wrappers);
 | 
						|
        SPIDER_PARAM_STR_LIST("ssl_key", tgt_ssl_keys);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("pk_name", 1104);
 | 
						|
        SPIDER_PARAM_STR_LIST("pk_name", tgt_pk_names);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 8:
 | 
						|
        SPIDER_PARAM_STR_LIST("database", tgt_dbs);
 | 
						|
        SPIDER_PARAM_STR_LIST("password", tgt_passwords);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sts_mode", 1007);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("sts_mode", sts_mode, 1, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sts_sync", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("sts_sync", sts_sync, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("crd_mode", 1007);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("crd_mode", crd_mode, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("crd_sync", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("crd_sync", crd_sync, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("crd_type", 1007);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("crd_type", crd_type, 0, 2);
 | 
						|
        SPIDER_PARAM_LONGLONG("priority", priority, 0);
 | 
						|
        SPIDER_PARAM_INT("bgs_mode", bgs_mode, 0);
 | 
						|
        SPIDER_PARAM_STR_LIST("ssl_cert", tgt_ssl_certs);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("bka_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("bka_mode", bka_mode, 0, 2);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 9:
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("max_order", 1104);
 | 
						|
        SPIDER_PARAM_INT("max_order", max_order, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("bulk_size", 1104);
 | 
						|
        SPIDER_PARAM_INT("bulk_size", bulk_size, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("scan_rate", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("scan_rate", scan_rate, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("read_rate", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("read_rate", read_rate, 0);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 10:
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("crd_weight", 1007);
 | 
						|
        SPIDER_PARAM_DOUBLE("crd_weight", crd_weight, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("split_read", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("split_read", split_read, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("quick_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("quick_mode", quick_mode, 0, 3);
 | 
						|
        SPIDER_PARAM_STR_LIST("ssl_cipher", tgt_ssl_ciphers);
 | 
						|
        SPIDER_PARAM_STR_LIST("ssl_capath", tgt_ssl_capaths);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("bka_engine", 1104);
 | 
						|
        SPIDER_PARAM_STR("bka_engine", bka_engine);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("first_read", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("first_read", first_read, 0);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 11:
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("query_cache", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("query_cache", query_cache, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("crd_bg_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("crd_bg_mode", crd_bg_mode, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sts_bg_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("sts_bg_mode", sts_bg_mode, 0, 2);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("link_status", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("link_status", link_statuses, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("casual_read", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("casual_read", casual_read, 0, 63);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("buffer_size", 1007);
 | 
						|
        SPIDER_PARAM_INT("buffer_size", buffer_size, 0);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 12:
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sts_interval", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("sts_interval", sts_interval, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("crd_interval", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("crd_interval", crd_interval, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("low_mem_read", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("low_mem_read", low_mem_read, 0, 1);
 | 
						|
        SPIDER_PARAM_STR_LIST("default_file", tgt_default_files);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 13:
 | 
						|
        SPIDER_PARAM_STR_LIST("default_group", tgt_default_groups);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("sequence_name", 1104);
 | 
						|
        SPIDER_PARAM_STR_LIST("sequence_name", tgt_sequence_names);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 14:
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("internal_limit", 1007);
 | 
						|
        SPIDER_PARAM_LONGLONG("internal_limit", internal_limit, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("bgs_first_read", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("bgs_first_read", bgs_first_read, 0);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("read_only_mode", read_only_mode, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("access_balance", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("access_balance", access_balances, 0,
 | 
						|
                                        2147483647);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("static_link_id", 1104);
 | 
						|
        SPIDER_PARAM_STR_LIST("static_link_id", static_link_ids);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("store_last_crd", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("store_last_crd", store_last_crd, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("store_last_sts", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("store_last_sts", store_last_sts, 0, 1);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 15:
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("internal_offset", 1007);
 | 
						|
        SPIDER_PARAM_LONGLONG("internal_offset", internal_offset, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("reset_sql_alloc", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("reset_sql_alloc", reset_sql_alloc, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("semi_table_lock", 1007);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("semi_table_lock", semi_table_lock, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("quick_page_byte", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("quick_page_byte", quick_page_byte, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("quick_page_size", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("quick_page_size", quick_page_size, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("bgs_second_read", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG("bgs_second_read", bgs_second_read, 0);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("monitoring_flag", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_flag", monitoring_flag, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("monitoring_kind", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_kind", monitoring_kind, 0, 3);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("semi_split_read", 1104);
 | 
						|
        SPIDER_PARAM_DOUBLE("semi_split_read", semi_split_read, 0);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("connect_timeout", connect_timeouts,
 | 
						|
                                        0, 2147483647);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("strict_group_by", 1104);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("strict_group_by",
 | 
						|
                                        strict_group_bys, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("error_read_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX("error_read_mode", error_read_mode, 0, 1);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 16:
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "multi_split_read", multi_split_read, 0, 2147483647);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("selupd_lock_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "selupd_lock_mode", selupd_lock_mode, 0, 2);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "table_count_mode", table_count_mode, 0, 3);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "use_pushdown_udf", use_pushdown_udf, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("monitoring_limit", 1104);
 | 
						|
        SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
 | 
						|
          "monitoring_limit", monitoring_limit, 0, 9223372036854775807LL);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("bulk_update_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "bulk_update_mode", bulk_update_mode, 0, 2);
 | 
						|
        SPIDER_PARAM_INT("bulk_update_size", bulk_update_size, 0);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("net_read_timeout",
 | 
						|
                                        net_read_timeouts, 0, 2147483647);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("error_write_mode", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "error_write_mode", error_write_mode, 0, 1);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "query_cache_sync", query_cache_sync, 0, 3);
 | 
						|
        error_num= parse.fail(true);
 | 
						|
        goto error;
 | 
						|
      case 17:
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("internal_optimize", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "internal_optimize", internal_optimize, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("use_table_charset", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "use_table_charset", use_table_charset, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("direct_dup_insert", 1104);
 | 
						|
        SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
          "direct_dup_insert", direct_dup_insert, 0, 1);
 | 
						|
        SPIDER_PARAM_DEPRECATED_WARNING("active_link_count", 1104);
 | 
						|
        SPIDER_PARAM_INT("active_link_count", active_link_count, 1);
 | 
						|
        SPIDER_PARAM_LONG_LIST_WITH_MAX("net_write_timeout",
 | 
						|
                                        net_write_timeouts, 0, 2147483647);
 | 
						|
#ifdef HA_CAN_FORCE_BULK_DELETE
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "force_bulk_delete", force_bulk_delete, 0, 1);
 | 
						|
#endif
 | 
						|
#ifdef HA_CAN_FORCE_BULK_UPDATE
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "force_bulk_update", force_bulk_update, 0, 1);
 | 
						|
#endif
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 18:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("select_column_mode", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "select_column_mode", select_column_mode, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("monitoring_bg_flag", 1104);
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX(
 | 
						|
            "monitoring_bg_flag", monitoring_bg_flag, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("monitoring_bg_kind", 1104);
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX(
 | 
						|
            "monitoring_bg_kind", monitoring_bg_kind, 0, 3);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("direct_order_limit", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG(
 | 
						|
            "direct_order_limit", direct_order_limit, 0);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 19:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("init_sql_alloc_size", 1007);
 | 
						|
          SPIDER_PARAM_INT("init_sql_alloc_size", init_sql_alloc_size, 0);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "auto_increment_mode", auto_increment_mode, 0, 3);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("bka_table_name_type", 1007);
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX("bka_table_name_type",
 | 
						|
            bka_table_name_types, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("load_crd_at_startup", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "load_crd_at_startup", load_crd_at_startup, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("load_sts_at_startup", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "load_sts_at_startup", load_sts_at_startup, 0, 1);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 20:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("monitoring_server_id", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
 | 
						|
            "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 = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 21:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("semi_split_read_limit", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG(
 | 
						|
            "semi_split_read_limit", semi_split_read_limit, 0);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 22:
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX(
 | 
						|
            "ssl_verify_server_cert", tgt_ssl_vscs, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("monitoring_bg_interval", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
 | 
						|
            "monitoring_bg_interval", monitoring_bg_interval, 0, 4294967295LL);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("skip_default_condition", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "skip_default_condition", skip_default_condition, 0, 1);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("static_mean_rec_length", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG(
 | 
						|
            "static_mean_rec_length", static_mean_rec_length, 0);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 23:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("internal_optimize_local", 1104);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "internal_optimize_local", internal_optimize_local, 0, 1);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 25:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("static_records_for_status", 1104);
 | 
						|
          SPIDER_PARAM_LONGLONG("static_records_for_status",
 | 
						|
            static_records_for_status, 0);
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("static_key_cardinality", 1104);
 | 
						|
          SPIDER_PARAM_NUMHINT("static_key_cardinality", static_key_cardinality,
 | 
						|
            3, (int) table_share->keys, spider_set_ll_value);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 26:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("semi_table_lock_connection", 1007);
 | 
						|
          SPIDER_PARAM_INT_WITH_MAX(
 | 
						|
            "semi_table_lock_connection", semi_table_lock_conn, 0, 1);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        case 32:
 | 
						|
          SPIDER_PARAM_DEPRECATED_WARNING("monitoring_binlog_pos_at_failing", 1104);
 | 
						|
          SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_binlog_pos_at_failing",
 | 
						|
            monitoring_binlog_pos_at_failing, 0, 2);
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
        default:
 | 
						|
          error_num = parse.fail(true);
 | 
						|
          goto error;
 | 
						|
      }
 | 
						|
      /* Restore delim */
 | 
						|
      *parse.end_value= parse.delim_value;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /* check all_link_count */
 | 
						|
  share->all_link_count = 1;
 | 
						|
  if (share->all_link_count < share->server_names_length)
 | 
						|
    share->all_link_count = share->server_names_length;
 | 
						|
  if (share->all_link_count < share->tgt_table_names_length)
 | 
						|
    share->all_link_count = share->tgt_table_names_length;
 | 
						|
  if (share->all_link_count < share->tgt_dbs_length)
 | 
						|
    share->all_link_count = share->tgt_dbs_length;
 | 
						|
  if (share->all_link_count < share->tgt_hosts_length)
 | 
						|
    share->all_link_count = share->tgt_hosts_length;
 | 
						|
  if (share->all_link_count < share->tgt_usernames_length)
 | 
						|
    share->all_link_count = share->tgt_usernames_length;
 | 
						|
  if (share->all_link_count < share->tgt_passwords_length)
 | 
						|
    share->all_link_count = share->tgt_passwords_length;
 | 
						|
  if (share->all_link_count < share->tgt_sockets_length)
 | 
						|
    share->all_link_count = share->tgt_sockets_length;
 | 
						|
  if (share->all_link_count < share->tgt_wrappers_length)
 | 
						|
    share->all_link_count = share->tgt_wrappers_length;
 | 
						|
  if (share->all_link_count < share->tgt_ssl_cas_length)
 | 
						|
    share->all_link_count = share->tgt_ssl_cas_length;
 | 
						|
  if (share->all_link_count < share->tgt_ssl_capaths_length)
 | 
						|
    share->all_link_count = share->tgt_ssl_capaths_length;
 | 
						|
  if (share->all_link_count < share->tgt_ssl_certs_length)
 | 
						|
    share->all_link_count = share->tgt_ssl_certs_length;
 | 
						|
  if (share->all_link_count < share->tgt_ssl_ciphers_length)
 | 
						|
    share->all_link_count = share->tgt_ssl_ciphers_length;
 | 
						|
  if (share->all_link_count < share->tgt_ssl_keys_length)
 | 
						|
    share->all_link_count = share->tgt_ssl_keys_length;
 | 
						|
  if (share->all_link_count < share->tgt_default_files_length)
 | 
						|
    share->all_link_count = share->tgt_default_files_length;
 | 
						|
  if (share->all_link_count < share->tgt_default_groups_length)
 | 
						|
    share->all_link_count = share->tgt_default_groups_length;
 | 
						|
  if (share->all_link_count < share->tgt_dsns_length)
 | 
						|
    share->all_link_count = share->tgt_dsns_length;
 | 
						|
  if (share->all_link_count < share->tgt_filedsns_length)
 | 
						|
    share->all_link_count = share->tgt_filedsns_length;
 | 
						|
  if (share->all_link_count < share->tgt_drivers_length)
 | 
						|
    share->all_link_count = share->tgt_drivers_length;
 | 
						|
  if (share->all_link_count < share->tgt_pk_names_length)
 | 
						|
    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)
 | 
						|
    share->all_link_count = share->monitoring_kind_length;
 | 
						|
  if (share->all_link_count < share->monitoring_limit_length)
 | 
						|
    share->all_link_count = share->monitoring_limit_length;
 | 
						|
  if (share->all_link_count < share->monitoring_sid_length)
 | 
						|
    share->all_link_count = share->monitoring_sid_length;
 | 
						|
  if (share->all_link_count < share->monitoring_bg_flag_length)
 | 
						|
    share->all_link_count = share->monitoring_bg_flag_length;
 | 
						|
  if (share->all_link_count < share->monitoring_bg_kind_length)
 | 
						|
    share->all_link_count = share->monitoring_bg_kind_length;
 | 
						|
  if (share->all_link_count < share->monitoring_bg_interval_length)
 | 
						|
    share->all_link_count = share->monitoring_bg_interval_length;
 | 
						|
  if (share->all_link_count < share->connect_timeouts_length)
 | 
						|
    share->all_link_count = share->connect_timeouts_length;
 | 
						|
  if (share->all_link_count < share->net_read_timeouts_length)
 | 
						|
    share->all_link_count = share->net_read_timeouts_length;
 | 
						|
  if (share->all_link_count < share->net_write_timeouts_length)
 | 
						|
    share->all_link_count = share->net_write_timeouts_length;
 | 
						|
  if (share->all_link_count < share->access_balances_length)
 | 
						|
    share->all_link_count = share->access_balances_length;
 | 
						|
  if (share->all_link_count < share->bka_table_name_types_length)
 | 
						|
    share->all_link_count = share->bka_table_name_types_length;
 | 
						|
  if (share->all_link_count < share->strict_group_bys_length)
 | 
						|
    share->all_link_count = share->strict_group_bys_length;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->server_names,
 | 
						|
    &share->server_names_lengths,
 | 
						|
    &share->server_names_length,
 | 
						|
    &share->server_names_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_table_names,
 | 
						|
    &share->tgt_table_names_lengths,
 | 
						|
    &share->tgt_table_names_length,
 | 
						|
    &share->tgt_table_names_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_dbs,
 | 
						|
    &share->tgt_dbs_lengths,
 | 
						|
    &share->tgt_dbs_length,
 | 
						|
    &share->tgt_dbs_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_hosts,
 | 
						|
    &share->tgt_hosts_lengths,
 | 
						|
    &share->tgt_hosts_length,
 | 
						|
    &share->tgt_hosts_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_usernames,
 | 
						|
    &share->tgt_usernames_lengths,
 | 
						|
    &share->tgt_usernames_length,
 | 
						|
    &share->tgt_usernames_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_passwords,
 | 
						|
    &share->tgt_passwords_lengths,
 | 
						|
    &share->tgt_passwords_length,
 | 
						|
    &share->tgt_passwords_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_sockets,
 | 
						|
    &share->tgt_sockets_lengths,
 | 
						|
    &share->tgt_sockets_length,
 | 
						|
    &share->tgt_sockets_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_wrappers,
 | 
						|
    &share->tgt_wrappers_lengths,
 | 
						|
    &share->tgt_wrappers_length,
 | 
						|
    &share->tgt_wrappers_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_ssl_cas,
 | 
						|
    &share->tgt_ssl_cas_lengths,
 | 
						|
    &share->tgt_ssl_cas_length,
 | 
						|
    &share->tgt_ssl_cas_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_ssl_capaths,
 | 
						|
    &share->tgt_ssl_capaths_lengths,
 | 
						|
    &share->tgt_ssl_capaths_length,
 | 
						|
    &share->tgt_ssl_capaths_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_ssl_certs,
 | 
						|
    &share->tgt_ssl_certs_lengths,
 | 
						|
    &share->tgt_ssl_certs_length,
 | 
						|
    &share->tgt_ssl_certs_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_ssl_ciphers,
 | 
						|
    &share->tgt_ssl_ciphers_lengths,
 | 
						|
    &share->tgt_ssl_ciphers_length,
 | 
						|
    &share->tgt_ssl_ciphers_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_ssl_keys,
 | 
						|
    &share->tgt_ssl_keys_lengths,
 | 
						|
    &share->tgt_ssl_keys_length,
 | 
						|
    &share->tgt_ssl_keys_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_default_files,
 | 
						|
    &share->tgt_default_files_lengths,
 | 
						|
    &share->tgt_default_files_length,
 | 
						|
    &share->tgt_default_files_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_default_groups,
 | 
						|
    &share->tgt_default_groups_lengths,
 | 
						|
    &share->tgt_default_groups_length,
 | 
						|
    &share->tgt_default_groups_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_dsns,
 | 
						|
    &share->tgt_dsns_lengths,
 | 
						|
    &share->tgt_dsns_length,
 | 
						|
    &share->tgt_dsns_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_filedsns,
 | 
						|
    &share->tgt_filedsns_lengths,
 | 
						|
    &share->tgt_filedsns_length,
 | 
						|
    &share->tgt_filedsns_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_drivers,
 | 
						|
    &share->tgt_drivers_lengths,
 | 
						|
    &share->tgt_drivers_length,
 | 
						|
    &share->tgt_drivers_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  uint unused_charlen;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_odbc_conn_strs,
 | 
						|
    &share->tgt_odbc_conn_strs_lengths,
 | 
						|
    &share->tgt_odbc_conn_strs_length,
 | 
						|
    &unused_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_pk_names,
 | 
						|
    &share->tgt_pk_names_lengths,
 | 
						|
    &share->tgt_pk_names_length,
 | 
						|
    &share->tgt_pk_names_charlen,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_string_list(
 | 
						|
    &share->tgt_sequence_names,
 | 
						|
    &share->tgt_sequence_names_lengths,
 | 
						|
    &share->tgt_sequence_names_length,
 | 
						|
    &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,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->tgt_ssl_vscs,
 | 
						|
    &share->tgt_ssl_vscs_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->link_statuses,
 | 
						|
    &share->link_statuses_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->monitoring_bg_flag,
 | 
						|
    &share->monitoring_bg_flag_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->monitoring_bg_kind,
 | 
						|
    &share->monitoring_bg_kind_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  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)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->monitoring_kind,
 | 
						|
    &share->monitoring_kind_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_longlong_list(
 | 
						|
    &share->monitoring_bg_interval,
 | 
						|
    &share->monitoring_bg_interval_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_longlong_list(
 | 
						|
    &share->monitoring_limit,
 | 
						|
    &share->monitoring_limit_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_longlong_list(
 | 
						|
    &share->monitoring_sid,
 | 
						|
    &share->monitoring_sid_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->connect_timeouts,
 | 
						|
    &share->connect_timeouts_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->net_read_timeouts,
 | 
						|
    &share->net_read_timeouts_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->net_write_timeouts,
 | 
						|
    &share->net_write_timeouts_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->access_balances,
 | 
						|
    &share->access_balances_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->bka_table_name_types,
 | 
						|
    &share->bka_table_name_types_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
  if ((error_num = spider_increase_long_list(
 | 
						|
    &share->strict_group_bys,
 | 
						|
    &share->strict_group_bys_length,
 | 
						|
    share->all_link_count)))
 | 
						|
    goto error;
 | 
						|
 | 
						|
  /* copy for tables start */
 | 
						|
  share_alter = &share->alter_table;
 | 
						|
  share_alter->all_link_count = share->all_link_count;
 | 
						|
  if (!(share_alter->tmp_server_names = (char **)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_PARSE_CONNECT_INFO_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &share_alter->tmp_server_names,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_table_names,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_dbs,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_hosts,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_usernames,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_passwords,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_sockets,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_wrappers,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_cas,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_capaths,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_certs,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_ciphers,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_keys,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_default_files,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_default_groups,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_dsns,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_filedsns,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_drivers,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_static_link_ids,
 | 
						|
      (uint) (sizeof(char *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_server_names_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_table_names_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_dbs_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_hosts_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_usernames_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_passwords_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_sockets_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_wrappers_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_cas_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_capaths_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_certs_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_ciphers_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_keys_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_default_files_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_default_groups_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_dsns_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_filedsns_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_drivers_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_static_link_ids_lengths,
 | 
						|
      (uint) (sizeof(uint *) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ports,
 | 
						|
      (uint) (sizeof(long) * share->all_link_count),
 | 
						|
      &share_alter->tmp_tgt_ssl_vscs,
 | 
						|
      (uint) (sizeof(long) * share->all_link_count),
 | 
						|
      &share_alter->tmp_monitoring_binlog_pos_at_failing,
 | 
						|
      (uint) (sizeof(long) * share->all_link_count),
 | 
						|
      &share_alter->tmp_link_statuses,
 | 
						|
      (uint) (sizeof(long) * share->all_link_count),
 | 
						|
      NullS))
 | 
						|
  ) {
 | 
						|
    error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  memcpy(share_alter->tmp_server_names, share->server_names,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_table_names, share->tgt_table_names,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_dbs, share->tgt_dbs,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_hosts, share->tgt_hosts,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_usernames, share->tgt_usernames,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_passwords, share->tgt_passwords,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_sockets, share->tgt_sockets,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_wrappers, share->tgt_wrappers,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_cas, share->tgt_ssl_cas,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_capaths, share->tgt_ssl_capaths,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_certs, share->tgt_ssl_certs,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_ciphers, share->tgt_ssl_ciphers,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_keys, share->tgt_ssl_keys,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_default_files, share->tgt_default_files,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_default_groups, share->tgt_default_groups,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_dsns, share->tgt_dsns,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_filedsns, share->tgt_filedsns,
 | 
						|
    sizeof(char *) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_drivers, share->tgt_drivers,
 | 
						|
    sizeof(char *) * 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);
 | 
						|
 | 
						|
  memcpy(share_alter->tmp_server_names_lengths,
 | 
						|
    share->server_names_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_table_names_lengths,
 | 
						|
    share->tgt_table_names_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_dbs_lengths, share->tgt_dbs_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_hosts_lengths, share->tgt_hosts_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_usernames_lengths,
 | 
						|
    share->tgt_usernames_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_passwords_lengths,
 | 
						|
    share->tgt_passwords_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_sockets_lengths, share->tgt_sockets_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_wrappers_lengths,
 | 
						|
    share->tgt_wrappers_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_cas_lengths,
 | 
						|
    share->tgt_ssl_cas_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_capaths_lengths,
 | 
						|
    share->tgt_ssl_capaths_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_certs_lengths,
 | 
						|
    share->tgt_ssl_certs_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_ciphers_lengths,
 | 
						|
    share->tgt_ssl_ciphers_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_ssl_keys_lengths,
 | 
						|
    share->tgt_ssl_keys_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_default_files_lengths,
 | 
						|
    share->tgt_default_files_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_default_groups_lengths,
 | 
						|
    share->tgt_default_groups_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_dsns_lengths,
 | 
						|
    share->tgt_dsns_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_filedsns_lengths,
 | 
						|
    share->tgt_filedsns_lengths,
 | 
						|
    sizeof(uint) * share->all_link_count);
 | 
						|
  memcpy(share_alter->tmp_tgt_drivers_lengths,
 | 
						|
    share->tgt_drivers_lengths,
 | 
						|
    sizeof(uint) * 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;
 | 
						|
  share_alter->tmp_tgt_dbs_charlen = share->tgt_dbs_charlen;
 | 
						|
  share_alter->tmp_tgt_hosts_charlen = share->tgt_hosts_charlen;
 | 
						|
  share_alter->tmp_tgt_usernames_charlen = share->tgt_usernames_charlen;
 | 
						|
  share_alter->tmp_tgt_passwords_charlen = share->tgt_passwords_charlen;
 | 
						|
  share_alter->tmp_tgt_sockets_charlen = share->tgt_sockets_charlen;
 | 
						|
  share_alter->tmp_tgt_wrappers_charlen = share->tgt_wrappers_charlen;
 | 
						|
  share_alter->tmp_tgt_ssl_cas_charlen = share->tgt_ssl_cas_charlen;
 | 
						|
  share_alter->tmp_tgt_ssl_capaths_charlen = share->tgt_ssl_capaths_charlen;
 | 
						|
  share_alter->tmp_tgt_ssl_certs_charlen = share->tgt_ssl_certs_charlen;
 | 
						|
  share_alter->tmp_tgt_ssl_ciphers_charlen = share->tgt_ssl_ciphers_charlen;
 | 
						|
  share_alter->tmp_tgt_ssl_keys_charlen = share->tgt_ssl_keys_charlen;
 | 
						|
  share_alter->tmp_tgt_default_files_charlen =
 | 
						|
    share->tgt_default_files_charlen;
 | 
						|
  share_alter->tmp_tgt_default_groups_charlen =
 | 
						|
    share->tgt_default_groups_charlen;
 | 
						|
  share_alter->tmp_tgt_dsns_charlen =
 | 
						|
    share->tgt_dsns_charlen;
 | 
						|
  share_alter->tmp_tgt_filedsns_charlen =
 | 
						|
    share->tgt_filedsns_charlen;
 | 
						|
  share_alter->tmp_tgt_drivers_charlen =
 | 
						|
    share->tgt_drivers_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;
 | 
						|
  share_alter->tmp_tgt_dbs_length = share->tgt_dbs_length;
 | 
						|
  share_alter->tmp_tgt_hosts_length = share->tgt_hosts_length;
 | 
						|
  share_alter->tmp_tgt_usernames_length = share->tgt_usernames_length;
 | 
						|
  share_alter->tmp_tgt_passwords_length = share->tgt_passwords_length;
 | 
						|
  share_alter->tmp_tgt_sockets_length = share->tgt_sockets_length;
 | 
						|
  share_alter->tmp_tgt_wrappers_length = share->tgt_wrappers_length;
 | 
						|
  share_alter->tmp_tgt_ssl_cas_length = share->tgt_ssl_cas_length;
 | 
						|
  share_alter->tmp_tgt_ssl_capaths_length = share->tgt_ssl_capaths_length;
 | 
						|
  share_alter->tmp_tgt_ssl_certs_length = share->tgt_ssl_certs_length;
 | 
						|
  share_alter->tmp_tgt_ssl_ciphers_length = share->tgt_ssl_ciphers_length;
 | 
						|
  share_alter->tmp_tgt_ssl_keys_length = share->tgt_ssl_keys_length;
 | 
						|
  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_tgt_dsns_length =
 | 
						|
    share->tgt_dsns_length;
 | 
						|
  share_alter->tmp_tgt_filedsns_length =
 | 
						|
    share->tgt_filedsns_length;
 | 
						|
  share_alter->tmp_tgt_drivers_length =
 | 
						|
    share->tgt_drivers_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 */
 | 
						|
 | 
						|
  if ((error_num = spider_set_connect_info_default(
 | 
						|
    share,
 | 
						|
    part_elem,
 | 
						|
    sub_elem,
 | 
						|
    table_share
 | 
						|
  )))
 | 
						|
    goto error;
 | 
						|
 | 
						|
  if (create_table)
 | 
						|
  {
 | 
						|
    for (int roop_count = 0; roop_count < (int) share->all_link_count;
 | 
						|
         roop_count++)
 | 
						|
    {
 | 
						|
      int roop_count2;
 | 
						|
      for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++)
 | 
						|
      {
 | 
						|
        if (
 | 
						|
          spider_dbton[roop_count2].wrapper &&
 | 
						|
          !strcasecmp(share->tgt_wrappers[roop_count],
 | 
						|
            spider_dbton[roop_count2].wrapper)
 | 
						|
        ) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (roop_count2 == SPIDER_DBTON_SIZE)
 | 
						|
      {
 | 
						|
        DBUG_PRINT("info",("spider err tgt_wrappers[%d]=%s", roop_count,
 | 
						|
          share->tgt_wrappers[roop_count]));
 | 
						|
        error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
 | 
						|
        my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
 | 
						|
          MYF(0), share->tgt_wrappers[roop_count]);
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider server_names_lengths[%d] = %u", roop_count,
 | 
						|
         share->server_names_lengths[roop_count]));
 | 
						|
      if (share->server_names_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->server_names[roop_count], "server");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_table_names_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_table_names_lengths[roop_count]));
 | 
						|
      if (share->tgt_table_names_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->tgt_table_names[roop_count], "table");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_dbs_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_dbs_lengths[roop_count]));
 | 
						|
      if (share->tgt_dbs_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->tgt_dbs[roop_count], "database");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_hosts_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_hosts_lengths[roop_count]));
 | 
						|
      if (share->tgt_hosts_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->tgt_hosts[roop_count], "host");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_usernames_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_usernames_lengths[roop_count]));
 | 
						|
      if (share->tgt_usernames_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->tgt_usernames[roop_count], "user");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_passwords_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_passwords_lengths[roop_count]));
 | 
						|
      if (share->tgt_passwords_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->tgt_passwords[roop_count], "password");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_sockets_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_sockets_lengths[roop_count]));
 | 
						|
      if (share->tgt_sockets_lengths[roop_count] >
 | 
						|
        SPIDER_CONNECT_INFO_PATH_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->tgt_sockets[roop_count], "socket");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_wrappers_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_wrappers_lengths[roop_count]));
 | 
						|
      if (share->tgt_wrappers_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->tgt_wrappers[roop_count], "wrapper");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_ssl_cas_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_ssl_cas_lengths[roop_count]));
 | 
						|
      if (share->tgt_ssl_cas_lengths[roop_count] >
 | 
						|
        SPIDER_CONNECT_INFO_PATH_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->tgt_ssl_cas[roop_count], "ssl_ca");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_ssl_capaths_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_ssl_capaths_lengths[roop_count]));
 | 
						|
      if (share->tgt_ssl_capaths_lengths[roop_count] >
 | 
						|
        SPIDER_CONNECT_INFO_PATH_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->tgt_ssl_capaths[roop_count], "ssl_capath");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_ssl_certs_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_ssl_certs_lengths[roop_count]));
 | 
						|
      if (share->tgt_ssl_certs_lengths[roop_count] >
 | 
						|
        SPIDER_CONNECT_INFO_PATH_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->tgt_ssl_certs[roop_count], "ssl_cert");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_ssl_ciphers_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_ssl_ciphers_lengths[roop_count]));
 | 
						|
      if (share->tgt_ssl_ciphers_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->tgt_ssl_ciphers[roop_count], "ssl_cipher");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_ssl_keys_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_ssl_keys_lengths[roop_count]));
 | 
						|
      if (share->tgt_ssl_keys_lengths[roop_count] >
 | 
						|
        SPIDER_CONNECT_INFO_PATH_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->tgt_ssl_keys[roop_count], "ssl_key");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_default_files_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_default_files_lengths[roop_count]));
 | 
						|
      if (share->tgt_default_files_lengths[roop_count] >
 | 
						|
        SPIDER_CONNECT_INFO_PATH_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->tgt_default_files[roop_count], "default_file");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_default_groups_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_default_groups_lengths[roop_count]));
 | 
						|
      if (share->tgt_default_groups_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->tgt_default_groups[roop_count], "default_group");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_dsns_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_dsns_lengths[roop_count]));
 | 
						|
      if (share->tgt_dsns_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->tgt_dsns[roop_count], "dsn");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_filedsns_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_filedsns_lengths[roop_count]));
 | 
						|
      if (share->tgt_filedsns_lengths[roop_count] >
 | 
						|
        SPIDER_CONNECT_INFO_PATH_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->tgt_filedsns[roop_count], "filedsn");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_drivers_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_drivers_lengths[roop_count]));
 | 
						|
      if (share->tgt_drivers_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->tgt_drivers[roop_count], "driver");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_pk_names_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_pk_names_lengths[roop_count]));
 | 
						|
      if (share->tgt_pk_names_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->tgt_pk_names[roop_count], "pk_name");
 | 
						|
        goto error;
 | 
						|
      }
 | 
						|
 | 
						|
      DBUG_PRINT("info",
 | 
						|
        ("spider tgt_sequence_names_lengths[%d] = %u", roop_count,
 | 
						|
        share->tgt_sequence_names_lengths[roop_count]));
 | 
						|
      if (share->tgt_sequence_names_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->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;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  DBUG_PRINT("info", ("spider share->active_link_count = %d",
 | 
						|
    share->active_link_count));
 | 
						|
  share->link_count = (uint) share->active_link_count;
 | 
						|
  share_alter->link_count = share->link_count;
 | 
						|
  share->link_bitmap_size = (share->link_count + 7) / 8;
 | 
						|
 | 
						|
  if (connect_string)
 | 
						|
    spider_free(spider_current_trx, connect_string, MYF(0));
 | 
						|
  DBUG_RETURN(0);
 | 
						|
 | 
						|
error:
 | 
						|
  if (connect_string)
 | 
						|
    spider_free(spider_current_trx, connect_string, MYF(0));
 | 
						|
error_alloc_conn_string:
 | 
						|
  DBUG_RETURN(error_num);
 | 
						|
}
 | 
						|
 | 
						|
/* Set default connect info of a SPIDER_SHARE if needed */
 | 
						|
int spider_set_connect_info_default(
 | 
						|
  SPIDER_SHARE *share,                /* The `SPIDER_SHARE' to set
 | 
						|
                                     default connect info */
 | 
						|
  partition_element *part_elem, /* partition info used as input */
 | 
						|
  partition_element *sub_elem,  /* subpartition info used as input */
 | 
						|
  TABLE_SHARE *table_share      /* table share info used as input */
 | 
						|
) {
 | 
						|
  bool check_socket;
 | 
						|
  bool check_database;
 | 
						|
  bool check_default_file;
 | 
						|
  bool check_host;
 | 
						|
  bool check_port;
 | 
						|
  bool socket_has_default_value;
 | 
						|
  bool database_has_default_value;
 | 
						|
  bool default_file_has_default_value;
 | 
						|
  bool host_has_default_value;
 | 
						|
  bool port_has_default_value;
 | 
						|
  int error_num, roop_count, roop_count2;
 | 
						|
  DBUG_ENTER("spider_set_connect_info_default");
 | 
						|
  for (roop_count = 0; roop_count < (int) share->all_link_count; roop_count++)
 | 
						|
  {
 | 
						|
    if (share->server_names[roop_count])
 | 
						|
    {
 | 
						|
      if ((error_num = spider_get_server(share, roop_count)))
 | 
						|
        DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
 | 
						|
    if (
 | 
						|
      !share->tgt_sockets[roop_count] &&
 | 
						|
      (
 | 
						|
        !share->tgt_hosts[roop_count] ||
 | 
						|
        !strcmp(share->tgt_hosts[roop_count], my_localhost)
 | 
						|
      )
 | 
						|
    ) {
 | 
						|
      check_socket = TRUE;
 | 
						|
    } else {
 | 
						|
      check_socket = FALSE;
 | 
						|
    }
 | 
						|
    if (!share->tgt_dbs[roop_count] && table_share)
 | 
						|
    {
 | 
						|
      check_database = TRUE;
 | 
						|
    } else {
 | 
						|
      check_database = FALSE;
 | 
						|
    }
 | 
						|
    if (
 | 
						|
      !share->tgt_default_files[roop_count] &&
 | 
						|
      share->tgt_default_groups[roop_count] &&
 | 
						|
      (*spd_defaults_file || *spd_defaults_extra_file)
 | 
						|
    ) {
 | 
						|
      check_default_file = TRUE;
 | 
						|
    } else {
 | 
						|
      check_default_file = FALSE;
 | 
						|
    }
 | 
						|
    if (!share->tgt_hosts[roop_count])
 | 
						|
    {
 | 
						|
      check_host = TRUE;
 | 
						|
    } else {
 | 
						|
      check_host = FALSE;
 | 
						|
    }
 | 
						|
    if (share->tgt_ports[roop_count] == -1)
 | 
						|
    {
 | 
						|
      check_port = TRUE;
 | 
						|
    } else {
 | 
						|
      check_port = FALSE;
 | 
						|
    }
 | 
						|
    if (check_socket || check_database || check_default_file || check_host ||
 | 
						|
      check_port)
 | 
						|
    {
 | 
						|
      socket_has_default_value = check_socket;
 | 
						|
      database_has_default_value = check_database;
 | 
						|
      default_file_has_default_value = check_default_file;
 | 
						|
      host_has_default_value = check_host;
 | 
						|
      port_has_default_value = check_port;
 | 
						|
      if (share->tgt_wrappers[roop_count])
 | 
						|
      {
 | 
						|
        for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++)
 | 
						|
        {
 | 
						|
          DBUG_PRINT("info",("spider share->tgt_wrappers[%d]=%s", roop_count,
 | 
						|
            share->tgt_wrappers[roop_count]));
 | 
						|
          DBUG_PRINT("info",("spider spider_dbton[%d].wrapper=%s", roop_count2,
 | 
						|
            spider_dbton[roop_count2].wrapper ?
 | 
						|
              spider_dbton[roop_count2].wrapper : "NULL"));
 | 
						|
          if (
 | 
						|
            spider_dbton[roop_count2].wrapper &&
 | 
						|
            !strcasecmp(share->tgt_wrappers[roop_count],
 | 
						|
              spider_dbton[roop_count2].wrapper)
 | 
						|
          ) {
 | 
						|
            if (spider_dbton[roop_count2].db_access_type ==
 | 
						|
              SPIDER_DB_ACCESS_TYPE_SQL)
 | 
						|
            {
 | 
						|
              if (check_socket)
 | 
						|
              {
 | 
						|
                socket_has_default_value = spider_dbton[roop_count2].
 | 
						|
                  db_util->socket_has_default_value();
 | 
						|
              }
 | 
						|
              if (check_database)
 | 
						|
              {
 | 
						|
                database_has_default_value = spider_dbton[roop_count2].
 | 
						|
                  db_util->database_has_default_value();
 | 
						|
              }
 | 
						|
              if (check_default_file)
 | 
						|
              {
 | 
						|
                default_file_has_default_value = spider_dbton[roop_count2].
 | 
						|
                  db_util->default_file_has_default_value();
 | 
						|
              }
 | 
						|
              if (check_host)
 | 
						|
              {
 | 
						|
                host_has_default_value = spider_dbton[roop_count2].
 | 
						|
                  db_util->host_has_default_value();
 | 
						|
              }
 | 
						|
              if (check_port)
 | 
						|
              {
 | 
						|
                port_has_default_value = spider_dbton[roop_count2].
 | 
						|
                  db_util->port_has_default_value();
 | 
						|
              }
 | 
						|
              break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      socket_has_default_value = FALSE;
 | 
						|
      database_has_default_value = FALSE;
 | 
						|
      default_file_has_default_value = FALSE;
 | 
						|
      host_has_default_value = FALSE;
 | 
						|
      port_has_default_value = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!share->tgt_wrappers[roop_count])
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_wrappers"));
 | 
						|
      share->tgt_wrappers_lengths[roop_count] = SPIDER_DB_WRAPPER_LEN;
 | 
						|
      if (
 | 
						|
        !(share->tgt_wrappers[roop_count] = spider_create_string(
 | 
						|
          SPIDER_DB_WRAPPER_STR,
 | 
						|
          share->tgt_wrappers_lengths[roop_count]))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (host_has_default_value)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_hosts"));
 | 
						|
      share->tgt_hosts_lengths[roop_count] = strlen(my_localhost);
 | 
						|
      if (
 | 
						|
        !(share->tgt_hosts[roop_count] = spider_create_string(
 | 
						|
          my_localhost,
 | 
						|
          share->tgt_hosts_lengths[roop_count]))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (database_has_default_value)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_dbs"));
 | 
						|
      share->tgt_dbs_lengths[roop_count] = table_share->db.length;
 | 
						|
      if (
 | 
						|
        !(share->tgt_dbs[roop_count] = spider_create_string(
 | 
						|
          table_share->db.str,
 | 
						|
          table_share->db.length))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!share->tgt_table_names[roop_count] && table_share)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_table_names"));
 | 
						|
      share->tgt_table_names_lengths[roop_count] =
 | 
						|
        table_share->table_name.length;
 | 
						|
      if (
 | 
						|
        !(share->tgt_table_names[roop_count] = spider_create_table_name_string(
 | 
						|
          table_share->table_name.str,
 | 
						|
          (part_elem ? part_elem->partition_name.str : NULL),
 | 
						|
          (sub_elem ? sub_elem->partition_name.str : NULL)
 | 
						|
        ))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (default_file_has_default_value)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_default_files"));
 | 
						|
      if (*spd_defaults_extra_file)
 | 
						|
      {
 | 
						|
        share->tgt_default_files_lengths[roop_count] =
 | 
						|
          strlen(*spd_defaults_extra_file);
 | 
						|
        if (
 | 
						|
          !(share->tgt_default_files[roop_count] = spider_create_string(
 | 
						|
            *spd_defaults_extra_file,
 | 
						|
            share->tgt_default_files_lengths[roop_count]))
 | 
						|
        ) {
 | 
						|
          my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
          DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        share->tgt_default_files_lengths[roop_count] =
 | 
						|
          strlen(*spd_defaults_file);
 | 
						|
        if (
 | 
						|
          !(share->tgt_default_files[roop_count] = spider_create_string(
 | 
						|
            *spd_defaults_file,
 | 
						|
            share->tgt_default_files_lengths[roop_count]))
 | 
						|
        ) {
 | 
						|
          my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
 | 
						|
          DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!share->tgt_pk_names[roop_count])
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_pk_names"));
 | 
						|
      share->tgt_pk_names_lengths[roop_count] = SPIDER_DB_PK_NAME_LEN;
 | 
						|
      if (
 | 
						|
        !(share->tgt_pk_names[roop_count] = spider_create_string(
 | 
						|
          SPIDER_DB_PK_NAME_STR,
 | 
						|
          share->tgt_pk_names_lengths[roop_count]))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!share->tgt_sequence_names[roop_count])
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_sequence_names"));
 | 
						|
      share->tgt_sequence_names_lengths[roop_count] =
 | 
						|
        SPIDER_DB_SEQUENCE_NAME_LEN;
 | 
						|
      if (
 | 
						|
        !(share->tgt_sequence_names[roop_count] = spider_create_string(
 | 
						|
          SPIDER_DB_SEQUENCE_NAME_STR,
 | 
						|
          share->tgt_sequence_names_lengths[roop_count]))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (port_has_default_value)
 | 
						|
    {
 | 
						|
      share->tgt_ports[roop_count] = MYSQL_PORT;
 | 
						|
    } else if (share->tgt_ports[roop_count] < 0)
 | 
						|
    {
 | 
						|
      share->tgt_ports[roop_count] = 0;
 | 
						|
    } else if (share->tgt_ports[roop_count] > 65535)
 | 
						|
    {
 | 
						|
      share->tgt_ports[roop_count] = 65535;
 | 
						|
    }
 | 
						|
 | 
						|
    if (share->tgt_ssl_vscs[roop_count] == -1)
 | 
						|
      share->tgt_ssl_vscs[roop_count] = 0;
 | 
						|
 | 
						|
    if (socket_has_default_value)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_sockets"));
 | 
						|
      share->tgt_sockets_lengths[roop_count] =
 | 
						|
        strlen((char *) MYSQL_UNIX_ADDR);
 | 
						|
      if (
 | 
						|
        !(share->tgt_sockets[roop_count] = spider_create_string(
 | 
						|
          (char *) MYSQL_UNIX_ADDR,
 | 
						|
          share->tgt_sockets_lengths[roop_count]))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (share->link_statuses[roop_count] == -1)
 | 
						|
      share->link_statuses[roop_count] = SPIDER_LINK_STATUS_NO_CHANGE;
 | 
						|
 | 
						|
    if (share->monitoring_bg_flag[roop_count] == -1)
 | 
						|
      share->monitoring_bg_flag[roop_count] = 0;
 | 
						|
    if (share->monitoring_bg_kind[roop_count] == -1)
 | 
						|
      share->monitoring_bg_kind[roop_count] = 0;
 | 
						|
    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)
 | 
						|
      share->monitoring_kind[roop_count] = 0;
 | 
						|
    if (share->monitoring_bg_interval[roop_count] == -1)
 | 
						|
      share->monitoring_bg_interval[roop_count] = 10000000;
 | 
						|
    if (share->monitoring_limit[roop_count] == -1)
 | 
						|
      share->monitoring_limit[roop_count] = 1;
 | 
						|
    if (share->monitoring_sid[roop_count] == -1)
 | 
						|
      share->monitoring_sid[roop_count] = global_system_variables.server_id;
 | 
						|
 | 
						|
    if (share->access_balances[roop_count] == -1)
 | 
						|
      share->access_balances[roop_count] = 100;
 | 
						|
  }
 | 
						|
 | 
						|
  if (share->query_cache == -1)
 | 
						|
    share->query_cache = 0;
 | 
						|
  if (share->query_cache_sync == -1)
 | 
						|
    share->query_cache_sync = 0;
 | 
						|
  if (share->scan_rate == -1)
 | 
						|
    share->scan_rate = 1;
 | 
						|
  if (share->read_rate == -1)
 | 
						|
    share->read_rate = 0.0002;
 | 
						|
  if (share->priority == -1)
 | 
						|
    share->priority = 1000000;
 | 
						|
  if (share->table_count_mode == -1)
 | 
						|
    share->table_count_mode = 0;
 | 
						|
  if (share->active_link_count == -1)
 | 
						|
    share->active_link_count = share->all_link_count;
 | 
						|
#ifdef HA_CAN_FORCE_BULK_UPDATE
 | 
						|
  if (share->force_bulk_update == -1)
 | 
						|
    share->force_bulk_update = 0;
 | 
						|
#endif
 | 
						|
#ifdef HA_CAN_FORCE_BULK_DELETE
 | 
						|
  if (share->force_bulk_delete == -1)
 | 
						|
    share->force_bulk_delete = 0;
 | 
						|
#endif
 | 
						|
  if (!share->bka_engine)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider create default bka_engine"));
 | 
						|
    share->bka_engine_length = SPIDER_SQL_TMP_BKA_ENGINE_LEN;
 | 
						|
    if (
 | 
						|
      !(share->bka_engine = spider_create_string(
 | 
						|
        SPIDER_SQL_TMP_BKA_ENGINE_STR,
 | 
						|
        SPIDER_SQL_TMP_BKA_ENGINE_LEN))
 | 
						|
    ) {
 | 
						|
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  This function is a no-op if all share->tgt_dbs and
 | 
						|
  share->tgt_table_names are non-null, otherwise it may assign them
 | 
						|
  with db_name and table_name
 | 
						|
*/
 | 
						|
int spider_set_connect_info_default_db_table(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  const char *db_name,
 | 
						|
  uint db_name_length,
 | 
						|
  const char *table_name,
 | 
						|
  uint table_name_length
 | 
						|
) {
 | 
						|
  uint roop_count, roop_count2;
 | 
						|
  bool check_database;
 | 
						|
  bool database_has_default_value;
 | 
						|
  DBUG_ENTER("spider_set_connect_info_default_db_table");
 | 
						|
  for (roop_count = 0; roop_count < share->link_count; roop_count++)
 | 
						|
  {
 | 
						|
    if (!share->tgt_dbs[roop_count] && db_name)
 | 
						|
    {
 | 
						|
      check_database = TRUE;
 | 
						|
    } else {
 | 
						|
      check_database = FALSE;
 | 
						|
    }
 | 
						|
    if (check_database)
 | 
						|
    {
 | 
						|
      database_has_default_value = check_database;
 | 
						|
      if (share->tgt_wrappers[roop_count])
 | 
						|
      {
 | 
						|
        for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++)
 | 
						|
        {
 | 
						|
          DBUG_PRINT("info",("spider share->tgt_wrappers[%d]=%s", roop_count,
 | 
						|
            share->tgt_wrappers[roop_count]));
 | 
						|
          DBUG_PRINT("info",("spider spider_dbton[%d].wrapper=%s", roop_count2,
 | 
						|
            spider_dbton[roop_count2].wrapper ?
 | 
						|
              spider_dbton[roop_count2].wrapper : "NULL"));
 | 
						|
          if (
 | 
						|
            spider_dbton[roop_count2].wrapper &&
 | 
						|
            !strcasecmp(share->tgt_wrappers[roop_count],
 | 
						|
              spider_dbton[roop_count2].wrapper)
 | 
						|
          ) {
 | 
						|
            if (spider_dbton[roop_count2].db_access_type ==
 | 
						|
              SPIDER_DB_ACCESS_TYPE_SQL)
 | 
						|
            {
 | 
						|
              if (check_database)
 | 
						|
              {
 | 
						|
                database_has_default_value = spider_dbton[roop_count2].
 | 
						|
                  db_util->database_has_default_value();
 | 
						|
              }
 | 
						|
              break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      database_has_default_value = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (database_has_default_value)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_dbs"));
 | 
						|
      share->tgt_dbs_lengths[roop_count] = db_name_length;
 | 
						|
      if (
 | 
						|
        !(share->tgt_dbs[roop_count] = spider_create_string(
 | 
						|
          db_name,
 | 
						|
          db_name_length))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!share->tgt_table_names[roop_count] && table_name)
 | 
						|
    {
 | 
						|
      const char *tmp_ptr;
 | 
						|
      DBUG_PRINT("info",("spider create default tgt_table_names"));
 | 
						|
      if ((tmp_ptr = strstr(table_name, "#P#")))
 | 
						|
        table_name_length = (uint) PTR_BYTE_DIFF(tmp_ptr, table_name);
 | 
						|
      share->tgt_table_names_lengths[roop_count] = table_name_length;
 | 
						|
      if (
 | 
						|
        !(share->tgt_table_names[roop_count] = spider_create_string(
 | 
						|
          table_name,
 | 
						|
          table_name_length))
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Parse `dbtable_name' into db name and table name, and call
 | 
						|
  spider_set_connect_info_default_db_table() to set the db/table name
 | 
						|
  values of `share' if needed
 | 
						|
*/
 | 
						|
int spider_set_connect_info_default_dbtable(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  const char *dbtable_name,
 | 
						|
  int dbtable_name_length
 | 
						|
) {
 | 
						|
  const char *ptr_db, *ptr_table;
 | 
						|
  my_ptrdiff_t ptr_diff_db, ptr_diff_table;
 | 
						|
  DBUG_ENTER("spider_set_connect_info_default_dbtable");
 | 
						|
  ptr_db = strchr(dbtable_name, FN_LIBCHAR);
 | 
						|
  ptr_db++;
 | 
						|
  ptr_diff_db = PTR_BYTE_DIFF(ptr_db, dbtable_name);
 | 
						|
  DBUG_PRINT("info",("spider ptr_diff_db = %lld", (longlong) ptr_diff_db));
 | 
						|
  ptr_table = strchr(ptr_db, FN_LIBCHAR);
 | 
						|
  ptr_table++;
 | 
						|
  ptr_diff_table = PTR_BYTE_DIFF(ptr_table, ptr_db);
 | 
						|
  DBUG_PRINT("info",("spider ptr_diff_table = %lld", (longlong) ptr_diff_table));
 | 
						|
  DBUG_RETURN(spider_set_connect_info_default_db_table(
 | 
						|
    share,
 | 
						|
    ptr_db,
 | 
						|
    (uint)(ptr_diff_table - 1),
 | 
						|
    ptr_table,
 | 
						|
    (uint)(dbtable_name_length - ptr_diff_db - ptr_diff_table)
 | 
						|
  ));
 | 
						|
}
 | 
						|
 | 
						|
#ifdef DBUG_TRACE
 | 
						|
void spider_print_keys(
 | 
						|
  const char *key,
 | 
						|
  uint length
 | 
						|
) {
 | 
						|
  const char *end_ptr;
 | 
						|
  uint roop_count = 1;
 | 
						|
  DBUG_ENTER("spider_print_keys");
 | 
						|
  DBUG_PRINT("info",("spider key_length=%u", length));
 | 
						|
  end_ptr = key + length;
 | 
						|
  while (key < end_ptr)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider key[%u]=%s", roop_count, key));
 | 
						|
    key = strchr(key, '\0') + 1;
 | 
						|
    roop_count++;
 | 
						|
  }
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void spider_create_conn_key_add_one(int* counter, char** target, char* src)
 | 
						|
{
 | 
						|
  (*counter)++;
 | 
						|
  if (src)
 | 
						|
  {
 | 
						|
    **target= (char) *counter;
 | 
						|
    *target= strmov(*target + 1, src);
 | 
						|
    (*target)++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  The conn keys are strings of the following format:
 | 
						|
 | 
						|
  0 \<idx1> <value1> \0 \<idx2> <value2> \0 ... \<idxN> <valueN> \0
 | 
						|
 | 
						|
  Where idx1, idx2, etc. are the index of first, second, etc. options
 | 
						|
  where the value is specified. We have the wrapper as the first
 | 
						|
  option, host as the second, port as the third, socket as the fourth,
 | 
						|
  and so on (see below for the order of all options). So here would be
 | 
						|
  a conn key where only the host and the port are specified and
 | 
						|
  nothing else:
 | 
						|
 | 
						|
  0\002localhost\000\00303306\000
 | 
						|
 | 
						|
  And it has length 1 + 1 + 9 + 1 + 1 + 5 + 1 = 19.
 | 
						|
 | 
						|
  In case of HA, say we have another link with the same options
 | 
						|
  specified except that the port is 3307, then we place an extra NUL
 | 
						|
  before placing the next conn_key:
 | 
						|
 | 
						|
  0\002localhost\000\00303306\000\0000\002localhost\000\00303307\000
 | 
						|
  ^                                  ^
 | 
						|
  conn_keys[0]                       conn_keys[1]
 | 
						|
 | 
						|
  Thus the total number of chars (share->conn_keys_charlen) needed is
 | 
						|
  (19 + 1) * 2 = 40
 | 
						|
*/
 | 
						|
int spider_create_conn_keys(
 | 
						|
  SPIDER_SHARE *share
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  char *tmp_name, port_str[6];
 | 
						|
  uint length_base = sizeof(uint) * share->all_link_count;
 | 
						|
  uint *conn_keys_lengths;
 | 
						|
  uint *sql_dbton_ids;
 | 
						|
  DBUG_ENTER("spider_create_conn_keys");
 | 
						|
  char *ptr;
 | 
						|
  uint length = length_base * 2;
 | 
						|
  ptr = (char *) my_alloca(length);
 | 
						|
  if (!ptr)
 | 
						|
  {
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  conn_keys_lengths = (uint *) ptr;
 | 
						|
  ptr += length_base;
 | 
						|
  sql_dbton_ids = (uint *) ptr;
 | 
						|
 | 
						|
  share->conn_keys_charlen = 0;
 | 
						|
  for (int all_link_idx = 0; all_link_idx < (int) share->all_link_count; all_link_idx++)
 | 
						|
  {
 | 
						|
    bool get_sql_id = FALSE;
 | 
						|
    /**
 | 
						|
      Find all `SPIDER_DBTON`s with the same wrapper as the target
 | 
						|
      server and set the bitmap. Stop at the first `SPIDER_DBTON` whose
 | 
						|
      db_access_type is sql
 | 
						|
 | 
						|
      fixme: the logic may be more complicated than the intended
 | 
						|
      one. For one thing, ALL `SPIDER_DBTON`s have sql access
 | 
						|
      type. Consider removing everything to do with the db access
 | 
						|
      type.
 | 
						|
    */
 | 
						|
    for (int dbton_idx = 0; dbton_idx < SPIDER_DBTON_SIZE; dbton_idx++)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider share->tgt_wrappers[%d]=%s", all_link_idx,
 | 
						|
        share->tgt_wrappers[all_link_idx]));
 | 
						|
      DBUG_PRINT("info",("spider spider_dbton[%d].wrapper=%s", dbton_idx,
 | 
						|
        spider_dbton[dbton_idx].wrapper ?
 | 
						|
          spider_dbton[dbton_idx].wrapper : "NULL"));
 | 
						|
      if (
 | 
						|
        spider_dbton[dbton_idx].wrapper &&
 | 
						|
        !strcasecmp(share->tgt_wrappers[all_link_idx],
 | 
						|
          spider_dbton[dbton_idx].wrapper)
 | 
						|
      ) {
 | 
						|
        spider_set_bit(share->dbton_bitmap, dbton_idx);
 | 
						|
        if (
 | 
						|
          !get_sql_id &&
 | 
						|
          spider_dbton[dbton_idx].db_access_type == SPIDER_DB_ACCESS_TYPE_SQL
 | 
						|
        ) {
 | 
						|
          sql_dbton_ids[all_link_idx] = dbton_idx;
 | 
						|
          get_sql_id = TRUE;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (!get_sql_id)
 | 
						|
      sql_dbton_ids[all_link_idx] = SPIDER_DBTON_SIZE;
 | 
						|
 | 
						|
    bool tables_on_different_db_are_joinable;
 | 
						|
    if (get_sql_id)
 | 
						|
    {
 | 
						|
      tables_on_different_db_are_joinable =
 | 
						|
        spider_dbton[sql_dbton_ids[all_link_idx]].db_util->
 | 
						|
          tables_on_different_db_are_joinable();
 | 
						|
    } else {
 | 
						|
      tables_on_different_db_are_joinable = TRUE;
 | 
						|
    }
 | 
						|
    conn_keys_lengths[all_link_idx]
 | 
						|
      = 1
 | 
						|
      + (share->tgt_wrappers[all_link_idx] ? share->tgt_wrappers_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_hosts[all_link_idx] ? share->tgt_hosts_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + 5 + 2
 | 
						|
      + (share->tgt_sockets[all_link_idx] ? share->tgt_sockets_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (!tables_on_different_db_are_joinable && share->tgt_dbs[all_link_idx] ?
 | 
						|
         share->tgt_dbs_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_usernames[all_link_idx] ? share->tgt_usernames_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_passwords[all_link_idx] ? share->tgt_passwords_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_ssl_cas[all_link_idx] ? share->tgt_ssl_cas_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_ssl_capaths[all_link_idx] ? share->tgt_ssl_capaths_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_ssl_certs[all_link_idx] ? share->tgt_ssl_certs_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_ssl_ciphers[all_link_idx] ? share->tgt_ssl_ciphers_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_ssl_keys[all_link_idx] ? share->tgt_ssl_keys_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + 1 + 2
 | 
						|
      + (share->tgt_default_files[all_link_idx] ? share->tgt_default_files_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_default_groups[all_link_idx] ? share->tgt_default_groups_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_dsns[all_link_idx] ? share->tgt_dsns_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_filedsns[all_link_idx] ? share->tgt_filedsns_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_drivers[all_link_idx] ? share->tgt_drivers_lengths[all_link_idx] + 2 : 0)
 | 
						|
      + (share->tgt_odbc_conn_strs[all_link_idx] ? share->tgt_odbc_conn_strs_lengths[all_link_idx] + 2 : 0);
 | 
						|
    share->conn_keys_charlen += conn_keys_lengths[all_link_idx] + 1;
 | 
						|
  }
 | 
						|
  if (!(share->conn_keys = (char **)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_CONN_KEYS_1,
 | 
						|
                       MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &share->conn_keys, sizeof(char *) * share->all_link_count,
 | 
						|
      &share->conn_keys_lengths, length_base,
 | 
						|
      &share->conn_keys_hash_value,
 | 
						|
        sizeof(my_hash_value_type) * share->all_link_count,
 | 
						|
      &tmp_name, sizeof(char) * share->conn_keys_charlen,
 | 
						|
      &share->sql_dbton_ids, length_base,
 | 
						|
      NullS))
 | 
						|
  ) {
 | 
						|
    my_afree(conn_keys_lengths);
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  share->conn_keys_length = share->all_link_count;
 | 
						|
  memcpy(share->conn_keys_lengths, conn_keys_lengths,
 | 
						|
    length_base);
 | 
						|
  memcpy(share->sql_dbton_ids, sql_dbton_ids, length_base);
 | 
						|
 | 
						|
  my_afree(conn_keys_lengths);
 | 
						|
 | 
						|
  for (roop_count = 0; roop_count < (int) share->all_link_count; roop_count++)
 | 
						|
  {
 | 
						|
    bool tables_on_different_db_are_joinable;
 | 
						|
    if (share->sql_dbton_ids[roop_count] != SPIDER_DBTON_SIZE)
 | 
						|
    {
 | 
						|
      tables_on_different_db_are_joinable =
 | 
						|
        spider_dbton[share->sql_dbton_ids[roop_count]].db_util->
 | 
						|
          tables_on_different_db_are_joinable();
 | 
						|
    } else {
 | 
						|
      tables_on_different_db_are_joinable = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    share->conn_keys[roop_count] = tmp_name;
 | 
						|
    *tmp_name = '0';
 | 
						|
    tmp_name++;
 | 
						|
    int counter= 0;
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_wrappers[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_hosts[roop_count]);
 | 
						|
    my_sprintf(port_str, (port_str, "%05ld", share->tgt_ports[roop_count]));
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, port_str);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_sockets[roop_count]);
 | 
						|
    counter++;
 | 
						|
    if (!tables_on_different_db_are_joinable && share->tgt_dbs[roop_count])
 | 
						|
    {
 | 
						|
      *tmp_name= (char) counter;
 | 
						|
      tmp_name = strmov(tmp_name + 1, share->tgt_dbs[roop_count]);
 | 
						|
      tmp_name++;
 | 
						|
    }
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_usernames[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_passwords[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_ssl_cas[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_ssl_capaths[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_ssl_certs[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_ssl_ciphers[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_ssl_keys[roop_count]);
 | 
						|
    counter++;
 | 
						|
    *tmp_name= (char) counter;
 | 
						|
    tmp_name++;
 | 
						|
    *tmp_name = '0' + ((char) share->tgt_ssl_vscs[roop_count]);
 | 
						|
    tmp_name++;
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_default_files[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_default_groups[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_dsns[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_filedsns[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_drivers[roop_count]);
 | 
						|
    spider_create_conn_key_add_one(&counter, &tmp_name, share->tgt_odbc_conn_strs[roop_count]);
 | 
						|
    tmp_name++;
 | 
						|
    tmp_name++;
 | 
						|
    share->conn_keys_hash_value[roop_count] = my_calc_hash(
 | 
						|
      &spider_open_connections, (uchar*) share->conn_keys[roop_count],
 | 
						|
      share->conn_keys_lengths[roop_count]);
 | 
						|
  }
 | 
						|
  for (int dbton_idx = 0; dbton_idx < SPIDER_DBTON_SIZE; dbton_idx++)
 | 
						|
  {
 | 
						|
    if (spider_bit_is_set(share->dbton_bitmap, dbton_idx))
 | 
						|
    {
 | 
						|
      share->use_sql_dbton_ids[share->use_dbton_count] = dbton_idx;
 | 
						|
      share->sql_dbton_id_to_seq[dbton_idx] = share->use_dbton_count;
 | 
						|
      share->use_sql_dbton_count++;
 | 
						|
      share->use_dbton_ids[share->use_dbton_count] = dbton_idx;
 | 
						|
      share->dbton_id_to_seq[dbton_idx] = share->use_dbton_count;
 | 
						|
      share->use_dbton_count++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
SPIDER_SHARE *spider_create_share(
 | 
						|
  const char *table_name,
 | 
						|
  TABLE_SHARE *table_share,
 | 
						|
  partition_info *part_info,
 | 
						|
  my_hash_value_type hash_value,
 | 
						|
  int *error_num
 | 
						|
) {
 | 
						|
  int bitmap_size, roop_count;
 | 
						|
  uint length;
 | 
						|
  int use_table_charset;
 | 
						|
  SPIDER_SHARE *share;
 | 
						|
  char *tmp_name;
 | 
						|
  longlong *tmp_cardinality, *tmp_static_key_cardinality;
 | 
						|
  uchar *tmp_cardinality_upd, *tmp_table_mon_mutex_bitmap;
 | 
						|
  char buf[MAX_FIELD_WIDTH], *buf_pos;
 | 
						|
  char link_idx_str[SPIDER_SQL_INT_LEN];
 | 
						|
  bool checksum_support = TRUE;
 | 
						|
  DBUG_ENTER("spider_create_share");
 | 
						|
  length = (uint) strlen(table_name);
 | 
						|
  bitmap_size = spider_bitmap_size(table_share->fields);
 | 
						|
  if (!(share = (SPIDER_SHARE *)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_SHARE_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &share, (uint) (sizeof(*share)),
 | 
						|
      &tmp_name, (uint) (length + 1),
 | 
						|
      &tmp_static_key_cardinality,
 | 
						|
        (uint) (sizeof(*tmp_static_key_cardinality) * table_share->keys),
 | 
						|
      &tmp_cardinality,
 | 
						|
        (uint) (sizeof(*tmp_cardinality) * table_share->fields),
 | 
						|
      &tmp_cardinality_upd,
 | 
						|
        (uint) (sizeof(*tmp_cardinality_upd) * bitmap_size),
 | 
						|
      &tmp_table_mon_mutex_bitmap,
 | 
						|
        (uint) (sizeof(*tmp_table_mon_mutex_bitmap) *
 | 
						|
          ((spider_udf_table_mon_mutex_count + 7) / 8)),
 | 
						|
      NullS))
 | 
						|
  ) {
 | 
						|
    *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    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;
 | 
						|
  share->table_name_length = length;
 | 
						|
  share->table_name = tmp_name;
 | 
						|
  strmov(share->table_name, table_name);
 | 
						|
  share->static_key_cardinality = tmp_static_key_cardinality;
 | 
						|
  share->cardinality = tmp_cardinality;
 | 
						|
  share->cardinality_upd = tmp_cardinality_upd;
 | 
						|
  share->table_mon_mutex_bitmap = tmp_table_mon_mutex_bitmap;
 | 
						|
  share->bitmap_size = bitmap_size;
 | 
						|
  share->table_share = table_share;
 | 
						|
  share->table_name_hash_value = hash_value;
 | 
						|
  share->table_path_hash_value = my_calc_hash(&spider_open_tables,
 | 
						|
    (uchar*) table_share->path.str, table_share->path.length);
 | 
						|
  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;
 | 
						|
 | 
						|
  if (table_share->keys > 0)
 | 
						|
    if (!(share->key_hint = new spider_string[table_share->keys]))
 | 
						|
    {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_init_hint_string;
 | 
						|
    }
 | 
						|
  for (roop_count = 0; roop_count < (int) table_share->keys; roop_count++)
 | 
						|
    share->key_hint[roop_count].init_calc_mem(SPD_MID_CREATE_SHARE_2);
 | 
						|
  DBUG_PRINT("info",("spider share->key_hint=%p", share->key_hint));
 | 
						|
 | 
						|
  if ((*error_num = spider_parse_connect_info(share, table_share,
 | 
						|
    part_info,
 | 
						|
    0)))
 | 
						|
    goto error_parse_connect_string;
 | 
						|
 | 
						|
  for (roop_count = 0; roop_count < (int) share->all_link_count;
 | 
						|
    roop_count++)
 | 
						|
  {
 | 
						|
    my_sprintf(link_idx_str, (link_idx_str, "%010d", roop_count));
 | 
						|
    buf_pos = strmov(buf, share->table_name);
 | 
						|
    buf_pos = strmov(buf_pos, link_idx_str);
 | 
						|
    *buf_pos = '\0';
 | 
						|
    spider_set_bit(tmp_table_mon_mutex_bitmap,
 | 
						|
      spider_udf_calc_hash(buf, spider_udf_table_mon_mutex_count)
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  use_table_charset = spider_param_use_table_charset(
 | 
						|
    share->use_table_charset);
 | 
						|
  if (table_share->table_charset && use_table_charset)
 | 
						|
    share->access_charset = table_share->table_charset;
 | 
						|
  else
 | 
						|
    share->access_charset = system_charset_info;
 | 
						|
 | 
						|
  if ((*error_num = spider_create_conn_keys(share)))
 | 
						|
    goto error_create_conn_keys;
 | 
						|
 | 
						|
  if (share->table_count_mode & 1)
 | 
						|
    share->additional_table_flags |= HA_STATS_RECORDS_IS_EXACT;
 | 
						|
  if (share->table_count_mode & 2)
 | 
						|
    share->additional_table_flags |= HA_HAS_RECORDS;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_share,
 | 
						|
    &share->mutex, MY_MUTEX_INIT_FAST))
 | 
						|
  {
 | 
						|
    *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error_init_mutex;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_share_sts,
 | 
						|
    &share->sts_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
  {
 | 
						|
    *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error_init_sts_mutex;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_share_crd,
 | 
						|
    &share->crd_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
  {
 | 
						|
    *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error_init_crd_mutex;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(share->lgtm_tblhnd_share =
 | 
						|
    spider_get_lgtm_tblhnd_share(tmp_name, length, hash_value, FALSE, TRUE,
 | 
						|
    error_num)))
 | 
						|
  {
 | 
						|
    goto error_get_lgtm_tblhnd_share;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(share->wide_share =
 | 
						|
    spider_get_wide_share(share, table_share, error_num)))
 | 
						|
    goto error_get_wide_share;
 | 
						|
 | 
						|
  for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++)
 | 
						|
  {
 | 
						|
    if (spider_bit_is_set(share->dbton_bitmap, roop_count))
 | 
						|
    {
 | 
						|
      if (!(share->dbton_share[roop_count] =
 | 
						|
        spider_dbton[roop_count].create_db_share(share)))
 | 
						|
      {
 | 
						|
        *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
        goto error_init_dbton;
 | 
						|
      }
 | 
						|
      if ((*error_num = share->dbton_share[roop_count]->init()))
 | 
						|
      {
 | 
						|
        goto error_init_dbton;
 | 
						|
      }
 | 
						|
      if (
 | 
						|
        spider_dbton[roop_count].db_access_type == SPIDER_DB_ACCESS_TYPE_SQL &&
 | 
						|
        !share->dbton_share[roop_count]->checksum_support()
 | 
						|
      ) {
 | 
						|
        checksum_support = FALSE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (checksum_support)
 | 
						|
  {
 | 
						|
    share->additional_table_flags |=
 | 
						|
      HA_HAS_OLD_CHECKSUM |
 | 
						|
      HA_HAS_NEW_CHECKSUM;
 | 
						|
  }
 | 
						|
  DBUG_RETURN(share);
 | 
						|
 | 
						|
/*
 | 
						|
  roop_count = SPIDER_DBTON_SIZE - 1;
 | 
						|
*/
 | 
						|
error_init_dbton:
 | 
						|
  for (; roop_count >= 0; roop_count--)
 | 
						|
  {
 | 
						|
    if (share->dbton_share[roop_count])
 | 
						|
    {
 | 
						|
      delete share->dbton_share[roop_count];
 | 
						|
      share->dbton_share[roop_count] = NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  spider_free_wide_share(share->wide_share);
 | 
						|
error_get_wide_share:
 | 
						|
error_get_lgtm_tblhnd_share:
 | 
						|
  pthread_mutex_destroy(&share->crd_mutex);
 | 
						|
error_init_crd_mutex:
 | 
						|
  pthread_mutex_destroy(&share->sts_mutex);
 | 
						|
error_init_sts_mutex:
 | 
						|
  pthread_mutex_destroy(&share->mutex);
 | 
						|
error_init_mutex:
 | 
						|
error_create_conn_keys:
 | 
						|
error_parse_connect_string:
 | 
						|
error_init_hint_string:
 | 
						|
  spider_free_share_alloc(share);
 | 
						|
  spider_free(spider_current_trx, share, MYF(0));
 | 
						|
error_alloc_share:
 | 
						|
  DBUG_RETURN(NULL);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Checks for spider table self-reference
 | 
						|
 | 
						|
  Get the user variable value (source) and compare it with the user
 | 
						|
  variable name (target). If the target is a substring of the source,
 | 
						|
  then there is a self-reference
 | 
						|
 | 
						|
  @param thd    Connection
 | 
						|
  @param share  The table share
 | 
						|
  @retval 0 for success, or else the error number
 | 
						|
*/
 | 
						|
int spider_check_for_self_reference(THD *thd, const TABLE_SHARE *share)
 | 
						|
{
 | 
						|
  String target(0);
 | 
						|
  LEX_CSTRING key;
 | 
						|
  DBUG_ENTER("spider_check_for_self_reference");
 | 
						|
 | 
						|
  target.append(STRING_WITH_LEN(SPIDER_SQL_LOP_CHK_PRM_PRF_STR));
 | 
						|
  target.append(share->path);
 | 
						|
  DBUG_PRINT("info",("spider loop check param name=%s", target.c_ptr()));
 | 
						|
  key = target.to_lex_cstring();
 | 
						|
  const user_var_entry *loop_check= get_variable(&thd->user_vars, &key, FALSE);
 | 
						|
  if (loop_check && loop_check->type_handler()->result_type() == STRING_RESULT)
 | 
						|
  {
 | 
						|
    String expected(0);
 | 
						|
    expected.append(spider_unique_id);
 | 
						|
    expected.append(share->path);
 | 
						|
    expected.append(STRING_WITH_LEN("-"));
 | 
						|
    DBUG_PRINT("info",("spider loop check expected=%s", expected.c_ptr()));
 | 
						|
    DBUG_PRINT("info",("spider loop check param value=%s",
 | 
						|
                       loop_check->value));
 | 
						|
    if (unlikely(strstr(loop_check->value, expected.c_ptr())))
 | 
						|
    {
 | 
						|
      const int error_num = ER_SPIDER_INFINITE_LOOP_NUM;
 | 
						|
      my_printf_error(error_num, ER_SPIDER_INFINITE_LOOP_STR, MYF(0),
 | 
						|
                      share->db.str, share->table_name.str);
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
/** Populate the init_errors and init of share and/or free it */
 | 
						|
void spider_share_init_error_free(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  const bool init,
 | 
						|
  const bool free_share
 | 
						|
)
 | 
						|
{
 | 
						|
  share->init_error= TRUE;
 | 
						|
  share->init_error_time= (time_t) time((time_t *) 0);
 | 
						|
  share->init= TRUE;
 | 
						|
  if (free_share)
 | 
						|
    spider_free_share(share);
 | 
						|
}
 | 
						|
 | 
						|
void spider_lock_udf_table_mon_mutexes(SPIDER_SHARE *share)
 | 
						|
{
 | 
						|
  pthread_mutex_lock(&share->mutex);
 | 
						|
  for (int roop_count = 0;
 | 
						|
       roop_count < (int) spider_udf_table_mon_mutex_count;
 | 
						|
       roop_count++)
 | 
						|
    {
 | 
						|
      if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count))
 | 
						|
        pthread_mutex_lock(&spider_udf_table_mon_mutexes[roop_count]);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void spider_unlock_udf_table_mon_mutexes(SPIDER_SHARE *share)
 | 
						|
{
 | 
						|
  for (int roop_count = 0;
 | 
						|
       roop_count < (int) spider_udf_table_mon_mutex_count;
 | 
						|
       roop_count++)
 | 
						|
    {
 | 
						|
      if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count))
 | 
						|
        pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]);
 | 
						|
    }
 | 
						|
  pthread_mutex_unlock(&share->mutex);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialises the link_statuses of a spider share
 | 
						|
 | 
						|
  Open the spider_tables system table, read the link_statuses and
 | 
						|
  update the spider share, and close the table. Frees share if
 | 
						|
  failure
 | 
						|
 | 
						|
  @param thd          Connection
 | 
						|
  @param share        The spider share to populate the link_statuses of
 | 
						|
  @param table_share  fixme
 | 
						|
  @param sql_command  The sql command of the thread
 | 
						|
  @param error_num    The error number
 | 
						|
  @retval true        Failure
 | 
						|
          false       Success
 | 
						|
*/
 | 
						|
bool spider_share_init_link_statuses(
 | 
						|
  THD *thd,
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  TABLE_SHARE *table_share,
 | 
						|
  const int sql_command,
 | 
						|
  const bool init_share,
 | 
						|
  int *error_num
 | 
						|
)
 | 
						|
{
 | 
						|
  MEM_ROOT mem_root;
 | 
						|
  bool init_mem_root= FALSE;
 | 
						|
  TABLE *table_tables;
 | 
						|
  SPIDER_Open_tables_backup open_tables_backup;
 | 
						|
  DBUG_ENTER("spider_share_init_link_statuses");
 | 
						|
  /*
 | 
						|
    The link statuses need to be refreshed from the spider_tables table
 | 
						|
    if the operation:
 | 
						|
    - Is not a DROP TABLE on a permanent table; or
 | 
						|
    - Is an ALTER TABLE.
 | 
						|
 | 
						|
    Note that SHOW CREATE TABLE is not excluded, because the commands
 | 
						|
    that follow it require up-to-date link statuses.
 | 
						|
  */
 | 
						|
  if ((table_share->tmp_table == NO_TMP_TABLE &&
 | 
						|
       sql_command != SQLCOM_DROP_TABLE) ||
 | 
						|
      /* for alter change link status */
 | 
						|
      sql_command == SQLCOM_ALTER_TABLE)
 | 
						|
  {
 | 
						|
    SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
 | 
						|
    init_mem_root = TRUE;
 | 
						|
 | 
						|
    if (!(table_tables =
 | 
						|
          spider_open_sys_table(thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
 | 
						|
                                SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE,
 | 
						|
                                &open_tables_backup, error_num)))
 | 
						|
    {
 | 
						|
      spider_unlock_udf_table_mon_mutexes(share);
 | 
						|
      spider_share_init_error_free(share, true, true);
 | 
						|
      free_root(&mem_root, MYF(0));
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
    }
 | 
						|
    if ((*error_num= spider_get_link_statuses(table_tables, share,
 | 
						|
                                              &mem_root)))
 | 
						|
    {
 | 
						|
      if (*error_num != HA_ERR_KEY_NOT_FOUND &&
 | 
						|
          *error_num != HA_ERR_END_OF_FILE)
 | 
						|
      {
 | 
						|
        spider_unlock_udf_table_mon_mutexes(share);
 | 
						|
        spider_share_init_error_free(share, init_share, true);
 | 
						|
        spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
        free_root(&mem_root, MYF(0));
 | 
						|
        DBUG_RETURN(TRUE);
 | 
						|
      }
 | 
						|
    } else
 | 
						|
    {
 | 
						|
      memcpy(share->alter_table.tmp_link_statuses, share->link_statuses,
 | 
						|
             sizeof(long) * share->all_link_count);
 | 
						|
      share->link_status_init = TRUE;
 | 
						|
    }
 | 
						|
    spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
  }
 | 
						|
  share->have_recovery_link = spider_conn_check_recovery_link(share);
 | 
						|
 | 
						|
  if (init_mem_root)
 | 
						|
    free_root(&mem_root, MYF(0));
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/** Creates an `ha_spider` for the sts thread of the spider share. */
 | 
						|
int spider_share_init_sts(
 | 
						|
  const char* table_name,
 | 
						|
  ha_spider *spider,
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  const bool init_share
 | 
						|
)
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_share_init_sts");
 | 
						|
  if (int error_num = spider_create_spider_object_for_share(
 | 
						|
        spider->wide_handler->trx, share, &share->sts_spider))
 | 
						|
    {
 | 
						|
      pthread_mutex_unlock(&share->mutex);
 | 
						|
      spider_share_init_error_free(share, init_share, true);
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
  share->sts_thread = spider_table_sts_thread;
 | 
						|
  share->sts_spider_init = TRUE;
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
/** Creates an `ha_spider` for the crd thread of the spider share */
 | 
						|
int spider_share_init_crd(
 | 
						|
  const char* table_name,
 | 
						|
  ha_spider *spider,
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  const bool init_share
 | 
						|
)
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_share_init_crd");
 | 
						|
  if (int error_num = spider_create_spider_object_for_share(
 | 
						|
        spider->wide_handler->trx, share, &share->crd_spider))
 | 
						|
    {
 | 
						|
      pthread_mutex_unlock(&share->mutex);
 | 
						|
      spider_share_init_error_free(share, init_share, true);
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
  share->crd_thread = spider_table_crd_thread;
 | 
						|
  share->crd_spider_init = TRUE;
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
void *spider_share_malloc_for_spider(
 | 
						|
  ha_spider *spider,
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  const uint id,
 | 
						|
  char** tmp_name,
 | 
						|
  SPIDER_RESULT_LIST* result_list
 | 
						|
)
 | 
						|
{
 | 
						|
  return spider_bulk_malloc(
 | 
						|
    spider_current_trx, id, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
    &spider->conn_keys, sizeof(char *) * share->link_count,
 | 
						|
    tmp_name, sizeof(char) * share->conn_keys_charlen,
 | 
						|
    &spider->conns, sizeof(SPIDER_CONN *) * share->link_count,
 | 
						|
    &spider->conn_link_idx, sizeof(uint) * share->link_count,
 | 
						|
    &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size,
 | 
						|
    &spider->connection_ids, sizeof(ulonglong) * share->link_count,
 | 
						|
    &spider->db_request_id, sizeof(ulonglong) * share->link_count,
 | 
						|
    &spider->db_request_phase, sizeof(uchar) * share->link_bitmap_size,
 | 
						|
    &spider->need_mons, sizeof(int) * share->link_count,
 | 
						|
    &spider->quick_targets, sizeof(void *) * share->link_count,
 | 
						|
    &result_list->upd_tmp_tbls, sizeof(TABLE *) * share->link_count,
 | 
						|
    &result_list->upd_tmp_tbl_prms,
 | 
						|
    sizeof(TMP_TABLE_PARAM) * share->link_count,
 | 
						|
    &result_list->tmp_table_join_first,
 | 
						|
    sizeof(uchar) * share->link_bitmap_size,
 | 
						|
    &result_list->tmp_table_created,
 | 
						|
    sizeof(uchar) * share->link_bitmap_size,
 | 
						|
    &result_list->casual_read, sizeof(int) * share->link_count,
 | 
						|
    &spider->dbton_handler,
 | 
						|
    sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE,
 | 
						|
    NullS);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialise dbton_handlers of a spider.
 | 
						|
*/
 | 
						|
int spider_share_init_spider_dbton_handlers(ha_spider *spider, SPIDER_SHARE *share)
 | 
						|
{
 | 
						|
  int roop_count, error_num= 0;
 | 
						|
  for (roop_count = 0; roop_count < (int) share->use_dbton_count;
 | 
						|
       roop_count++)
 | 
						|
  {
 | 
						|
    uint dbton_id = share->use_dbton_ids[roop_count];
 | 
						|
    if (!(spider->dbton_handler[dbton_id]=
 | 
						|
          spider_dbton[dbton_id].create_db_handler(spider,
 | 
						|
            share->dbton_share[dbton_id])))
 | 
						|
    {
 | 
						|
      error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if ((error_num = spider->dbton_handler[dbton_id]->init()))
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  /* Failure: rollback */
 | 
						|
  if (roop_count < (int) share->use_dbton_count)
 | 
						|
  {
 | 
						|
    for (; roop_count >= 0; roop_count--)
 | 
						|
    {
 | 
						|
      uint dbton_id = share->use_dbton_ids[roop_count];
 | 
						|
      if (spider->dbton_handler[dbton_id])
 | 
						|
      {
 | 
						|
        delete spider->dbton_handler[dbton_id];
 | 
						|
        spider->dbton_handler[dbton_id]= NULL;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return error_num;
 | 
						|
}
 | 
						|
 | 
						|
/** Gets or creates connections to all active servers */
 | 
						|
bool spider_share_get_conns(ha_spider *spider, SPIDER_SHARE *share,
 | 
						|
                            int *error_num)
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_share_get_conns");
 | 
						|
  for (int 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))
 | 
						|
  {
 | 
						|
    if (!(spider->conns[roop_count] =
 | 
						|
          spider_get_conn(share, roop_count, spider->conn_keys[roop_count],
 | 
						|
                          spider->wide_handler->trx, spider, FALSE, TRUE,
 | 
						|
                          error_num)))
 | 
						|
    {
 | 
						|
      if (share->monitoring_kind[roop_count] && spider->need_mons[roop_count])
 | 
						|
      {
 | 
						|
        *error_num = spider_ping_table_mon_from_table(
 | 
						|
          spider->wide_handler->trx,
 | 
						|
          spider->wide_handler->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],
 | 
						|
          FALSE
 | 
						|
        );
 | 
						|
      }
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
    }
 | 
						|
    spider->conns[roop_count]->error_mode &= spider->error_mode;
 | 
						|
  }
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Handles a failed search for usable servers
 | 
						|
 | 
						|
  @param share          The spider share to update its init error
 | 
						|
  @param table_share    The table share
 | 
						|
  @param search_result  The search result, either -1 (no usable server) or
 | 
						|
                        -2 (out of memory)
 | 
						|
  @return Error code associated with the failure
 | 
						|
*/
 | 
						|
int spider_share_handle_search_link_failure(
 | 
						|
  SPIDER_SHARE* share,
 | 
						|
  TABLE_SHARE* table_share,
 | 
						|
  const int search_result,
 | 
						|
  const bool init_share
 | 
						|
)
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_share_handle_search_link_failure");
 | 
						|
  if (likely(search_result == -1))  /* No available servers. */
 | 
						|
  {
 | 
						|
    char *db = (char *) my_alloca(
 | 
						|
      table_share->db.length + 1 + table_share->table_name.length + 1);
 | 
						|
    if (unlikely(!db))
 | 
						|
    {
 | 
						|
      spider_share_init_error_free(share, init_share, false);
 | 
						|
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
    }
 | 
						|
    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,
 | 
						|
           table_share->table_name.length);
 | 
						|
    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);
 | 
						|
    my_afree(db);
 | 
						|
    spider_share_init_error_free(share, init_share, false);
 | 
						|
    DBUG_RETURN(ER_SPIDER_ALL_LINKS_FAILED_NUM);
 | 
						|
  }
 | 
						|
  spider_share_init_error_free(share, init_share, false);
 | 
						|
  DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
}
 | 
						|
 | 
						|
/** Gets sts and crd for spider_init_share() */
 | 
						|
bool spider_share_get_sts_crd(
 | 
						|
  THD *thd,
 | 
						|
  ha_spider *spider,
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  TABLE *table,
 | 
						|
  const bool init_share,
 | 
						|
  /* fixme: do we need this? */
 | 
						|
  const bool has_lock,
 | 
						|
  int *error_num
 | 
						|
)
 | 
						|
{
 | 
						|
  const bool same_server_link = spider_param_same_server_link(thd);
 | 
						|
  const int load_sts_at_startup =
 | 
						|
    spider_param_load_sts_at_startup(share->load_sts_at_startup);
 | 
						|
  const int load_crd_at_startup =
 | 
						|
    spider_param_load_crd_at_startup(share->load_crd_at_startup);
 | 
						|
  DBUG_ENTER("spider_share_get_sts_crd");
 | 
						|
  if (!spider->error_mode &&
 | 
						|
      (!same_server_link || load_sts_at_startup || load_crd_at_startup))
 | 
						|
  {
 | 
						|
    const double sts_interval = spider_param_sts_interval(thd, share->sts_interval);
 | 
						|
    const int sts_mode = spider_param_sts_mode(thd, share->sts_mode);
 | 
						|
    const int auto_increment_mode = spider_param_auto_increment_mode(
 | 
						|
      thd, share->auto_increment_mode);
 | 
						|
    const int sts_sync = auto_increment_mode == 1 ? 0 :
 | 
						|
      spider_param_sts_sync(thd, share->sts_sync);
 | 
						|
    const double crd_interval = spider_param_crd_interval(thd, share->crd_interval);
 | 
						|
    int crd_mode = spider_param_crd_mode(thd, share->crd_mode);
 | 
						|
    /* TODO(MDEV-27996): Delete spider_crd_mode and spider_sts_mode */
 | 
						|
    if (crd_mode == 3)
 | 
						|
      crd_mode = 1;
 | 
						|
    const int crd_sync = spider_param_crd_sync(thd, share->crd_sync);
 | 
						|
 | 
						|
    const time_t tmp_time = (time_t) time((time_t*) 0);
 | 
						|
    if (!has_lock)
 | 
						|
    {
 | 
						|
      pthread_mutex_lock(&share->sts_mutex);
 | 
						|
      pthread_mutex_lock(&share->crd_mutex);
 | 
						|
    }
 | 
						|
    /* If not enough time has passed since the last init error, abort */
 | 
						|
    if (const SPIDER_INIT_ERROR_TABLE *spider_init_error_table =
 | 
						|
        spider_get_init_error_table(spider->wide_handler->trx, share, FALSE))
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider diff1=%f",
 | 
						|
                         difftime(tmp_time, spider_init_error_table->init_error_time)));
 | 
						|
      if (difftime(tmp_time,
 | 
						|
                   spider_init_error_table->init_error_time) <
 | 
						|
          spider_param_table_init_error_interval())
 | 
						|
      {
 | 
						|
        *error_num = spider_init_error_table->init_error;
 | 
						|
        if (spider_init_error_table->init_error_with_message)
 | 
						|
          my_message(spider_init_error_table->init_error,
 | 
						|
                     spider_init_error_table->init_error_msg, MYF(0));
 | 
						|
        spider_share_init_error_free(share, init_share, false);
 | 
						|
        pthread_mutex_unlock(&share->crd_mutex);
 | 
						|
        pthread_mutex_unlock(&share->sts_mutex);
 | 
						|
        DBUG_RETURN(TRUE);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((!same_server_link || load_sts_at_startup) &&
 | 
						|
        (*error_num = spider_get_sts(share, spider->search_link_idx, tmp_time,
 | 
						|
                                     spider, sts_interval, sts_mode, sts_sync,
 | 
						|
                                     1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO))
 | 
						|
    )
 | 
						|
    {
 | 
						|
      if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM &&
 | 
						|
          *error_num != ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_NUM)
 | 
						|
        thd->clear_error();
 | 
						|
      else
 | 
						|
      {
 | 
						|
        pthread_mutex_unlock(&share->crd_mutex);
 | 
						|
        pthread_mutex_unlock(&share->sts_mutex);
 | 
						|
        spider_share_init_error_free(share, init_share, false);
 | 
						|
        DBUG_RETURN(TRUE);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((!same_server_link || load_crd_at_startup) &&
 | 
						|
        (*error_num = spider_get_crd(share, spider->search_link_idx, tmp_time,
 | 
						|
                                     spider, table, crd_interval, crd_mode,
 | 
						|
                                     crd_sync,
 | 
						|
                                     1)))
 | 
						|
    {
 | 
						|
      if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM &&
 | 
						|
          *error_num != ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_NUM)
 | 
						|
        thd->clear_error();
 | 
						|
      else
 | 
						|
      {
 | 
						|
        pthread_mutex_unlock(&share->crd_mutex);
 | 
						|
        pthread_mutex_unlock(&share->sts_mutex);
 | 
						|
        spider_share_init_error_free(share, init_share, false);
 | 
						|
        DBUG_RETURN(TRUE);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (!has_lock)
 | 
						|
    {
 | 
						|
      pthread_mutex_unlock(&share->crd_mutex);
 | 
						|
      pthread_mutex_unlock(&share->sts_mutex);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/** Initialises a `SPIDER_SHARE` */
 | 
						|
bool spider_init_share(
 | 
						|
  const char *table_name,
 | 
						|
  TABLE *table,
 | 
						|
  THD *thd,
 | 
						|
  ha_spider *spider,
 | 
						|
  int *error_num,
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  TABLE_SHARE *table_share,
 | 
						|
  const bool new_share
 | 
						|
)
 | 
						|
{
 | 
						|
  char *tmp_name;
 | 
						|
  SPIDER_RESULT_LIST *result_list = &spider->result_list;
 | 
						|
  int search_link_idx;
 | 
						|
  const uint sql_command = thd_sql_command(thd);
 | 
						|
  const bool continue_with_sql_command =
 | 
						|
    sql_command != SQLCOM_DROP_TABLE &&
 | 
						|
    sql_command != SQLCOM_ALTER_TABLE &&
 | 
						|
    sql_command != SQLCOM_SHOW_CREATE;
 | 
						|
  DBUG_ENTER("spider_init_share");
 | 
						|
  if (!share->link_status_init)
 | 
						|
  {
 | 
						|
    spider_lock_udf_table_mon_mutexes(share);
 | 
						|
    if (!share->link_status_init &&
 | 
						|
        spider_share_init_link_statuses(thd, share, table_share,
 | 
						|
                                        sql_command, new_share, error_num))
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
    spider_unlock_udf_table_mon_mutexes(share);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(spider->wide_handler->trx = spider_get_trx(thd, TRUE, error_num)))
 | 
						|
  {
 | 
						|
    spider_share_init_error_free(share, new_share, true);
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  }
 | 
						|
  spider->set_error_mode();
 | 
						|
 | 
						|
  /* There's no other place doing anything that
 | 
						|
  `spider_share_init_sts()` does or updating
 | 
						|
  `st_spider_share::sts_spider_init`, therefore there's no need to
 | 
						|
  lock/unlock. Same goes for crd */
 | 
						|
  if (!share->sts_spider_init &&
 | 
						|
      (*error_num= spider_share_init_sts(table_name, spider, share, new_share)))
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
 | 
						|
  if (!share->crd_spider_init &&
 | 
						|
      (*error_num= spider_share_init_crd(table_name, spider, share, new_share)))
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
 | 
						|
  if (continue_with_sql_command &&
 | 
						|
      (*error_num = spider_create_mon_threads(spider->wide_handler->trx,
 | 
						|
                                              share)))
 | 
						|
  {
 | 
						|
    spider_share_init_error_free(share, new_share, true);
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(spider_share_malloc_for_spider(spider, share,  SPD_MID_GET_SHARE_1,
 | 
						|
                                       &tmp_name, result_list)))
 | 
						|
  {
 | 
						|
    spider_share_init_error_free(share, new_share, true);
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  }
 | 
						|
  memcpy(tmp_name, share->conn_keys[0], share->conn_keys_charlen);
 | 
						|
 | 
						|
  spider->conn_keys_first_ptr = tmp_name;
 | 
						|
  for (int link_idx = 0; link_idx < (int) share->link_count; link_idx++)
 | 
						|
  {
 | 
						|
    spider->conn_keys[link_idx] = tmp_name;
 | 
						|
    tmp_name += share->conn_keys_lengths[link_idx] + 1;
 | 
						|
    result_list->upd_tmp_tbl_prms[link_idx].init();
 | 
						|
    result_list->upd_tmp_tbl_prms[link_idx].field_count = 1;
 | 
						|
  }
 | 
						|
  spider_trx_set_link_idx_for_all(spider);
 | 
						|
 | 
						|
  if ((*error_num= spider_share_init_spider_dbton_handlers(spider, share)))
 | 
						|
  {
 | 
						|
    spider_share_init_error_free(share, new_share, false);
 | 
						|
    goto error_after_alloc_conn_keys;
 | 
						|
  }
 | 
						|
 | 
						|
  if (continue_with_sql_command &&
 | 
						|
      spider_share_get_conns(spider, share, error_num))
 | 
						|
  {
 | 
						|
    spider_share_init_error_free(share, new_share, false);
 | 
						|
    goto error_after_alloc_dbton_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  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 (search_link_idx < 0)
 | 
						|
  {
 | 
						|
    *error_num= spider_share_handle_search_link_failure(
 | 
						|
      share, table_share, search_link_idx, new_share);
 | 
						|
    goto error_after_alloc_dbton_handler;
 | 
						|
  }
 | 
						|
  spider->search_link_idx= search_link_idx;
 | 
						|
 | 
						|
  if (continue_with_sql_command)
 | 
						|
  {
 | 
						|
    if (new_share)
 | 
						|
    {
 | 
						|
      if (spider_share_get_sts_crd(thd, spider, share, table, true, false,
 | 
						|
                                 error_num))
 | 
						|
        goto error_after_alloc_dbton_handler;
 | 
						|
    } else if (share->init_error)
 | 
						|
    {
 | 
						|
      /* fixme: can we move the locking and unlocking into
 | 
						|
         spider_share_get_sts_crd()? */
 | 
						|
      pthread_mutex_lock(&share->sts_mutex);
 | 
						|
      pthread_mutex_lock(&share->crd_mutex);
 | 
						|
      if (share->init_error)
 | 
						|
      {
 | 
						|
        if (spider_share_get_sts_crd(thd, spider, share, table, FALSE, TRUE,
 | 
						|
                                     error_num))
 | 
						|
          goto error_after_alloc_dbton_handler;
 | 
						|
        share->init_error= FALSE;
 | 
						|
      }
 | 
						|
      pthread_mutex_unlock(&share->crd_mutex);
 | 
						|
      pthread_mutex_unlock(&share->sts_mutex);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
 | 
						|
error_after_alloc_dbton_handler:
 | 
						|
  for (int roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count)
 | 
						|
  {
 | 
						|
    uint dbton_id = share->use_dbton_ids[roop_count];
 | 
						|
    if (spider->dbton_handler[dbton_id])
 | 
						|
    {
 | 
						|
      delete spider->dbton_handler[dbton_id];
 | 
						|
      spider->dbton_handler[dbton_id] = NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
error_after_alloc_conn_keys:
 | 
						|
  spider_free(spider_current_trx, spider->conn_keys, MYF(0));
 | 
						|
  spider->conn_keys = NULL;
 | 
						|
  spider_free_share(share);
 | 
						|
  DBUG_RETURN(TRUE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Gets or creates a spider share, then initialises it
 | 
						|
*/
 | 
						|
SPIDER_SHARE *spider_get_share(
 | 
						|
  const char *table_name,
 | 
						|
  TABLE *table,
 | 
						|
  THD *thd,
 | 
						|
  ha_spider *spider,
 | 
						|
  int *error_num
 | 
						|
) {
 | 
						|
  SPIDER_SHARE *share;
 | 
						|
  TABLE_SHARE *table_share = table->s;
 | 
						|
  DBUG_ENTER("spider_get_share");
 | 
						|
 | 
						|
  const TABLE_SHARE *top_share = spider->wide_handler->top_share;
 | 
						|
  if (top_share &&
 | 
						|
      (*error_num = spider_check_for_self_reference(thd, top_share)))
 | 
						|
    DBUG_RETURN(NULL);
 | 
						|
 | 
						|
  const uint length = (uint) strlen(table_name);
 | 
						|
  const my_hash_value_type hash_value =
 | 
						|
    my_calc_hash(&spider_open_tables, (uchar*) table_name, length);
 | 
						|
  pthread_mutex_lock(&spider_tbl_mutex);
 | 
						|
  if (!(share = (SPIDER_SHARE*) my_hash_search_using_hash_value(
 | 
						|
    &spider_open_tables, hash_value, (uchar*) table_name, length)))
 | 
						|
  {
 | 
						|
    if (!(share = spider_create_share(table_name, table_share,
 | 
						|
                                      table->part_info, hash_value,
 | 
						|
                                      error_num)))
 | 
						|
      goto error_alloc_share;
 | 
						|
 | 
						|
    uint old_elements = spider_open_tables.array.max_element;
 | 
						|
    if (my_hash_insert(&spider_open_tables, (uchar*) share))
 | 
						|
    {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_hash_insert;
 | 
						|
    }
 | 
						|
    if (spider_open_tables.array.max_element > old_elements)
 | 
						|
    {
 | 
						|
      spider_alloc_calc_mem(spider_current_trx,
 | 
						|
        spider_open_tables,
 | 
						|
        (spider_open_tables.array.max_element - old_elements) *
 | 
						|
        spider_open_tables.array.size_of_element);
 | 
						|
    }
 | 
						|
 | 
						|
    spider->share = share;
 | 
						|
    uint tmp_conn_link_idx= 0;
 | 
						|
    spider->conn_link_idx = &tmp_conn_link_idx;
 | 
						|
 | 
						|
    share->use_count++;
 | 
						|
    pthread_mutex_unlock(&spider_tbl_mutex);
 | 
						|
 | 
						|
    if (spider_init_share(table_name, table, thd, spider, error_num, share,
 | 
						|
                          table_share, TRUE))
 | 
						|
      DBUG_RETURN(NULL);
 | 
						|
 | 
						|
    share->init = TRUE;
 | 
						|
  } else
 | 
						|
  {
 | 
						|
    share->use_count++;
 | 
						|
    pthread_mutex_unlock(&spider_tbl_mutex);
 | 
						|
 | 
						|
    int sleep_cnt = 0;
 | 
						|
    while (!share->init)
 | 
						|
    {
 | 
						|
      // 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);
 | 
						|
        spider_free_share(share);
 | 
						|
        DBUG_RETURN(NULL);
 | 
						|
      }
 | 
						|
      my_sleep(10000); // wait 10 ms
 | 
						|
    }
 | 
						|
 | 
						|
    spider->share = share;
 | 
						|
 | 
						|
    if (spider_init_share(table_name, table, thd, spider, error_num, share,
 | 
						|
                          table_share, FALSE))
 | 
						|
      DBUG_RETURN(NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  DBUG_PRINT("info",("spider share=%p", share));
 | 
						|
  DBUG_RETURN(share);
 | 
						|
 | 
						|
error_hash_insert:
 | 
						|
  spider_free_share_resource_only(share);
 | 
						|
error_alloc_share:
 | 
						|
  pthread_mutex_unlock(&spider_tbl_mutex);
 | 
						|
  DBUG_RETURN(NULL);
 | 
						|
}
 | 
						|
 | 
						|
void spider_free_share_resource_only(
 | 
						|
  SPIDER_SHARE *share
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_free_share_resource_only");
 | 
						|
  spider_free_share_alloc(share);
 | 
						|
  pthread_mutex_destroy(&share->crd_mutex);
 | 
						|
  pthread_mutex_destroy(&share->sts_mutex);
 | 
						|
  pthread_mutex_destroy(&share->mutex);
 | 
						|
  spider_free(spider_current_trx, share, MYF(0));
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
int spider_free_share(
 | 
						|
  SPIDER_SHARE *share
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_free_share");
 | 
						|
  pthread_mutex_lock(&spider_tbl_mutex);
 | 
						|
  if (!--share->use_count)
 | 
						|
  {
 | 
						|
    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);
 | 
						|
    }
 | 
						|
    spider_free_share_alloc(share);
 | 
						|
    my_hash_delete(&spider_open_tables, (uchar*) 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);
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
void spider_update_link_status_for_share(
 | 
						|
  const char *table_name,
 | 
						|
  uint table_name_length,
 | 
						|
  int link_idx,
 | 
						|
  long link_status
 | 
						|
) {
 | 
						|
  SPIDER_SHARE *share;
 | 
						|
  DBUG_ENTER("spider_update_link_status_for_share");
 | 
						|
 | 
						|
  my_hash_value_type hash_value = my_calc_hash(&spider_open_tables,
 | 
						|
    (uchar*) table_name, table_name_length);
 | 
						|
  pthread_mutex_lock(&spider_tbl_mutex);
 | 
						|
  if ((share = (SPIDER_SHARE*) my_hash_search_using_hash_value(
 | 
						|
    &spider_open_tables, hash_value, (uchar*) table_name,
 | 
						|
    table_name_length)))
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info", ("spider share->link_status_init=%s",
 | 
						|
      share->link_status_init ? "TRUE" : "FALSE"));
 | 
						|
    if (share->link_status_init)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info", ("spider share->link_statuses[%d]=%ld",
 | 
						|
        link_idx, link_status));
 | 
						|
      share->link_statuses[link_idx] = link_status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_tbl_mutex);
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
SPIDER_LGTM_TBLHND_SHARE *spider_get_lgtm_tblhnd_share(
 | 
						|
  const char *table_name,
 | 
						|
  uint table_name_length,
 | 
						|
  my_hash_value_type hash_value,
 | 
						|
  bool locked,
 | 
						|
  bool need_to_create,
 | 
						|
  int *error_num
 | 
						|
)
 | 
						|
{
 | 
						|
  SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
 | 
						|
  char *tmp_name;
 | 
						|
  DBUG_ENTER("spider_get_lgtm_tblhnd_share");
 | 
						|
 | 
						|
  if (!locked)
 | 
						|
    pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
  if (!(lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE*)
 | 
						|
    my_hash_search_using_hash_value(
 | 
						|
    &spider_lgtm_tblhnd_share_hash, hash_value,
 | 
						|
    (uchar*) table_name, table_name_length)))
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider create new lgtm tblhnd share"));
 | 
						|
    if (!(lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE *)
 | 
						|
      spider_bulk_malloc(spider_current_trx, SPD_MID_GET_LGTM_TBLHND_SHARE_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
        &lgtm_tblhnd_share, (uint) (sizeof(*lgtm_tblhnd_share)),
 | 
						|
        &tmp_name, (uint) (table_name_length + 1),
 | 
						|
        NullS))
 | 
						|
    ) {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_alloc_share;
 | 
						|
    }
 | 
						|
 | 
						|
    lgtm_tblhnd_share->table_name_length = table_name_length;
 | 
						|
    lgtm_tblhnd_share->table_name = tmp_name;
 | 
						|
    memcpy(lgtm_tblhnd_share->table_name, table_name,
 | 
						|
      lgtm_tblhnd_share->table_name_length);
 | 
						|
    lgtm_tblhnd_share->table_path_hash_value = hash_value;
 | 
						|
 | 
						|
    if (mysql_mutex_init(spd_key_mutex_share_auto_increment,
 | 
						|
      &lgtm_tblhnd_share->auto_increment_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_init_auto_increment_mutex;
 | 
						|
    }
 | 
						|
 | 
						|
    uint old_elements = spider_lgtm_tblhnd_share_hash.array.max_element;
 | 
						|
    if (my_hash_insert(&spider_lgtm_tblhnd_share_hash,
 | 
						|
      (uchar*) lgtm_tblhnd_share))
 | 
						|
    {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_hash_insert;
 | 
						|
    }
 | 
						|
    if (spider_lgtm_tblhnd_share_hash.array.max_element > old_elements)
 | 
						|
    {
 | 
						|
      spider_alloc_calc_mem(spider_current_trx,
 | 
						|
        spider_lgtm_tblhnd_share_hash,
 | 
						|
        (spider_lgtm_tblhnd_share_hash.array.max_element - old_elements) *
 | 
						|
        spider_lgtm_tblhnd_share_hash.array.size_of_element);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (!locked)
 | 
						|
    pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
 | 
						|
  DBUG_PRINT("info",("spider lgtm_tblhnd_share=%p", lgtm_tblhnd_share));
 | 
						|
  DBUG_RETURN(lgtm_tblhnd_share);
 | 
						|
 | 
						|
error_hash_insert:
 | 
						|
  pthread_mutex_destroy(&lgtm_tblhnd_share->auto_increment_mutex);
 | 
						|
error_init_auto_increment_mutex:
 | 
						|
  spider_free(spider_current_trx, lgtm_tblhnd_share, MYF(0));
 | 
						|
error_alloc_share:
 | 
						|
  if (!locked)
 | 
						|
    pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
  DBUG_RETURN(NULL);
 | 
						|
}
 | 
						|
 | 
						|
void spider_free_lgtm_tblhnd_share_alloc(
 | 
						|
  SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share,
 | 
						|
  bool locked
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_free_lgtm_tblhnd_share");
 | 
						|
  if (!locked)
 | 
						|
    pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
  my_hash_delete(&spider_lgtm_tblhnd_share_hash, (uchar*) lgtm_tblhnd_share);
 | 
						|
  pthread_mutex_destroy(&lgtm_tblhnd_share->auto_increment_mutex);
 | 
						|
  spider_free(spider_current_trx, lgtm_tblhnd_share, MYF(0));
 | 
						|
  if (!locked)
 | 
						|
    pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
SPIDER_WIDE_SHARE *spider_get_wide_share(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  TABLE_SHARE *table_share,
 | 
						|
  int *error_num
 | 
						|
) {
 | 
						|
  SPIDER_WIDE_SHARE *wide_share;
 | 
						|
  char *tmp_name;
 | 
						|
  longlong *tmp_cardinality;
 | 
						|
  DBUG_ENTER("spider_get_wide_share");
 | 
						|
 | 
						|
  pthread_mutex_lock(&spider_wide_share_mutex);
 | 
						|
  if (!(wide_share = (SPIDER_WIDE_SHARE*)
 | 
						|
    my_hash_search_using_hash_value(
 | 
						|
    &spider_open_wide_share, share->table_path_hash_value,
 | 
						|
    (uchar*) table_share->path.str, table_share->path.length)))
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider create new wide share"));
 | 
						|
    if (!(wide_share = (SPIDER_WIDE_SHARE *)
 | 
						|
      spider_bulk_malloc(spider_current_trx,  SPD_MID_GET_PT_SHARE_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
        &wide_share, sizeof(SPIDER_WIDE_SHARE),
 | 
						|
        &tmp_name, (uint) (table_share->path.length + 1),
 | 
						|
        &tmp_cardinality,
 | 
						|
          (uint) (sizeof(*tmp_cardinality) * table_share->fields),
 | 
						|
        NullS))
 | 
						|
    ) {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_alloc_share;
 | 
						|
    }
 | 
						|
 | 
						|
    wide_share->use_count = 0;
 | 
						|
    wide_share->table_name_length = table_share->path.length;
 | 
						|
    wide_share->table_name = tmp_name;
 | 
						|
    memcpy(wide_share->table_name, table_share->path.str,
 | 
						|
      wide_share->table_name_length);
 | 
						|
    wide_share->table_path_hash_value = share->table_path_hash_value;
 | 
						|
    wide_share->cardinality = tmp_cardinality;
 | 
						|
 | 
						|
    wide_share->crd_get_time = wide_share->sts_get_time =
 | 
						|
      share->crd_get_time;
 | 
						|
 | 
						|
    if (mysql_mutex_init(spd_key_mutex_wide_share_sts,
 | 
						|
      &wide_share->sts_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_init_sts_mutex;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mysql_mutex_init(spd_key_mutex_wide_share_crd,
 | 
						|
      &wide_share->crd_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_init_crd_mutex;
 | 
						|
    }
 | 
						|
 | 
						|
    thr_lock_init(&wide_share->lock);
 | 
						|
 | 
						|
    uint old_elements = spider_open_wide_share.array.max_element;
 | 
						|
    if (my_hash_insert(&spider_open_wide_share, (uchar*) wide_share))
 | 
						|
    {
 | 
						|
      *error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
      goto error_hash_insert;
 | 
						|
    }
 | 
						|
    if (spider_open_wide_share.array.max_element > old_elements)
 | 
						|
    {
 | 
						|
      spider_alloc_calc_mem(spider_current_trx,
 | 
						|
        spider_open_wide_share,
 | 
						|
        (spider_open_wide_share.array.max_element - old_elements) *
 | 
						|
        spider_open_wide_share.array.size_of_element);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  wide_share->use_count++;
 | 
						|
  pthread_mutex_unlock(&spider_wide_share_mutex);
 | 
						|
 | 
						|
  DBUG_PRINT("info",("spider wide_share=%p", wide_share));
 | 
						|
  DBUG_RETURN(wide_share);
 | 
						|
 | 
						|
error_hash_insert:
 | 
						|
  pthread_mutex_destroy(&wide_share->crd_mutex);
 | 
						|
error_init_crd_mutex:
 | 
						|
  pthread_mutex_destroy(&wide_share->sts_mutex);
 | 
						|
error_init_sts_mutex:
 | 
						|
  spider_free(spider_current_trx, wide_share, MYF(0));
 | 
						|
error_alloc_share:
 | 
						|
  pthread_mutex_unlock(&spider_wide_share_mutex);
 | 
						|
  DBUG_RETURN(NULL);
 | 
						|
}
 | 
						|
 | 
						|
int spider_free_wide_share(
 | 
						|
  SPIDER_WIDE_SHARE *wide_share
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_free_wide_share");
 | 
						|
  pthread_mutex_lock(&spider_wide_share_mutex);
 | 
						|
  if (!--wide_share->use_count)
 | 
						|
  {
 | 
						|
    thr_lock_delete(&wide_share->lock);
 | 
						|
    my_hash_delete(&spider_open_wide_share, (uchar*) wide_share);
 | 
						|
    pthread_mutex_destroy(&wide_share->crd_mutex);
 | 
						|
    pthread_mutex_destroy(&wide_share->sts_mutex);
 | 
						|
    spider_free(spider_current_trx, wide_share, MYF(0));
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_wide_share_mutex);
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
int spider_open_all_tables(
 | 
						|
  SPIDER_TRX *trx,
 | 
						|
  bool lock
 | 
						|
) {
 | 
						|
  THD *thd = trx->thd;
 | 
						|
  TABLE *table_tables;
 | 
						|
  int error_num, *need_mon, mon_val;
 | 
						|
  /* This share has only one link */
 | 
						|
  SPIDER_SHARE tmp_share;
 | 
						|
  char *db_name, *table_name;
 | 
						|
  uint db_name_length, table_name_length;
 | 
						|
  char *tmp_connect_info[SPIDER_TMP_SHARE_CHAR_PTR_COUNT];
 | 
						|
  uint tmp_connect_info_length[SPIDER_TMP_SHARE_UINT_COUNT];
 | 
						|
  long tmp_long[SPIDER_TMP_SHARE_LONG_COUNT];
 | 
						|
  longlong tmp_longlong[SPIDER_TMP_SHARE_LONGLONG_COUNT];
 | 
						|
  SPIDER_CONN *conn, **conns;
 | 
						|
  ha_spider *spider;
 | 
						|
  SPIDER_SHARE *share;
 | 
						|
  char **connect_info;
 | 
						|
  uint *connect_info_length;
 | 
						|
  long *long_info;
 | 
						|
  longlong *longlong_info;
 | 
						|
  MEM_ROOT mem_root;
 | 
						|
  SPIDER_Open_tables_backup open_tables_backup;
 | 
						|
  DBUG_ENTER("spider_open_all_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,
 | 
						|
      &error_num))
 | 
						|
  )
 | 
						|
    DBUG_RETURN(error_num);
 | 
						|
  if (
 | 
						|
    (error_num = spider_sys_index_first(table_tables, 1))
 | 
						|
  ) {
 | 
						|
    if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
 | 
						|
    {
 | 
						|
      table_tables->file->print_error(error_num, MYF(0));
 | 
						|
      spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    } else {
 | 
						|
      spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
      DBUG_RETURN(0);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
 | 
						|
  memset((void*)&tmp_share, 0, sizeof(SPIDER_SHARE));
 | 
						|
  memset(&tmp_connect_info, 0,
 | 
						|
    sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT);
 | 
						|
  memset(tmp_connect_info_length, 0,
 | 
						|
    sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT);
 | 
						|
  memset(tmp_long, 0, sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT);
 | 
						|
  memset(tmp_longlong, 0, sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT);
 | 
						|
  spider_set_tmp_share_pointer(&tmp_share, (char **) &tmp_connect_info,
 | 
						|
    tmp_connect_info_length, tmp_long, tmp_longlong);
 | 
						|
  tmp_share.link_statuses[0] = -1;
 | 
						|
 | 
						|
  do {
 | 
						|
    if (
 | 
						|
      (error_num = spider_get_sys_tables(
 | 
						|
        table_tables, &db_name, &table_name, &mem_root)) ||
 | 
						|
      (error_num = spider_get_sys_tables_connect_info(
 | 
						|
        table_tables, &tmp_share, &mem_root)) ||
 | 
						|
      (error_num = spider_set_connect_info_default(
 | 
						|
        &tmp_share,
 | 
						|
        NULL,
 | 
						|
        NULL,
 | 
						|
        NULL
 | 
						|
      ))
 | 
						|
    ) {
 | 
						|
      spider_sys_index_end(table_tables);
 | 
						|
      spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
      spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
      free_root(&mem_root, MYF(0));
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
    db_name_length = strlen(db_name);
 | 
						|
    table_name_length = strlen(table_name);
 | 
						|
 | 
						|
    if (
 | 
						|
      (error_num = spider_set_connect_info_default_db_table(
 | 
						|
        &tmp_share,
 | 
						|
        db_name,
 | 
						|
        db_name_length,
 | 
						|
        table_name,
 | 
						|
        table_name_length
 | 
						|
      )) ||
 | 
						|
      (error_num = spider_create_conn_keys(&tmp_share)) ||
 | 
						|
      (error_num = spider_create_tmp_dbton_share(&tmp_share))
 | 
						|
    ) {
 | 
						|
      spider_sys_index_end(table_tables);
 | 
						|
      spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
      spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
      free_root(&mem_root, MYF(0));
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
 | 
						|
    /* create conn */
 | 
						|
    if (!(conn= spider_get_conn(&tmp_share, 0, tmp_share.conn_keys[0], trx,
 | 
						|
                                NULL, FALSE, FALSE, &error_num)))
 | 
						|
    {
 | 
						|
      spider_sys_index_end(table_tables);
 | 
						|
      spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
      spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
      spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
      free_root(&mem_root, MYF(0));
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
    conn->error_mode &= spider_param_error_read_mode(thd, 0);
 | 
						|
    conn->error_mode &= spider_param_error_write_mode(thd, 0);
 | 
						|
    spider_lock_before_query(conn, &mon_val);
 | 
						|
    if ((error_num = spider_db_before_query(conn, &mon_val)))
 | 
						|
    {
 | 
						|
      spider_unlock_after_query(conn, 0);
 | 
						|
      spider_sys_index_end(table_tables);
 | 
						|
      spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
      spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
      spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
      free_root(&mem_root, MYF(0));
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
    spider_unlock_after_query(conn, 0);
 | 
						|
 | 
						|
    if (lock && spider_param_use_snapshot_with_flush_tables(thd) == 2)
 | 
						|
    {
 | 
						|
      if (!(spider = new ha_spider()))
 | 
						|
      {
 | 
						|
        spider_sys_index_end(table_tables);
 | 
						|
        spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
        spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
        spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
        free_root(&mem_root, MYF(0));
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
      spider->wide_handler->lock_type = TL_READ_NO_INSERT;
 | 
						|
 | 
						|
      if (!(share = (SPIDER_SHARE *)
 | 
						|
        spider_bulk_malloc(spider_current_trx, SPD_MID_OPEN_ALL_TABLES_1, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
          &share, (uint) (sizeof(*share)),
 | 
						|
          &connect_info,
 | 
						|
            (uint) (sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT),
 | 
						|
          &connect_info_length,
 | 
						|
            (uint) (sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT),
 | 
						|
          &long_info, (uint) (sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT),
 | 
						|
          &longlong_info,
 | 
						|
            (uint) (sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT),
 | 
						|
          &conns, (uint) (sizeof(SPIDER_CONN *)),
 | 
						|
          &need_mon, (uint) (sizeof(int)),
 | 
						|
          &spider->conn_link_idx, (uint) (sizeof(uint)),
 | 
						|
          &spider->conn_can_fo, (uint) (sizeof(uchar)),
 | 
						|
          NullS))
 | 
						|
      ) {
 | 
						|
        delete spider;
 | 
						|
        spider_sys_index_end(table_tables);
 | 
						|
        spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
        spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
        spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
        free_root(&mem_root, MYF(0));
 | 
						|
        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
      }
 | 
						|
      memcpy((void*)share, &tmp_share, sizeof(*share));
 | 
						|
      spider_set_tmp_share_pointer(share, connect_info,
 | 
						|
        connect_info_length, long_info, longlong_info);
 | 
						|
      memcpy(connect_info, &tmp_connect_info, sizeof(char *) *
 | 
						|
        SPIDER_TMP_SHARE_CHAR_PTR_COUNT);
 | 
						|
      memcpy(connect_info_length, &tmp_connect_info_length, sizeof(uint) *
 | 
						|
        SPIDER_TMP_SHARE_UINT_COUNT);
 | 
						|
      memcpy(long_info, &tmp_long, sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT);
 | 
						|
      memcpy(longlong_info, &tmp_longlong, sizeof(longlong) *
 | 
						|
        SPIDER_TMP_SHARE_LONGLONG_COUNT);
 | 
						|
      spider->share = share;
 | 
						|
      spider->wide_handler->trx = trx;
 | 
						|
      spider->conns = conns;
 | 
						|
      spider->need_mons = need_mon;
 | 
						|
      spider->conn_link_idx[0] = 0;
 | 
						|
      spider->conn_can_fo[0] = 0;
 | 
						|
      if ((error_num = spider_create_tmp_dbton_handler(spider)))
 | 
						|
      {
 | 
						|
        spider_free(trx, share, MYF(0));
 | 
						|
        delete spider;
 | 
						|
        spider_sys_index_end(table_tables);
 | 
						|
        spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
        spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
        spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
        free_root(&mem_root, MYF(0));
 | 
						|
        DBUG_RETURN(error_num);
 | 
						|
      }
 | 
						|
 | 
						|
      /* create another conn */
 | 
						|
      if ((!(conn= spider_get_conn(&tmp_share, 0, tmp_share.conn_keys[0], trx,
 | 
						|
                                   spider, TRUE, FALSE, &error_num))))
 | 
						|
      {
 | 
						|
        spider_free_tmp_dbton_handler(spider);
 | 
						|
        spider_free(trx, share, MYF(0));
 | 
						|
        delete spider;
 | 
						|
        spider_sys_index_end(table_tables);
 | 
						|
        spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
        spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
        spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
        free_root(&mem_root, MYF(0));
 | 
						|
        DBUG_RETURN(error_num);
 | 
						|
      }
 | 
						|
      conn->error_mode &= spider_param_error_read_mode(thd, 0);
 | 
						|
      conn->error_mode &= spider_param_error_write_mode(thd, 0);
 | 
						|
 | 
						|
      spider->next = NULL;
 | 
						|
      if (conn->another_ha_last)
 | 
						|
      {
 | 
						|
        ((ha_spider*) conn->another_ha_last)->next = spider;
 | 
						|
      } else {
 | 
						|
        conn->another_ha_first = (void*) spider;
 | 
						|
      }
 | 
						|
      conn->another_ha_last = (void*) spider;
 | 
						|
 | 
						|
      int appended = 0;
 | 
						|
      if ((error_num = spider->dbton_handler[conn->dbton_id]->
 | 
						|
        append_lock_tables_list(conn, 0, &appended)))
 | 
						|
      {
 | 
						|
        spider_free_tmp_dbton_handler(spider);
 | 
						|
        spider_free(trx, share, MYF(0));
 | 
						|
        delete spider;
 | 
						|
        spider_sys_index_end(table_tables);
 | 
						|
        spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
        spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
        spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
        free_root(&mem_root, MYF(0));
 | 
						|
        DBUG_RETURN(error_num);
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      spider_free_tmp_dbton_share(&tmp_share);
 | 
						|
      spider_free_tmp_share_alloc(&tmp_share);
 | 
						|
    }
 | 
						|
    error_num = spider_sys_index_next(table_tables);
 | 
						|
  } while (error_num == 0);
 | 
						|
  free_root(&mem_root, MYF(0));
 | 
						|
 | 
						|
  spider_sys_index_end(table_tables);
 | 
						|
  spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
bool spider_flush_logs(
 | 
						|
  handlerton *hton
 | 
						|
) {
 | 
						|
  int error_num;
 | 
						|
  THD* thd = current_thd;
 | 
						|
  SPIDER_TRX *trx;
 | 
						|
  DBUG_ENTER("spider_flush_logs");
 | 
						|
 | 
						|
  if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
 | 
						|
  {
 | 
						|
    my_errno = error_num;
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  }
 | 
						|
  if (
 | 
						|
    spider_param_use_flash_logs(trx->thd) &&
 | 
						|
    (
 | 
						|
      !trx->trx_consistent_snapshot ||
 | 
						|
      !spider_param_use_all_conns_snapshot(trx->thd) ||
 | 
						|
      !spider_param_use_snapshot_with_flush_tables(trx->thd)
 | 
						|
    )
 | 
						|
  ) {
 | 
						|
    if (
 | 
						|
      (error_num = spider_open_all_tables(trx, FALSE)) ||
 | 
						|
      (error_num = spider_trx_all_flush_logs(trx))
 | 
						|
    ) {
 | 
						|
      my_errno = error_num;
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
handler* spider_create_handler(
 | 
						|
  handlerton *hton,
 | 
						|
  TABLE_SHARE *table, 
 | 
						|
  MEM_ROOT *mem_root
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_create_handler");
 | 
						|
  DBUG_RETURN(new (mem_root) ha_spider(hton, table));
 | 
						|
}
 | 
						|
 | 
						|
int spider_close_connection(
 | 
						|
  THD* thd
 | 
						|
) {
 | 
						|
  int roop_count = 0;
 | 
						|
  SPIDER_CONN *conn;
 | 
						|
  SPIDER_TRX *trx;
 | 
						|
  DBUG_ENTER("spider_close_connection");
 | 
						|
  if (!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr)))
 | 
						|
    DBUG_RETURN(0); /* transaction is not started */
 | 
						|
 | 
						|
  trx->tmp_spider->conns = &conn;
 | 
						|
  while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash,
 | 
						|
    roop_count)))
 | 
						|
  {
 | 
						|
    SPIDER_BACKUP_DASTATUS;
 | 
						|
    DBUG_PRINT("info",("spider conn->table_lock=%d", conn->table_lock));
 | 
						|
    if (conn->table_lock > 0)
 | 
						|
    {
 | 
						|
      if (!conn->trx_start)
 | 
						|
        conn->disable_reconnect = FALSE;
 | 
						|
      if (conn->table_lock != 2)
 | 
						|
      {
 | 
						|
        spider_db_unlock_tables(trx->tmp_spider, 0);
 | 
						|
      }
 | 
						|
      conn->table_lock = 0;
 | 
						|
    }
 | 
						|
    roop_count++;
 | 
						|
    SPIDER_CONN_RESTORE_DASTATUS;
 | 
						|
  }
 | 
						|
 | 
						|
  spider_rollback(thd, TRUE);
 | 
						|
 | 
						|
  Dummy_error_handler deh; // suppress network errors at this stage
 | 
						|
  thd->push_internal_handler(&deh);
 | 
						|
  spider_free_trx(trx, TRUE, false);
 | 
						|
  thd->pop_internal_handler();
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
void spider_drop_database(
 | 
						|
  handlerton *hton,
 | 
						|
  char* path
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_drop_database");
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
bool spider_show_status(
 | 
						|
  handlerton *hton,
 | 
						|
  THD *thd, 
 | 
						|
  stat_print_fn *stat_print,
 | 
						|
  enum ha_stat_type stat_type
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_show_status");
 | 
						|
  switch (stat_type) {
 | 
						|
    case HA_ENGINE_STATUS:
 | 
						|
    default:
 | 
						|
      DBUG_RETURN(FALSE);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
int spider_db_done(
 | 
						|
  void *p
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  THD *tmp_thd;
 | 
						|
  SPIDER_CONN *conn;
 | 
						|
  SPIDER_INIT_ERROR_TABLE *spider_init_error_table;
 | 
						|
  SPIDER_TABLE_MON_LIST *table_mon_list;
 | 
						|
  SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
 | 
						|
  DBUG_ENTER("spider_db_done");
 | 
						|
 | 
						|
  for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; roop_count--)
 | 
						|
  {
 | 
						|
    if (spider_dbton[roop_count].deinit)
 | 
						|
    {
 | 
						|
      spider_dbton[roop_count].deinit();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  spider_free_sts_crd_threads(spider_table_crd_thread);
 | 
						|
  spider_free_sts_crd_threads(spider_table_sts_thread);
 | 
						|
  spider_free(NULL, spider_table_sts_thread, MYF(0));
 | 
						|
 | 
						|
  for (roop_count= spider_udf_table_mon_mutex_count - 1;
 | 
						|
    roop_count >= 0; roop_count--)
 | 
						|
  {
 | 
						|
    while ((table_mon_list = (SPIDER_TABLE_MON_LIST *) my_hash_element(
 | 
						|
      &spider_udf_table_mon_list_hash[roop_count], 0)))
 | 
						|
    {
 | 
						|
      my_hash_delete(&spider_udf_table_mon_list_hash[roop_count],
 | 
						|
        (uchar*) table_mon_list);
 | 
						|
      spider_ping_table_free_mon_list(table_mon_list);
 | 
						|
    }
 | 
						|
    spider_free_mem_calc(spider_current_trx,
 | 
						|
      spider_udf_table_mon_list_hash_id,
 | 
						|
      spider_udf_table_mon_list_hash[roop_count].array.max_element *
 | 
						|
      spider_udf_table_mon_list_hash[roop_count].array.size_of_element);
 | 
						|
    my_hash_free(&spider_udf_table_mon_list_hash[roop_count]);
 | 
						|
  }
 | 
						|
  for (roop_count= spider_udf_table_mon_mutex_count - 1;
 | 
						|
    roop_count >= 0; roop_count--)
 | 
						|
    pthread_cond_destroy(&spider_udf_table_mon_conds[roop_count]);
 | 
						|
  for (roop_count= spider_udf_table_mon_mutex_count - 1;
 | 
						|
    roop_count >= 0; roop_count--)
 | 
						|
    pthread_mutex_destroy(&spider_udf_table_mon_mutexes[roop_count]);
 | 
						|
  spider_free(NULL, spider_udf_table_mon_mutexes, MYF(0));
 | 
						|
 | 
						|
  pthread_mutex_lock(&spider_allocated_thds_mutex);
 | 
						|
  while ((tmp_thd = (THD *) my_hash_element(&spider_allocated_thds, 0)))
 | 
						|
  {
 | 
						|
    SPIDER_TRX *trx = (SPIDER_TRX *)
 | 
						|
                      thd_get_ha_data(tmp_thd, spider_hton_ptr);
 | 
						|
    if (trx)
 | 
						|
    {
 | 
						|
      DBUG_ASSERT(tmp_thd == trx->thd);
 | 
						|
      spider_free_trx(trx, FALSE);
 | 
						|
      thd_set_ha_data(tmp_thd, spider_hton_ptr, NULL);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      my_hash_delete(&spider_allocated_thds, (uchar *) tmp_thd);
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_allocated_thds_mutex);
 | 
						|
 | 
						|
  pthread_mutex_lock(&spider_conn_mutex);
 | 
						|
  while ((conn = (SPIDER_CONN*) my_hash_element(&spider_open_connections, 0)))
 | 
						|
  {
 | 
						|
    my_hash_delete(&spider_open_connections, (uchar*) conn);
 | 
						|
    spider_free_conn(conn);
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_conn_mutex);
 | 
						|
  pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
  while ((lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE*) my_hash_element(
 | 
						|
    &spider_lgtm_tblhnd_share_hash, 0)))
 | 
						|
  {
 | 
						|
    spider_free_lgtm_tblhnd_share_alloc(lgtm_tblhnd_share, TRUE);
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
  spider_free_mem_calc(spider_current_trx,
 | 
						|
    spider_mon_table_cache_id,
 | 
						|
    spider_mon_table_cache.max_element *
 | 
						|
    spider_mon_table_cache.size_of_element);
 | 
						|
  delete_dynamic(&spider_mon_table_cache);
 | 
						|
  spider_free_mem_calc(spider_current_trx,
 | 
						|
    spider_allocated_thds_id,
 | 
						|
    spider_allocated_thds.array.max_element *
 | 
						|
    spider_allocated_thds.array.size_of_element);
 | 
						|
  my_hash_free(&spider_allocated_thds);
 | 
						|
  spider_free_mem_calc(spider_current_trx,
 | 
						|
    spider_open_connections_id,
 | 
						|
    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 *
 | 
						|
    spider_lgtm_tblhnd_share_hash.array.size_of_element);
 | 
						|
  my_hash_free(&spider_lgtm_tblhnd_share_hash);
 | 
						|
  spider_free_mem_calc(spider_current_trx,
 | 
						|
    spider_open_wide_share_id,
 | 
						|
    spider_open_wide_share.array.max_element *
 | 
						|
    spider_open_wide_share.array.size_of_element);
 | 
						|
  my_hash_free(&spider_open_wide_share);
 | 
						|
  pthread_mutex_lock(&spider_init_error_tbl_mutex);
 | 
						|
  while ((spider_init_error_table = (SPIDER_INIT_ERROR_TABLE*)
 | 
						|
    my_hash_element(&spider_init_error_tables, 0)))
 | 
						|
  {
 | 
						|
    my_hash_delete(&spider_init_error_tables,
 | 
						|
      (uchar*) spider_init_error_table);
 | 
						|
    spider_free(NULL, spider_init_error_table, MYF(0));
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_init_error_tbl_mutex);
 | 
						|
  spider_free_mem_calc(spider_current_trx,
 | 
						|
    spider_init_error_tables_id,
 | 
						|
    spider_init_error_tables.array.max_element *
 | 
						|
    spider_init_error_tables.array.size_of_element);
 | 
						|
  my_hash_free(&spider_init_error_tables);
 | 
						|
  spider_free_mem_calc(spider_current_trx,
 | 
						|
    spider_open_tables_id,
 | 
						|
    spider_open_tables.array.max_element *
 | 
						|
    spider_open_tables.array.size_of_element);
 | 
						|
  my_hash_free(&spider_open_tables);
 | 
						|
  pthread_mutex_destroy(&spider_mem_calc_mutex);
 | 
						|
  pthread_mutex_destroy(&spider_mon_table_cache_mutex);
 | 
						|
  pthread_mutex_destroy(&spider_allocated_thds_mutex);
 | 
						|
  pthread_mutex_destroy(&spider_open_conn_mutex);
 | 
						|
  pthread_mutex_destroy(&spider_conn_mutex);
 | 
						|
  pthread_mutex_destroy(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
  pthread_mutex_destroy(&spider_wide_share_mutex);
 | 
						|
  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);
 | 
						|
  pthread_attr_destroy(&spider_pt_attr);
 | 
						|
 | 
						|
  spider_hton_ptr= NULL;
 | 
						|
  for (roop_count = 0; roop_count < SPIDER_MEM_CALC_LIST_NUM; roop_count++)
 | 
						|
  {
 | 
						|
    if (spider_alloc_func_name[roop_count])
 | 
						|
      DBUG_PRINT("info",("spider %d %s %s %lu %llu %lld %llu %llu %s",
 | 
						|
        roop_count,
 | 
						|
        spider_alloc_func_name[roop_count],
 | 
						|
        spider_alloc_file_name[roop_count],
 | 
						|
        spider_alloc_line_no[roop_count],
 | 
						|
        spider_total_alloc_mem[roop_count],
 | 
						|
        spider_current_alloc_mem[roop_count],
 | 
						|
        spider_alloc_mem_count[roop_count],
 | 
						|
        spider_free_mem_count[roop_count],
 | 
						|
        spider_current_alloc_mem[roop_count] ? "NG" : "OK"
 | 
						|
      ));
 | 
						|
  }
 | 
						|
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
int spider_panic(
 | 
						|
  handlerton *hton,
 | 
						|
  ha_panic_function type
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_panic");
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
static void spider_update_optimizer_costs(OPTIMIZER_COSTS *costs)
 | 
						|
{
 | 
						|
  /* Assume 1 Gigabyte network */
 | 
						|
  costs->disk_read_cost=       IO_SIZE/(1000000000/8)*1000.00000;
 | 
						|
  costs->index_block_copy_cost= 0;              // Not used
 | 
						|
 | 
						|
  /*
 | 
						|
    The following costs are copied from ha_innodb.cc
 | 
						|
    The assumption is that the default storage engine used with Spider is
 | 
						|
    InnoDB.
 | 
						|
   */
 | 
						|
  costs->row_next_find_cost= 0.00007013;
 | 
						|
  costs->row_lookup_cost=    0.00076597;
 | 
						|
  costs->key_next_find_cost= 0.00009900;
 | 
						|
  costs->key_lookup_cost=    0.00079112;
 | 
						|
  costs->row_copy_cost=      0.00006087;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Create or fix the system tables. See spd_init_query.h for the details.
 | 
						|
*/
 | 
						|
bool spider_init_system_tables()
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_init_system_tables");
 | 
						|
 | 
						|
  MYSQL *mysql= mysql_init(NULL);
 | 
						|
  if (!mysql)
 | 
						|
  {
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!mysql_real_connect_local(mysql))
 | 
						|
  {
 | 
						|
    mysql_close(mysql);
 | 
						|
    DBUG_RETURN(TRUE);
 | 
						|
  }
 | 
						|
 | 
						|
  const int size= sizeof(spider_init_queries) / sizeof(spider_init_queries[0]);
 | 
						|
  for (int i= 0; i < size; i++)
 | 
						|
  {
 | 
						|
    const LEX_STRING *query= &spider_init_queries[i];
 | 
						|
    if (mysql_real_query(mysql, query->str, query->length))
 | 
						|
    {
 | 
						|
      fprintf(stderr,
 | 
						|
              "[ERROR] SPIDER plugin initialization failed at '%s' by '%s'\n",
 | 
						|
              query->str, mysql_error(mysql));
 | 
						|
 | 
						|
      mysql_close(mysql);
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
    if (MYSQL_RES *res= mysql_store_result(mysql))
 | 
						|
    {
 | 
						|
      mysql_free_result(res);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  mysql_close(mysql);
 | 
						|
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
  Spider may be loaded before ddl_recovery (e.g. with
 | 
						|
  --plugin-load-add), but DDL statements in spider init queries cannot
 | 
						|
  be executed before ddl_recovery, so we execute these queries only
 | 
						|
  after ddl recovery.
 | 
						|
*/
 | 
						|
static int spider_after_ddl_recovery(handlerton *)
 | 
						|
{
 | 
						|
  DBUG_EXECUTE_IF("fail_spider_ddl_recovery_done", return 1;);
 | 
						|
  return spider_init_system_tables();
 | 
						|
}
 | 
						|
 | 
						|
int spider_db_init(
 | 
						|
  void *p
 | 
						|
) {
 | 
						|
  int error_num = HA_ERR_OUT_OF_MEM, roop_count;
 | 
						|
  uint dbton_id;
 | 
						|
  uchar addr[6];
 | 
						|
  handlerton *spider_hton = (handlerton *)p;
 | 
						|
  DBUG_ENTER("spider_db_init");
 | 
						|
 | 
						|
  spider_mon_table_cache_version= 0;
 | 
						|
  spider_mon_table_cache_version_req= 1;
 | 
						|
  spider_conn_id= 1;
 | 
						|
  spider_conn_mutex_id= 0;
 | 
						|
  UTC = 0;
 | 
						|
  spider_thread_id = 1;
 | 
						|
  const LEX_CSTRING aria_name={STRING_WITH_LEN("Aria")};
 | 
						|
  if (!plugin_is_ready(&aria_name, MYSQL_STORAGE_ENGINE_PLUGIN))
 | 
						|
    DBUG_RETURN(HA_ERR_RETRY_INIT);
 | 
						|
 | 
						|
  spider_hton_ptr = spider_hton;
 | 
						|
 | 
						|
  spider_hton->flags = HTON_TEMPORARY_NOT_SUPPORTED;
 | 
						|
#ifdef HTON_CAN_READ_CONNECT_STRING_IN_PARTITION
 | 
						|
  spider_hton->flags |= HTON_CAN_READ_CONNECT_STRING_IN_PARTITION;
 | 
						|
#endif
 | 
						|
  spider_hton->panic = spider_panic;
 | 
						|
  spider_hton->signal_ddl_recovery_done= spider_after_ddl_recovery;
 | 
						|
  spider_hton->close_connection = spider_close_connection;
 | 
						|
  spider_hton->start_consistent_snapshot = spider_start_consistent_snapshot;
 | 
						|
  spider_hton->flush_logs = spider_flush_logs;
 | 
						|
  spider_hton->commit = spider_commit;
 | 
						|
  spider_hton->rollback = spider_rollback;
 | 
						|
  spider_hton->discover_table_structure = spider_discover_table_structure;
 | 
						|
  if (spider_param_support_xa())
 | 
						|
  {
 | 
						|
    spider_hton->prepare = spider_xa_prepare;
 | 
						|
    spider_hton->recover = spider_xa_recover;
 | 
						|
    spider_hton->commit_by_xid = spider_xa_commit_by_xid;
 | 
						|
    spider_hton->rollback_by_xid = spider_xa_rollback_by_xid;
 | 
						|
  }
 | 
						|
  spider_hton->create = spider_create_handler;
 | 
						|
  spider_hton->drop_database = spider_drop_database;
 | 
						|
  spider_hton->show_status = spider_show_status;
 | 
						|
  spider_hton->create_group_by = spider_create_group_by_handler;
 | 
						|
  spider_hton->table_options= spider_table_option_list;
 | 
						|
  spider_hton->update_optimizer_costs= spider_update_optimizer_costs;
 | 
						|
 | 
						|
  if (my_gethwaddr((uchar *) addr))
 | 
						|
  {
 | 
						|
    my_printf_error(ER_SPIDER_CANT_NUM, ER_SPIDER_CANT_STR1, MYF(ME_WARNING),
 | 
						|
      "get hardware address with error ", errno);
 | 
						|
    bzero(addr,6);
 | 
						|
  }
 | 
						|
  spider_unique_id.str = spider_unique_id_buf;
 | 
						|
  spider_unique_id.length = my_sprintf(spider_unique_id_buf,
 | 
						|
    (spider_unique_id_buf, "-%02x%02x%02x%02x%02x%02x-%lx-",
 | 
						|
      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], (ulong) getpid()));
 | 
						|
 | 
						|
  memset(&spider_alloc_func_name, 0, sizeof(spider_alloc_func_name));
 | 
						|
  memset(&spider_alloc_file_name, 0, sizeof(spider_alloc_file_name));
 | 
						|
  memset(&spider_alloc_line_no, 0, sizeof(spider_alloc_line_no));
 | 
						|
  memset(&spider_total_alloc_mem, 0, sizeof(spider_total_alloc_mem));
 | 
						|
  memset(&spider_current_alloc_mem, 0, sizeof(spider_current_alloc_mem));
 | 
						|
  memset(&spider_alloc_mem_count, 0, sizeof(spider_alloc_mem_count));
 | 
						|
  memset(&spider_free_mem_count, 0, sizeof(spider_free_mem_count));
 | 
						|
 | 
						|
#ifndef SPIDER_HAS_NEXT_THREAD_ID
 | 
						|
  spd_db_att_thread_id = &thread_id;
 | 
						|
#endif
 | 
						|
  spd_charset_utf8mb3_bin = &my_charset_utf8mb3_bin;
 | 
						|
  spd_defaults_extra_file = &my_defaults_extra_file;
 | 
						|
  spd_defaults_file = &my_defaults_file;
 | 
						|
  spd_mysqld_unix_port = (const char **) &mysqld_unix_port;
 | 
						|
  spd_mysqld_port = &mysqld_port;
 | 
						|
  spd_abort_loop = &abort_loop;
 | 
						|
  spd_tz_system = my_tz_SYSTEM;
 | 
						|
 | 
						|
#ifdef HAVE_PSI_INTERFACE
 | 
						|
  init_spider_psi_keys();
 | 
						|
#endif
 | 
						|
 | 
						|
  if (pthread_attr_init(&spider_pt_attr))
 | 
						|
    goto error_pt_attr_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_tbl,
 | 
						|
    &spider_tbl_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_tbl_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_thread_id,
 | 
						|
    &spider_thread_id_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_thread_id_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_conn_id,
 | 
						|
    &spider_conn_id_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_conn_id_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_ipport_count,
 | 
						|
    &spider_ipport_conn_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_ipport_count_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_init_error_tbl,
 | 
						|
    &spider_init_error_tbl_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_init_error_tbl_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_wide_share,
 | 
						|
    &spider_wide_share_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_wide_share_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_lgtm_tblhnd_share,
 | 
						|
    &spider_lgtm_tblhnd_share_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_lgtm_tblhnd_share_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_conn,
 | 
						|
    &spider_conn_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_conn_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_open_conn,
 | 
						|
    &spider_open_conn_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_open_conn_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_allocated_thds,
 | 
						|
    &spider_allocated_thds_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_allocated_thds_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_mon_table_cache,
 | 
						|
    &spider_mon_table_cache_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_mon_table_cache_mutex_init;
 | 
						|
 | 
						|
  if (mysql_mutex_init(spd_key_mutex_mem_calc,
 | 
						|
    &spider_mem_calc_mutex, MY_MUTEX_INIT_FAST))
 | 
						|
    goto error_mem_calc_mutex_init;
 | 
						|
 | 
						|
  if (my_hash_init(PSI_INSTRUMENT_ME, &spider_open_tables,
 | 
						|
                   spd_charset_utf8mb3_bin, 32, 0, 0, spider_tbl_get_key, 0,
 | 
						|
                   0))
 | 
						|
    goto error_open_tables_hash_init;
 | 
						|
 | 
						|
  spider_alloc_calc_mem_init(spider_open_tables, SPD_MID_DB_INIT_1);
 | 
						|
  spider_alloc_calc_mem(NULL,
 | 
						|
    spider_open_tables,
 | 
						|
    spider_open_tables.array.max_element *
 | 
						|
    spider_open_tables.array.size_of_element);
 | 
						|
  if (my_hash_init(PSI_INSTRUMENT_ME, &spider_init_error_tables,
 | 
						|
                   spd_charset_utf8mb3_bin, 32, 0, 0, spider_tbl_get_key, 0,
 | 
						|
                   0))
 | 
						|
    goto error_init_error_tables_hash_init;
 | 
						|
 | 
						|
  spider_alloc_calc_mem_init(spider_init_error_tables, SPD_MID_DB_INIT_2);
 | 
						|
  spider_alloc_calc_mem(NULL,
 | 
						|
    spider_init_error_tables,
 | 
						|
    spider_init_error_tables.array.max_element *
 | 
						|
    spider_init_error_tables.array.size_of_element);
 | 
						|
  if (my_hash_init(PSI_INSTRUMENT_ME, &spider_open_wide_share,
 | 
						|
                   spd_charset_utf8mb3_bin, 32, 0, 0,
 | 
						|
                   spider_wide_share_get_key, 0, 0))
 | 
						|
    goto error_open_wide_share_hash_init;
 | 
						|
 | 
						|
  spider_alloc_calc_mem_init(spider_open_wide_share, SPD_MID_DB_INIT_3);
 | 
						|
  spider_alloc_calc_mem(NULL,
 | 
						|
    spider_open_wide_share,
 | 
						|
    spider_open_wide_share.array.max_element *
 | 
						|
    spider_open_wide_share.array.size_of_element);
 | 
						|
  if (my_hash_init(PSI_INSTRUMENT_ME, &spider_lgtm_tblhnd_share_hash,
 | 
						|
                   spd_charset_utf8mb3_bin, 32, 0, 0,
 | 
						|
                   spider_lgtm_tblhnd_share_hash_get_key, 0, 0))
 | 
						|
    goto error_lgtm_tblhnd_share_hash_init;
 | 
						|
 | 
						|
  spider_alloc_calc_mem_init(spider_lgtm_tblhnd_share_hash, SPD_MID_DB_INIT_4);
 | 
						|
  spider_alloc_calc_mem(NULL,
 | 
						|
    spider_lgtm_tblhnd_share_hash,
 | 
						|
    spider_lgtm_tblhnd_share_hash.array.max_element *
 | 
						|
    spider_lgtm_tblhnd_share_hash.array.size_of_element);
 | 
						|
  if (my_hash_init(PSI_INSTRUMENT_ME, &spider_open_connections,
 | 
						|
                   spd_charset_utf8mb3_bin, 32, 0, 0, spider_conn_get_key, 0,
 | 
						|
                   0))
 | 
						|
    goto error_open_connections_hash_init;
 | 
						|
 | 
						|
  if (my_hash_init(PSI_INSTRUMENT_ME, &spider_ipport_conns,
 | 
						|
                   spd_charset_utf8mb3_bin, 32, 0, 0,
 | 
						|
                   spider_ipport_conn_get_key, spider_free_ipport_conn, 0))
 | 
						|
    goto error_ipport_conn__hash_init;
 | 
						|
 | 
						|
  spider_alloc_calc_mem_init(spider_open_connections, SPD_MID_DB_INIT_5);
 | 
						|
  spider_alloc_calc_mem(NULL,
 | 
						|
    spider_open_connections,
 | 
						|
    spider_open_connections.array.max_element *
 | 
						|
    spider_open_connections.array.size_of_element);
 | 
						|
  if (my_hash_init(PSI_INSTRUMENT_ME, &spider_allocated_thds,
 | 
						|
                   spd_charset_utf8mb3_bin, 32, 0, 0,
 | 
						|
                   spider_allocated_thds_get_key, 0, 0))
 | 
						|
    goto error_allocated_thds_hash_init;
 | 
						|
 | 
						|
  spider_alloc_calc_mem_init(spider_allocated_thds, SPD_MID_DB_INIT_8);
 | 
						|
  spider_alloc_calc_mem(NULL,
 | 
						|
    spider_allocated_thds,
 | 
						|
    spider_allocated_thds.array.max_element *
 | 
						|
    spider_allocated_thds.array.size_of_element);
 | 
						|
 | 
						|
  if (SPD_INIT_DYNAMIC_ARRAY2(&spider_mon_table_cache, sizeof(SPIDER_MON_KEY),
 | 
						|
      NULL, 64, 64, MYF(MY_WME)))
 | 
						|
    goto error_mon_table_cache_array_init;
 | 
						|
 | 
						|
  spider_alloc_calc_mem_init(spider_mon_table_cache, SPD_MID_DB_INIT_9);
 | 
						|
  spider_alloc_calc_mem(NULL,
 | 
						|
    spider_mon_table_cache,
 | 
						|
    spider_mon_table_cache.max_element *
 | 
						|
    spider_mon_table_cache.size_of_element);
 | 
						|
 | 
						|
  if (!(spider_udf_table_mon_mutexes = (pthread_mutex_t *)
 | 
						|
    spider_bulk_malloc(NULL, SPD_MID_DB_INIT_10, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &spider_udf_table_mon_mutexes, (uint) (sizeof(pthread_mutex_t) *
 | 
						|
        spider_udf_table_mon_mutex_count),
 | 
						|
      &spider_udf_table_mon_conds, (uint) (sizeof(pthread_cond_t) *
 | 
						|
        spider_udf_table_mon_mutex_count),
 | 
						|
      &spider_udf_table_mon_list_hash, (uint) (sizeof(HASH) *
 | 
						|
        spider_udf_table_mon_mutex_count),
 | 
						|
      NullS))
 | 
						|
  )
 | 
						|
    goto error_alloc_mon_mutxes;
 | 
						|
 | 
						|
  for (roop_count = 0;
 | 
						|
    roop_count < (int) spider_udf_table_mon_mutex_count;
 | 
						|
    roop_count++)
 | 
						|
  {
 | 
						|
    if (mysql_mutex_init(spd_key_mutex_udf_table_mon,
 | 
						|
      &spider_udf_table_mon_mutexes[roop_count], MY_MUTEX_INIT_FAST))
 | 
						|
      goto error_init_udf_table_mon_mutex;
 | 
						|
  }
 | 
						|
  for (roop_count = 0;
 | 
						|
    roop_count < (int) spider_udf_table_mon_mutex_count;
 | 
						|
    roop_count++)
 | 
						|
  {
 | 
						|
    if (mysql_cond_init(spd_key_cond_udf_table_mon,
 | 
						|
      &spider_udf_table_mon_conds[roop_count], NULL))
 | 
						|
      goto error_init_udf_table_mon_cond;
 | 
						|
  }
 | 
						|
  for (roop_count = 0;
 | 
						|
    roop_count < (int) spider_udf_table_mon_mutex_count;
 | 
						|
    roop_count++)
 | 
						|
  {
 | 
						|
    if (my_hash_init(PSI_INSTRUMENT_ME,
 | 
						|
                     &spider_udf_table_mon_list_hash[roop_count],
 | 
						|
                     spd_charset_utf8mb3_bin, 32, 0, 0,
 | 
						|
                     spider_udf_tbl_mon_list_key, 0, 0))
 | 
						|
      goto error_init_udf_table_mon_list_hash;
 | 
						|
 | 
						|
    spider_alloc_calc_mem_init(spider_udf_table_mon_list_hash, SPD_MID_DB_INIT_11);
 | 
						|
    spider_alloc_calc_mem(NULL,
 | 
						|
      spider_udf_table_mon_list_hash,
 | 
						|
      spider_udf_table_mon_list_hash[roop_count].array.max_element *
 | 
						|
      spider_udf_table_mon_list_hash[roop_count].array.size_of_element);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(spider_table_sts_thread = (SPIDER_THREAD *)
 | 
						|
    spider_bulk_malloc(NULL, SPD_MID_DB_INIT_12, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &spider_table_sts_thread, (uint) (sizeof(SPIDER_THREAD)),
 | 
						|
      &spider_table_crd_thread, (uint) (sizeof(SPIDER_THREAD)),
 | 
						|
      NullS))
 | 
						|
  )
 | 
						|
    goto error_alloc_table_sts_crd_threads;
 | 
						|
 | 
						|
  if ((error_num = spider_create_sts_crd_threads(spider_table_sts_thread, 1)))
 | 
						|
    goto error_init_table_sts_threads;
 | 
						|
  if ((error_num = spider_create_sts_crd_threads(spider_table_crd_thread, 0)))
 | 
						|
    goto error_init_table_crd_threads;
 | 
						|
 | 
						|
  /** Populates `spider_dbton` with available `SPIDER_DBTON`s */
 | 
						|
  dbton_id = 0;
 | 
						|
  spider_dbton_mysql.dbton_id = dbton_id;
 | 
						|
  spider_dbton_mysql.db_util->dbton_id = dbton_id;
 | 
						|
  spider_dbton[dbton_id] = spider_dbton_mysql;
 | 
						|
  ++dbton_id;
 | 
						|
  spider_dbton_mariadb.dbton_id = dbton_id;
 | 
						|
  spider_dbton_mariadb.db_util->dbton_id = dbton_id;
 | 
						|
  spider_dbton[dbton_id] = spider_dbton_mariadb;
 | 
						|
  ++dbton_id;
 | 
						|
  for (roop_count = 0; roop_count < (int) dbton_id; roop_count++)
 | 
						|
  {
 | 
						|
    if (spider_dbton[roop_count].init &&
 | 
						|
        (error_num = spider_dbton[roop_count].init()))
 | 
						|
        goto error_init_dbton;
 | 
						|
  }
 | 
						|
  DBUG_RETURN(0);
 | 
						|
 | 
						|
error_init_dbton:
 | 
						|
  for (roop_count--; roop_count >= 0; roop_count--)
 | 
						|
  {
 | 
						|
    if (spider_dbton[roop_count].deinit)
 | 
						|
      spider_dbton[roop_count].deinit();
 | 
						|
  }
 | 
						|
error_init_table_crd_threads:
 | 
						|
  spider_free_sts_crd_threads(spider_table_crd_thread);
 | 
						|
error_init_table_sts_threads:
 | 
						|
  spider_free_sts_crd_threads(spider_table_sts_thread);
 | 
						|
error_alloc_table_sts_crd_threads:
 | 
						|
  spider_free(NULL, spider_table_sts_thread, MYF(0));
 | 
						|
  roop_count= spider_udf_table_mon_mutex_count - 1;
 | 
						|
error_init_udf_table_mon_list_hash:
 | 
						|
  for (; roop_count >= 0; roop_count--)
 | 
						|
  {
 | 
						|
    spider_free_mem_calc(NULL,
 | 
						|
      spider_udf_table_mon_list_hash_id,
 | 
						|
      spider_udf_table_mon_list_hash[roop_count].array.max_element *
 | 
						|
      spider_udf_table_mon_list_hash[roop_count].array.size_of_element);
 | 
						|
    my_hash_free(&spider_udf_table_mon_list_hash[roop_count]);
 | 
						|
  }
 | 
						|
  roop_count= spider_udf_table_mon_mutex_count - 1;
 | 
						|
error_init_udf_table_mon_cond:
 | 
						|
  for (; roop_count >= 0; roop_count--)
 | 
						|
    pthread_cond_destroy(&spider_udf_table_mon_conds[roop_count]);
 | 
						|
  roop_count= spider_udf_table_mon_mutex_count - 1;
 | 
						|
error_init_udf_table_mon_mutex:
 | 
						|
  for (; roop_count >= 0; roop_count--)
 | 
						|
    pthread_mutex_destroy(&spider_udf_table_mon_mutexes[roop_count]);
 | 
						|
  spider_free(NULL, spider_udf_table_mon_mutexes, MYF(0));
 | 
						|
error_alloc_mon_mutxes:
 | 
						|
  spider_free_mem_calc(NULL,
 | 
						|
    spider_mon_table_cache_id,
 | 
						|
    spider_mon_table_cache.max_element *
 | 
						|
    spider_mon_table_cache.size_of_element);
 | 
						|
  delete_dynamic(&spider_mon_table_cache);
 | 
						|
error_mon_table_cache_array_init:
 | 
						|
  spider_free_mem_calc(NULL,
 | 
						|
    spider_allocated_thds_id,
 | 
						|
    spider_allocated_thds.array.max_element *
 | 
						|
    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:
 | 
						|
  spider_free_mem_calc(NULL,
 | 
						|
    spider_open_connections_id,
 | 
						|
    spider_open_connections.array.max_element *
 | 
						|
    spider_open_connections.array.size_of_element);
 | 
						|
  my_hash_free(&spider_open_connections);
 | 
						|
error_open_connections_hash_init:
 | 
						|
  spider_free_mem_calc(NULL,
 | 
						|
    spider_lgtm_tblhnd_share_hash_id,
 | 
						|
    spider_lgtm_tblhnd_share_hash.array.max_element *
 | 
						|
    spider_lgtm_tblhnd_share_hash.array.size_of_element);
 | 
						|
  my_hash_free(&spider_lgtm_tblhnd_share_hash);
 | 
						|
error_lgtm_tblhnd_share_hash_init:
 | 
						|
  spider_free_mem_calc(NULL,
 | 
						|
    spider_open_wide_share_id,
 | 
						|
    spider_open_wide_share.array.max_element *
 | 
						|
    spider_open_wide_share.array.size_of_element);
 | 
						|
  my_hash_free(&spider_open_wide_share);
 | 
						|
error_open_wide_share_hash_init:
 | 
						|
  spider_free_mem_calc(NULL,
 | 
						|
    spider_init_error_tables_id,
 | 
						|
    spider_init_error_tables.array.max_element *
 | 
						|
    spider_init_error_tables.array.size_of_element);
 | 
						|
  my_hash_free(&spider_init_error_tables);
 | 
						|
error_init_error_tables_hash_init:
 | 
						|
  spider_free_mem_calc(NULL,
 | 
						|
    spider_open_tables_id,
 | 
						|
    spider_open_tables.array.max_element *
 | 
						|
    spider_open_tables.array.size_of_element);
 | 
						|
  my_hash_free(&spider_open_tables);
 | 
						|
error_open_tables_hash_init:
 | 
						|
  pthread_mutex_destroy(&spider_mem_calc_mutex);
 | 
						|
error_mem_calc_mutex_init:
 | 
						|
  pthread_mutex_destroy(&spider_mon_table_cache_mutex);
 | 
						|
error_mon_table_cache_mutex_init:
 | 
						|
  pthread_mutex_destroy(&spider_allocated_thds_mutex);
 | 
						|
error_allocated_thds_mutex_init:
 | 
						|
  pthread_mutex_destroy(&spider_open_conn_mutex);
 | 
						|
error_open_conn_mutex_init:
 | 
						|
  pthread_mutex_destroy(&spider_conn_mutex);
 | 
						|
error_conn_mutex_init:
 | 
						|
  pthread_mutex_destroy(&spider_lgtm_tblhnd_share_mutex);
 | 
						|
error_lgtm_tblhnd_share_mutex_init:
 | 
						|
  pthread_mutex_destroy(&spider_wide_share_mutex);
 | 
						|
error_wide_share_mutex_init:
 | 
						|
  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);
 | 
						|
error_thread_id_mutex_init:
 | 
						|
  pthread_mutex_destroy(&spider_tbl_mutex);
 | 
						|
error_tbl_mutex_init:
 | 
						|
/*
 | 
						|
error_pt_attr_setstate:
 | 
						|
*/
 | 
						|
  pthread_attr_destroy(&spider_pt_attr);
 | 
						|
error_pt_attr_init:
 | 
						|
  spider_hton_ptr= NULL;
 | 
						|
  DBUG_RETURN(error_num);
 | 
						|
}
 | 
						|
 | 
						|
char *spider_create_string(
 | 
						|
  const char *str,
 | 
						|
  uint length
 | 
						|
) {
 | 
						|
  char *res;
 | 
						|
  DBUG_ENTER("spider_create_string");
 | 
						|
  if (!(res = (char*) spider_malloc(spider_current_trx, SPD_MID_CREATE_STRING_1, length + 1,
 | 
						|
    MYF(MY_WME))))
 | 
						|
    DBUG_RETURN(NULL);
 | 
						|
  memcpy(res, str, length);
 | 
						|
  res[length] = '\0';
 | 
						|
  DBUG_RETURN(res);
 | 
						|
}
 | 
						|
 | 
						|
char *spider_create_table_name_string(
 | 
						|
  const char *table_name,
 | 
						|
  const char *part_name,
 | 
						|
  const char *sub_name
 | 
						|
) {
 | 
						|
  char *res, *tmp;
 | 
						|
  uint length = strlen(table_name);
 | 
						|
  DBUG_ENTER("spider_create_table_name_string");
 | 
						|
  if (part_name)
 | 
						|
  {
 | 
						|
    length += sizeof("#P#") - 1 + strlen(part_name);
 | 
						|
    if (sub_name)
 | 
						|
      length += sizeof("#SP#") - 1 + strlen(sub_name);
 | 
						|
  }
 | 
						|
  if (!(res = (char*) spider_malloc(spider_current_trx, SPD_MID_CREATE_TABLE_NAME_STRING_1, length + 1,
 | 
						|
    MYF(MY_WME))))
 | 
						|
    DBUG_RETURN(NULL);
 | 
						|
  tmp = strmov(res, table_name);
 | 
						|
  if (part_name)
 | 
						|
  {
 | 
						|
    tmp = strmov(tmp, "#P#");
 | 
						|
    tmp = strmov(tmp, part_name);
 | 
						|
    if (sub_name)
 | 
						|
    {
 | 
						|
      tmp = strmov(tmp, "#SP#");
 | 
						|
      tmp = strmov(tmp, sub_name);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(res);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Get the target partition_elements.
 | 
						|
 | 
						|
  The target partition and subpartition are detected by the table name,
 | 
						|
  which is in the form like "t1#P#pt1".
 | 
						|
*/
 | 
						|
void spider_get_partition_info(
 | 
						|
  const char *table_name,
 | 
						|
  uint table_name_length,
 | 
						|
  const TABLE_SHARE *table_share,
 | 
						|
  partition_info *part_info,
 | 
						|
  partition_element **part_elem,
 | 
						|
  partition_element **sub_elem
 | 
						|
) {
 | 
						|
  char tmp_name[FN_REFLEN + 1];
 | 
						|
  partition_element *tmp_part_elem = NULL, *tmp_sub_elem = NULL;
 | 
						|
  bool tmp_flg = FALSE, tmp_find_flg = FALSE;
 | 
						|
  DBUG_ENTER("spider_get_partition_info");
 | 
						|
  *part_elem = NULL;
 | 
						|
  *sub_elem = NULL;
 | 
						|
  if (!part_info)
 | 
						|
    DBUG_VOID_RETURN;
 | 
						|
 | 
						|
  if (!memcmp(table_name + table_name_length - 5, "#TMP#", 5))
 | 
						|
    tmp_flg = TRUE;
 | 
						|
 | 
						|
  DBUG_PRINT("info",("spider table_name=%s", table_name));
 | 
						|
  List_iterator<partition_element> part_it(part_info->partitions);
 | 
						|
  while ((*part_elem = part_it++))
 | 
						|
  {
 | 
						|
    if ((*part_elem)->subpartitions.elements)
 | 
						|
    {
 | 
						|
      List_iterator<partition_element> sub_it((*part_elem)->subpartitions);
 | 
						|
      while ((*sub_elem = sub_it++))
 | 
						|
      {
 | 
						|
        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;
 | 
						|
        if (
 | 
						|
          tmp_flg &&
 | 
						|
          *(tmp_name + table_name_length - 5) == '\0' &&
 | 
						|
          !memcmp(table_name, tmp_name, table_name_length - 5)
 | 
						|
        ) {
 | 
						|
          tmp_part_elem = *part_elem;
 | 
						|
          tmp_sub_elem = *sub_elem;
 | 
						|
          tmp_flg = FALSE;
 | 
						|
          tmp_find_flg = TRUE;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      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;
 | 
						|
      if (
 | 
						|
        tmp_flg &&
 | 
						|
        *(tmp_name + table_name_length - 5) == '\0' &&
 | 
						|
        !memcmp(table_name, tmp_name, table_name_length - 5)
 | 
						|
      ) {
 | 
						|
        tmp_part_elem = *part_elem;
 | 
						|
        tmp_flg = FALSE;
 | 
						|
        tmp_find_flg = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (tmp_find_flg)
 | 
						|
  {
 | 
						|
    *part_elem = tmp_part_elem;
 | 
						|
    *sub_elem = tmp_sub_elem;
 | 
						|
    DBUG_PRINT("info",("spider tmp find"));
 | 
						|
    DBUG_VOID_RETURN;
 | 
						|
  }
 | 
						|
  *part_elem = NULL;
 | 
						|
  *sub_elem = NULL;
 | 
						|
  DBUG_PRINT("info",("spider no hit"));
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
/** Determines the get type for spider_get_sts() */
 | 
						|
enum ha_sts_crd_get_type spider_get_sts_type(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  double sts_interval,
 | 
						|
  int sts_sync
 | 
						|
) {
 | 
						|
  if (sts_sync == 0)
 | 
						|
    return HA_GET_FETCH;
 | 
						|
  if (!share->wide_share->sts_init)
 | 
						|
  {
 | 
						|
    pthread_mutex_lock(&share->wide_share->sts_mutex);
 | 
						|
    if (!share->wide_share->sts_init)
 | 
						|
      return HA_GET_AFTER_LOCK;
 | 
						|
    pthread_mutex_unlock(&share->wide_share->sts_mutex);
 | 
						|
    return HA_GET_COPY;
 | 
						|
  }
 | 
						|
  if (difftime(share->sts_get_time, share->wide_share->sts_get_time) <
 | 
						|
      sts_interval)
 | 
						|
    return HA_GET_COPY;
 | 
						|
  if (!pthread_mutex_trylock(&share->wide_share->sts_mutex))
 | 
						|
    return HA_GET_AFTER_TRYLOCK;
 | 
						|
  return HA_GET_COPY;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Populates share->stat or share->wide_share->stat with table status.
 | 
						|
*/
 | 
						|
int spider_get_sts(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  int link_idx,
 | 
						|
  time_t tmp_time,
 | 
						|
  ha_spider *spider,
 | 
						|
  double sts_interval,
 | 
						|
  int sts_mode,
 | 
						|
  int sts_sync,
 | 
						|
  int sts_sync_level,
 | 
						|
  uint flag
 | 
						|
) {
 | 
						|
  int error_num = 0;
 | 
						|
  DBUG_ENTER("spider_get_sts");
 | 
						|
 | 
						|
  enum ha_sts_crd_get_type get_type =
 | 
						|
    spider_get_sts_type(share, sts_interval, sts_sync);
 | 
						|
  if (get_type == HA_GET_COPY)
 | 
						|
    share->stat = share->wide_share->stat;
 | 
						|
  else
 | 
						|
    /* Executes a `show table status` query and store the results in
 | 
						|
    share->stat */
 | 
						|
    error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag);
 | 
						|
  if (get_type >= HA_GET_AFTER_LOCK)
 | 
						|
    pthread_mutex_unlock(&share->wide_share->sts_mutex);
 | 
						|
 | 
						|
  if (error_num)
 | 
						|
  {
 | 
						|
    SPIDER_PARTITION_HANDLER *partition_handler =
 | 
						|
      spider->partition_handler;
 | 
						|
    if (!share->wide_share->sts_init &&
 | 
						|
        sts_sync >= sts_sync_level &&
 | 
						|
        get_type > HA_GET_FETCH &&
 | 
						|
        partition_handler &&
 | 
						|
        partition_handler->handlers &&
 | 
						|
        partition_handler->handlers[0] == spider)
 | 
						|
    {
 | 
						|
      int roop_count;
 | 
						|
      ha_spider *tmp_spider;
 | 
						|
      SPIDER_SHARE *tmp_share;
 | 
						|
      double tmp_sts_interval;
 | 
						|
      int tmp_sts_mode;
 | 
						|
      int tmp_sts_sync;
 | 
						|
      THD *thd = spider->wide_handler->trx->thd;
 | 
						|
      for (roop_count = 1;
 | 
						|
           roop_count < (int) partition_handler->no_parts;
 | 
						|
           roop_count++)
 | 
						|
      {
 | 
						|
        tmp_spider = (ha_spider *) partition_handler->handlers[roop_count];
 | 
						|
        tmp_share = tmp_spider->share;
 | 
						|
        tmp_sts_interval = spider_param_sts_interval(thd, share->sts_interval);
 | 
						|
        tmp_sts_mode = spider_param_sts_mode(thd, share->sts_mode);
 | 
						|
        tmp_sts_sync = spider_param_sts_sync(thd, share->sts_sync);
 | 
						|
        spider_get_sts(tmp_share, tmp_spider->search_link_idx, tmp_time,
 | 
						|
                       tmp_spider, tmp_sts_interval, tmp_sts_mode,
 | 
						|
                       tmp_sts_sync, 1, flag);
 | 
						|
        if (share->wide_share->sts_init)
 | 
						|
        {
 | 
						|
          error_num = 0;
 | 
						|
          thd->clear_error();
 | 
						|
          get_type = HA_GET_COPY;
 | 
						|
          share->stat = share->wide_share->stat;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (error_num)
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
  }
 | 
						|
 | 
						|
  if (sts_sync >= sts_sync_level && get_type > HA_GET_COPY)
 | 
						|
  {
 | 
						|
    share->wide_share->stat = share->stat;
 | 
						|
    share->wide_share->sts_get_time = tmp_time;
 | 
						|
    share->wide_share->sts_init = TRUE;
 | 
						|
  }
 | 
						|
  share->sts_get_time = tmp_time;
 | 
						|
  share->sts_init = TRUE;
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
/** Determines the get type for spider_get_crd() */
 | 
						|
enum ha_sts_crd_get_type spider_get_crd_type(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  double crd_interval,
 | 
						|
  int crd_sync
 | 
						|
) {
 | 
						|
  if (crd_sync == 0)
 | 
						|
    return HA_GET_FETCH;
 | 
						|
  if (!share->wide_share->crd_init)
 | 
						|
  {
 | 
						|
    pthread_mutex_lock(&share->wide_share->crd_mutex);
 | 
						|
    if (!share->wide_share->crd_init)
 | 
						|
      return HA_GET_AFTER_LOCK;
 | 
						|
    pthread_mutex_unlock(&share->wide_share->crd_mutex);
 | 
						|
    return HA_GET_COPY;
 | 
						|
  }
 | 
						|
  if (difftime(share->crd_get_time, share->wide_share->crd_get_time) <
 | 
						|
      crd_interval)
 | 
						|
    return HA_GET_COPY;
 | 
						|
  if (!pthread_mutex_trylock(&share->wide_share->crd_mutex))
 | 
						|
    return HA_GET_AFTER_TRYLOCK;
 | 
						|
  return HA_GET_COPY;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Populates share->cardinality or share->wide_share->cardinality with
 | 
						|
  table index
 | 
						|
*/
 | 
						|
int spider_get_crd(
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  int link_idx,
 | 
						|
  time_t tmp_time,
 | 
						|
  ha_spider *spider,
 | 
						|
  TABLE *table,
 | 
						|
  double crd_interval,
 | 
						|
  int crd_mode,
 | 
						|
  int crd_sync,
 | 
						|
  int crd_sync_level
 | 
						|
) {
 | 
						|
  int error_num = 0;
 | 
						|
  DBUG_ENTER("spider_get_crd");
 | 
						|
 | 
						|
  enum ha_sts_crd_get_type get_type =
 | 
						|
    spider_get_crd_type(share, crd_interval, crd_sync);
 | 
						|
 | 
						|
  if (get_type == HA_GET_COPY)
 | 
						|
    memcpy(share->cardinality, share->wide_share->cardinality,
 | 
						|
           sizeof(longlong) * table->s->fields);
 | 
						|
  else
 | 
						|
    error_num= spider_db_show_index(spider, link_idx, table, crd_mode);
 | 
						|
 | 
						|
  if (get_type >= HA_GET_AFTER_LOCK)
 | 
						|
    pthread_mutex_unlock(&share->wide_share->crd_mutex);
 | 
						|
  if (error_num)
 | 
						|
  {
 | 
						|
    SPIDER_PARTITION_HANDLER *partition_handler = spider->partition_handler;
 | 
						|
    if (!share->wide_share->crd_init &&
 | 
						|
        crd_sync >= crd_sync_level &&
 | 
						|
        get_type > HA_GET_FETCH &&
 | 
						|
        partition_handler &&
 | 
						|
        partition_handler->handlers &&
 | 
						|
        partition_handler->handlers[0] == spider)
 | 
						|
    {
 | 
						|
      int roop_count;
 | 
						|
      ha_spider *tmp_spider;
 | 
						|
      SPIDER_SHARE *tmp_share;
 | 
						|
      double tmp_crd_interval;
 | 
						|
      int tmp_crd_mode;
 | 
						|
      int tmp_crd_sync;
 | 
						|
      THD *thd = spider->wide_handler->trx->thd;
 | 
						|
      for (roop_count = 1;
 | 
						|
           roop_count < (int) partition_handler->no_parts;
 | 
						|
           roop_count++)
 | 
						|
      {
 | 
						|
        tmp_spider = (ha_spider *) partition_handler->handlers[roop_count];
 | 
						|
        tmp_share = tmp_spider->share;
 | 
						|
        tmp_crd_interval = spider_param_crd_interval(thd, share->crd_interval);
 | 
						|
        tmp_crd_mode = spider_param_crd_mode(thd, share->crd_mode);
 | 
						|
        tmp_crd_sync = spider_param_crd_sync(thd, share->crd_sync);
 | 
						|
        spider_get_crd(tmp_share, tmp_spider->search_link_idx, tmp_time,
 | 
						|
                       tmp_spider, table, tmp_crd_interval, tmp_crd_mode,
 | 
						|
                       tmp_crd_sync, 1);
 | 
						|
        if (share->wide_share->crd_init)
 | 
						|
        {
 | 
						|
          error_num = 0;
 | 
						|
          thd->clear_error();
 | 
						|
          get_type = HA_GET_COPY;
 | 
						|
          memcpy(share->cardinality, share->wide_share->cardinality,
 | 
						|
                 sizeof(longlong) * table->s->fields);
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (error_num)
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
  }
 | 
						|
  if (crd_sync >= crd_sync_level && get_type > HA_GET_COPY)
 | 
						|
  {
 | 
						|
    memcpy(share->wide_share->cardinality, share->cardinality,
 | 
						|
           sizeof(longlong) * table->s->fields);
 | 
						|
    share->wide_share->crd_get_time = tmp_time;
 | 
						|
    share->wide_share->crd_init = TRUE;
 | 
						|
  }
 | 
						|
  share->crd_get_time = tmp_time;
 | 
						|
  share->crd_init = TRUE;
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
void spider_set_result_list_param(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
  SPIDER_RESULT_LIST *result_list = &spider->result_list;
 | 
						|
  SPIDER_SHARE *share = spider->share;
 | 
						|
  THD *thd = spider->wide_handler->trx->thd;
 | 
						|
  DBUG_ENTER("spider_set_result_list_param");
 | 
						|
  result_list->internal_offset =
 | 
						|
    spider_param_internal_offset(thd, share->internal_offset);
 | 
						|
  result_list->internal_limit =
 | 
						|
#ifdef INFO_KIND_FORCE_LIMIT_BEGIN
 | 
						|
    spider->wide_handler->info_limit < 9223372036854775807LL ?
 | 
						|
    spider->wide_handler->info_limit :
 | 
						|
#endif
 | 
						|
    spider_param_internal_limit(thd, share->internal_limit);
 | 
						|
  result_list->split_read = spider_split_read_param(spider);
 | 
						|
  if (spider->support_multi_split_read_sql())
 | 
						|
  {
 | 
						|
    result_list->multi_split_read =
 | 
						|
      spider_param_multi_split_read(thd, share->multi_split_read);
 | 
						|
  } else {
 | 
						|
    result_list->multi_split_read = 1;
 | 
						|
  }
 | 
						|
  result_list->max_order =
 | 
						|
    spider_param_max_order(thd, share->max_order);
 | 
						|
  result_list->quick_mode =
 | 
						|
    spider_param_quick_mode(thd, share->quick_mode);
 | 
						|
  result_list->quick_page_size =
 | 
						|
    spider_param_quick_page_size(thd, share->quick_page_size);
 | 
						|
  result_list->quick_page_byte =
 | 
						|
    spider_param_quick_page_byte(thd, share->quick_page_byte);
 | 
						|
  result_list->low_mem_read =
 | 
						|
    spider_param_low_mem_read(thd, share->low_mem_read);
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Gets or creates a `SPIDER_INIT_ERROR_TABLE` with the table name from
 | 
						|
  a given `SPIDER_SHARE`
 | 
						|
 | 
						|
  When creating, also add the newly created object to
 | 
						|
  `spider_init_error_tables`
 | 
						|
 | 
						|
  @param trx     Transaction
 | 
						|
  @param share   The spider share providing the table name
 | 
						|
  @param create  Whether to create a new `SPIDER_INIT_ERROR_TABLE` if one wi                 th the required table name does not exist yet
 | 
						|
  @return A `SPIDER_INIT_ERROR_TABLE` or NULL if failure
 | 
						|
*/
 | 
						|
SPIDER_INIT_ERROR_TABLE *spider_get_init_error_table(
 | 
						|
  SPIDER_TRX *trx,
 | 
						|
  SPIDER_SHARE *share,
 | 
						|
  bool create
 | 
						|
) {
 | 
						|
  SPIDER_INIT_ERROR_TABLE *spider_init_error_table;
 | 
						|
  char *tmp_name;
 | 
						|
  DBUG_ENTER("spider_get_init_error_table");
 | 
						|
  pthread_mutex_lock(&spider_init_error_tbl_mutex);
 | 
						|
  if (!(spider_init_error_table = (SPIDER_INIT_ERROR_TABLE *)
 | 
						|
    my_hash_search_using_hash_value(
 | 
						|
    &spider_init_error_tables, share->table_name_hash_value,
 | 
						|
    (uchar*) share->table_name, share->table_name_length)))
 | 
						|
  {
 | 
						|
    if (!create)
 | 
						|
    {
 | 
						|
      pthread_mutex_unlock(&spider_init_error_tbl_mutex);
 | 
						|
      DBUG_RETURN(NULL);
 | 
						|
    }
 | 
						|
    if (!spider_bulk_malloc(spider_current_trx, SPD_MID_GET_INIT_ERROR_TABLE_1,
 | 
						|
                            MYF(MY_WME | MY_ZEROFILL),
 | 
						|
        &spider_init_error_table, (uint) (sizeof(*spider_init_error_table)),
 | 
						|
        &tmp_name, (uint) (share->table_name_length + 1),
 | 
						|
        NullS)
 | 
						|
    ) {
 | 
						|
      pthread_mutex_unlock(&spider_init_error_tbl_mutex);
 | 
						|
      DBUG_RETURN(NULL);
 | 
						|
    }
 | 
						|
    memcpy(tmp_name, share->table_name, share->table_name_length);
 | 
						|
    spider_init_error_table->table_name = tmp_name;
 | 
						|
    spider_init_error_table->table_name_length = share->table_name_length;
 | 
						|
    spider_init_error_table->table_name_hash_value =
 | 
						|
      share->table_name_hash_value;
 | 
						|
    uint old_elements = spider_init_error_tables.array.max_element;
 | 
						|
    if (my_hash_insert(&spider_init_error_tables,
 | 
						|
      (uchar*) spider_init_error_table))
 | 
						|
    {
 | 
						|
      spider_free(trx, spider_init_error_table, MYF(0));
 | 
						|
      pthread_mutex_unlock(&spider_init_error_tbl_mutex);
 | 
						|
      DBUG_RETURN(NULL);
 | 
						|
    }
 | 
						|
    if (spider_init_error_tables.array.max_element > old_elements)
 | 
						|
    {
 | 
						|
      spider_alloc_calc_mem(spider_current_trx,
 | 
						|
        spider_init_error_tables,
 | 
						|
        (spider_init_error_tables.array.max_element - old_elements) *
 | 
						|
        spider_init_error_tables.array.size_of_element);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_init_error_tbl_mutex);
 | 
						|
  DBUG_RETURN(spider_init_error_table);
 | 
						|
}
 | 
						|
 | 
						|
void spider_delete_init_error_table(
 | 
						|
  const char *name
 | 
						|
) {
 | 
						|
  SPIDER_INIT_ERROR_TABLE *spider_init_error_table;
 | 
						|
  uint length = strlen(name);
 | 
						|
  my_hash_value_type hash_value = my_calc_hash(&spider_open_tables,
 | 
						|
    (uchar*) name, length);
 | 
						|
  DBUG_ENTER("spider_delete_init_error_table");
 | 
						|
  pthread_mutex_lock(&spider_init_error_tbl_mutex);
 | 
						|
  if ((spider_init_error_table = (SPIDER_INIT_ERROR_TABLE *)
 | 
						|
    my_hash_search_using_hash_value(&spider_init_error_tables, hash_value,
 | 
						|
      (uchar*) name, length)))
 | 
						|
  {
 | 
						|
    my_hash_delete(&spider_init_error_tables,
 | 
						|
      (uchar*) spider_init_error_table);
 | 
						|
    spider_free(spider_current_trx, spider_init_error_table, MYF(0));
 | 
						|
  }
 | 
						|
  pthread_mutex_unlock(&spider_init_error_tbl_mutex);
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
bool spider_check_pk_update(
 | 
						|
  TABLE *table
 | 
						|
) {
 | 
						|
  int roop_count;
 | 
						|
  TABLE_SHARE *table_share = table->s;
 | 
						|
  KEY *key_info;
 | 
						|
  KEY_PART_INFO *key_part;
 | 
						|
  DBUG_ENTER("spider_check_pk_update");
 | 
						|
  if (table_share->primary_key == MAX_KEY)
 | 
						|
    DBUG_RETURN(FALSE);
 | 
						|
 | 
						|
  key_info = &table_share->key_info[table_share->primary_key];
 | 
						|
  key_part = key_info->key_part;
 | 
						|
  for (roop_count = 0;
 | 
						|
    roop_count < (int) spider_user_defined_key_parts(key_info); roop_count++)
 | 
						|
  {
 | 
						|
    if (bitmap_is_set(table->write_set,
 | 
						|
      key_part[roop_count].field->field_index))
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
  }
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Set fields of a tmp share which has only one link. For use in
 | 
						|
  monitoring, spider_copy_tables udf etc.
 | 
						|
*/
 | 
						|
void spider_set_tmp_share_pointer(
 | 
						|
  SPIDER_SHARE *tmp_share,
 | 
						|
  char **tmp_connect_info,
 | 
						|
  uint *tmp_connect_info_length,
 | 
						|
  long *tmp_long,
 | 
						|
  longlong *tmp_longlong
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_set_tmp_share_pointer");
 | 
						|
  tmp_share->link_count = 1;
 | 
						|
  tmp_share->all_link_count = 1;
 | 
						|
  tmp_share->server_names = &tmp_connect_info[0];
 | 
						|
  tmp_share->tgt_table_names = &tmp_connect_info[1];
 | 
						|
  tmp_share->tgt_dbs = &tmp_connect_info[2];
 | 
						|
  tmp_share->tgt_hosts = &tmp_connect_info[3];
 | 
						|
  tmp_share->tgt_usernames = &tmp_connect_info[4];
 | 
						|
  tmp_share->tgt_passwords = &tmp_connect_info[5];
 | 
						|
  tmp_share->tgt_sockets = &tmp_connect_info[6];
 | 
						|
  tmp_share->tgt_wrappers = &tmp_connect_info[7];
 | 
						|
  tmp_share->tgt_ssl_cas = &tmp_connect_info[8];
 | 
						|
  tmp_share->tgt_ssl_capaths = &tmp_connect_info[9];
 | 
						|
  tmp_share->tgt_ssl_certs = &tmp_connect_info[10];
 | 
						|
  tmp_share->tgt_ssl_ciphers = &tmp_connect_info[11];
 | 
						|
  tmp_share->tgt_ssl_keys = &tmp_connect_info[12];
 | 
						|
  tmp_share->tgt_default_files = &tmp_connect_info[13];
 | 
						|
  tmp_share->tgt_default_groups = &tmp_connect_info[14];
 | 
						|
  tmp_share->tgt_dsns = &tmp_connect_info[15];
 | 
						|
  tmp_share->tgt_filedsns = &tmp_connect_info[16];
 | 
						|
  tmp_share->tgt_drivers = &tmp_connect_info[17];
 | 
						|
  tmp_share->tgt_pk_names = &tmp_connect_info[18];
 | 
						|
  tmp_share->tgt_sequence_names = &tmp_connect_info[19];
 | 
						|
  tmp_share->static_link_ids = &tmp_connect_info[20];
 | 
						|
  tmp_share->tgt_odbc_conn_strs = &tmp_connect_info[23];
 | 
						|
  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_binlog_pos_at_failing = &tmp_long[3];
 | 
						|
  tmp_share->monitoring_flag = &tmp_long[4];
 | 
						|
  tmp_share->monitoring_kind = &tmp_long[5];
 | 
						|
  tmp_share->monitoring_bg_flag = &tmp_long[6];
 | 
						|
  tmp_share->monitoring_bg_kind = &tmp_long[7];
 | 
						|
  tmp_share->connect_timeouts = &tmp_long[13];
 | 
						|
  tmp_share->net_read_timeouts = &tmp_long[14];
 | 
						|
  tmp_long[13] = -1;
 | 
						|
  tmp_share->net_write_timeouts = &tmp_long[15];
 | 
						|
  tmp_long[14] = -1;
 | 
						|
  tmp_share->access_balances = &tmp_long[16];
 | 
						|
  tmp_share->bka_table_name_types = &tmp_long[17];
 | 
						|
  tmp_share->strict_group_bys = &tmp_long[18];
 | 
						|
  tmp_share->monitoring_limit = &tmp_longlong[0];
 | 
						|
  tmp_share->monitoring_sid = &tmp_longlong[1];
 | 
						|
  tmp_share->monitoring_bg_interval = &tmp_longlong[2];
 | 
						|
  tmp_share->server_names_lengths = &tmp_connect_info_length[0];
 | 
						|
  tmp_share->tgt_table_names_lengths = &tmp_connect_info_length[1];
 | 
						|
  tmp_share->tgt_dbs_lengths = &tmp_connect_info_length[2];
 | 
						|
  tmp_share->tgt_hosts_lengths = &tmp_connect_info_length[3];
 | 
						|
  tmp_share->tgt_usernames_lengths = &tmp_connect_info_length[4];
 | 
						|
  tmp_share->tgt_passwords_lengths = &tmp_connect_info_length[5];
 | 
						|
  tmp_share->tgt_sockets_lengths = &tmp_connect_info_length[6];
 | 
						|
  tmp_share->tgt_wrappers_lengths = &tmp_connect_info_length[7];
 | 
						|
  tmp_share->tgt_ssl_cas_lengths = &tmp_connect_info_length[8];
 | 
						|
  tmp_share->tgt_ssl_capaths_lengths = &tmp_connect_info_length[9];
 | 
						|
  tmp_share->tgt_ssl_certs_lengths = &tmp_connect_info_length[10];
 | 
						|
  tmp_share->tgt_ssl_ciphers_lengths = &tmp_connect_info_length[11];
 | 
						|
  tmp_share->tgt_ssl_keys_lengths = &tmp_connect_info_length[12];
 | 
						|
  tmp_share->tgt_default_files_lengths = &tmp_connect_info_length[13];
 | 
						|
  tmp_share->tgt_default_groups_lengths = &tmp_connect_info_length[14];
 | 
						|
  tmp_share->tgt_dsns_lengths = &tmp_connect_info_length[15];
 | 
						|
  tmp_share->tgt_filedsns_lengths = &tmp_connect_info_length[16];
 | 
						|
  tmp_share->tgt_drivers_lengths = &tmp_connect_info_length[17];
 | 
						|
  tmp_share->tgt_pk_names_lengths = &tmp_connect_info_length[18];
 | 
						|
  tmp_share->tgt_sequence_names_lengths = &tmp_connect_info_length[19];
 | 
						|
  tmp_share->static_link_ids_lengths = &tmp_connect_info_length[20];
 | 
						|
  tmp_share->tgt_odbc_conn_strs_lengths = &tmp_connect_info_length[23];
 | 
						|
  tmp_share->server_names_length = 1;
 | 
						|
  tmp_share->tgt_table_names_length = 1;
 | 
						|
  tmp_share->tgt_dbs_length = 1;
 | 
						|
  tmp_share->tgt_hosts_length = 1;
 | 
						|
  tmp_share->tgt_usernames_length = 1;
 | 
						|
  tmp_share->tgt_passwords_length = 1;
 | 
						|
  tmp_share->tgt_sockets_length = 1;
 | 
						|
  tmp_share->tgt_wrappers_length = 1;
 | 
						|
  tmp_share->tgt_ssl_cas_length = 1;
 | 
						|
  tmp_share->tgt_ssl_capaths_length = 1;
 | 
						|
  tmp_share->tgt_ssl_certs_length = 1;
 | 
						|
  tmp_share->tgt_ssl_ciphers_length = 1;
 | 
						|
  tmp_share->tgt_ssl_keys_length = 1;
 | 
						|
  tmp_share->tgt_default_files_length = 1;
 | 
						|
  tmp_share->tgt_default_groups_length = 1;
 | 
						|
  tmp_share->tgt_dsns_length = 1;
 | 
						|
  tmp_share->tgt_filedsns_length = 1;
 | 
						|
  tmp_share->tgt_drivers_length = 1;
 | 
						|
  tmp_share->tgt_odbc_conn_strs_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;
 | 
						|
  tmp_share->monitoring_bg_flag_length = 1;
 | 
						|
  tmp_share->monitoring_bg_kind_length = 1;
 | 
						|
  tmp_share->monitoring_limit_length = 1;
 | 
						|
  tmp_share->monitoring_sid_length = 1;
 | 
						|
  tmp_share->monitoring_bg_interval_length = 1;
 | 
						|
  tmp_share->connect_timeouts_length = 1;
 | 
						|
  tmp_share->net_read_timeouts_length = 1;
 | 
						|
  tmp_share->net_write_timeouts_length = 1;
 | 
						|
  tmp_share->access_balances_length = 1;
 | 
						|
  tmp_share->bka_table_name_types_length = 1;
 | 
						|
  tmp_share->strict_group_bys_length = 1;
 | 
						|
 | 
						|
  tmp_share->monitoring_bg_flag[0] = -1;
 | 
						|
  tmp_share->monitoring_bg_kind[0] = -1;
 | 
						|
  tmp_share->monitoring_binlog_pos_at_failing[0] = -1;
 | 
						|
  tmp_share->monitoring_flag[0] = -1;
 | 
						|
  tmp_share->monitoring_kind[0] = -1;
 | 
						|
  tmp_share->monitoring_bg_interval[0] = -1;
 | 
						|
  tmp_share->monitoring_limit[0] = -1;
 | 
						|
  tmp_share->monitoring_sid[0] = -1;
 | 
						|
  tmp_share->bka_engine = NULL;
 | 
						|
  tmp_share->use_dbton_count = 0;
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
int spider_create_tmp_dbton_share(
 | 
						|
  SPIDER_SHARE *tmp_share
 | 
						|
) {
 | 
						|
  int error_num;
 | 
						|
  uint dbton_id = tmp_share->use_dbton_ids[0];
 | 
						|
  DBUG_ENTER("spider_create_tmp_dbton_share");
 | 
						|
  if (!(tmp_share->dbton_share[dbton_id] =
 | 
						|
    spider_dbton[dbton_id].create_db_share(tmp_share)))
 | 
						|
  {
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  if ((error_num = tmp_share->dbton_share[dbton_id]->init()))
 | 
						|
  {
 | 
						|
    delete tmp_share->dbton_share[dbton_id];
 | 
						|
    tmp_share->dbton_share[dbton_id] = NULL;
 | 
						|
    DBUG_RETURN(error_num);
 | 
						|
  }
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
void spider_free_tmp_dbton_share(
 | 
						|
  SPIDER_SHARE *tmp_share
 | 
						|
) {
 | 
						|
  uint dbton_id = tmp_share->use_dbton_ids[0];
 | 
						|
  DBUG_ENTER("spider_free_tmp_dbton_share");
 | 
						|
  if (tmp_share->dbton_share[dbton_id])
 | 
						|
  {
 | 
						|
    delete tmp_share->dbton_share[dbton_id];
 | 
						|
    tmp_share->dbton_share[dbton_id] = NULL;
 | 
						|
  }
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
int spider_create_tmp_dbton_handler(
 | 
						|
  ha_spider *tmp_spider
 | 
						|
) {
 | 
						|
  int error_num;
 | 
						|
  SPIDER_SHARE *tmp_share = tmp_spider->share;
 | 
						|
  uint dbton_id = tmp_share->use_dbton_ids[0];
 | 
						|
  DBUG_ENTER("spider_create_tmp_dbton_handler");
 | 
						|
  if (!(tmp_spider->dbton_handler[dbton_id] =
 | 
						|
    spider_dbton[dbton_id].create_db_handler(tmp_spider,
 | 
						|
    tmp_share->dbton_share[dbton_id])))
 | 
						|
  {
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  if ((error_num = tmp_spider->dbton_handler[dbton_id]->init()))
 | 
						|
  {
 | 
						|
    delete tmp_spider->dbton_handler[dbton_id];
 | 
						|
    tmp_spider->dbton_handler[dbton_id] = NULL;
 | 
						|
    DBUG_RETURN(error_num);
 | 
						|
  }
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
void spider_free_tmp_dbton_handler(
 | 
						|
  ha_spider *tmp_spider
 | 
						|
) {
 | 
						|
  SPIDER_SHARE *tmp_share = tmp_spider->share;
 | 
						|
  uint dbton_id = tmp_share->use_dbton_ids[0];
 | 
						|
  DBUG_ENTER("spider_create_tmp_dbton_handler");
 | 
						|
  if (tmp_spider->dbton_handler[dbton_id])
 | 
						|
  {
 | 
						|
    delete tmp_spider->dbton_handler[dbton_id];
 | 
						|
    tmp_spider->dbton_handler[dbton_id] = NULL;
 | 
						|
  }
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
TABLE_LIST *spider_get_parent_table_list(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
  TABLE *table = spider->get_table();
 | 
						|
  DBUG_ENTER("spider_get_parent_table_list");
 | 
						|
  DBUG_RETURN(table->pos_in_table_list);
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
) {
 | 
						|
  TABLE_LIST *table_list = spider_get_parent_table_list(spider);
 | 
						|
  DBUG_ENTER("spider_get_select_lex");
 | 
						|
  if (table_list)
 | 
						|
  {
 | 
						|
    DBUG_RETURN(table_list->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->limit_params.explicit_limit)
 | 
						|
  {
 | 
						|
    *select_limit = select_lex->limit_params.select_limit ?
 | 
						|
      select_lex->limit_params.select_limit->val_int() : 0;
 | 
						|
    *offset_limit = select_lex->limit_params.offset_limit ?
 | 
						|
      select_lex->limit_params.offset_limit->val_int() : 0;
 | 
						|
  }
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
void spider_get_select_limit(
 | 
						|
  ha_spider *spider,
 | 
						|
  st_select_lex **select_lex,
 | 
						|
  longlong *select_limit,
 | 
						|
  longlong *offset_limit
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_get_select_limit");
 | 
						|
  *select_lex = spider_get_select_lex(spider);
 | 
						|
  spider_get_select_limit_from_select_lex(
 | 
						|
    *select_lex, select_limit, offset_limit);
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
longlong spider_split_read_param(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
  SPIDER_SHARE *share = spider->share;
 | 
						|
  SPIDER_RESULT_LIST *result_list = &spider->result_list;
 | 
						|
  THD *thd = spider->wide_handler->trx->thd;
 | 
						|
  st_select_lex *select_lex;
 | 
						|
  longlong select_limit;
 | 
						|
  longlong offset_limit;
 | 
						|
  double semi_split_read;
 | 
						|
  longlong split_read;
 | 
						|
  DBUG_ENTER("spider_split_read_param");
 | 
						|
  result_list->set_split_read_count = 1;
 | 
						|
#ifdef INFO_KIND_FORCE_LIMIT_BEGIN
 | 
						|
  if (spider->wide_handler->info_limit < 9223372036854775807LL)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider info_limit=%lld",
 | 
						|
      spider->wide_handler->info_limit));
 | 
						|
    longlong info_limit = spider->wide_handler->info_limit;
 | 
						|
    result_list->split_read_base = info_limit;
 | 
						|
    result_list->semi_split_read = 0;
 | 
						|
    result_list->first_read = info_limit;
 | 
						|
    result_list->second_read = info_limit;
 | 
						|
    result_list->semi_split_read_base = 0;
 | 
						|
    result_list->set_split_read = FALSE;
 | 
						|
    DBUG_RETURN(info_limit);
 | 
						|
  }
 | 
						|
#endif
 | 
						|
  spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit);
 | 
						|
  DBUG_PRINT("info",("spider result_list->set_split_read=%s", result_list->set_split_read ? "TRUE" : "FALSE"));
 | 
						|
  if (!result_list->set_split_read)
 | 
						|
  {
 | 
						|
    int bulk_update_mode = spider_param_bulk_update_mode(thd,
 | 
						|
      share->bulk_update_mode);
 | 
						|
    DBUG_PRINT("info",("spider sql_command=%u",
 | 
						|
      spider->wide_handler->sql_command));
 | 
						|
    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"));
 | 
						|
    bool inserting =
 | 
						|
      (
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_INSERT ||
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_INSERT_SELECT
 | 
						|
      );
 | 
						|
    bool updating =
 | 
						|
      (
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_UPDATE ||
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_UPDATE_MULTI
 | 
						|
      );
 | 
						|
    bool deleting =
 | 
						|
      (
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_DELETE ||
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_DELETE_MULTI
 | 
						|
      );
 | 
						|
    bool replacing =
 | 
						|
      (
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_REPLACE ||
 | 
						|
        spider->wide_handler->sql_command == SQLCOM_REPLACE_SELECT
 | 
						|
      );
 | 
						|
    DBUG_PRINT("info",("spider updating=%s", updating ? "TRUE" : "FALSE"));
 | 
						|
    DBUG_PRINT("info",("spider deleting=%s", deleting ? "TRUE" : "FALSE"));
 | 
						|
    DBUG_PRINT("info",("spider replacing=%s", replacing ? "TRUE" : "FALSE"));
 | 
						|
    TABLE *table = spider->get_table();
 | 
						|
    if (
 | 
						|
      (
 | 
						|
        inserting &&
 | 
						|
        spider->use_fields
 | 
						|
      ) ||
 | 
						|
      replacing ||
 | 
						|
      (
 | 
						|
        (
 | 
						|
          updating ||
 | 
						|
          deleting
 | 
						|
        ) &&
 | 
						|
        (
 | 
						|
          bulk_update_mode != 2 ||
 | 
						|
          !spider->support_bulk_update_sql() ||
 | 
						|
          (
 | 
						|
            updating &&
 | 
						|
            table->triggers &&
 | 
						|
#ifdef HA_CAN_FORCE_BULK_UPDATE
 | 
						|
            !(table->file->ha_table_flags() & HA_CAN_FORCE_BULK_UPDATE) &&
 | 
						|
#endif
 | 
						|
            table->triggers->has_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER)
 | 
						|
          ) ||
 | 
						|
          (
 | 
						|
            deleting &&
 | 
						|
            table->triggers &&
 | 
						|
#ifdef HA_CAN_FORCE_BULK_DELETE
 | 
						|
            !(table->file->ha_table_flags() & HA_CAN_FORCE_BULK_DELETE) &&
 | 
						|
#endif
 | 
						|
            table->triggers->has_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER)
 | 
						|
          )
 | 
						|
        )
 | 
						|
      )
 | 
						|
    ) {
 | 
						|
      /* This case must select by one shot */
 | 
						|
      DBUG_PRINT("info",("spider cancel split read"));
 | 
						|
      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;
 | 
						|
      result_list->semi_split_read_base = 0;
 | 
						|
      result_list->set_split_read = TRUE;
 | 
						|
      DBUG_RETURN(9223372036854775807LL);
 | 
						|
    }
 | 
						|
#ifdef SPIDER_HAS_EXPLAIN_QUERY
 | 
						|
    Explain_query *explain = thd->lex->explain;
 | 
						|
    bool filesort = FALSE;
 | 
						|
    if (explain)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider explain=%p", explain));
 | 
						|
      Explain_select *explain_select = NULL;
 | 
						|
      if (select_lex)
 | 
						|
      {
 | 
						|
        DBUG_PRINT("info",("spider select_lex=%p", select_lex));
 | 
						|
        DBUG_PRINT("info",("spider select_number=%u",
 | 
						|
          select_lex->select_number));
 | 
						|
        explain_select =
 | 
						|
          explain->get_select(select_lex->select_number);
 | 
						|
      }
 | 
						|
      if (explain_select)
 | 
						|
      {
 | 
						|
        DBUG_PRINT("info",("spider explain_select=%p", explain_select));
 | 
						|
        if (explain_select->using_filesort)
 | 
						|
        {
 | 
						|
          DBUG_PRINT("info",("spider using filesort"));
 | 
						|
          filesort = TRUE;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    result_list->split_read_base =
 | 
						|
      spider_param_split_read(thd, share->split_read);
 | 
						|
#ifdef SPIDER_HAS_EXPLAIN_QUERY
 | 
						|
    if (filesort)
 | 
						|
    {
 | 
						|
      result_list->semi_split_read = 0;
 | 
						|
      result_list->semi_split_read_limit = 9223372036854775807LL;
 | 
						|
    } else {
 | 
						|
#endif
 | 
						|
      result_list->semi_split_read =
 | 
						|
        spider_param_semi_split_read(thd, share->semi_split_read);
 | 
						|
      result_list->semi_split_read_limit =
 | 
						|
        spider_param_semi_split_read_limit(thd, share->semi_split_read_limit);
 | 
						|
#ifdef SPIDER_HAS_EXPLAIN_QUERY
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    result_list->first_read =
 | 
						|
      spider_param_first_read(thd, share->first_read);
 | 
						|
    result_list->second_read =
 | 
						|
      spider_param_second_read(thd, share->second_read);
 | 
						|
    result_list->semi_split_read_base = 0;
 | 
						|
    result_list->set_split_read = TRUE;
 | 
						|
  }
 | 
						|
  DBUG_PRINT("info",("spider result_list->semi_split_read=%f", result_list->semi_split_read));
 | 
						|
  DBUG_PRINT("info",("spider select_lex->explicit_limit=%d", select_lex ? select_lex->limit_params.explicit_limit : 0));
 | 
						|
  DBUG_PRINT("info",("spider OPTION_FOUND_ROWS=%s", select_lex && (select_lex->options & OPTION_FOUND_ROWS) ? "TRUE" : "FALSE"));
 | 
						|
  DBUG_PRINT("info",("spider select_lex->group_list.elements=%u", select_lex ? select_lex->group_list.elements : 0));
 | 
						|
  DBUG_PRINT("info",("spider select_lex->with_sum_func=%s", select_lex && select_lex->with_sum_func ? "TRUE" : "FALSE"));
 | 
						|
  if (
 | 
						|
    result_list->semi_split_read > 0 &&
 | 
						|
    select_lex && select_lex->limit_params.explicit_limit &&
 | 
						|
    !(select_lex->options & OPTION_FOUND_ROWS) &&
 | 
						|
    !select_lex->group_list.elements &&
 | 
						|
    !select_lex->with_sum_func
 | 
						|
  ) {
 | 
						|
    semi_split_read = result_list->semi_split_read *
 | 
						|
      (select_limit + offset_limit);
 | 
						|
    DBUG_PRINT("info",("spider semi_split_read=%f", semi_split_read));
 | 
						|
    if (semi_split_read >= result_list->semi_split_read_limit)
 | 
						|
    {
 | 
						|
      result_list->semi_split_read_base = result_list->semi_split_read_limit;
 | 
						|
      DBUG_RETURN(result_list->semi_split_read_limit);
 | 
						|
    } else {
 | 
						|
      split_read = (longlong) semi_split_read;
 | 
						|
      if (split_read < 0)
 | 
						|
      {
 | 
						|
        result_list->semi_split_read_base = result_list->semi_split_read_limit;
 | 
						|
        DBUG_RETURN(result_list->semi_split_read_limit);
 | 
						|
      } else if (split_read == 0)
 | 
						|
      {
 | 
						|
        result_list->semi_split_read_base = 1;
 | 
						|
        DBUG_RETURN(1);
 | 
						|
      } else {
 | 
						|
        result_list->semi_split_read_base = split_read;
 | 
						|
        DBUG_RETURN(split_read);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else if (result_list->first_read > 0)
 | 
						|
    DBUG_RETURN(result_list->first_read);
 | 
						|
  DBUG_RETURN(result_list->split_read_base);
 | 
						|
}
 | 
						|
 | 
						|
longlong spider_bg_split_read_param(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
  SPIDER_RESULT_LIST *result_list = &spider->result_list;
 | 
						|
  DBUG_ENTER("spider_bg_split_read_param");
 | 
						|
  if (result_list->semi_split_read_base)
 | 
						|
    DBUG_RETURN(result_list->semi_split_read_base);
 | 
						|
  DBUG_RETURN(result_list->split_read_base);
 | 
						|
}
 | 
						|
 | 
						|
void spider_first_split_read_param(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
  SPIDER_RESULT_LIST *result_list = &spider->result_list;
 | 
						|
  DBUG_ENTER("spider_first_split_read_param");
 | 
						|
  if (result_list->semi_split_read_base)
 | 
						|
    result_list->split_read = result_list->semi_split_read_base;
 | 
						|
  else if (result_list->second_read > 0)
 | 
						|
    result_list->split_read = result_list->first_read;
 | 
						|
  else
 | 
						|
    result_list->split_read = result_list->split_read_base;
 | 
						|
  result_list->set_split_read_count = 1;
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
void spider_next_split_read_param(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
  SPIDER_RESULT_LIST *result_list = &spider->result_list;
 | 
						|
  DBUG_ENTER("spider_next_split_read_param");
 | 
						|
  if (result_list->semi_split_read_base)
 | 
						|
    result_list->split_read = result_list->semi_split_read_base;
 | 
						|
  else if (
 | 
						|
    result_list->set_split_read_count == 1 &&
 | 
						|
    result_list->second_read > 0
 | 
						|
  )
 | 
						|
    result_list->split_read = result_list->second_read;
 | 
						|
  else
 | 
						|
    result_list->split_read = result_list->split_read_base;
 | 
						|
  result_list->set_split_read_count++;
 | 
						|
  DBUG_VOID_RETURN;
 | 
						|
}
 | 
						|
 | 
						|
bool spider_check_direct_order_limit(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
  THD *thd = spider->wide_handler->trx->thd;
 | 
						|
  SPIDER_SHARE *share = spider->share;
 | 
						|
  st_select_lex *select_lex;
 | 
						|
  longlong select_limit;
 | 
						|
  longlong offset_limit;
 | 
						|
  DBUG_ENTER("spider_check_direct_order_limit");
 | 
						|
  if (spider_check_index_merge(spider->get_table(),
 | 
						|
    spider_get_select_lex(spider)))
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider set use_index_merge"));
 | 
						|
    spider->use_index_merge = TRUE;
 | 
						|
  }
 | 
						|
  DBUG_PRINT("info",("spider SQLCOM_HA_READ=%s",
 | 
						|
    (spider->wide_handler->sql_command == SQLCOM_HA_READ) ? "TRUE" : "FALSE"));
 | 
						|
  DBUG_PRINT("info",("spider use_index_merge=%s",
 | 
						|
    spider->use_index_merge ? "TRUE" : "FALSE"));
 | 
						|
  DBUG_PRINT("info",("spider is_clone=%s",
 | 
						|
    spider->is_clone ? "TRUE" : "FALSE"));
 | 
						|
  if (
 | 
						|
    spider->wide_handler->sql_command != SQLCOM_HA_READ &&
 | 
						|
    !spider->use_index_merge &&
 | 
						|
    !spider->is_clone
 | 
						|
  ) {
 | 
						|
    spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit);
 | 
						|
    bool first_check = TRUE;
 | 
						|
    DBUG_PRINT("info",("spider select_lex=%p", select_lex));
 | 
						|
    DBUG_PRINT("info",("spider leaf_tables.elements=%u",
 | 
						|
      select_lex ? select_lex->leaf_tables.elements : 0));
 | 
						|
 | 
						|
    if (select_lex && (select_lex->options & SELECT_DISTINCT))
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider with distinct"));
 | 
						|
      spider->result_list.direct_distinct = TRUE;
 | 
						|
    }
 | 
						|
    spider->result_list.direct_aggregate = spider_param_direct_aggregate(thd);
 | 
						|
    DBUG_PRINT("info",("spider select_limit=%lld", select_limit));
 | 
						|
    DBUG_PRINT("info",("spider offset_limit=%lld", offset_limit));
 | 
						|
    if (
 | 
						|
#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
 | 
						|
#else
 | 
						|
      !(thd->variables.optimizer_switch &
 | 
						|
        OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) ||
 | 
						|
#endif
 | 
						|
#ifdef SPIDER_NEED_CHECK_CONDITION_AT_CHECKING_DIRECT_ORDER_LIMIT
 | 
						|
      !spider->condition ||
 | 
						|
#endif
 | 
						|
      !select_lex ||
 | 
						|
      select_lex->leaf_tables.elements != 1 ||
 | 
						|
      select_lex->table_list.elements != 1
 | 
						|
    ) {
 | 
						|
      DBUG_PRINT("info",("spider first_check is FALSE"));
 | 
						|
      first_check = FALSE;
 | 
						|
      spider->result_list.direct_distinct = FALSE;
 | 
						|
      spider->result_list.direct_aggregate = FALSE;
 | 
						|
    } else if (spider_db_append_condition(spider, NULL, 0, TRUE))
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider FALSE by condition"));
 | 
						|
      first_check = FALSE;
 | 
						|
      spider->result_list.direct_distinct = FALSE;
 | 
						|
      spider->result_list.direct_aggregate = FALSE;
 | 
						|
    } else if (
 | 
						|
      !select_lex->group_list.elements &&
 | 
						|
      !select_lex->with_sum_func
 | 
						|
    ) {
 | 
						|
      DBUG_PRINT("info",("spider this SQL is not aggregate SQL"));
 | 
						|
      spider->result_list.direct_aggregate = FALSE;
 | 
						|
    } else {
 | 
						|
      ORDER *group;
 | 
						|
      for (group = (ORDER *) select_lex->group_list.first; group;
 | 
						|
        group = group->next)
 | 
						|
      {
 | 
						|
        if (spider->print_item_type((*group->item), NULL, NULL, 0))
 | 
						|
        {
 | 
						|
          DBUG_PRINT("info",("spider aggregate FALSE by group"));
 | 
						|
          spider->result_list.direct_aggregate = FALSE;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      JOIN *join = select_lex->join;
 | 
						|
      Item_sum **item_sum_ptr;
 | 
						|
      for (item_sum_ptr = join->sum_funcs; *item_sum_ptr; ++item_sum_ptr)
 | 
						|
      {
 | 
						|
        if (spider->print_item_type(*item_sum_ptr, NULL, NULL, 0))
 | 
						|
        {
 | 
						|
          DBUG_PRINT("info",("spider aggregate FALSE by not supported"));
 | 
						|
          spider->result_list.direct_aggregate = FALSE;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (!spider_all_part_in_order((ORDER *) select_lex->group_list.first,
 | 
						|
        spider->get_table()))
 | 
						|
      {
 | 
						|
        DBUG_PRINT("info",("spider FALSE by group condition"));
 | 
						|
        first_check = FALSE;
 | 
						|
        spider->result_list.direct_distinct = FALSE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    longlong direct_order_limit = spider_param_direct_order_limit(thd,
 | 
						|
      share->direct_order_limit);
 | 
						|
    DBUG_PRINT("info",("spider direct_order_limit=%lld", direct_order_limit));
 | 
						|
    if (direct_order_limit)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider first_check=%s",
 | 
						|
        first_check ? "TRUE" : "FALSE"));
 | 
						|
      DBUG_PRINT("info",("spider (select_lex->options & OPTION_FOUND_ROWS)=%s",
 | 
						|
        select_lex && (select_lex->options & OPTION_FOUND_ROWS) ? "TRUE" : "FALSE"));
 | 
						|
      DBUG_PRINT("info",("spider direct_aggregate=%s",
 | 
						|
        spider->result_list.direct_aggregate ? "TRUE" : "FALSE"));
 | 
						|
      DBUG_PRINT("info",("spider select_lex->group_list.elements=%u",
 | 
						|
        select_lex ? select_lex->group_list.elements : 0));
 | 
						|
      DBUG_PRINT("info",("spider select_lex->with_sum_func=%s",
 | 
						|
        select_lex && select_lex->with_sum_func ? "TRUE" : "FALSE"));
 | 
						|
      DBUG_PRINT("info",("spider select_lex->having=%s",
 | 
						|
        select_lex && select_lex->having ? "TRUE" : "FALSE"));
 | 
						|
      DBUG_PRINT("info",("spider select_lex->order_list.elements=%u",
 | 
						|
        select_lex ? select_lex->order_list.elements : 0));
 | 
						|
      if (
 | 
						|
        !first_check ||
 | 
						|
        !select_lex->limit_params.explicit_limit ||
 | 
						|
        (select_lex->options & OPTION_FOUND_ROWS) ||
 | 
						|
        (
 | 
						|
          !spider->result_list.direct_aggregate &&
 | 
						|
          (
 | 
						|
            select_lex->group_list.elements ||
 | 
						|
            select_lex->with_sum_func
 | 
						|
          )
 | 
						|
        ) ||
 | 
						|
        select_lex->having ||
 | 
						|
        !select_lex->order_list.elements ||
 | 
						|
        select_limit > direct_order_limit - offset_limit
 | 
						|
      ) {
 | 
						|
        DBUG_PRINT("info",("spider FALSE by select_lex"));
 | 
						|
        DBUG_RETURN(FALSE);
 | 
						|
      }
 | 
						|
      ORDER *order;
 | 
						|
      for (order = (ORDER *) select_lex->order_list.first; order;
 | 
						|
        order = order->next)
 | 
						|
      {
 | 
						|
        if (spider->print_item_type((*order->item), NULL, NULL, 0))
 | 
						|
        {
 | 
						|
          DBUG_PRINT("info",("spider FALSE by order"));
 | 
						|
          DBUG_RETURN(FALSE);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      DBUG_PRINT("info",("spider TRUE"));
 | 
						|
      spider->result_list.internal_limit = select_limit + offset_limit;
 | 
						|
      spider->result_list.split_read = select_limit + offset_limit;
 | 
						|
      spider->wide_handler->trx->direct_order_limit_count++;
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_PRINT("info",("spider FALSE by parameter"));
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
bool spider_all_part_in_order(
 | 
						|
  ORDER *order,
 | 
						|
  TABLE *table
 | 
						|
) {
 | 
						|
  TABLE_LIST *parent;
 | 
						|
  partition_info *part_info;
 | 
						|
  Field **part_fields;
 | 
						|
  ORDER *ptr;
 | 
						|
  Item *item;
 | 
						|
  Item_field *item_field;
 | 
						|
  DBUG_ENTER("spider_all_part_in_order");
 | 
						|
  while (TRUE)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info", ("spider table_name = %s", table->s->db.str));
 | 
						|
    DBUG_PRINT("info",("spider part_info=%p", table->part_info));
 | 
						|
    if ((part_info = table->part_info))
 | 
						|
    {
 | 
						|
      for (part_fields = part_info->full_part_field_array;
 | 
						|
        *part_fields; ++part_fields)
 | 
						|
      {
 | 
						|
        DBUG_PRINT("info", ("spider part_field = %s",
 | 
						|
          SPIDER_field_name_str(*part_fields)));
 | 
						|
        for (ptr = order; ptr; ptr = ptr->next)
 | 
						|
        {
 | 
						|
          item = *ptr->item;
 | 
						|
          if (item->type() != Item::FIELD_ITEM)
 | 
						|
          {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
          item_field = (Item_field *) item;
 | 
						|
          Field *field = item_field->field;
 | 
						|
          if (!field)
 | 
						|
          {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
          DBUG_PRINT("info", ("spider field_name = %s.%s",
 | 
						|
            field->table->s->db.str, SPIDER_field_name_str(field)));
 | 
						|
          if (*part_fields == spider_field_exchange(table->file, field))
 | 
						|
          {
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
        if (!ptr)
 | 
						|
        {
 | 
						|
          DBUG_RETURN(FALSE);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (!(parent = table->pos_in_table_list->parent_l))
 | 
						|
    {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    table = parent->table;
 | 
						|
  }
 | 
						|
  DBUG_RETURN(TRUE);
 | 
						|
}
 | 
						|
 | 
						|
Field *spider_field_exchange(
 | 
						|
  handler *handler,
 | 
						|
  Field *field
 | 
						|
) {
 | 
						|
  DBUG_ENTER("spider_field_exchange");
 | 
						|
  DBUG_PRINT("info",("spider in field=%p", field));
 | 
						|
  DBUG_PRINT("info",("spider in field->table=%p", field->table));
 | 
						|
    DBUG_PRINT("info",("spider table=%p", handler->get_table()));
 | 
						|
    if (field->table != handler->get_table())
 | 
						|
      DBUG_RETURN(NULL);
 | 
						|
  DBUG_PRINT("info",("spider out field=%p", field));
 | 
						|
  DBUG_RETURN(field);
 | 
						|
}
 | 
						|
 | 
						|
int spider_set_direct_limit_offset(
 | 
						|
  ha_spider *spider
 | 
						|
) {
 | 
						|
#ifndef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
 | 
						|
  THD *thd = spider->wide_handler->trx->thd;
 | 
						|
#endif
 | 
						|
  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->partition_handler &&
 | 
						|
    !spider->wide_handler_owner
 | 
						|
  ) {
 | 
						|
    if (spider->partition_handler->owner->
 | 
						|
      result_list.direct_limit_offset == TRUE)
 | 
						|
    {
 | 
						|
      spider->result_list.direct_limit_offset = TRUE;
 | 
						|
      DBUG_RETURN(TRUE);
 | 
						|
    } else {
 | 
						|
      DBUG_RETURN(FALSE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (
 | 
						|
    spider->wide_handler->sql_command != SQLCOM_SELECT ||
 | 
						|
    spider->result_list.direct_aggregate ||
 | 
						|
    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 (
 | 
						|
#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
 | 
						|
#else
 | 
						|
    !(thd->variables.optimizer_switch &
 | 
						|
      OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) ||
 | 
						|
#endif
 | 
						|
    // conditions is null may be no where condition in rand_init
 | 
						|
    spider->wide_handler->condition
 | 
						|
  )
 | 
						|
    DBUG_RETURN(FALSE);
 | 
						|
 | 
						|
  // ignore condition like 1=1
 | 
						|
#ifdef SPIDER_has_Item_has_subquery
 | 
						|
  if (select_lex->where && select_lex->where->has_subquery())
 | 
						|
#else
 | 
						|
    if (select_lex->where && select_lex->where->with_subquery())
 | 
						|
#endif
 | 
						|
    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 (SPIDER_get_linkage(select_lex) == DERIVED_TABLE_TYPE)
 | 
						|
    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
 | 
						|
) {
 | 
						|
  uint roop_count;
 | 
						|
  JOIN *join;
 | 
						|
  DBUG_ENTER("spider_check_index_merge");
 | 
						|
  if (!select_lex)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider select_lex is null"));
 | 
						|
    DBUG_RETURN(FALSE);
 | 
						|
  }
 | 
						|
  join = select_lex->join;
 | 
						|
  if (!join)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider join is null"));
 | 
						|
    DBUG_RETURN(FALSE);
 | 
						|
  }
 | 
						|
  if (!join->join_tab)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider join->join_tab is null"));
 | 
						|
    DBUG_RETURN(FALSE);
 | 
						|
  }
 | 
						|
  for (roop_count = 0; roop_count < spider_join_table_count(join); ++roop_count)
 | 
						|
  {
 | 
						|
    JOIN_TAB *join_tab = &join->join_tab[roop_count];
 | 
						|
    if (join_tab->table == table)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider join_tab->type=%u", join_tab->type));
 | 
						|
      if (
 | 
						|
#ifdef SPIDER_HAS_JT_HASH_INDEX_MERGE
 | 
						|
        join_tab->type == JT_HASH_INDEX_MERGE ||
 | 
						|
#endif
 | 
						|
        join_tab->type == JT_INDEX_MERGE
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(TRUE);
 | 
						|
      }
 | 
						|
/*
 | 
						|
      DBUG_PRINT("info",("spider join_tab->quick->get_type()=%u",
 | 
						|
        join_tab->quick ? join_tab->quick->get_type() : 0));
 | 
						|
      if (
 | 
						|
        join_tab->quick &&
 | 
						|
        join_tab->quick->get_type() == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(TRUE);
 | 
						|
      }
 | 
						|
*/
 | 
						|
      DBUG_PRINT("info",("spider join_tab->select->quick->get_type()=%u",
 | 
						|
        join_tab->select && join_tab->select->quick ? join_tab->select->quick->get_type() : 0));
 | 
						|
      if (
 | 
						|
        join_tab->select &&
 | 
						|
        join_tab->select->quick &&
 | 
						|
        join_tab->select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE
 | 
						|
      ) {
 | 
						|
        DBUG_RETURN(TRUE);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
int spider_compare_for_sort(
 | 
						|
  const void *a_,
 | 
						|
  const void *b_
 | 
						|
) {
 | 
						|
  const SPIDER_SORT *a= static_cast<const SPIDER_SORT *>(a_);
 | 
						|
  const SPIDER_SORT *b= static_cast<const SPIDER_SORT *>(b_);
 | 
						|
  DBUG_ENTER("spider_compare_for_sort");
 | 
						|
  if (a->sort > b->sort)
 | 
						|
    DBUG_RETURN(-1);
 | 
						|
  if (a->sort < b->sort)
 | 
						|
    DBUG_RETURN(1);
 | 
						|
  DBUG_RETURN(0);
 | 
						|
}
 | 
						|
 | 
						|
ulong spider_calc_for_sort(
 | 
						|
  uint count,
 | 
						|
  ...
 | 
						|
) {
 | 
						|
  ulong sort = 0;
 | 
						|
  va_list args;
 | 
						|
  va_start(args, count);
 | 
						|
  DBUG_ENTER("spider_calc_for_sort");
 | 
						|
  while (count--)
 | 
						|
  {
 | 
						|
    char *start = va_arg(args, char *), *str;
 | 
						|
    uint wild_pos = 0;
 | 
						|
 | 
						|
    if ((str = start))
 | 
						|
    {
 | 
						|
      wild_pos = 128;
 | 
						|
      for (; *str; str++)
 | 
						|
      {
 | 
						|
        if (*str == spider_wild_prefix && str[1])
 | 
						|
          str++;
 | 
						|
        else if (*str == spider_wild_many || *str == spider_wild_one)
 | 
						|
        {
 | 
						|
          wild_pos = (uint) (str - start) + 1;
 | 
						|
          if (wild_pos > 127)
 | 
						|
            wild_pos = 127;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    sort = (sort << 8) + wild_pos;
 | 
						|
  }
 | 
						|
  va_end(args);
 | 
						|
  DBUG_RETURN(sort);
 | 
						|
}
 | 
						|
 | 
						|
/** Generates a random number between 0 and 1 */
 | 
						|
double spider_rand(
 | 
						|
  uint32 rand_source
 | 
						|
) {
 | 
						|
  struct my_rnd_struct rand;
 | 
						|
  DBUG_ENTER("spider_rand");
 | 
						|
  /* generate same as rand function for applications */
 | 
						|
  my_rnd_init(&rand, (uint32) (rand_source * 65537L + 55555555L),
 | 
						|
    (uint32) (rand_source * 268435457L));
 | 
						|
  DBUG_RETURN(my_rnd(&rand));
 | 
						|
}
 | 
						|
 | 
						|
int spider_discover_table_structure_internal(
 | 
						|
  SPIDER_TRX *trx,
 | 
						|
  SPIDER_SHARE *spider_share,
 | 
						|
  spider_string *str
 | 
						|
) {
 | 
						|
  int error_num = 0, roop_count;
 | 
						|
  DBUG_ENTER("spider_discover_table_structure_internal");
 | 
						|
  for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++)
 | 
						|
  {
 | 
						|
    if (spider_bit_is_set(spider_share->dbton_bitmap, roop_count))
 | 
						|
    {
 | 
						|
      if ((error_num = spider_share->dbton_share[roop_count]->
 | 
						|
        discover_table_structure(trx, spider_share, str)))
 | 
						|
      {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  DBUG_RETURN(error_num);
 | 
						|
}
 | 
						|
 | 
						|
int spider_discover_table_structure(
 | 
						|
  handlerton *hton,
 | 
						|
  THD* thd,
 | 
						|
  TABLE_SHARE *share,
 | 
						|
  HA_CREATE_INFO *info
 | 
						|
) {
 | 
						|
  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);
 | 
						|
  SPIDER_TRX *trx;
 | 
						|
  partition_info *part_info = thd->work_part_info;
 | 
						|
  SPIDER_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);
 | 
						|
  DBUG_ENTER("spider_discover_table_structure");
 | 
						|
  str.init_calc_mem(SPD_MID_DISCOVER_TABLE_STRUCTURE_1);
 | 
						|
  str.length(0);
 | 
						|
  if (str.reserve(
 | 
						|
    SPIDER_SQL_CREATE_TABLE_LEN + share->db.length +
 | 
						|
    SPIDER_SQL_DOT_LEN + share->table_name.length +
 | 
						|
    /* SPIDER_SQL_LCL_NAME_QUOTE_LEN */ 4 + SPIDER_SQL_OPEN_PAREN_LEN
 | 
						|
  )) {
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  str.q_append(SPIDER_SQL_CREATE_TABLE_STR, SPIDER_SQL_CREATE_TABLE_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_LCL_NAME_QUOTE_STR, SPIDER_SQL_LCL_NAME_QUOTE_LEN);
 | 
						|
  str.q_append(share->db.str, share->db.length);
 | 
						|
  str.q_append(SPIDER_SQL_LCL_NAME_QUOTE_STR, SPIDER_SQL_LCL_NAME_QUOTE_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_DOT_STR, SPIDER_SQL_DOT_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_LCL_NAME_QUOTE_STR, SPIDER_SQL_LCL_NAME_QUOTE_LEN);
 | 
						|
  str.q_append(share->table_name.str, share->table_name.length);
 | 
						|
  str.q_append(SPIDER_SQL_LCL_NAME_QUOTE_STR, SPIDER_SQL_LCL_NAME_QUOTE_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN);
 | 
						|
  str_len = str.length();
 | 
						|
  my_hash_value_type hash_value = my_calc_hash(&spider_open_tables,
 | 
						|
    (uchar*) table_name, table_name_length);
 | 
						|
  if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider spider_get_trx error"));
 | 
						|
    my_error(error_num, MYF(0));
 | 
						|
    DBUG_RETURN(error_num);
 | 
						|
  }
 | 
						|
  share->table_charset = info->default_table_charset;
 | 
						|
  share->comment = info->comment;
 | 
						|
  if (!part_info)
 | 
						|
  {
 | 
						|
    if (!(spider_share = spider_create_share(table_name, share,
 | 
						|
      NULL,
 | 
						|
      hash_value,
 | 
						|
      &error_num
 | 
						|
    ))) {
 | 
						|
      DBUG_RETURN(error_num);
 | 
						|
    }
 | 
						|
 | 
						|
    error_num = spider_discover_table_structure_internal(trx, spider_share, &str);
 | 
						|
 | 
						|
    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,
 | 
						|
          &error_num))
 | 
						|
      ) {
 | 
						|
        if (thd->lex->create_info.or_replace())
 | 
						|
        {
 | 
						|
          error_num = spider_delete_tables(table_tables,
 | 
						|
            spider_share->table_name, &dummy);
 | 
						|
        }
 | 
						|
        if (!error_num)
 | 
						|
        {
 | 
						|
          error_num = spider_insert_tables(table_tables, spider_share);
 | 
						|
        }
 | 
						|
        spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    spider_free_share_resource_only(spider_share);
 | 
						|
  } 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++))
 | 
						|
    {
 | 
						|
      if ((part_elem)->subpartitions.elements)
 | 
						|
      {
 | 
						|
        List_iterator<partition_element> sub_it((part_elem)->subpartitions);
 | 
						|
        while ((sub_elem = sub_it++))
 | 
						|
        {
 | 
						|
          str.length(str_len);
 | 
						|
          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,
 | 
						|
            hash_value,
 | 
						|
            &error_num
 | 
						|
          ))) {
 | 
						|
            DBUG_RETURN(error_num);
 | 
						|
          }
 | 
						|
 | 
						|
          error_num = spider_discover_table_structure_internal(
 | 
						|
            trx, spider_share, &str);
 | 
						|
 | 
						|
          spider_free_share_resource_only(spider_share);
 | 
						|
          if (!error_num)
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        if (!error_num)
 | 
						|
          break;
 | 
						|
      } else {
 | 
						|
        str.length(str_len);
 | 
						|
        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,
 | 
						|
          hash_value,
 | 
						|
          &error_num
 | 
						|
        ))) {
 | 
						|
          DBUG_RETURN(error_num);
 | 
						|
        }
 | 
						|
 | 
						|
        error_num = spider_discover_table_structure_internal(
 | 
						|
          trx, spider_share, &str);
 | 
						|
 | 
						|
        spider_free_share_resource_only(spider_share);
 | 
						|
        if (!error_num)
 | 
						|
          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,
 | 
						|
          &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,
 | 
						|
              hash_value,
 | 
						|
              &error_num
 | 
						|
            ))) {
 | 
						|
              DBUG_RETURN(error_num);
 | 
						|
            }
 | 
						|
 | 
						|
            if (thd->lex->create_info.or_replace())
 | 
						|
            {
 | 
						|
              error_num = spider_delete_tables(table_tables,
 | 
						|
                spider_share->table_name, &dummy);
 | 
						|
            }
 | 
						|
            if (!error_num)
 | 
						|
            {
 | 
						|
              error_num = spider_insert_tables(table_tables, spider_share);
 | 
						|
            }
 | 
						|
 | 
						|
            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,
 | 
						|
            hash_value,
 | 
						|
            &error_num
 | 
						|
          ))) {
 | 
						|
            DBUG_RETURN(error_num);
 | 
						|
          }
 | 
						|
 | 
						|
          if (thd->lex->create_info.or_replace())
 | 
						|
          {
 | 
						|
            error_num = spider_delete_tables(table_tables,
 | 
						|
              spider_share->table_name, &dummy);
 | 
						|
          }
 | 
						|
          if (!error_num)
 | 
						|
          {
 | 
						|
            error_num = spider_insert_tables(table_tables, spider_share);
 | 
						|
          }
 | 
						|
 | 
						|
          spider_free_share_resource_only(spider_share);
 | 
						|
          if (error_num)
 | 
						|
            break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      spider_sys_close_table(thd, &open_tables_backup);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!error_num)
 | 
						|
    thd->clear_error();
 | 
						|
  else
 | 
						|
    DBUG_RETURN(error_num);
 | 
						|
 | 
						|
  str.length(str.length() - SPIDER_SQL_COMMA_LEN);
 | 
						|
  CHARSET_INFO *table_charset;
 | 
						|
  if (share->table_charset)
 | 
						|
  {
 | 
						|
    table_charset = share->table_charset;
 | 
						|
  } else {
 | 
						|
    table_charset = system_charset_info;
 | 
						|
  }
 | 
						|
  uint csnamelen = table_charset->cs_name.length;
 | 
						|
  uint collatelen = table_charset->coll_name.length;
 | 
						|
  if (str.reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_DEFAULT_CHARSET_LEN +
 | 
						|
    csnamelen + SPIDER_SQL_COLLATE_LEN + collatelen +
 | 
						|
    SPIDER_SQL_CONNECTION_LEN + SPIDER_SQL_VALUE_QUOTE_LEN +
 | 
						|
    (share->comment.length * 2)
 | 
						|
  )) {
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  str.q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_DEFAULT_CHARSET_STR, SPIDER_SQL_DEFAULT_CHARSET_LEN);
 | 
						|
  str.q_append(table_charset->cs_name.str, csnamelen);
 | 
						|
  str.q_append(SPIDER_SQL_COLLATE_STR, SPIDER_SQL_COLLATE_LEN);
 | 
						|
  str.q_append(table_charset->coll_name.str, collatelen);
 | 
						|
  str.q_append(SPIDER_SQL_COMMENT_STR, SPIDER_SQL_COMMENT_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
 | 
						|
  str.append_escape_string(share->comment.str, share->comment.length);
 | 
						|
  if (str.reserve(SPIDER_SQL_CONNECTION_LEN +
 | 
						|
    (SPIDER_SQL_VALUE_QUOTE_LEN * 2) +
 | 
						|
    (share->connect_string.length * 2)))
 | 
						|
  {
 | 
						|
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
  }
 | 
						|
  str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_CONNECTION_STR, SPIDER_SQL_CONNECTION_LEN);
 | 
						|
  str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
 | 
						|
  str.append_escape_string(share->connect_string.str,
 | 
						|
    share->connect_string.length);
 | 
						|
  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);
 | 
						|
  DBUG_PRINT("info",("spider part_info=%p", part_info));
 | 
						|
  if (part_info)
 | 
						|
  {
 | 
						|
    uint part_syntax_len;
 | 
						|
    char *part_syntax;
 | 
						|
    List_iterator<partition_element> part_it(part_info->partitions);
 | 
						|
    partition_element *part_elem, *sub_elem;
 | 
						|
    while ((part_elem = part_it++))
 | 
						|
    {
 | 
						|
      part_elem->engine_type = hton;
 | 
						|
      if ((part_elem)->subpartitions.elements)
 | 
						|
      {
 | 
						|
        List_iterator<partition_element> sub_it((part_elem)->subpartitions);
 | 
						|
        while ((sub_elem = sub_it++))
 | 
						|
        {
 | 
						|
          sub_elem->engine_type = hton;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (part_info->fix_parser_data(thd))
 | 
						|
    {
 | 
						|
      DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM);
 | 
						|
    }
 | 
						|
    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);
 | 
						|
    }
 | 
						|
    if (str.reserve(part_syntax_len))
 | 
						|
    {
 | 
						|
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | 
						|
    }
 | 
						|
    str.q_append(part_syntax, part_syntax_len);
 | 
						|
    SPIDER_free_part_syntax(part_syntax, MYF(0));
 | 
						|
  }
 | 
						|
  DBUG_PRINT("info",("spider str=%s", str.c_ptr_safe()));
 | 
						|
 | 
						|
  error_num = share->init_from_sql_statement_string(thd, TRUE, str.ptr(),
 | 
						|
    str.length());
 | 
						|
  DBUG_RETURN(error_num);
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
  spider_db_handler **dbton_hdl;
 | 
						|
  SPIDER_WIDE_HANDLER *wide_handler;
 | 
						|
  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 (!(need_mons = (int *)
 | 
						|
    spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_SPIDER_OBJECT_FOR_SHARE_2, MYF(MY_WME | MY_ZEROFILL),
 | 
						|
      &need_mons, (uint) (sizeof(int) * share->link_count),
 | 
						|
      &conns, (uint) (sizeof(SPIDER_CONN *) * share->link_count),
 | 
						|
      &conn_link_idx, (uint) (sizeof(uint) * share->link_count),
 | 
						|
      &conn_can_fo, (uint) (sizeof(uchar) * share->link_bitmap_size),
 | 
						|
      &conn_keys, (uint) (sizeof(char *) * share->link_count),
 | 
						|
      &dbton_hdl, (uint) (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE),
 | 
						|
      &wide_handler, (uint) sizeof(SPIDER_WIDE_HANDLER),
 | 
						|
      NullS))
 | 
						|
  )
 | 
						|
  {
 | 
						|
    error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error_need_mons_alloc;
 | 
						|
  }
 | 
						|
  DBUG_PRINT("info",("spider need_mons=%p", need_mons));
 | 
						|
  (*spider)->wide_handler = wide_handler;
 | 
						|
  wide_handler->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;
 | 
						|
  (*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_crd_threads(
 | 
						|
  SPIDER_THREAD *spider_thread,
 | 
						|
  bool is_sts
 | 
						|
) {
 | 
						|
  int error_num;
 | 
						|
  DBUG_ENTER("spider_create_sts_crd_threads");
 | 
						|
#ifdef HAVE_PSI_INTERFACE
 | 
						|
  PSI_mutex_key mutex_bg= is_sts ? spd_key_mutex_bg_stss :
 | 
						|
    spd_key_mutex_bg_crds;
 | 
						|
  PSI_cond_key cond_bg= is_sts ? spd_key_cond_bg_stss :
 | 
						|
    spd_key_cond_bg_crds;
 | 
						|
  PSI_cond_key cond_bg_syncs= is_sts ? spd_key_cond_bg_sts_syncs :
 | 
						|
    spd_key_cond_bg_crd_syncs;
 | 
						|
#endif
 | 
						|
  if (mysql_mutex_init(mutex_bg,
 | 
						|
    &spider_thread->mutex, MY_MUTEX_INIT_FAST))
 | 
						|
  {
 | 
						|
    error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error_mutex_init;
 | 
						|
  }
 | 
						|
  if (mysql_cond_init(cond_bg,
 | 
						|
    &spider_thread->cond, NULL))
 | 
						|
  {
 | 
						|
    error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error_cond_init;
 | 
						|
  }
 | 
						|
  if (mysql_cond_init(cond_bg_syncs,
 | 
						|
    &spider_thread->sync_cond, NULL))
 | 
						|
  {
 | 
						|
    error_num = HA_ERR_OUT_OF_MEM;
 | 
						|
    goto error_sync_cond_init;
 | 
						|
  }
 | 
						|
  error_num = is_sts ?
 | 
						|
    mysql_thread_create(spd_key_thd_bg_stss, &spider_thread->thread,
 | 
						|
                        &spider_pt_attr, spider_table_bg_sts_action,
 | 
						|
                        (void *) spider_thread) :
 | 
						|
    mysql_thread_create(spd_key_thd_bg_crds, &spider_thread->thread,
 | 
						|
                        &spider_pt_attr, spider_table_bg_crd_action,
 | 
						|
                        (void *) spider_thread);
 | 
						|
  if (error_num)
 | 
						|
  {
 | 
						|
    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_crd_threads(
 | 
						|
  SPIDER_THREAD *spider_thread
 | 
						|
) {
 | 
						|
  bool thread_killed;
 | 
						|
  DBUG_ENTER("spider_free_sts_crd_threads");
 | 
						|
  pthread_mutex_lock(&spider_thread->mutex);
 | 
						|
  thread_killed = spider_thread->killed;
 | 
						|
  spider_thread->killed = TRUE;
 | 
						|
  if (!thread_killed)
 | 
						|
  {
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
static void *spider_table_bg_sts_crd_action(
 | 
						|
  void *arg,
 | 
						|
  bool is_sts
 | 
						|
) {
 | 
						|
  SPIDER_THREAD *thread = (SPIDER_THREAD *) arg;
 | 
						|
  SPIDER_SHARE *share;
 | 
						|
  SPIDER_TRX *trx;
 | 
						|
  int error_num;
 | 
						|
  ha_spider *spider;
 | 
						|
  TABLE *table;                 /* only needed for crd */
 | 
						|
  SPIDER_CONN **conns;
 | 
						|
  THD *thd;
 | 
						|
  my_thread_init();
 | 
						|
  DBUG_ENTER("spider_table_bg_sts_crd_action");
 | 
						|
  /* init start */
 | 
						|
  pthread_mutex_lock(&thread->mutex);
 | 
						|
  if (!(thd = spider_create_sys_thd(thread)))
 | 
						|
  {
 | 
						|
    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_proc_info(thd, "Spider table background statistics/cardinality"
 | 
						|
                     " action handler");
 | 
						|
  if (!(trx = spider_get_trx(NULL, FALSE, &error_num)))
 | 
						|
  {
 | 
						|
    spider_destroy_sys_thd(thd);
 | 
						|
    thread->thd_wait = FALSE;
 | 
						|
    thread->killed = FALSE;
 | 
						|
    pthread_mutex_unlock(&thread->mutex);
 | 
						|
#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
 | 
						|
    set_current_thd(nullptr);
 | 
						|
#endif
 | 
						|
    my_thread_end();
 | 
						|
    DBUG_RETURN(NULL);
 | 
						|
  }
 | 
						|
  trx->thd = thd;
 | 
						|
  /* init end */
 | 
						|
 | 
						|
  if (thd->killed)
 | 
						|
  {
 | 
						|
    thread->killed = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  while (TRUE)
 | 
						|
  {
 | 
						|
    DBUG_PRINT("info",("spider bg sts/crd loop start"));
 | 
						|
    if (thread->killed)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider bg sts/crd kill start"));
 | 
						|
      trx->thd = NULL;
 | 
						|
      spider_free_trx(trx, TRUE);
 | 
						|
      spider_destroy_sys_thd(thd);
 | 
						|
      pthread_cond_signal(&thread->sync_cond);
 | 
						|
      pthread_mutex_unlock(&thread->mutex);
 | 
						|
#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
 | 
						|
      set_current_thd(nullptr);
 | 
						|
#endif
 | 
						|
      my_thread_end();
 | 
						|
      DBUG_RETURN(NULL);
 | 
						|
    }
 | 
						|
    if (!thread->queue_first)
 | 
						|
    {
 | 
						|
      DBUG_PRINT("info",("spider bg sts/crd has no job"));
 | 
						|
      thread->thd_wait = TRUE;
 | 
						|
      pthread_cond_wait(&thread->cond, &thread->mutex);
 | 
						|
      thread->thd_wait = FALSE;
 | 
						|
      if (thd->killed)
 | 
						|
        thread->killed = TRUE;
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    share = (SPIDER_SHARE *) thread->queue_first;
 | 
						|
    if (is_sts)
 | 
						|
      share->sts_working = TRUE;
 | 
						|
    else
 | 
						|
      share->crd_working = TRUE;
 | 
						|
    pthread_mutex_unlock(&thread->mutex);
 | 
						|
    table = &share->table;
 | 
						|
    if (is_sts)
 | 
						|
      spider = share->sts_spider;
 | 
						|
    else
 | 
						|
      spider = share->crd_spider;
 | 
						|
    conns = spider->conns;
 | 
						|
    if (spider->search_link_idx < 0)
 | 
						|
    {
 | 
						|
      spider->wide_handler->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)
 | 
						|
    {
 | 
						|
      double diff_time= is_sts ?
 | 
						|
        difftime(share->bg_sts_try_time, share->sts_get_time) :
 | 
						|
        difftime(share->bg_crd_try_time, share->crd_get_time);
 | 
						|
      double interval= is_sts? share->bg_sts_interval : share->bg_crd_interval;
 | 
						|
      DBUG_PRINT("info", ("spider difftime=%f", diff_time));
 | 
						|
      DBUG_PRINT("info", ("spider bg_sts_interval=%f", interval));
 | 
						|
      if (diff_time >= 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, &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])
 | 
						|
        {
 | 
						|
          int result = is_sts ?
 | 
						|
            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) :
 | 
						|
            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);
 | 
						|
          if (result)
 | 
						|
          {
 | 
						|
            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 {
 | 
						|
      if (is_sts)
 | 
						|
      {
 | 
						|
        thread->queue_first = share->sts_next;
 | 
						|
        share->sts_next->sts_prev = NULL;
 | 
						|
        share->sts_next = NULL;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        thread->queue_first = share->crd_next;
 | 
						|
        share->crd_next->crd_prev = NULL;
 | 
						|
        share->crd_next = NULL;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (is_sts)
 | 
						|
    {
 | 
						|
      share->sts_working= FALSE;
 | 
						|
      share->sts_wait= FALSE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      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);
 | 
						|
      if (thd->killed)
 | 
						|
        thread->killed = TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void *spider_table_bg_sts_action(void *arg)
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_table_bg_sts_action");
 | 
						|
  DBUG_RETURN(spider_table_bg_sts_crd_action(arg, true));
 | 
						|
}
 | 
						|
 | 
						|
void *spider_table_bg_crd_action(void *arg)
 | 
						|
{
 | 
						|
  DBUG_ENTER("spider_table_bg_crd_action");
 | 
						|
  DBUG_RETURN(spider_table_bg_sts_crd_action(arg, false));
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
uchar *spider_duplicate_char(
 | 
						|
  uchar *dst,
 | 
						|
  uchar esc,
 | 
						|
  uchar *src,
 | 
						|
  uint src_lgt
 | 
						|
) {
 | 
						|
  uchar *ed = src + src_lgt;
 | 
						|
  DBUG_ENTER("spider_duplicate_char");
 | 
						|
  while (src < ed)
 | 
						|
  {
 | 
						|
    *dst = *src;
 | 
						|
    if (*src == esc)
 | 
						|
    {
 | 
						|
      ++dst;
 | 
						|
      *dst = esc;
 | 
						|
    }
 | 
						|
    ++dst;
 | 
						|
    ++src;
 | 
						|
  }
 | 
						|
  DBUG_RETURN(dst);
 | 
						|
}
 |