mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 01:34:17 +01:00
e1d31a10af
The existing (incorrect) overriding mechanism is: Non-minus-one var value overrides table param overrides default value. Before MDEV-27169, unspecified var value is -1. So if the user sets both the var to be a value other than -1 and the table param, the var value will prevail, which is incorrect. After MDEV-27169, unspecified var value is default value. So if the user does not set the var but sets the table param, the default value will prevail, which is even more incorrect. This patch fixes it so that table param, if specified, always overrides var value, and the latter if not specified or set to -1, falls back to the default value We achieve this by replacing all such overriding in spd_param.cc with macros that override in the correct way, and removing all the "overriding -1" lines involving table params in spider_set_connect_info_default() except for those table params not defined as sysvar/thdvar in spd_params.cc We also introduced macros for non-overriding sysvar and thdvar, so that the code is cleaner and less error-prone In server versions where MDEV-27169 has not been applied, we also backport the patch, that is, replacing -1 default values with real default values In server versions where MDEV-28006 has not been applied, we do the same for udf params
1354 lines
42 KiB
C++
1354 lines
42 KiB
C++
/* Copyright (C) 2009-2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 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 = SPIDER_THD_db_length(copy_tables->trx->thd);
|
|
if (
|
|
!(copy_tables->database = spider_create_string(
|
|
SPIDER_THD_db_str(copy_tables->trx->thd),
|
|
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->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, ¶m_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;
|
|
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 = param_string;
|
|
param_string_parse.init(param_string, ER_SPIDER_INVALID_UDF_PARAM_NUM);
|
|
while (sprit_ptr)
|
|
{
|
|
tmp_ptr = sprit_ptr;
|
|
while (*tmp_ptr == ' ' || *tmp_ptr == '\r' ||
|
|
*tmp_ptr == '\n' || *tmp_ptr == '\t')
|
|
tmp_ptr++;
|
|
|
|
if (*tmp_ptr == '\0')
|
|
break;
|
|
|
|
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);
|
|
if ((error_num = param_string_parse.get_next_parameter_head(
|
|
start_ptr, &sprit_ptr)))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
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),
|
|
©_tables->link_idxs[0],
|
|
sizeof(int) * copy_tables->link_idx_count[0],
|
|
©_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),
|
|
©_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 = ©_tables->spider_table_list;
|
|
SPIDER_TABLE_LIST_db_str(table_list) = copy_tables->spider_db_name;
|
|
SPIDER_TABLE_LIST_db_length(table_list) = copy_tables->spider_db_name_length;
|
|
SPIDER_TABLE_LIST_alias_str(table_list) =
|
|
SPIDER_TABLE_LIST_table_name_str(table_list) =
|
|
copy_tables->spider_real_table_name;
|
|
SPIDER_TABLE_LIST_table_name_length(table_list) =
|
|
copy_tables->spider_real_table_name_length;
|
|
#ifdef SPIDER_use_LEX_CSTRING_for_database_tablename_alias
|
|
SPIDER_TABLE_LIST_alias_length(table_list) =
|
|
SPIDER_TABLE_LIST_table_name_length(table_list);
|
|
#endif
|
|
table_list->lock_type = TL_READ;
|
|
|
|
DBUG_PRINT("info",("spider db=%s", SPIDER_TABLE_LIST_db_str(table_list)));
|
|
DBUG_PRINT("info",("spider db_length=%zd", SPIDER_TABLE_LIST_db_length(table_list)));
|
|
DBUG_PRINT("info",("spider table_name=%s",
|
|
SPIDER_TABLE_LIST_table_name_str(table_list)));
|
|
DBUG_PRINT("info",("spider table_name_length=%zd",
|
|
SPIDER_TABLE_LIST_table_name_length(table_list)));
|
|
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,
|
|
SPIDER_TABLE_LIST_db_str(table_list),
|
|
SPIDER_TABLE_LIST_table_name_str(table_list),
|
|
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),
|
|
SPIDER_TABLE_LIST_db_str(table_list),
|
|
SPIDER_TABLE_LIST_table_name_str(table_list));
|
|
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),
|
|
SPIDER_TABLE_LIST_db_str(table_list),
|
|
SPIDER_TABLE_LIST_table_name_str(table_list));
|
|
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;
|
|
}
|