Commit e9f3ca61 authored by Yuchen Pei's avatar Yuchen Pei

MDEV-31117 Fix spider connection info parsing

Spider connection string is a comma-separated parameter definitions,
where each definition is of the form "<param_title> <param_value>",
where <param_value> is quote delimited on both ends, with backslashes
acting as an escaping prefix.

Despite the simple syntax, the existing spider connection string
parser was poorly-written, complex, hard to reason and error-prone,
causing issues like the one described in MDEV-31117. For example it
treated param title the same way as param value when assigning, and
have nonsensical fields like delim_title_len and delim_title.

Thus as part of the bugfix, we clean up the spider comment connection
string parsing, including:

- Factoring out some code from the parsing function
- Simplify the struct `st_spider_param_string_parse`
- And any necessary changes caused by the above changes
parent ff682ead
#
# MDEV-31117 Spider UBSAN runtime error: applying non-zero offset x to null pointer in st_spider_param_string_parse::restore_delims
#
for master_1
for child2
for child3
CREATE TABLE t (c INT) ENGINE=Spider COMMENT='abc';
ERROR HY000: The connect info 'abc' is invalid
ALTER TABLE mysql.help_topic ENGINE=Spider;
ERROR HY000: The connect info 'help topics' is invalid
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (c int);
create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", "srv" "srv",TABLE "t2"';
ERROR HY000: The connect info '"srv" "srv",TABLE "t2"' is invalid
create table t1 (c int) ENGINE=Spider CONNECTION='WRAPPER "mysql", srv \'srv\',TABLE "t2", password "say \\"hello\\ world!\\""';
drop table t1, t2;
for master_1
for child2
for child3
--echo #
--echo # MDEV-31117 Spider UBSAN runtime error: applying non-zero offset x to null pointer in st_spider_param_string_parse::restore_delims
--echo #
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
--error 12501
CREATE TABLE t (c INT) ENGINE=Spider COMMENT='abc';
--error 12501
ALTER TABLE mysql.help_topic ENGINE=Spider;
evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (c int);
# param title should not have delimiter
--error 12501
create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", "srv" "srv",TABLE "t2"';
# test escaping
create table t1 (c int) ENGINE=Spider CONNECTION='WRAPPER "mysql", srv \'srv\',TABLE "t2", password "say \\"hello\\ world!\\""';
drop table t1, t2;
--disable_query_log
--disable_result_log
--source ../t/test_deinit.inc
--enable_query_log
--enable_result_log
......@@ -75,146 +75,69 @@ int spider_udf_set_copy_tables_param_default(
#define SPIDER_PARAM_STR_LEN(name) name ## _length
#define SPIDER_PARAM_STR(title_name, param_name) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, 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))) \
if ((copy_tables->param_name = spider_create_string(parse.start_value, \
value_length))) \
copy_tables->SPIDER_PARAM_STR_LEN(param_name) = \
strlen(copy_tables->param_name); \
else { \
error_num = param_string_parse.print_param_error(); \
error_num= parse.fail(true); \
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)) \
if (!strncasecmp(parse.start_title, 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; \
} \
copy_tables->param_name = atoi(parse.start_value); \
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; \
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)) \
if (!strncasecmp(parse.start_title, 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; \
} \
copy_tables->param_name = atoi(parse.start_value); \
if (copy_tables->param_name < min_val) \
copy_tables->param_name = min_val; \
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)) \
if (!strncasecmp(parse.start_title, 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; \
} \
copy_tables->param_name = \
my_strtoll10(parse.start_value, (char**) NULL, &error_num); \
if (copy_tables->param_name < min_val) \
copy_tables->param_name = min_val; \
DBUG_PRINT("info",("spider " title_name "=%lld", \
copy_tables->param_name)); \
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");
static void spider_minus_1(SPIDER_COPY_TABLES *copy_tables)
{
copy_tables->bulk_insert_interval = -1;
copy_tables->bulk_insert_rows = -1;
copy_tables->use_table_charset = -1;
......@@ -222,57 +145,49 @@ int spider_udf_parse_copy_tables_param(
#ifndef WITHOUT_SPIDER_BG_SEARCH
copy_tables->bg_mode = -1;
#endif
}
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 *start_param;
int title_length, value_length;
SPIDER_PARAM_STRING_PARSE parse;
DBUG_ENTER("spider_udf_parse_copy_tables_param");
spider_minus_1(copy_tables);
if (param_length == 0)
goto set_default;
DBUG_PRINT("info",("spider create param_string string"));
if (
!(param_string = spider_create_string(
param,
param_length))
) {
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)
start_param = param_string;
parse.error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
while (*start_param != '\0')
{
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)))
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)
switch (title_length = (int) (parse.end_title - parse.start_title))
{
case 0:
error_num = param_string_parse.print_param_error();
if (error_num)
goto error;
continue;
error_num= parse.fail(true);
goto error;
case 3:
#ifndef WITHOUT_SPIDER_BG_SEARCH
SPIDER_PARAM_INT_WITH_MAX("bgm", bg_mode, 0, 1);
......@@ -282,55 +197,45 @@ int spider_udf_parse_copy_tables_param(
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();
error_num= parse.fail(true);
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();
error_num= parse.fail(true);
goto error;
#endif
case 8:
SPIDER_PARAM_STR("database", database);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 15:
SPIDER_PARAM_INT_WITH_MAX("use_transaction", use_transaction, 0, 1);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 16:
SPIDER_PARAM_LONGLONG("bulk_insert_rows", bulk_insert_rows, 1);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
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();
error_num= parse.fail(true);
goto error;
case 20:
SPIDER_PARAM_INT("bulk_insert_interval", bulk_insert_interval, 0);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
default:
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
}
/* Verify that the remainder of the parameter value is whitespace */
if ((error_num = param_string_parse.has_extra_parameter_values()))
goto error;
/* Restore delim */
*parse.end_value= parse.delim_value;
}
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_num = spider_udf_set_copy_tables_param_default(copy_tables);
error:
if (param_string)
spider_free(spider_current_trx, param_string, MYF(0));
......
......@@ -978,17 +978,16 @@ int spider_udf_direct_sql_get_server(
#define SPIDER_PARAM_STR_LEN(name) name ## _length
#define SPIDER_PARAM_STR(title_name, param_name) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (!direct_sql->param_name) \
{ \
if ((direct_sql->param_name = spider_get_string_between_quote( \
start_ptr, TRUE, &param_string_parse))) \
direct_sql->SPIDER_PARAM_STR_LEN(param_name) = \
strlen(direct_sql->param_name); \
if ((direct_sql->param_name = spider_create_string(parse.start_value, \
value_length))) \
direct_sql->SPIDER_PARAM_STR_LEN(param_name) = strlen(direct_sql->param_name); \
else { \
error_num = param_string_parse.print_param_error(); \
error_num= parse.fail(true); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%s", direct_sql->param_name)); \
......@@ -996,130 +995,81 @@ int spider_udf_direct_sql_get_server(
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)) \
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(tmp_ptr + check_length) - 1; \
int hint_num = atoi(parse.start_title + check_length) - 1; \
DBUG_PRINT("info",("spider hint_num=%d", hint_num)); \
DBUG_PRINT("info",("spider direct_sql->param_name=%p", \
direct_sql->param_name)); \
direct_sql->param_name)); \
if (direct_sql->param_name) \
{ \
if (hint_num < 0 || hint_num >= max_size) \
{ \
error_num = param_string_parse.print_param_error(); \
error_num= parse.fail(true); \
goto error; \
} else if (direct_sql->param_name[hint_num] != -1) \
break; \
char *hint_str = spider_get_string_between_quote(start_ptr, FALSE); \
if (hint_str) \
{ \
direct_sql->param_name[hint_num] = atoi(hint_str); \
if (direct_sql->param_name[hint_num] < min_val) \
direct_sql->param_name[hint_num] = min_val; \
else if (direct_sql->param_name[hint_num] > max_val) \
direct_sql->param_name[hint_num] = max_val; \
} else { \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
direct_sql->param_name[hint_num] = atoi(parse.start_value); \
if (direct_sql->param_name[hint_num] < min_val) \
direct_sql->param_name[hint_num] = min_val; \
else if (direct_sql->param_name[hint_num] > max_val) \
direct_sql->param_name[hint_num] = max_val; \
DBUG_PRINT("info",("spider " title_name "[%d]=%d", hint_num, \
direct_sql->param_name[hint_num])); \
direct_sql->param_name[hint_num])); \
} else { \
error_num = param_string_parse.print_param_error(); \
error_num= parse.fail(true); \
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)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (direct_sql->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
direct_sql->param_name = atoi(tmp_ptr2); \
if (direct_sql->param_name < min_val) \
direct_sql->param_name = min_val; \
else if (direct_sql->param_name > max_val) \
direct_sql->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; \
} \
direct_sql->param_name = atoi(parse.start_value); \
if (direct_sql->param_name < min_val) \
direct_sql->param_name = min_val; \
else if (direct_sql->param_name > max_val) \
direct_sql->param_name = max_val; \
DBUG_PRINT("info",("spider " title_name "=%d", \
(int) direct_sql->param_name)); \
(int) direct_sql->param_name)); \
} \
break; \
}
#define SPIDER_PARAM_INT(title_name, param_name, min_val) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (direct_sql->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
direct_sql->param_name = atoi(tmp_ptr2); \
if (direct_sql->param_name < min_val) \
direct_sql->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; \
} \
direct_sql->param_name = atoi(parse.start_value); \
if (direct_sql->param_name < min_val) \
direct_sql->param_name = min_val; \
DBUG_PRINT("info",("spider " title_name "=%d", direct_sql->param_name)); \
} \
break; \
}
#define SPIDER_PARAM_LONGLONG(title_name, param_name, min_val) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (direct_sql->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
direct_sql->param_name = \
my_strtoll10(tmp_ptr2, (char**) NULL, &error_num); \
if (direct_sql->param_name < min_val) \
direct_sql->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", \
direct_sql->param_name)); \
direct_sql->param_name = my_strtoll10(parse.start_value, (char**) NULL, \
&error_num); \
if (direct_sql->param_name < min_val) \
direct_sql->param_name = min_val; \
DBUG_PRINT("info",("spider " title_name "=%lld", direct_sql->param_name)); \
} \
break; \
}
int spider_udf_parse_direct_sql_param(
SPIDER_TRX *trx,
SPIDER_DIRECT_SQL *direct_sql,
const char *param,
int param_length
) {
int error_num = 0, roop_count;
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_direct_sql_param");
static void spider_minus_1(SPIDER_DIRECT_SQL *direct_sql)
{
direct_sql->tgt_port = -1;
direct_sql->tgt_ssl_vsc = -1;
direct_sql->table_loop_mode = -1;
......@@ -1137,59 +1087,53 @@ int spider_udf_parse_direct_sql_param(
direct_sql->use_real_table = -1;
#endif
direct_sql->error_rw_mode = -1;
for (roop_count = 0; roop_count < direct_sql->table_count; roop_count++)
direct_sql->iop[roop_count] = -1;
for (int i = 0; i < direct_sql->table_count; i++)
direct_sql->iop[i] = -1;
}
int spider_udf_parse_direct_sql_param(
SPIDER_TRX *trx,
SPIDER_DIRECT_SQL *direct_sql,
const char *param,
int param_length
) {
int error_num = 0;
char *param_string = NULL;
char *start_param;
int title_length, value_length;
SPIDER_PARAM_STRING_PARSE parse;
DBUG_ENTER("spider_udf_parse_direct_sql_param");
spider_minus_1(direct_sql);
if (param_length == 0)
goto set_default;
DBUG_PRINT("info",("spider create param_string string"));
if (
!(param_string = spider_create_string(
param,
param_length))
) {
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)
start_param = param_string;
parse.error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
while (*start_param != '\0')
{
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)))
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)
switch (title_length = (int) (parse.end_title - parse.start_title))
{
case 0:
error_num = param_string_parse.print_param_error();
if (error_num)
goto error;
continue;
error_num= parse.fail(true);
goto error;
case 3:
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
SPIDER_PARAM_INT_WITH_MAX("acm", access_mode, 0, 2);
......@@ -1214,112 +1158,97 @@ int spider_udf_parse_direct_sql_param(
SPIDER_PARAM_INT_WITH_MAX("urt", use_real_table, 0, 1);
#endif
SPIDER_PARAM_INT("wto", net_write_timeout, 0);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 4:
SPIDER_PARAM_INT_WITH_MAX("erwm", error_rw_mode, 0, 1);
SPIDER_PARAM_STR("host", tgt_host);
SPIDER_PARAM_INT_WITH_MAX("port", tgt_port, 0, 65535);
SPIDER_PARAM_STR("user", tgt_username);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 6:
SPIDER_PARAM_STR("server", server_name);
SPIDER_PARAM_STR("socket", tgt_socket);
SPIDER_PARAM_HINT_WITH_MAX("iop", iop, 3, direct_sql->table_count, 0, 2);
SPIDER_PARAM_STR("ssl_ca", tgt_ssl_ca);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 7:
SPIDER_PARAM_STR("wrapper", tgt_wrapper);
SPIDER_PARAM_STR("ssl_key", tgt_ssl_key);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 8:
SPIDER_PARAM_STR("database", tgt_default_db_name);
SPIDER_PARAM_STR("password", tgt_password);
SPIDER_PARAM_LONGLONG("priority", priority, 0);
SPIDER_PARAM_STR("ssl_cert", tgt_ssl_cert);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 10:
SPIDER_PARAM_STR("ssl_cipher", tgt_ssl_cipher);
SPIDER_PARAM_STR("ssl_capath", tgt_ssl_capath);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 11:
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
SPIDER_PARAM_INT_WITH_MAX("access_mode", access_mode, 0, 2);
#endif
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 12:
SPIDER_PARAM_STR("default_file", tgt_default_file);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 13:
SPIDER_PARAM_STR("default_group", tgt_default_group);
SPIDER_PARAM_INT_WITH_MAX("error_rw_mode", error_rw_mode, 0, 1);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 14:
#if MYSQL_VERSION_ID < 50500
#else
SPIDER_PARAM_INT_WITH_MAX("use_real_table", use_real_table, 0, 1);
#endif
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 15:
SPIDER_PARAM_INT_WITH_MAX("table_loop_mode", table_loop_mode, 0, 2);
SPIDER_PARAM_INT("connect_timeout", connect_timeout, 0);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 16:
SPIDER_PARAM_LONGLONG("bulk_insert_rows", bulk_insert_rows, 1);
SPIDER_PARAM_INT("net_read_timeout", net_read_timeout, 0);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 17:
SPIDER_PARAM_INT("net_write_timeout", net_write_timeout, 0);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 18:
SPIDER_PARAM_INT_WITH_MAX(
"connection_channel", connection_channel, 0, 63);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
case 22:
SPIDER_PARAM_INT_WITH_MAX("ssl_verify_server_cert", tgt_ssl_vsc, 0, 1);
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
default:
error_num = param_string_parse.print_param_error();
error_num= parse.fail(true);
goto error;
}
/* Verify that the remainder of the parameter value is whitespace */
if ((error_num = param_string_parse.has_extra_parameter_values()))
goto error;
/* Restore delim */
*parse.end_value= parse.delim_value;
}
set_default:
if ((error_num = spider_udf_set_direct_sql_param_default(
trx,
direct_sql
)))
goto error;
if (param_string)
{
spider_free(spider_current_trx, param_string, MYF(0));
}
DBUG_RETURN(0);
error_num = spider_udf_set_direct_sql_param_default(trx, direct_sql);
error:
if (param_string)
{
spider_free(spider_current_trx, param_string, MYF(0));
}
error_alloc_param_string:
DBUG_RETURN(error_num);
}
......
......@@ -1046,123 +1046,12 @@ void spider_free_tmp_share_alloc(
DBUG_VOID_RETURN;
}
char *spider_get_string_between_quote(
char *ptr,
bool alloc,
SPIDER_PARAM_STRING_PARSE *param_string_parse
) {
char *start_ptr, *end_ptr, *tmp_ptr, *esc_ptr;
bool find_flg = FALSE, esc_flg = FALSE;
DBUG_ENTER("spider_get_string_between_quote");
start_ptr = strchr(ptr, '\'');
end_ptr = strchr(ptr, '"');
if (start_ptr && (!end_ptr || start_ptr < end_ptr))
{
tmp_ptr = ++start_ptr;
while (!find_flg)
{
if (!(end_ptr = strchr(tmp_ptr, '\'')))
DBUG_RETURN(NULL);
esc_ptr = tmp_ptr;
while (!find_flg)
{
esc_ptr = strchr(esc_ptr, '\\');
if (!esc_ptr || esc_ptr > end_ptr)
find_flg = TRUE;
else if (esc_ptr == end_ptr - 1)
{
esc_flg = TRUE;
tmp_ptr = end_ptr + 1;
break;
} else {
esc_flg = TRUE;
esc_ptr += 2;
}
}
}
} else if (end_ptr)
{
start_ptr = end_ptr;
tmp_ptr = ++start_ptr;
while (!find_flg)
{
if (!(end_ptr = strchr(tmp_ptr, '"')))
DBUG_RETURN(NULL);
esc_ptr = tmp_ptr;
while (!find_flg)
{
esc_ptr = strchr(esc_ptr, '\\');
if (!esc_ptr || esc_ptr > end_ptr)
find_flg = TRUE;
else if (esc_ptr == end_ptr - 1)
{
esc_flg = TRUE;
tmp_ptr = end_ptr + 1;
break;
} else {
esc_flg = TRUE;
esc_ptr += 2;
}
}
}
} else
DBUG_RETURN(NULL);
*end_ptr = '\0';
if (esc_flg)
{
esc_ptr = start_ptr;
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++;
strcpy(esc_ptr, esc_ptr + 1);
}
}
if (param_string_parse)
param_string_parse->set_param_value(start_ptr, start_ptr + strlen(start_ptr) + 1);
if (alloc)
{
DBUG_RETURN(
spider_create_string(
start_ptr,
strlen(start_ptr))
);
} else {
DBUG_RETURN(start_ptr);
}
}
int spider_create_string_list(
char ***string_list,
uint **string_length_list,
uint *list_length,
char *str,
uint length,
SPIDER_PARAM_STRING_PARSE *param_string_parse
uint length
) {
int roop_count;
char *tmp_ptr, *tmp_ptr2, *tmp_ptr3, *esc_ptr;
......@@ -1170,7 +1059,6 @@ int spider_create_string_list(
DBUG_ENTER("spider_create_string_list");
*list_length = 0;
param_string_parse->init_param_value();
if (!str)
{
*string_list = NULL;
......@@ -1282,9 +1170,6 @@ int spider_create_string_list(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
param_string_parse->set_param_value(tmp_ptr3,
tmp_ptr3 + strlen(tmp_ptr3) + 1);
DBUG_PRINT("info",("spider string_list[%d]=%s", roop_count,
(*string_list)[roop_count]));
......@@ -1297,15 +1182,13 @@ int spider_create_long_list(
char *str,
uint length,
long min_val,
long max_val,
SPIDER_PARAM_STRING_PARSE *param_string_parse
long max_val
) {
int roop_count;
char *tmp_ptr;
DBUG_ENTER("spider_create_long_list");
*list_length = 0;
param_string_parse->init_param_value();
if (!str)
{
*long_list = NULL;
......@@ -1361,9 +1244,6 @@ int spider_create_long_list(
(*long_list)[roop_count] = max_val;
}
param_string_parse->set_param_value(tmp_ptr,
tmp_ptr + strlen(tmp_ptr) + 1);
#ifndef DBUG_OFF
for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
{
......@@ -1381,15 +1261,13 @@ int spider_create_longlong_list(
char *str,
uint length,
longlong min_val,
longlong max_val,
SPIDER_PARAM_STRING_PARSE *param_string_parse
longlong max_val
) {
int error_num, roop_count;
char *tmp_ptr;
DBUG_ENTER("spider_create_longlong_list");
*list_length = 0;
param_string_parse->init_param_value();
if (!str)
{
*longlong_list = NULL;
......@@ -1446,9 +1324,6 @@ int spider_create_longlong_list(
(*longlong_list)[roop_count] = max_val;
}
param_string_parse->set_param_value(tmp_ptr,
tmp_ptr + strlen(tmp_ptr) + 1);
#ifndef DBUG_OFF
for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
{
......@@ -1688,50 +1563,18 @@ static int spider_set_ll_value(
DBUG_RETURN(error_num);
}
/**
Print a parameter string error message.
@return Error code.
*/
int st_spider_param_string_parse::print_param_error()
{
if (start_title_ptr)
{
/* Restore the input delimiter characters */
restore_delims();
/* 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_ptr);
break;
case ER_SPIDER_INVALID_CONNECT_INFO_NUM:
default:
my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
MYF(0), start_title_ptr);
}
return error_num;
}
else
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)) \
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_get_string_between_quote( \
start_ptr, TRUE, &connect_string_parse))) \
if ((share->param_name = spider_create_string(parse.start_value, \
value_length))) \
share->SPIDER_PARAM_STR_LEN(param_name) = strlen(share->param_name); \
else { \
error_num = connect_string_parse.print_param_error(); \
error_num= parse.fail(true); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%s", share->param_name)); \
......@@ -1741,272 +1584,171 @@ int st_spider_param_string_parse::print_param_error()
#define SPIDER_PARAM_STR_LENS(name) name ## _lengths
#define SPIDER_PARAM_STR_CHARLEN(name) name ## _charlen
#define SPIDER_PARAM_STR_LIST(title_name, param_name) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
DBUG_PRINT("info", ("spider " title_name " start")); \
if (!share->param_name) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
share->SPIDER_PARAM_STR_CHARLEN(param_name) = strlen(tmp_ptr2); \
if ((error_num = spider_create_string_list( \
&share->param_name, \
&share->SPIDER_PARAM_STR_LENS(param_name), \
&share->SPIDER_PARAM_STR_LEN(param_name), \
tmp_ptr2, \
share->SPIDER_PARAM_STR_CHARLEN(param_name), \
&connect_string_parse))) \
goto error; \
} else { \
error_num = connect_string_parse.print_param_error(); \
share->SPIDER_PARAM_STR_CHARLEN(param_name)= value_length; \
if ((error_num= spider_create_string_list( \
&share->param_name, \
&share->SPIDER_PARAM_STR_LENS(param_name), \
&share->SPIDER_PARAM_STR_LEN(param_name), \
parse.start_value, \
share->SPIDER_PARAM_STR_CHARLEN(param_name)))) \
goto error; \
} \
} \
break; \
}
#define SPIDER_PARAM_HINT(title_name, param_name, check_length, max_size, append_method) \
if (!strncasecmp(tmp_ptr, title_name, check_length)) \
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(tmp_ptr + check_length); \
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)); \
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 = connect_string_parse.print_param_error(); \
error_num= parse.fail(true); \
goto error; \
} else if (share->param_name[hint_num].length() > 0) \
break; \
char *hint_str = spider_get_string_between_quote(start_ptr, FALSE); \
if ((error_num = \
append_method(&share->param_name[hint_num], hint_str))) \
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())); \
share->param_name[hint_num].ptr())); \
} else { \
error_num = connect_string_parse.print_param_error(); \
error_num= parse.fail(true); \
goto error; \
} \
break; \
}
#define SPIDER_PARAM_NUMHINT(title_name, param_name, check_length, max_size, append_method) \
if (!strncasecmp(tmp_ptr, title_name, check_length)) \
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(tmp_ptr + check_length); \
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 = connect_string_parse.print_param_error(); \
error_num= parse.fail(true); \
goto error; \
} else if (share->param_name[hint_num] != -1) \
break; \
char *hint_str = spider_get_string_between_quote(start_ptr, FALSE); \
if ((error_num = \
append_method(&share->param_name[hint_num], hint_str))) \
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])); \
share->param_name[hint_num])); \
} else { \
error_num = connect_string_parse.print_param_error(); \
error_num= parse.fail(true); \
goto error; \
} \
break; \
}
#define SPIDER_PARAM_LONG_LEN(name) name ## _length
#define SPIDER_PARAM_LONG_LIST_WITH_MAX(title_name, param_name, \
min_val, max_val) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
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 ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
if ((error_num = spider_create_long_list( \
&share->param_name, \
&share->SPIDER_PARAM_LONG_LEN(param_name), \
tmp_ptr2, \
strlen(tmp_ptr2), \
min_val, max_val, \
&connect_string_parse))) \
goto error; \
} else { \
error_num = connect_string_parse.print_param_error(); \
if ((error_num = spider_create_long_list( \
&share->param_name, \
&share->SPIDER_PARAM_LONG_LEN(param_name), \
parse.start_value, \
value_length, \
min_val, max_val))) \
goto error; \
} \
} \
break; \
}
#define SPIDER_PARAM_LONGLONG_LEN(name) name ## _length
#define SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(title_name, param_name, \
min_val, max_val) \
if (!strncasecmp(tmp_ptr, title_name, title_length)) \
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 ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
if ((error_num = spider_create_longlong_list( \
&share->param_name, \
&share->SPIDER_PARAM_LONGLONG_LEN(param_name), \
tmp_ptr2, \
strlen(tmp_ptr2), \
min_val, max_val, \
&connect_string_parse))) \
goto error; \
} else { \
error_num = connect_string_parse.print_param_error(); \
if ((error_num = spider_create_longlong_list( \
&share->param_name, \
&share->SPIDER_PARAM_LONGLONG_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(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (share->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
share->param_name = atoi(tmp_ptr2); \
if (share->param_name < min_val) \
share->param_name = min_val; \
else if (share->param_name > max_val) \
share->param_name = max_val; \
connect_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = connect_string_parse.print_param_error(); \
goto error; \
} \
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(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (share->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
share->param_name = atoi(tmp_ptr2); \
if (share->param_name < min_val) \
share->param_name = min_val; \
connect_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = connect_string_parse.print_param_error(); \
goto error; \
} \
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(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (share->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
share->param_name = my_atof(tmp_ptr2); \
if (share->param_name < min_val) \
share->param_name = min_val; \
connect_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = connect_string_parse.print_param_error(); \
goto error; \
} \
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(tmp_ptr, title_name, title_length)) \
if (!strncasecmp(parse.start_title, title_name, title_length)) \
{ \
DBUG_PRINT("info",("spider " title_name " start")); \
if (share->param_name == -1) \
{ \
if ((tmp_ptr2 = spider_get_string_between_quote( \
start_ptr, FALSE))) \
{ \
share->param_name = my_strtoll10(tmp_ptr2, (char**) NULL, &error_num); \
if (share->param_name < min_val) \
share->param_name = min_val; \
connect_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = connect_string_parse.print_param_error(); \
goto error; \
} \
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; \
}
int spider_parse_connect_info(
SPIDER_SHARE *share,
TABLE_SHARE *table_share,
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *part_info,
#endif
uint create_table
) {
int error_num = 0;
char *connect_string = NULL;
char *sprit_ptr;
char *tmp_ptr, *tmp_ptr2, *start_ptr;
int roop_count;
int title_length;
SPIDER_PARAM_STRING_PARSE connect_string_parse;
SPIDER_ALTER_TABLE *share_alter;
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_element *part_elem;
partition_element *sub_elem;
#endif
DBUG_ENTER("spider_parse_connect_info");
#ifdef WITH_PARTITION_STORAGE_ENGINE
#if MYSQL_VERSION_ID < 50500
DBUG_PRINT("info",("spider partition_info=%s", table_share->partition_info));
#else
DBUG_PRINT("info",("spider partition_info=%s",
table_share->partition_info_str));
#endif
DBUG_PRINT("info",("spider part_info=%p", part_info));
#endif
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));
#ifdef WITH_PARTITION_STORAGE_ENGINE
spider_get_partition_info(share->table_name, share->table_name_length,
table_share, part_info, &part_elem, &sub_elem);
#endif
static void spider_minus_1(SPIDER_SHARE *share, TABLE_SHARE *table_share)
{
#ifndef WITHOUT_SPIDER_BG_SEARCH
share->sts_bg_mode = -1;
#endif
......@@ -2092,13 +1834,275 @@ int spider_parse_connect_info(
share->delete_all_rows_type = -1;
share->static_records_for_status = -1;
share->static_mean_rec_length = -1;
for (roop_count = 0; roop_count < (int) table_share->keys; roop_count++)
for (uint i = 0; i < table_share->keys; i++)
{
share->static_key_cardinality[roop_count] = -1;
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)
{
#ifdef WITH_PARTITION_STORAGE_ENGINE
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;
#endif
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.
TODO: Deprecate the connection specification by COMMENT and CONNECT,
and then solely utilize 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;
partition_element *part_elem;
partition_element *sub_elem;
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));
spider_get_partition_info(share->table_name, share->table_name_length,
table_share, part_info, &part_elem, &sub_elem);
spider_minus_1(share, table_share);
#ifdef WITH_PARTITION_STORAGE_ENGINE
for (roop_count = 4; roop_count > 0; roop_count--)
for (int i = 4; i > 0; i--)
#else
for (roop_count = 2; roop_count > 0; roop_count--)
#endif
......@@ -2108,104 +2112,35 @@ int spider_parse_connect_info(
spider_free(spider_current_trx, connect_string, MYF(0));
connect_string = NULL;
}
switch (roop_count)
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)
{
#ifdef WITH_PARTITION_STORAGE_ENGINE
case 4:
if (!sub_elem || !sub_elem->part_comment)
continue;
DBUG_PRINT("info",("spider create sub comment string"));
if (
!(connect_string = spider_create_string(
sub_elem->part_comment,
strlen(sub_elem->part_comment)))
) {
error_num = HA_ERR_OUT_OF_MEM;
goto error_alloc_conn_string;
}
DBUG_PRINT("info",("spider sub comment string=%s", connect_string));
break;
case 3:
if (!part_elem || !part_elem->part_comment)
continue;
DBUG_PRINT("info",("spider create part comment string"));
if (
!(connect_string = spider_create_string(
part_elem->part_comment,
strlen(part_elem->part_comment)))
) {
error_num = HA_ERR_OUT_OF_MEM;
goto error_alloc_conn_string;
}
DBUG_PRINT("info",("spider part comment string=%s", connect_string));
break;
#endif
case 2:
if (table_share->comment.length == 0)
continue;
DBUG_PRINT("info",("spider create comment string"));
if (
!(connect_string = spider_create_string(
table_share->comment.str,
table_share->comment.length))
) {
error_num = HA_ERR_OUT_OF_MEM;
goto error_alloc_conn_string;
}
DBUG_PRINT("info",("spider comment string=%s", connect_string));
break;
default:
if (table_share->connect_string.length == 0)
continue;
DBUG_PRINT("info",("spider create connect_string string"));
if (
!(connect_string = spider_create_string(
table_share->connect_string.str,
table_share->connect_string.length))
) {
error_num = HA_ERR_OUT_OF_MEM;
goto error_alloc_conn_string;
}
DBUG_PRINT("info",("spider connect_string=%s", connect_string));
break;
error_num= HA_ERR_OUT_OF_MEM;
goto error_alloc_conn_string;
}
DBUG_ASSERT(error_num_1 == 0);
sprit_ptr = connect_string;
connect_string_parse.init(connect_string, ER_SPIDER_INVALID_CONNECT_INFO_NUM);
while (sprit_ptr)
start_param = connect_string;
parse.error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
while (*start_param != '\0')
{
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++;
}
connect_string_parse.set_param_title(tmp_ptr, tmp_ptr + title_length);
if ((error_num = connect_string_parse.get_next_parameter_head(
start_ptr, &sprit_ptr)))
if (parse.locate_param_def(start_param))
{
error_num= parse.fail(false);
goto error;
}
switch (title_length)
/* 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 = connect_string_parse.print_param_error();
if (error_num)
goto error;
continue;
error_num= parse.fail(true);
goto error;
case 3:
SPIDER_PARAM_LONG_LIST_WITH_MAX("abl", access_balances, 0,
2147483647);
......@@ -2345,17 +2280,17 @@ int spider_parse_connect_info(
#endif
SPIDER_PARAM_INT_WITH_MAX("upu", use_pushdown_udf, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("utc", use_table_charset, 0, 1);
error_num = connect_string_parse.print_param_error();
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 = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 5:
SPIDER_PARAM_STR_LIST("table", tgt_table_names);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 6:
SPIDER_PARAM_STR_LIST("server", server_names);
......@@ -2365,13 +2300,13 @@ int spider_parse_connect_info(
SPIDER_PARAM_STR_LIST("ssl_ca", tgt_ssl_cas);
SPIDER_PARAM_NUMHINT("skc", static_key_cardinality, 3,
(int) table_share->keys, spider_set_ll_value);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 7:
SPIDER_PARAM_STR_LIST("wrapper", tgt_wrappers);
SPIDER_PARAM_STR_LIST("ssl_key", tgt_ssl_keys);
SPIDER_PARAM_STR_LIST("pk_name", tgt_pk_names);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 8:
SPIDER_PARAM_STR_LIST("database", tgt_dbs);
......@@ -2391,14 +2326,14 @@ int spider_parse_connect_info(
#endif
SPIDER_PARAM_STR_LIST("ssl_cert", tgt_ssl_certs);
SPIDER_PARAM_INT_WITH_MAX("bka_mode", bka_mode, 0, 2);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 9:
SPIDER_PARAM_INT("max_order", max_order, 0);
SPIDER_PARAM_INT("bulk_size", bulk_size, 0);
SPIDER_PARAM_DOUBLE("scan_rate", scan_rate, 0);
SPIDER_PARAM_DOUBLE("read_rate", read_rate, 0);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 10:
SPIDER_PARAM_DOUBLE("crd_weight", crd_weight, 1);
......@@ -2408,7 +2343,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_STR_LIST("ssl_capath", tgt_ssl_capaths);
SPIDER_PARAM_STR("bka_engine", bka_engine);
SPIDER_PARAM_LONGLONG("first_read", first_read, 0);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 11:
SPIDER_PARAM_INT_WITH_MAX("query_cache", query_cache, 0, 2);
......@@ -2422,7 +2357,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_LONG_LIST_WITH_MAX("use_hs_read", use_hs_reads, 0, 1);
#endif
SPIDER_PARAM_INT_WITH_MAX("casual_read", casual_read, 0, 63);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 12:
SPIDER_PARAM_DOUBLE("sts_interval", sts_interval, 0);
......@@ -2435,7 +2370,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_LONG_LIST_WITH_MAX(
"hs_read_port", hs_read_ports, 0, 65535);
#endif
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 13:
SPIDER_PARAM_STR_LIST("default_group", tgt_default_groups);
......@@ -2444,7 +2379,7 @@ int spider_parse_connect_info(
"hs_write_port", hs_write_ports, 0, 65535);
#endif
SPIDER_PARAM_STR_LIST("sequence_name", tgt_sequence_names);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 14:
SPIDER_PARAM_LONGLONG("internal_limit", internal_limit, 0);
......@@ -2461,7 +2396,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_STR_LIST("static_link_id", static_link_ids);
SPIDER_PARAM_INT_WITH_MAX("store_last_crd", store_last_crd, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("store_last_sts", store_last_sts, 0, 1);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 15:
SPIDER_PARAM_LONGLONG("internal_offset", internal_offset, 0);
......@@ -2482,7 +2417,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_LONG_LIST_WITH_MAX("connect_timeout", connect_timeouts,
0, 2147483647);
SPIDER_PARAM_INT_WITH_MAX("error_read_mode", error_read_mode, 0, 1);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 16:
SPIDER_PARAM_INT_WITH_MAX(
......@@ -2512,7 +2447,7 @@ int spider_parse_connect_info(
#endif
SPIDER_PARAM_INT_WITH_MAX(
"query_cache_sync", query_cache_sync, 0, 3);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 17:
SPIDER_PARAM_INT_WITH_MAX(
......@@ -2532,7 +2467,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX(
"force_bulk_update", force_bulk_update, 0, 1);
#endif
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 18:
SPIDER_PARAM_INT_WITH_MAX(
......@@ -2545,7 +2480,7 @@ int spider_parse_connect_info(
#endif
SPIDER_PARAM_LONGLONG(
"direct_order_limit", direct_order_limit, 0);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 19:
SPIDER_PARAM_INT("init_sql_alloc_size", init_sql_alloc_size, 0);
......@@ -2560,7 +2495,7 @@ int spider_parse_connect_info(
"load_crd_at_startup", load_crd_at_startup, 0, 1);
SPIDER_PARAM_INT_WITH_MAX(
"load_sts_at_startup", load_sts_at_startup, 0, 1);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 20:
SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
......@@ -2569,12 +2504,12 @@ int spider_parse_connect_info(
"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 = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 21:
SPIDER_PARAM_LONGLONG(
"semi_split_read_limit", semi_split_read_limit, 0);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 22:
SPIDER_PARAM_LONG_LIST_WITH_MAX(
......@@ -2587,38 +2522,36 @@ int spider_parse_connect_info(
"skip_default_condition", skip_default_condition, 0, 1);
SPIDER_PARAM_LONGLONG(
"static_mean_rec_length", static_mean_rec_length, 0);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 23:
SPIDER_PARAM_INT_WITH_MAX(
"internal_optimize_local", internal_optimize_local, 0, 1);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 25:
SPIDER_PARAM_LONGLONG("static_records_for_status",
static_records_for_status, 0);
SPIDER_PARAM_NUMHINT("static_key_cardinality", static_key_cardinality,
3, (int) table_share->keys, spider_set_ll_value);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 26:
SPIDER_PARAM_INT_WITH_MAX(
"semi_table_lock_connection", semi_table_lock_conn, 0, 1);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
case 32:
SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_binlog_pos_at_failing",
monitoring_binlog_pos_at_failing, 0, 2);
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
default:
error_num = connect_string_parse.print_param_error();
error_num = parse.fail(true);
goto error;
}
/* Verify that the remainder of the parameter value is whitespace */
if ((error_num = connect_string_parse.has_extra_parameter_values()))
goto error;
/* Restore delim */
*parse.end_value= parse.delim_value;
}
}
......@@ -3199,8 +3132,8 @@ int spider_parse_connect_info(
if (create_table)
{
for (roop_count = 0; roop_count < (int) share->all_link_count;
roop_count++)
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++)
......
......@@ -30,281 +30,21 @@
typedef struct st_spider_param_string_parse
{
char *start_ptr; /* Pointer to the start of the parameter string */
char *end_ptr; /* Pointer to the end of the parameter string */
char *start_title_ptr; /* Pointer to the start of the current parameter
title */
char *end_title_ptr; /* Pointer to the end of the current parameter
title */
char *start_value_ptr; /* Pointer to the start of the current parameter
value */
char *end_value_ptr; /* Pointer to the end of the current parameter
value */
int error_num; /* Error code of the error message to print when
an error is detected */
uint delim_title_len; /* Length of the paramater title's delimiter */
uint delim_value_len; /* Length of the paramater value's delimiter */
char delim_title; /* Current parameter title's delimiter character */
char delim_value; /* Current parameter value's delimiter character */
/**
Initialize the parameter string parse information.
@param param_string Pointer to the parameter string being parsed.
@param error_code Error code of the error message to print when
an error is detected.
*/
inline void init(char *param_string, int error_code)
{
start_ptr = param_string;
end_ptr = start_ptr + strlen(start_ptr);
init_param_title();
init_param_value();
error_num = error_code;
}
/**
Initialize the current parameter title.
*/
inline void init_param_title()
{
start_title_ptr = end_title_ptr = NULL;
delim_title_len = 0;
delim_title = '\0';
}
/**
Save pointers to the start and end positions of the current parameter
title in the parameter string. Also save the parameter title's
delimiter character.
@param start_value Pointer to the start position of the current
parameter title.
@param end_value Pointer to the end position of the current
parameter title.
*/
inline void set_param_title(char *start_title, char *end_title)
{
start_title_ptr = start_title;
end_title_ptr = end_title;
if (*start_title == '"' ||
*start_title == '\'')
{
delim_title = *start_title;
if (start_title >= start_ptr && *--start_title == '\\')
delim_title_len = 2;
else
delim_title_len = 1;
}
}
/**
Initialize the current parameter value.
*/
inline void init_param_value()
{
start_value_ptr = end_value_ptr = NULL;
delim_value_len = 0;
delim_value = '\0';
}
/**
Save pointers to the start and end positions of the current parameter
value in the parameter string. Also save the parameter value's
delimiter character.
@param start_value Pointer to the start position of the current
parameter value.
@param end_value Pointer to the end position of the current
parameter value.
*/
inline void set_param_value(char *start_value, char *end_value)
{
start_value_ptr = start_value--;
end_value_ptr = end_value;
if (*start_value == '"' ||
*start_value == '\'')
{
delim_value = *start_value;
if (*--start_value == '\\')
delim_value_len = 2;
else
delim_value_len = 1;
}
}
/**
Determine whether the current parameter in the parameter string has
extra parameter values.
@return 0 Current parameter value in the parameter string
does not have extra parameter values.
<> 0 Error code indicating that the current parameter
value in the parameter string has extra
parameter values.
*/
inline int has_extra_parameter_values()
{
int error_num = 0;
DBUG_ENTER("has_extra_parameter_values");
if (end_value_ptr)
{
/* There is a current parameter value */
char *end_param_ptr = end_value_ptr;
while (end_param_ptr < end_ptr &&
(*end_param_ptr == ' ' || *end_param_ptr == '\r' ||
*end_param_ptr == '\n' || *end_param_ptr == '\t'))
end_param_ptr++;
if (end_param_ptr < end_ptr && *end_param_ptr != '\0')
{
/* Extra values in parameter definition */
error_num = print_param_error();
}
}
DBUG_RETURN(error_num);
}
inline int get_next_parameter_head(char *st, char **nx)
{
DBUG_ENTER("get_next_parameter_head");
char *sq = strchr(st, '\'');
char *dq = strchr(st, '"');
if (!sq && !dq)
{
DBUG_RETURN(print_param_error());
}
if (dq && (!sq || sq > dq))
{
while (1)
{
++dq;
if (*dq == '\\')
{
++dq;
}
else if (*dq == '"')
{
break;
}
else if (*dq == '\0')
{
DBUG_RETURN(print_param_error());
}
}
while (1)
{
++dq;
if (*dq == '\0')
{
*nx = dq;
break;
}
else if (*dq == ',')
{
*dq = '\0';
*nx = dq + 1;
break;
}
else if (*dq != ' ' && *dq != '\r' && *dq != '\n' && *dq != '\t')
{
DBUG_RETURN(print_param_error());
}
}
}
else /* sq && (!dq || sq <= dq) */
{
while (1)
{
++sq;
if (*sq == '\\')
{
++sq;
}
else if (*sq == '\'')
{
break;
}
else if (*sq == '\0')
{
DBUG_RETURN(print_param_error());
}
}
while (1)
{
++sq;
if (*sq == '\0')
{
*nx = sq;
break;
}
else if (*sq == ',')
{
*sq = '\0';
*nx = sq + 1;
break;
}
else if (*sq != ' ' && *sq != '\r' && *sq != '\n' && *sq != '\t')
{
DBUG_RETURN(print_param_error());
}
}
}
DBUG_RETURN(0);
}
/**
Restore the current parameter's input delimiter characters in the
parameter string. They were NULLed during parameter parsing.
*/
inline void restore_delims()
{
char *end = end_title_ptr - 1;
switch (delim_title_len)
{
case 2:
*end++ = '\\';
/* Fall through */
case 1:
*end = delim_title;
}
end = end_value_ptr - 1;
switch (delim_value_len)
{
case 2:
*end++ = '\\';
/* Fall through */
case 1:
*end = delim_value;
}
}
/**
Print a parameter string error message.
@return Error code.
*/
int print_param_error();
char *start_title; /* Pointer to the start of the current parameter
title */
char *end_title; /* Pointer to the end of the current
parameter value */
char *start_value; /* Pointer to the start of the current parameter
value */
char *end_value; /* Pointer to the end of the current parameter
value */
char delim_value; /* Current parameter value's delimiter
character, either a single or a double quote */
int error_num; /* Error code of the error message to print when
an error is detected */
int fail(bool restore_delim);
bool locate_param_def(char*& start_param);
} SPIDER_PARAM_STRING_PARSE;
uchar *spider_tbl_get_key(
......@@ -352,19 +92,12 @@ void spider_free_tmp_share_alloc(
SPIDER_SHARE *share
);
char *spider_get_string_between_quote(
char *ptr,
bool alloc,
SPIDER_PARAM_STRING_PARSE *param_string_parse = NULL
);
int spider_create_string_list(
char ***string_list,
uint **string_length_list,
uint *list_length,
char *str,
uint length,
SPIDER_PARAM_STRING_PARSE *param_string_parse
uint length
);
int spider_create_long_list(
......@@ -373,8 +106,7 @@ int spider_create_long_list(
char *str,
uint length,
long min_val,
long max_val,
SPIDER_PARAM_STRING_PARSE *param_string_parse
long max_val
);
int spider_create_longlong_list(
......@@ -383,8 +115,7 @@ int spider_create_longlong_list(
char *str,
uint length,
longlong min_val,
longlong max_val,
SPIDER_PARAM_STRING_PARSE *param_string_parse
longlong max_val
);
int spider_increase_string_list(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment