mariadb/storage/spider/spd_copy_tables.cc
Jacob Mathew c10da98b62 MDEV-15698: Spider ignores syntax errors in connection string in COMMENT field
When a comma separator is missing between COMMENT fields, Spider ignores the
parameter values that are beyond the last expected parameter value.  There are
also some error messages that Spider does generate on COMMENT fields that are
incorrectly formed.

I have introduced additional infrastructure in Spider to fix these problems.

Author:
  Jacob Mathew.

Reviewer:
  Kentoku Shiba.
2018-04-24 19:41:04 -07:00

1354 lines
42 KiB
C++

/* Copyright (C) 2009-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
#else
#include "sql_priv.h"
#include "probes_mysql.h"
#include "sql_class.h"
#include "sql_base.h"
#include "sql_partition.h"
#include "transaction.h"
#endif
#include "spd_err.h"
#include "spd_param.h"
#include "spd_db_include.h"
#include "spd_include.h"
#include "ha_spider.h"
#include "spd_db_conn.h"
#include "spd_trx.h"
#include "spd_conn.h"
#include "spd_sys_table.h"
#include "spd_table.h"
#include "spd_copy_tables.h"
#include "spd_udf.h"
#include "spd_malloc.h"
extern handlerton *spider_hton_ptr;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
int spider_udf_set_copy_tables_param_default(
SPIDER_COPY_TABLES *copy_tables
) {
DBUG_ENTER("spider_udf_set_copy_tables_param_default");
if (!copy_tables->database)
{
DBUG_PRINT("info",("spider create default database"));
copy_tables->database_length = copy_tables->trx->thd->db.length;
if (
!(copy_tables->database = spider_create_string(
copy_tables->trx->thd->db.str,
copy_tables->database_length))
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
}
if (copy_tables->bulk_insert_interval == -1)
copy_tables->bulk_insert_interval = 10;
if (copy_tables->bulk_insert_rows == -1)
copy_tables->bulk_insert_rows = 100;
if (copy_tables->use_table_charset == -1)
copy_tables->use_table_charset = 1;
if (copy_tables->use_transaction == -1)
copy_tables->use_transaction = 1;
#ifndef WITHOUT_SPIDER_BG_SEARCH
if (copy_tables->bg_mode == -1)
copy_tables->bg_mode = 0;
#endif
DBUG_RETURN(0);
}
#define SPIDER_PARAM_STR_LEN(name) name ## _length
#define SPIDER_PARAM_STR(title_name, param_name) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (!copy_tables->param_name) \
{ \
if ((copy_tables->param_name = spider_get_string_between_quote( \
start_ptr, TRUE, &param_string_parse))) \
copy_tables->SPIDER_PARAM_STR_LEN(param_name) = \
strlen(copy_tables->param_name); \
else \
{ \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%s", copy_tables->param_name)); \
} \
break; \
}
#define SPIDER_PARAM_HINT_WITH_MAX(title_name, param_name, check_length, max_size, min_val, max_val) \
if (!strncasecmp(tmp_ptr, title_name, check_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
DBUG_PRINT("info",("spider max_size=%d", max_size)); \
int hint_num = atoi(tmp_ptr + check_length) - 1; \
DBUG_PRINT("info",("spider hint_num=%d", hint_num)); \
DBUG_PRINT("info",("spider copy_tables->param_name=%x", \
copy_tables->param_name)); \
if (copy_tables->param_name) \
{ \
if (hint_num < 0 || hint_num >= max_size) \
{ \
error_num = param_string_parse.print_param_error(); \
goto error; \
} else if (copy_tables->param_name[hint_num] != -1) \
break; \
char *hint_str = spider_get_string_between_quote(start_ptr, FALSE); \
if (hint_str) \
{ \
copy_tables->param_name[hint_num] = atoi(hint_str); \
if (copy_tables->param_name[hint_num] < min_val) \
copy_tables->param_name[hint_num] = min_val; \
else if (copy_tables->param_name[hint_num] > max_val) \
copy_tables->param_name[hint_num] = max_val; \
} else { \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "[%d]=%d", hint_num, \
copy_tables->param_name[hint_num])); \
} else { \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
break; \
}
#define SPIDER_PARAM_INT_WITH_MAX(title_name, param_name, min_val, max_val) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (copy_tables->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
copy_tables->param_name = atoi(tmp_ptr2); \
if (copy_tables->param_name < min_val) \
copy_tables->param_name = min_val; \
else if (copy_tables->param_name > max_val) \
copy_tables->param_name = max_val; \
param_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%d", copy_tables->param_name)); \
} \
break; \
}
#define SPIDER_PARAM_INT(title_name, param_name, min_val) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (copy_tables->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
copy_tables->param_name = atoi(tmp_ptr2); \
if (copy_tables->param_name < min_val) \
copy_tables->param_name = min_val; \
param_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%d", copy_tables->param_name)); \
} \
break; \
}
#define SPIDER_PARAM_LONGLONG(title_name, param_name, min_val) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (copy_tables->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
copy_tables->param_name = \
my_strtoll10(tmp_ptr2, (char**) NULL, &error_num); \
if (copy_tables->param_name < min_val) \
copy_tables->param_name = min_val; \
param_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%lld", \
copy_tables->param_name)); \
} \
break; \
}
int spider_udf_parse_copy_tables_param(
SPIDER_COPY_TABLES *copy_tables,
char *param,
int param_length
) {
int error_num = 0;
char *param_string = NULL;
char *sprit_ptr[2];
char *tmp_ptr, *tmp_ptr2, *start_ptr;
int title_length;
SPIDER_PARAM_STRING_PARSE param_string_parse;
DBUG_ENTER("spider_udf_parse_copy_tables_param");
copy_tables->bulk_insert_interval = -1;
copy_tables->bulk_insert_rows = -1;
copy_tables->use_table_charset = -1;
copy_tables->use_transaction = -1;
#ifndef WITHOUT_SPIDER_BG_SEARCH
copy_tables->bg_mode = -1;
#endif
if (param_length == 0)
goto set_default;
DBUG_PRINT("info",("spider create param_string string"));
if (
!(param_string = spider_create_string(
param,
param_length))
) {
error_num = HA_ERR_OUT_OF_MEM;
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error_alloc_param_string;
}
DBUG_PRINT("info",("spider param_string=%s", param_string));
sprit_ptr[0] = param_string;
param_string_parse.init(param_string, ER_SPIDER_INVALID_UDF_PARAM_NUM);
while (sprit_ptr[0])
{
if ((sprit_ptr[1] = strchr(sprit_ptr[0], ',')))
{
*sprit_ptr[1] = '\0';
sprit_ptr[1]++;
}
tmp_ptr = sprit_ptr[0];
sprit_ptr[0] = sprit_ptr[1];
while (*tmp_ptr == ' ' || *tmp_ptr == '\r' ||
*tmp_ptr == '\n' || *tmp_ptr == '\t')
tmp_ptr++;
if (*tmp_ptr == '\0')
continue;
title_length = 0;
start_ptr = tmp_ptr;
while (*start_ptr != ' ' && *start_ptr != '\'' &&
*start_ptr != '"' && *start_ptr != '\0' &&
*start_ptr != '\r' && *start_ptr != '\n' &&
*start_ptr != '\t')
{
title_length++;
start_ptr++;
}
param_string_parse.set_param_title(tmp_ptr, tmp_ptr + title_length);
switch (title_length)
{
case 0:
error_num = param_string_parse.print_param_error();
if (error_num)
goto error;
continue;
case 3:
#ifndef WITHOUT_SPIDER_BG_SEARCH
SPIDER_PARAM_INT_WITH_MAX("bgm", bg_mode, 0, 1);
#endif
SPIDER_PARAM_INT("bii", bulk_insert_interval, 0);
SPIDER_PARAM_LONGLONG("bir", bulk_insert_rows, 1);
SPIDER_PARAM_STR("dtb", database);
SPIDER_PARAM_INT_WITH_MAX("utc", use_table_charset, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("utr", use_transaction, 0, 1);
error_num = param_string_parse.print_param_error();
goto error;
#ifndef WITHOUT_SPIDER_BG_SEARCH
case 7:
SPIDER_PARAM_INT_WITH_MAX("bg_mode", bg_mode, 0, 1);
error_num = param_string_parse.print_param_error();
goto error;
#endif
case 8:
SPIDER_PARAM_STR("database", database);
error_num = param_string_parse.print_param_error();
goto error;
case 15:
SPIDER_PARAM_INT_WITH_MAX("use_transaction", use_transaction, 0, 1);
error_num = param_string_parse.print_param_error();
goto error;
case 16:
SPIDER_PARAM_LONGLONG("bulk_insert_rows", bulk_insert_rows, 1);
error_num = param_string_parse.print_param_error();
goto error;
case 17:
SPIDER_PARAM_INT_WITH_MAX(
"use_table_charset", use_table_charset, 0, 1);
error_num = param_string_parse.print_param_error();
goto error;
case 20:
SPIDER_PARAM_INT("bulk_insert_interval", bulk_insert_interval, 0);
error_num = param_string_parse.print_param_error();
goto error;
default:
error_num = param_string_parse.print_param_error();
goto error;
}
/* Verify that the remainder of the parameter value is whitespace */
if ((error_num = param_string_parse.has_extra_parameter_values()))
goto error;
}
set_default:
if ((error_num = spider_udf_set_copy_tables_param_default(
copy_tables
)))
goto error;
if (param_string)
spider_free(spider_current_trx, param_string, MYF(0));
DBUG_RETURN(0);
error:
if (param_string)
spider_free(spider_current_trx, param_string, MYF(0));
error_alloc_param_string:
DBUG_RETURN(error_num);
}
int spider_udf_get_copy_tgt_tables(
THD *thd,
SPIDER_COPY_TABLES *copy_tables,
MEM_ROOT *mem_root,
bool need_lock
) {
int error_num, roop_count;
TABLE *table_tables = NULL;
#if MYSQL_VERSION_ID < 50500
Open_tables_state open_tables_backup;
#else
Open_tables_backup open_tables_backup;
#endif
char table_key[MAX_KEY_LENGTH];
SPIDER_COPY_TABLE_CONN *table_conn = NULL, *src_table_conn_prev = NULL,
*dst_table_conn_prev = NULL;
SPIDER_SHARE *tmp_share;
char **tmp_connect_info;
uint *tmp_connect_info_length;
long *tmp_long;
longlong *tmp_longlong;
DBUG_ENTER("spider_udf_get_copy_tgt_tables");
if (
!(table_tables = spider_open_sys_table(
thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup,
need_lock, &error_num))
) {
my_error(error_num, MYF(0));
goto error;
}
spider_store_db_and_table_name(table_tables,
copy_tables->spider_db_name, copy_tables->spider_db_name_length,
copy_tables->spider_table_name, copy_tables->spider_table_name_length
);
if ((error_num = spider_get_sys_table_by_idx(table_tables, table_key,
table_tables->s->primary_key, 2)))
{
table_tables->file->print_error(error_num, MYF(0));
goto error;
}
do {
if (!(table_conn = (SPIDER_COPY_TABLE_CONN *)
spider_bulk_malloc(spider_current_trx, 25, MYF(MY_WME | MY_ZEROFILL),
&table_conn, sizeof(SPIDER_COPY_TABLE_CONN),
&tmp_share, sizeof(SPIDER_SHARE),
&tmp_connect_info, sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT,
&tmp_connect_info_length, sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT,
&tmp_long, sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT,
&tmp_longlong, sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT,
NullS))
) {
spider_sys_index_end(table_tables);
error_num = HA_ERR_OUT_OF_MEM;
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
goto error;
}
spider_set_tmp_share_pointer(tmp_share, tmp_connect_info,
tmp_connect_info_length, tmp_long, tmp_longlong);
tmp_share->link_statuses[0] = -1;
table_conn->share = tmp_share;
if (
(error_num = spider_get_sys_tables_connect_info(
table_tables, tmp_share, 0, mem_root)) ||
(error_num = spider_get_sys_tables_link_status(
table_tables, tmp_share, 0, mem_root)) ||
(error_num = spider_get_sys_tables_link_idx(
table_tables, &table_conn->link_idx, mem_root))
) {
table_tables->file->print_error(error_num, MYF(0));
spider_sys_index_end(table_tables);
goto error;
}
if (
(error_num = spider_set_connect_info_default(
tmp_share,
#ifdef WITH_PARTITION_STORAGE_ENGINE
NULL,
NULL,
#endif
NULL
)) ||
(error_num = spider_set_connect_info_default_db_table(
tmp_share,
copy_tables->spider_db_name, copy_tables->spider_db_name_length,
copy_tables->spider_table_name, copy_tables->spider_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);
goto error;
}
/*
if (spider_db_create_table_names_str(tmp_share))
{
spider_sys_index_end(table_tables);
error_num = HA_ERR_OUT_OF_MEM;
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
goto error;
}
*/
for (roop_count = 0; roop_count < (int) tmp_share->use_dbton_count;
roop_count++)
{
uint dbton_id = tmp_share->use_dbton_ids[roop_count];
if (!spider_dbton[dbton_id].create_db_copy_table)
continue;
if (!(table_conn->copy_table =
spider_dbton[dbton_id].create_db_copy_table(
tmp_share->dbton_share[dbton_id])))
{
spider_sys_index_end(table_tables);
error_num = HA_ERR_OUT_OF_MEM;
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
goto error;
}
if ((error_num = table_conn->copy_table->init()))
goto error;
break;
}
if (
!copy_tables->use_auto_mode[0]
) {
for (roop_count = 0; roop_count < copy_tables->link_idx_count[0];
roop_count++)
{
if (table_conn->link_idx == copy_tables->link_idxs[0][roop_count])
{
if (tmp_share->link_statuses[0] == SPIDER_LINK_STATUS_NG)
{
spider_sys_index_end(table_tables);
error_num = ER_SPIDER_UDF_COPY_TABLE_SRC_NG_STATUS_NUM;
my_printf_error(ER_SPIDER_UDF_COPY_TABLE_SRC_NG_STATUS_NUM,
ER_SPIDER_UDF_COPY_TABLE_SRC_NG_STATUS_STR, MYF(0));
goto error;
}
if (src_table_conn_prev)
src_table_conn_prev->next = table_conn;
else
copy_tables->table_conn[0] = table_conn;
src_table_conn_prev = table_conn;
table_conn = NULL;
break;
}
}
}
if (table_conn && !copy_tables->use_auto_mode[1])
{
for (roop_count = 0; roop_count < copy_tables->link_idx_count[1];
roop_count++)
{
if (table_conn->link_idx == copy_tables->link_idxs[1][roop_count])
{
if (tmp_share->link_statuses[0] == SPIDER_LINK_STATUS_NG)
{
spider_sys_index_end(table_tables);
error_num = ER_SPIDER_UDF_COPY_TABLE_SRC_NG_STATUS_NUM;
my_printf_error(ER_SPIDER_UDF_COPY_TABLE_SRC_NG_STATUS_NUM,
ER_SPIDER_UDF_COPY_TABLE_SRC_NG_STATUS_STR, MYF(0));
goto error;
}
if (dst_table_conn_prev)
dst_table_conn_prev->next = table_conn;
else
copy_tables->table_conn[1] = table_conn;
dst_table_conn_prev = table_conn;
table_conn = NULL;
break;
}
}
}
if (table_conn && copy_tables->use_auto_mode[0] &&
tmp_share->link_statuses[0] == SPIDER_LINK_STATUS_OK)
{
if (src_table_conn_prev)
src_table_conn_prev->next = table_conn;
else
copy_tables->table_conn[0] = table_conn;
src_table_conn_prev = table_conn;
copy_tables->link_idx_count[0]++;
table_conn = NULL;
}
if (table_conn && copy_tables->use_auto_mode[1] &&
tmp_share->link_statuses[0] == SPIDER_LINK_STATUS_RECOVERY)
{
if (dst_table_conn_prev)
dst_table_conn_prev->next = table_conn;
else
copy_tables->table_conn[1] = table_conn;
dst_table_conn_prev = table_conn;
copy_tables->link_idx_count[1]++;
table_conn = NULL;
}
if (table_conn)
{
spider_free_tmp_dbton_share(tmp_share);
spider_free_tmp_share_alloc(tmp_share);
if (table_conn->copy_table)
delete table_conn->copy_table;
spider_free(spider_current_trx, table_conn, MYF(0));
table_conn = NULL;
}
error_num = spider_sys_index_next_same(table_tables, table_key);
} while (error_num == 0);
spider_sys_index_end(table_tables);
spider_close_sys_table(thd, table_tables,
&open_tables_backup, need_lock);
table_tables = NULL;
if (!copy_tables->table_conn[0])
{
error_num = ER_SPIDER_UDF_COPY_TABLE_SRC_NOT_FOUND_NUM;
my_printf_error(ER_SPIDER_UDF_COPY_TABLE_SRC_NOT_FOUND_NUM,
ER_SPIDER_UDF_COPY_TABLE_SRC_NOT_FOUND_STR, MYF(0));
goto error;
}
if (!copy_tables->table_conn[1])
{
error_num = ER_SPIDER_UDF_COPY_TABLE_DST_NOT_FOUND_NUM;
my_printf_error(ER_SPIDER_UDF_COPY_TABLE_DST_NOT_FOUND_NUM,
ER_SPIDER_UDF_COPY_TABLE_DST_NOT_FOUND_STR, MYF(0));
goto error;
}
DBUG_RETURN(0);
error:
if (table_tables)
spider_close_sys_table(thd, table_tables,
&open_tables_backup, need_lock);
if (table_conn)
{
spider_free_tmp_dbton_share(tmp_share);
spider_free_tmp_share_alloc(tmp_share);
if (table_conn->copy_table)
delete table_conn->copy_table;
spider_free(spider_current_trx, table_conn, MYF(0));
}
DBUG_RETURN(error_num);
}
int spider_udf_get_copy_tgt_conns(
SPIDER_COPY_TABLES *copy_tables
) {
int error_num, roop_count;
SPIDER_TRX *trx = copy_tables->trx;
SPIDER_SHARE *share;
SPIDER_COPY_TABLE_CONN *table_conn;
DBUG_ENTER("spider_udf_get_copy_tgt_conns");
for (roop_count = 0; roop_count < 2; roop_count++)
{
table_conn = copy_tables->table_conn[roop_count];
while (table_conn)
{
share = table_conn->share;
if (
!(table_conn->conn = spider_get_conn(
share, 0, share->conn_keys[0], trx, NULL, FALSE, FALSE,
SPIDER_CONN_KIND_MYSQL, &error_num))
) {
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), share->server_names[0]);
DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE);
}
table_conn->conn->error_mode = 0;
table_conn = table_conn->next;
}
}
DBUG_RETURN(0);
}
void spider_udf_free_copy_tables_alloc(
SPIDER_COPY_TABLES *copy_tables
) {
int roop_count;
SPIDER_COPY_TABLE_CONN *table_conn, *table_conn_next;
DBUG_ENTER("spider_udf_free_copy_tables_alloc");
for (roop_count = 0; roop_count < 2; roop_count++)
{
table_conn = copy_tables->table_conn[roop_count];
while (table_conn)
{
table_conn_next = table_conn->next;
spider_free_tmp_dbton_share(table_conn->share);
spider_free_tmp_share_alloc(table_conn->share);
if (table_conn->copy_table)
delete table_conn->copy_table;
spider_free(spider_current_trx, table_conn, MYF(0));
table_conn = table_conn_next;
}
}
if (copy_tables->link_idxs[0])
spider_free(spider_current_trx, copy_tables->link_idxs[0], MYF(0));
if (copy_tables->database)
spider_free(spider_current_trx, copy_tables->database, MYF(0));
spider_free(spider_current_trx, copy_tables, MYF(0));
DBUG_VOID_RETURN;
}
int spider_udf_copy_tables_create_table_list(
SPIDER_COPY_TABLES *copy_tables,
char *spider_table_name,
uint spider_table_name_length,
char *src_link_idx_list,
uint src_link_idx_list_length,
char *dst_link_idx_list,
uint dst_link_idx_list_length
) {
int roop_count, roop_count2, length;
char *tmp_ptr, *tmp_ptr2, *tmp_ptr3, *tmp_name_ptr;
DBUG_ENTER("spider_udf_copy_tables_create_table_list");
if (!spider_table_name_length)
{
my_printf_error(ER_SPIDER_BLANK_UDF_ARGUMENT_NUM,
ER_SPIDER_BLANK_UDF_ARGUMENT_STR, MYF(0), 1);
DBUG_RETURN(ER_SPIDER_BLANK_UDF_ARGUMENT_NUM);
}
for (roop_count2 = 0; roop_count2 < 2; roop_count2++)
{
if (roop_count2 == 0)
tmp_ptr = src_link_idx_list;
else
tmp_ptr = dst_link_idx_list;
while (*tmp_ptr == ' ')
tmp_ptr++;
if (*tmp_ptr)
copy_tables->link_idx_count[roop_count2] = 1;
else {
/* use auto detect */
copy_tables->use_auto_mode[roop_count2] = TRUE;
copy_tables->link_idx_count[roop_count2] = 0;
continue;
}
while (TRUE)
{
if ((tmp_ptr2 = strchr(tmp_ptr, ' ')))
{
copy_tables->link_idx_count[roop_count2]++;
tmp_ptr = tmp_ptr2 + 1;
while (*tmp_ptr == ' ')
tmp_ptr++;
} else
break;
}
}
if (!(copy_tables->link_idxs[0] = (int *)
spider_bulk_malloc(spider_current_trx, 26, MYF(MY_WME | MY_ZEROFILL),
&copy_tables->link_idxs[0],
sizeof(int) * copy_tables->link_idx_count[0],
&copy_tables->link_idxs[1],
sizeof(int) * copy_tables->link_idx_count[1],
&tmp_name_ptr, sizeof(char) * (
spider_table_name_length * 2 + copy_tables->database_length + 3
),
NullS))
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
copy_tables->spider_db_name = tmp_name_ptr;
if ((tmp_ptr3 = strchr(spider_table_name, '.')))
{
/* exist database name */
*tmp_ptr3 = '\0';
length = strlen(spider_table_name);
memcpy(tmp_name_ptr, spider_table_name, length + 1);
copy_tables->spider_db_name_length = length;
tmp_name_ptr += length + 1;
tmp_ptr3++;
} else {
memcpy(tmp_name_ptr, copy_tables->database,
copy_tables->database_length + 1);
copy_tables->spider_db_name_length = copy_tables->database_length;
tmp_name_ptr += copy_tables->database_length + 1;
tmp_ptr3 = spider_table_name;
length = -1;
}
copy_tables->spider_table_name = tmp_name_ptr;
length = spider_table_name_length - length - 1;
memcpy(tmp_name_ptr, tmp_ptr3, length + 1);
copy_tables->spider_table_name_length = length;
tmp_name_ptr += length + 1;
memcpy(tmp_name_ptr, tmp_ptr3, length + 1);
copy_tables->spider_real_table_name = tmp_name_ptr;
if ((tmp_ptr2 = strstr(tmp_name_ptr, "#P#")))
{
*tmp_ptr2 = '\0';
copy_tables->spider_real_table_name_length = strlen(tmp_name_ptr);
} else
copy_tables->spider_real_table_name_length = length;
DBUG_PRINT("info",("spider spider_db=%s", copy_tables->spider_db_name));
DBUG_PRINT("info",("spider spider_table_name=%s",
copy_tables->spider_table_name));
DBUG_PRINT("info",("spider spider_real_table_name=%s",
copy_tables->spider_real_table_name));
for (roop_count2 = 0; roop_count2 < 2; roop_count2++)
{
if (roop_count2 == 0)
tmp_ptr = src_link_idx_list;
else
tmp_ptr = dst_link_idx_list;
while (*tmp_ptr == ' ')
tmp_ptr++;
roop_count = 0;
while (*tmp_ptr)
{
if ((tmp_ptr2 = strchr(tmp_ptr, ' ')))
*tmp_ptr2 = '\0';
copy_tables->link_idxs[roop_count2][roop_count] = atoi(tmp_ptr);
DBUG_PRINT("info",("spider link_idx[%d][%d]=%d",
roop_count2, roop_count,
copy_tables->link_idxs[roop_count2][roop_count]));
if (!tmp_ptr2)
break;
tmp_ptr = tmp_ptr2 + 1;
while (*tmp_ptr == ' ')
tmp_ptr++;
roop_count++;
}
}
DBUG_RETURN(0);
}
#ifndef WITHOUT_SPIDER_BG_SEARCH
int spider_udf_bg_copy_exec_sql(
SPIDER_COPY_TABLE_CONN *table_conn
) {
int error_num;
SPIDER_CONN *conn = table_conn->conn;
ha_spider *spider = table_conn->spider;
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
DBUG_ENTER("spider_udf_bg_copy_exec_sql");
if ((error_num = spider_create_conn_thread(conn)))
DBUG_RETURN(error_num);
if ((error_num = dbton_hdl->set_sql_for_exec(table_conn->copy_table,
SPIDER_SQL_TYPE_INSERT_SQL)))
DBUG_RETURN(error_num);
pthread_mutex_lock(&conn->bg_conn_mutex);
conn->bg_target = spider;
conn->bg_error_num = &table_conn->bg_error_num;
conn->bg_sql_type = SPIDER_SQL_TYPE_INSERT_SQL;
conn->link_idx = 0;
conn->bg_exec_sql = TRUE;
conn->bg_caller_sync_wait = TRUE;
pthread_mutex_lock(&conn->bg_conn_sync_mutex);
pthread_cond_signal(&conn->bg_conn_cond);
pthread_mutex_unlock(&conn->bg_conn_mutex);
pthread_cond_wait(&conn->bg_conn_sync_cond, &conn->bg_conn_sync_mutex);
pthread_mutex_unlock(&conn->bg_conn_sync_mutex);
conn->bg_caller_sync_wait = FALSE;
DBUG_RETURN(0);
}
#endif
long long spider_copy_tables_body(
UDF_INIT *initid,
UDF_ARGS *args,
char *is_null,
char *error
) {
int error_num, roop_count, all_link_cnt = 0, use_table_charset;
SPIDER_COPY_TABLES *copy_tables = NULL;
THD *thd = current_thd;
TABLE_LIST *table_list = NULL;
TABLE *table;
TABLE_SHARE *table_share;
KEY *key_info;
ha_spider *spider = NULL, *tmp_spider;
spider_string *tmp_sql = NULL;
SPIDER_COPY_TABLE_CONN *table_conn, *src_tbl_conn, *dst_tbl_conn;
SPIDER_CONN *tmp_conn;
spider_db_copy_table *select_ct, *insert_ct;
MEM_ROOT mem_root;
longlong bulk_insert_rows;
Reprepare_observer *reprepare_observer_backup;
uint tmp_conn_link_idx = 0;
DBUG_ENTER("spider_copy_tables_body");
if (
thd->open_tables != 0 ||
thd->handler_tables_hash.records != 0 ||
thd->derived_tables != 0 ||
thd->lock != 0 ||
#if MYSQL_VERSION_ID < 50500
thd->locked_tables != 0 ||
thd->prelocked_mode != NON_PRELOCKED
#else
thd->locked_tables_list.locked_tables() ||
thd->locked_tables_mode != LTM_NONE
#endif
) {
if (thd->open_tables != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->open_tables", thd->open_tables);
} else if (thd->handler_tables_hash.records != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0),
"thd->handler_tables_hash.records",
(longlong) thd->handler_tables_hash.records);
} else if (thd->derived_tables != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->derived_tables", thd->derived_tables);
} else if (thd->lock != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->lock", thd->lock);
#if MYSQL_VERSION_ID < 50500
} else if (thd->locked_tables != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->locked_tables", thd->locked_tables);
} else if (thd->prelocked_mode != NON_PRELOCKED)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0),
"thd->prelocked_mode", (longlong) thd->prelocked_mode);
#else
} else if (thd->locked_tables_list.locked_tables())
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->locked_tables_list.locked_tables()",
thd->locked_tables_list.locked_tables());
} else if (thd->locked_tables_mode != LTM_NONE)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0),
"thd->locked_tables_mode", (longlong) thd->locked_tables_mode);
#endif
}
goto error;
}
if (!(copy_tables = (SPIDER_COPY_TABLES *)
spider_bulk_malloc(spider_current_trx, 27, MYF(MY_WME | MY_ZEROFILL),
&copy_tables, sizeof(SPIDER_COPY_TABLES),
NullS))
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
if (!(copy_tables->trx = spider_get_trx(thd, TRUE, &error_num)))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
if (args->arg_count == 4)
{
if (spider_udf_parse_copy_tables_param(
copy_tables,
args->args[3] ? args->args[3] : (char *) "",
args->args[3] ? args->lengths[3] : 0
))
goto error;
} else {
if (spider_udf_parse_copy_tables_param(
copy_tables,
(char *) "",
0
))
goto error;
}
if (
spider_udf_copy_tables_create_table_list(
copy_tables,
args->args[0],
args->lengths[0],
args->args[1] ? args->args[1] : (char *) "",
args->args[1] ? args->lengths[1] : 0,
args->args[2] ? args->args[2] : (char *) "",
args->args[2] ? args->lengths[2] : 0
)
)
goto error;
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
if (
spider_udf_get_copy_tgt_tables(
thd,
copy_tables,
&mem_root,
TRUE
)
) {
free_root(&mem_root, MYF(0));
goto error;
}
free_root(&mem_root, MYF(0));
if (
spider_udf_get_copy_tgt_conns(copy_tables)
)
goto error;
table_list = &copy_tables->spider_table_list;
table_list->db.str = copy_tables->spider_db_name;
table_list->db.length = copy_tables->spider_db_name_length;
table_list->alias.str = table_list->table_name.str =
copy_tables->spider_real_table_name;
table_list->table_name.length = copy_tables->spider_real_table_name_length;
table_list->alias.length= table_list->table_name.length;
table_list->lock_type = TL_READ;
DBUG_PRINT("info",("spider db=%s", table_list->db.str));
DBUG_PRINT("info",("spider db_length=%zd", table_list->db.length));
DBUG_PRINT("info",("spider table_name=%s", table_list->table_name.str));
DBUG_PRINT("info",("spider table_name_length=%zd",
table_list->table_name.length));
reprepare_observer_backup = thd->m_reprepare_observer;
thd->m_reprepare_observer = NULL;
copy_tables->trx->trx_start = TRUE;
copy_tables->trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
#if MYSQL_VERSION_ID < 50500
if (open_and_lock_tables(thd, table_list))
#else
table_list->mdl_request.init(
MDL_key::TABLE,
table_list->db.str,
table_list->table_name.str,
MDL_SHARED_READ,
MDL_TRANSACTION
);
if (open_and_lock_tables(thd, table_list, FALSE, 0))
#endif
{
thd->m_reprepare_observer = reprepare_observer_backup;
copy_tables->trx->trx_start = FALSE;
copy_tables->trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
my_printf_error(ER_SPIDER_UDF_CANT_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_OPEN_TABLE_STR, MYF(0), table_list->db,
table_list->table_name);
goto error;
}
thd->m_reprepare_observer = reprepare_observer_backup;
copy_tables->trx->trx_start = FALSE;
copy_tables->trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
table = table_list->table;
table_share = table->s;
if (table_share->primary_key == MAX_KEY)
{
my_printf_error(ER_SPIDER_UDF_COPY_TABLE_NEED_PK_NUM,
ER_SPIDER_UDF_COPY_TABLE_NEED_PK_STR, MYF(0),
table_list->db, table_list->table_name);
goto error;
}
key_info = &table->key_info[table_share->primary_key];
use_table_charset = spider_param_use_table_charset(
copy_tables->use_table_charset);
if (use_table_charset)
copy_tables->access_charset = table_share->table_charset;
else
copy_tables->access_charset = system_charset_info;
bulk_insert_rows = spider_param_udf_ct_bulk_insert_rows(
copy_tables->bulk_insert_rows);
for (src_tbl_conn = copy_tables->table_conn[0]; src_tbl_conn;
src_tbl_conn = src_tbl_conn->next)
{
select_ct = src_tbl_conn->copy_table;
src_tbl_conn->share->access_charset = copy_tables->access_charset;
select_ct->set_sql_charset(copy_tables->access_charset);
if (
select_ct->append_select_str() ||
select_ct->append_table_columns(table_share)
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
if (
select_ct->append_from_str() ||
select_ct->append_table_name(0)
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
select_ct->set_sql_pos();
if (
select_ct->append_key_order_str(key_info, 0, FALSE) ||
select_ct->append_limit(0, bulk_insert_rows)
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
if (
copy_tables->use_transaction &&
select_ct->append_select_lock_str(SPIDER_LOCK_MODE_SHARED)
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
}
for (dst_tbl_conn = copy_tables->table_conn[1]; dst_tbl_conn;
dst_tbl_conn = dst_tbl_conn->next)
{
insert_ct = dst_tbl_conn->copy_table;
dst_tbl_conn->share->access_charset = copy_tables->access_charset;
insert_ct->set_sql_charset(copy_tables->access_charset);
if (
insert_ct->append_insert_str(SPIDER_DB_INSERT_IGNORE) ||
insert_ct->append_into_str() ||
insert_ct->append_table_name(0) ||
insert_ct->append_open_paren_str() ||
insert_ct->append_table_columns(table_share) ||
insert_ct->append_values_str()
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
insert_ct->set_sql_pos();
}
all_link_cnt =
copy_tables->link_idx_count[0] + copy_tables->link_idx_count[1];
if (
!(tmp_sql = new spider_string[all_link_cnt]) ||
!(spider = new ha_spider[all_link_cnt])
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
for (roop_count = 0; roop_count < all_link_cnt; roop_count++)
{
spider[roop_count].conns = NULL;
spider[roop_count].change_table_ptr(table, table_share);
}
for (roop_count = 0, table_conn = copy_tables->table_conn[0];
table_conn; roop_count++, table_conn = table_conn->next)
{
tmp_spider = &spider[roop_count];
if (!(tmp_spider->dbton_handler = (spider_db_handler **)
spider_bulk_alloc_mem(spider_current_trx, 205,
__func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL),
&tmp_spider->dbton_handler,
sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE,
NullS))
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
tmp_spider->share = table_conn->share;
tmp_spider->trx = copy_tables->trx;
/*
if (spider_db_append_set_names(table_conn->share))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error_append_set_names;
}
*/
tmp_spider->conns = &table_conn->conn;
tmp_sql[roop_count].init_calc_mem(122);
tmp_sql[roop_count].set_charset(copy_tables->access_charset);
tmp_spider->result_list.sqls = &tmp_sql[roop_count];
tmp_spider->need_mons = &table_conn->need_mon;
tmp_spider->lock_type = TL_READ;
tmp_spider->conn_link_idx = &tmp_conn_link_idx;
uint dbton_id = tmp_spider->share->use_dbton_ids[0];
if (!(tmp_spider->dbton_handler[dbton_id] =
spider_dbton[dbton_id].create_db_handler(tmp_spider,
tmp_spider->share->dbton_share[dbton_id])))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error_create_dbton_handler;
}
if ((error_num = tmp_spider->dbton_handler[dbton_id]->init()))
{
goto error_init_dbton_handler;
}
table_conn->spider = tmp_spider;
}
for (table_conn = copy_tables->table_conn[1];
table_conn; roop_count++, table_conn = table_conn->next)
{
tmp_spider = &spider[roop_count];
if (!(tmp_spider->dbton_handler = (spider_db_handler **)
spider_bulk_alloc_mem(spider_current_trx, 206,
__func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL),
&tmp_spider->dbton_handler,
sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE,
NullS))
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error;
}
tmp_spider->share = table_conn->share;
tmp_spider->trx = copy_tables->trx;
/*
if (spider_db_append_set_names(table_conn->share))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error_append_set_names;
}
*/
tmp_spider->conns = &table_conn->conn;
tmp_sql[roop_count].init_calc_mem(201);
tmp_sql[roop_count].set_charset(copy_tables->access_charset);
tmp_spider->result_list.sqls = &tmp_sql[roop_count];
tmp_spider->need_mons = &table_conn->need_mon;
tmp_spider->lock_type = TL_WRITE;
tmp_spider->conn_link_idx = &tmp_conn_link_idx;
uint dbton_id = tmp_spider->share->use_dbton_ids[0];
if (!(tmp_spider->dbton_handler[dbton_id] =
spider_dbton[dbton_id].create_db_handler(tmp_spider,
tmp_spider->share->dbton_share[dbton_id])))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error_create_dbton_handler;
}
if ((error_num = tmp_spider->dbton_handler[dbton_id]->init()))
{
goto error_init_dbton_handler;
}
table_conn->spider = tmp_spider;
}
if ((error_num = spider_db_udf_copy_tables(copy_tables, spider, table,
bulk_insert_rows)))
goto error_db_udf_copy_tables;
/*
for (table_conn = copy_tables->table_conn[0];
table_conn; table_conn = table_conn->next)
spider_db_free_set_names(table_conn->share);
for (table_conn = copy_tables->table_conn[1];
table_conn; table_conn = table_conn->next)
spider_db_free_set_names(table_conn->share);
*/
if (table_list->table)
{
#if MYSQL_VERSION_ID < 50500
ha_autocommit_or_rollback(thd, 0);
#else
(thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
#endif
close_thread_tables(thd);
}
if (spider)
{
for (roop_count = 0; roop_count < all_link_cnt; roop_count++)
{
if (spider[roop_count].share && spider[roop_count].dbton_handler)
{
uint dbton_id = spider[roop_count].share->use_dbton_ids[0];
if (spider[roop_count].dbton_handler[dbton_id])
delete spider[roop_count].dbton_handler[dbton_id];
spider_free(spider_current_trx, spider[roop_count].dbton_handler,
MYF(0));
}
}
delete [] spider;
}
if (tmp_sql)
delete [] tmp_sql;
spider_udf_free_copy_tables_alloc(copy_tables);
DBUG_RETURN(1);
error_db_udf_copy_tables:
error_create_dbton_handler:
error_init_dbton_handler:
/*
error_append_set_names:
*/
/*
for (table_conn = copy_tables->table_conn[0];
table_conn; table_conn = table_conn->next)
spider_db_free_set_names(table_conn->share);
for (table_conn = copy_tables->table_conn[1];
table_conn; table_conn = table_conn->next)
spider_db_free_set_names(table_conn->share);
*/
error:
if (spider)
{
for (roop_count = 0; roop_count < all_link_cnt; roop_count++)
{
tmp_spider = &spider[roop_count];
if (tmp_spider->conns)
{
tmp_conn = tmp_spider->conns[0];
if (tmp_conn && tmp_conn->db_conn &&
tmp_conn->db_conn->get_lock_table_hash_count()
) {
tmp_conn->db_conn->reset_lock_table_hash();
tmp_conn->table_lock = 0;
}
}
}
}
if (table_list && table_list->table)
{
#if MYSQL_VERSION_ID < 50500
ha_autocommit_or_rollback(thd, 0);
#else
(thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
#endif
close_thread_tables(thd);
}
if (spider)
{
for (roop_count = 0; roop_count < all_link_cnt; roop_count++)
{
tmp_spider = &spider[roop_count];
if (tmp_spider->share && spider[roop_count].dbton_handler)
{
uint dbton_id = tmp_spider->share->use_dbton_ids[0];
if (tmp_spider->dbton_handler[dbton_id])
delete tmp_spider->dbton_handler[dbton_id];
spider_free(spider_current_trx, spider[roop_count].dbton_handler,
MYF(0));
}
}
delete [] spider;
}
if (tmp_sql)
{
delete [] tmp_sql;
}
if (copy_tables)
{
spider_udf_free_copy_tables_alloc(copy_tables);
}
*error = 1;
DBUG_RETURN(0);
}
my_bool spider_copy_tables_init_body(
UDF_INIT *initid,
UDF_ARGS *args,
char *message
) {
DBUG_ENTER("spider_copy_tables_init_body");
if (args->arg_count != 3 && args->arg_count != 4)
{
strcpy(message, "spider_copy_tables() requires 3 or 4 arguments");
goto error;
}
if (
args->arg_type[0] != STRING_RESULT ||
args->arg_type[1] != STRING_RESULT ||
args->arg_type[2] != STRING_RESULT ||
(
args->arg_count == 4 &&
args->arg_type[3] != STRING_RESULT
)
) {
strcpy(message, "spider_copy_tables() requires string arguments");
goto error;
}
DBUG_RETURN(FALSE);
error:
DBUG_RETURN(TRUE);
}
void spider_copy_tables_deinit_body(
UDF_INIT *initid
) {
int error_num;
THD *thd = current_thd;
SPIDER_TRX *trx;
DBUG_ENTER("spider_copy_tables_deinit_body");
if (
!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) &&
(trx = spider_get_trx(thd, TRUE, &error_num))
)
spider_copy_table_free_trx_conn(trx);
DBUG_VOID_RETURN;
}